按照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()这样解码就是正确的帧。
没有解码正确,图片是这样的