新版本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.
");
            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()这样解码就是正确的帧。

没有解码正确,图片是这样的

原文地址:https://www.cnblogs.com/zzugyl/p/4448722.html