Michael IV
Michael IV

Reputation: 11436

Reading out specific video frame using FFMPEG API

I read frames from video stream in FFMPEG using this loop:

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);
    }

So in this way the stream is read sequentially.What I want is to have a random access to the frame to be able reading a specific frame (by frame number).How is it done?

Upvotes: 9

Views: 12294

Answers (2)

mpenkov
mpenkov

Reputation: 21906

Since most frames in a video depend on previous and next frames, in general, accessing random frames in a video is not straightforward. However, some frames, are encoded independently of any other frames, and occur regularly throughout the video. These frames are known as I-frames. Accessing these frames is straightforward through seeking.

If you want to "randomly" access any frame in the video, then you must:

  1. Seek to the previous I-frame
  2. Read the frames one by one until you get to the frame number that you want

You've already got the code for the second point, so all you need to do is take care of the first point and you're done. Here's an updated version of the Dranger tutorials that people often refer to -- it may be of help.

Upvotes: 3

praks411
praks411

Reputation: 1992

You may want to look

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

The above api will seek to the keyframe at give timestamp. After seeking you can read the frame. Also the tutorial below explain conversion between position and timestamp.

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

Upvotes: 9

Related Questions