[Libav-user] Grabbing individual frames from a movie

wm4 nfxjfg at googlemail.com
Thu Apr 10 00:32:23 CEST 2014


On Wed, 9 Apr 2014 23:51:44 +0200
Info || Non-Lethal Applications <info at non-lethal-applications.com>
wrote:

> I’m using libav for my own playback engine and it works like a charm.
> 
> But I have trouble with seeking ...
> I’d like to pull individual frames from a stream at a given index.

Sounds like a job for https://github.com/FFMS/ffms2

It basically takes a frame number, and returns a decoded image.

> To do that I’m using the following code:
> 
> int64_t seekTarget = theFrameIndex;
> int res = avformat_seek_file(pFormatCtx, self.videoStreamIndex, seekTarget, seekTarget, seekTarget, AVSEEK_FLAG_FRAME);
> . . . 
> while (av_read_frame(pFormatCtx, &packet)>=0)
> {
>     int idx = packet.stream_index;
>         
>     if(idx != self.videoStreamIndex)
>     {
>         av_free_packet(&packet);
>         continue;
>     }
> 
>     int len = avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);
>     if (len < 0)
>     {
>         av_free_packet(&packet);
>         break;
>     }     
> 
>     if(!frameFinished)
>     {
>         av_free_packet(&packet);
>         continue;
>     }
> 
>     presentationTimeStamp = av_frame_get_best_effort_timestamp(pFrame);
>     
>     AVRational timeBase = pFormatCtx->streams[self.videoStreamIndex]->time_base;
>     float ptsInSeconds = presentationTimeStamp * av_q2d(timeBase);
>     int frameIndex = (int)(ptsInSeconds * self.videoFrameRate);
> . . .
> }
> 
> And that’s how I am pulling the duration that is used to seek:
> 
> float mediaDurationInSecs = pFormatCtx->duration / 1000000.0f;
> int durationInFrames = (int)(mediaDurationInSecs * self.videoFrameRate);
> 
> The slider used for seeking returns a value from 0-1 which is then multiplied by the duration to get the frame index.
> 
> I’m not getting any errors but the frames returned don’t belong to the frame index provided.
> It looks like the AVSEEK_FLAG_FRAME doesn’t do what I’d expect.

It doesn't. How reliable seeking is generally depends on the input
format. Most times it's not very reliable. Typical media file types
like avi, mp4, ts, etc. do not support this kind of seeking at all.
Instead, they seek somewhere to the closest key frame. ffms2 does this
stuff automatically.

> I would convert the frame index to stream time units but I don’t know why.
> I’d need a frame duration and I don’t have one at that point…
> 
> I’d appreciate any hint!!
> Thanks!
> 



More information about the Libav-user mailing list