ffmpeg解码花屏

问题:

解码为YUV420转为Bitmap后显示在屏幕上时,有三分之二为花屏:如图:

ffmpeg解码花屏_第1张图片

首先用h264Visa分析帧:

ffmpeg解码花屏_第2张图片

已经读出了sps等信息,这些信在解码第一帧时被写入环境变量中,所以下边的帧不需要sps了

而且在解码时必须为完整的一帧或者数帧。

只有IDR帧才需要带sps、pps信息。


ffmpeg中的av_read_frame()的作用是读取码流中的音频若干帧或者视频一帧。例如,解码视频的时候,每解码一个视频帧,需要先调用 av_read_frame()获得一帧视频的压缩数据,然后才能对该数据进行解码(例如H.264中一帧压缩数据通常对应一个NAL)。

通过av_read_packet(***),读取一个包,需要说明的是此函数必须是包含整数帧的,不存在半帧的情况,以ts流为例,是读取一个完整的PES包(一个完整pes包包含若干视频或音频es包),读取完毕后,通过av_parser_parse2(***)分析出视频一帧(或音频若干帧),返回,下次进入循环的时候,如果上次的数据没有完全取完,则st = s->cur_st;不会是NULL,即再此进入av_parser_parse2(***)流程,而不是下面的av_read_packet(**)流程,这样就保证了,如果读取一次包含了N帧视频数据(以视频为例),则调用av_read_frame(***)N次都不会去读数据,而是返回第一次读取的数据,直到全部解析完毕。


直接解码00 00 01之间的数据,很可能不是一帧完整的数据,所以需要先取到完整的数据,方法是使用:av_parser_parse2判断也就是说分帧的话在函数av_read_frame()会调用av_parse_parse2()函数,这只针对本地文件,如果解码网络流,需要自己调用av_parse_parse2()函数;

参照:http://blog.163.com/cho_ku2000/blog/static/913118220120553024697/

摘抄1:

如果由H264字节流格式去解码,在每次读取一段数据之后(不管每次读多少都可以),都调用av_parser_parse2去分帧,这个函数会将每次读取的264数据进行存储分析,直到得到完整的H264数据为止,然后送出,此时我们可以用avcodec_decode_video2来解码。

摘抄2:

那么送出的数据有什么规律呢? 对于IDR帧,除了IDR自身的数据外,会连同前面的SPS,PPS,SEI一并合在一起。在avcodec_decode_video2函数里面,包含了对SPS等的解析。

如果是P帧或者B帧,则不会送SPS,PPS等参赛信息。这个也很合理,因为本来就只有IDR帧才需要带参数信息


摘抄3:

需要av_parser_parse2先解析数据,再调用avcodec_decode_video2
如果av_parser_parse2的输入是1000k,但是av_parser_parse2的解析出来的数据可能只有200k
这200k作为avcodec_decode_video2的输入,剩下的800k需要再次av_parser_parse2,循环往复
如果直接将这1000k,扔进avcodec_decode_video2,返回正确,但是没有结果



你可能感兴趣的:(ffmpeg解码花屏)