按照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()這樣解碼就是正確的幀。
沒有解碼正確,圖片是這樣的