As far as random frame extraction for MPEG's is concerned, it gets a little tricky. The FFmpeg libraries do not have a consistent interface to seeking into files of all different formats and extracting their frames. The reason why is because different video formats treat time differently from others, which means that the way they record time is also different.<div>
<br></div><div>After doing some experiments with MPEG's, I found that the best way to extract frames based on a specific time is the following:</div><div><br></div><div>1) Convert the time you want (in seconds) to a PTS value for your stream. This is the value you are trying to seek to. To do so, use the video stream's (AVStream) time_base and multiply your time by it.</div>
<div>2) Initialize your frame counter to 0.</div><div>3) Go into a reading loop just like in the tutorials.</div><div>4) After decoding and getting a finished frame, add 1 to your frame counter and calculate the current frame's PTS using the following:</div>
<div>    calcPts = (frame->coded_picture_number * (1.0 / fps) * formatContext->streams[reader->videoStream]->time_base.den) / formatContext->streams[reader->videoStream]->time_base.num;</div><div>5) Compare your frame's PTS with your seek PTS and see if it is the same or greater.</div>
<div><br></div><div>It all boils down to converting a video frame number into an accurate PTS and comparing them. I had to do slightly different hacks to get accurate PTS values for other formats.</div><div><br><div class="gmail_quote">
On Wed, Apr 6, 2011 at 10:26 PM, Carson Harper <span dir="ltr"><<a href="mailto:carsonharper@gmail.com">carsonharper@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div>Hey Amir,</div><div><br></div><div>Could you tell us a little bit more about what you want to do with the "raw" YUV or RGB data? For instance, do you want to save those individual frames as still images (BMP, PNG...) or are you wanting to transcode them for use in another video stream? </div>

<div><br></div><div>If you want to just save to disk try-</div><div><br></div><div>ffmpeg -f image2 </path/to/your/video.mp4> frame_%06d.png</div><div><br></div><div>See <a href="http://www.catswhocode.com/blog/19-ffmpeg-commands-for-all-needs" target="_blank">here</a> for some other useful CLI stuff.</div>

<div><br></div><div>I recently went through the tutorials listed above and came up with a C++ routine that convert's the first video stream from an input file to a vector of ImageMagick objects, but it would be trivial to adapt it to something else. </div>


<div><br></div><div>You mentioned having random access to frames by selecting frame number, which is something I'll need to write eventually anyways, but this may work for you as a lazy solution. I mostly deal with small/short video clips which is why I can get aways with loading the whole video into memory.</div>


<div><br></div><div>I tried to tweak a few things to make it easier to understand, but you will definitely still need to change things to get it to work for you. Obviously, I'm throwing my own custom exceptions etc... You could return an array of (int8_t *) if you don't want to use the ImageMagick stuff, and then just play with the raw data from there.</div>

<div><br></div><div>Hope this helps,</div><div><br></div><font color="#888888"><div>CH</div>
</font><br>_______________________________________________<br>
Libav-user mailing list<br>
<a href="mailto:Libav-user@ffmpeg.org">Libav-user@ffmpeg.org</a><br>
<a href="http://ffmpeg.org/mailman/listinfo/libav-user" target="_blank">http://ffmpeg.org/mailman/listinfo/libav-user</a><br>
<br></blockquote></div><br><br clear="all"><br>-- <br>Spencer Graffe<br>- A Guy<br>
</div>