如下所示代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
while (av_read_frame(pFormatCtx, &packet) >= 0) { // Is this a packet from the video stream? if (packet.stream_index == videoStream) { // Decode video frame int iret = avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet); // Did we get a video frame? if (frameFinished) { do something······ } } // Free the packet that was allocated by av_read_frame av_packet_unref(&packet); } |
在使用avcodec_decode_video2函数解码时经常会遇到frameFinished == 0,也就是无法得到一帧解码后的图像。有些人可能会怀疑是哪里出错了,其实这是正常的现象,ffmpeg内部解码时做了处理。处理如下:
1)该帧为B帧,由于B帧是前后参考帧,需要结合前面的I帧或者P帧,以及后面的P帧来生成完整图像,所以该帧如果是B帧,就无法立即解码,所以返回的frameFinished为0,需要解码完后一帧后才可以解码该帧;
2)缓存处理,解码器解码时会缓存几帧提高程序的效率,防止程序在解码这一步等待太久。当解码到最后av_read_frame没有返回新的packet时,由于解码器存在缓存,所以最后我们需要清空解码器,通过传入空的packet给avcodec_decode_video2,直到没有新的解码后的frame返回这一方法来清空解码器。
文章评论