2016-12-15 54 views
0

我正在尝试使用ffmpeg C库设置代码转换管道,但是如果将其转置,则视频已损坏,如下所示。FFMpeg C Lib - 转置导致损坏的图像

如果我不转置,视频是好的,即管道的其余部分正确设置。

我需要将AVFrame转换为另一种数据类型以与其他软件一起使用。我相信腐败发生在副本上,但我不知道为什么。可能与旋转YUV420P像素有关?

video is rotated but corrupted

构造函数(代码被送往from here

MyFilter::MyFilter(const std::string filter_desc, AVCodecContext *data_ctx){ 
    avfilter_register_all(); 
    buffersrc_ctx = NULL; 
    buffersink_ctx = NULL; 

    filter_graph = avfilter_graph_alloc(); 

    AVFilter *buffersink = avfilter_get_by_name("buffersink"); 
    if (!buffersink) { 
    throw error("filtering sink element not found\n"); 
    } 

    if (avfilter_graph_create_filter(&buffersink_ctx, buffersink, "out", NULL, NULL, filter_graph) < 0) { 
    throw error("Cannot create buffer sink\n"); 
    } 


filterInputs = avfilter_inout_alloc(); 
    filterInputs->name  = av_strdup("out"); 
    filterInputs->filter_ctx = buffersink_ctx; 
    filterInputs->pad_idx = 0; 
    filterInputs->next  = NULL; 

    AVFilter *buffersrc = avfilter_get_by_name("buffer"); 
    if (!buffersrc) { 
     throw error("filtering source element not found\n"); 
    } 

    char args[512]; 
    snprintf(args, sizeof(args), "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d", 
        data_ctx->width, data_ctx->height, data_ctx->pix_fmt, 
        data_ctx->time_base.num, data_ctx->time_base.den, 
        data_ctx->sample_aspect_ratio.num, data_ctx->sample_aspect_ratio.den); 

    log(Info, "Setting filter input with %s", args); 


    if (avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in", args, NULL, filter_graph) < 0) { 
     throw error("Cannot create buffer source\n"); 
    } 

    filterOutputs = avfilter_inout_alloc(); 
    filterOutputs->name  = av_strdup("in"); 
    filterOutputs->filter_ctx = buffersrc_ctx; 
    filterOutputs->pad_idx = 0; 
    filterOutputs->next  = NULL; 

    if ((avfilter_graph_parse(filter_graph, filter_desc.c_str(), filterInputs, filterOutputs, NULL)) < 0) 
      log(Warning,"Could not parse input filters"); 

    if ((avfilter_graph_config(filter_graph, NULL)) < 0) 
     log(Warning,"Could not configure filter graph"); 

} 

,过程

AVFrame * MyFilter::process(AVFrame *inFrame){ 

    if (av_buffersrc_add_frame_flags(buffersrc_ctx, inFrame->get(), AV_BUFFERSRC_FLAG_PUSH | AV_BUFFERSRC_FLAG_KEEP_REF) < 0) { 
     throw error("Error while feeding the filtergraph\n"); 
    } 

    int i = 0; 
    AVFrame* outFrame = av_frame_alloc(); 
    if(av_buffersink_get_frame(buffersink_ctx, outFrame) < 0){ 
    throw error("Couldnt find a frame\n"); 
    } 
    return outFrame; 
} 

而且我使用的过滤器是:

std::string filter_desc = "transpose=cclock" 

作为一个额外的注意事项,它似乎像顶部栏(在上面的屏幕截图中可见)实际上是由正确旋转的像素组成的,并且这适用于整个视频。只剩下99%的像素。

使用此作品: std::string filter_desc = "rotate=PI/2",但分辨率未正确移位。如果我尝试 std::string filter_desc = "rotate='PI/2:ow=ih:oh=iw'" 与以前相同的问题开始再次出现。这似乎与决议的变化有关。

我认为腐败可能来自后制作的拷贝这就是(与别的兼容性我使用):

void copyToPicture(AVFrame const* avFrame, DataPicture* pic) { 
    for (size_t comp=0; comp<pic->getNumPlanes(); ++comp) { 
     auto const subsampling = comp == 0 ? 1 : 2; 
     auto const bytePerPixel = pic->getFormat().format == YUYV422 ? 2 : 1; 
     // std::cout<<"Pixel format is "<<pic->getFormat().format<<std::endl; 
     auto src = avFrame->data[comp]; 
     auto const srcPitch = avFrame->linesize[comp]; 

     auto dst = pic->getPlane(comp); 
     auto const dstPitch = pic->getPitch(comp); 

     auto const w = avFrame->width * bytePerPixel/subsampling; 
     auto const h = avFrame->height/subsampling; 

     for (int y=0; y<h; ++y) { 
      memcpy(dst, src, w); 
      src += srcPitch; 
      dst += dstPitch; 
     } 
    } 
} 

回答

0

其实这是一个完全不相关的问题,此代码的工作!