新版本ffmpeg解碼非完整H264幀失敗


按照ffmpeg/doc/examples/decoding_encoding.c中video_decode_example解碼H264,
新版本ffmpeg解碼非完整H264幀,定量讀取數據直接給avcodec_decode_video2會解碼失敗。
具體從哪個版本開始,已經不記得了。感覺老版本是可以的。
其中有一句
if(codec->capabilities&CODEC_CAP_TRUNCATED)
c->flags|= CODEC_FLAG_TRUNCATED; /* we do not send complete frames */
現在只跳過,不會執行。
即便強制使用c->flags|= CODEC_FLAG_TRUNCATED;也不會生效。解碼還是會失敗。花屏,數據量大小也不對。
在qq群也和網友聊過,有人說現在這一句就是一個坑。

正確的做法應該是,1.要么每次給解碼器一個完整的幀,2.要么用av_parser_parse2(流讀取),查找一個完整的幀。

參考代碼 測試用例 參考 decoding_encoding.c 和 雷霄驊博客http://blog.csdn.net/leixiaohua1020

while (1)
{
    cur_size = fread(in_buffer, 1, in_buffer_size, fp_in);
    if (cur_size == 0)
        break;
    cur_ptr = in_buffer;
    while (cur_size > 0)
    {
        int len = av_parser_parse2(
            pCodecParserCtx, pCodecCtx,
            &packet.data, &packet.size,
            cur_ptr, cur_size,
            AV_NOPTS_VALUE, AV_NOPTS_VALUE, AV_NOPTS_VALUE);
        cur_ptr += len;
        cur_size -= len;
        if (packet.size == 0)
            continue;

        ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, &packet);
        if (ret < 0) 
        {
            printf("Decode Error.\n");
            return ret;
        }
        if (got_picture) 
        {
            fwrite(raw_data, 1, data_size, fp_out);
        }
    }
}

3. 文件讀取方式

AVFormatContext *pFormatCtx = avformat_alloc_context();
avformat_open_input()
avformat_find_stream_info()
avcodec_find_decoder()
avcodec_open2()
av_dump_format()
av_read_frame()每次從文件中讀取一個幀
avcodec_decode_video2()這樣解碼就是正確的幀。

沒有解碼正確,圖片是這樣的


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM