2016-12-15 8 views
0

ffmpeg C libでトランスコードパイプラインを設定しようとしていますが、転記した場合、ビデオは以下のように破損します。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'" 以前と同じ問題が再び表示され始めます。それは解決の変化と関連しているようです。

私は破損が(私が使用している何か他のものとの互換性のために)後に作られたコピーの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

実際には全く関係のない問題だった、このコードは動作します!

関連する問題