使用FFMPEG API读取特定视频帧

时间:2013-04-23 07:35:10

标签: c++ ffmpeg

我使用这个循环从FFMPEG的视频流中读取帧:

while(av_read_frame(pFormatCtx, &packet)>=0) {
        // Is this a packet from the video stream?
        if(packet.stream_index==videoStream) {
            // Decode video frame
            avcodec_decode_video2(pCodecCtx,pFrame,&frameFinished,&packet);

            // Did we get a video frame?
            if(frameFinished) {


                sws_scale(img_convert_context ,pFrame->data,pFrame->linesize,0,
                     pCodecCtx->height, pFrameRGBA->data, pFrameRGBA->linesize);
                printf("%s\n","Frame read finished ");

                                       ExportFrame(pFrameRGBA->data[0]);
                    break;
                }
            }
            // Save the frame to disk

        }
            printf("%s\n","Read next frame ");

        // Free the packet that was allocated by av_read_frame
        av_free_packet(&packet);
    }

因此以这种方式顺序读取流。我想要的是随机访问帧以便能够读取特定帧(按帧号)。它是如何完成的?

2 个答案:

答案 0 :(得分:6)

你可能想要看

int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp,
                  int flags);

上面的api会在给出时间戳时寻找关键帧。寻求你可以阅读框架。此外,下面的教程还解释了位置和时间戳之间的转换。

http://dranger.com/ffmpeg/tutorial07.html

答案 1 :(得分:2)

由于视频中的大多数帧依赖于前一帧和下一帧,因此通常,访问视频中的随机帧并不简单。但是,某些帧独立于任何其他帧进行编码,并在整个视频中定期出现。这些帧称为I帧。通过搜索来直接访问这些框架

如果您想“随机”访问视频中的任何帧,那么您必须:

  1. 寻找前一个I-frame
  2. 逐个阅读框架,直至找到您想要的框架编号
  3. 你已经获得了第二点的代码,所以你需要做的就是照顾第一点,然后你就完成了。这是人们经常提到的Dranger教程的updated version - 它可能会有所帮助。