2016-12-15 2 views
0

Я пытаюсь настроить транскодирующий конвейер с помощью ffmpeg C lib, но если я его перенесу, видео будет повреждено, как показано ниже.FFMpeg C Lib - Transpose вызывает поврежденное изображение

Если я не транспонирую, видео в порядке, то есть остальная часть конвейера будет правильно настроена.

Мне нужно преобразовать 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'" повторится тот же вопрос, что и раньше. Кажется, что это связано с изменением резолюции.

Я думаю, что коррупция может прийти из копии Thats, сделанные после того, как (для совместимости с чем-то другим, я использую):

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

На самом деле это был совершенно не связан вопрос, этот код работает!

Смежные вопросы