[Libav-user] Grabbing individual frames from a movie

Info || Non-Lethal Applications info at non-lethal-applications.com
Thu Apr 10 12:08:53 CEST 2014


On 10 Apr 2014, at 00:32, wm4 <nfxjfg at googlemail.com> wrote:

> 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.

Wow, this looks awesome!! 
Exactly what I need, pulling frames of video and audio. Will try immediately!
Thanks!!

>> 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.

Yes I saw that … worked with a Pro Res and an H.264 file. Pro Res seeking worked flawlessly (as you might expect with an non GOP codec).
H.264 showed a lot of issues …
It looks like ffms is the way to go for me.

>> 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!
>> 
> 
> _______________________________________________
> Libav-user mailing list
> Libav-user at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/libav-user


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://ffmpeg.org/pipermail/libav-user/attachments/20140410/a48d48cb/attachment.html>


More information about the Libav-user mailing list