<html><head><meta http-equiv="Content-Type" content="text/html charset=windows-1252"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;">On 10 Apr 2014, at 00:32, wm4 <<a href="mailto:nfxjfg@googlemail.com">nfxjfg@googlemail.com</a>> wrote:<br><div><br class="Apple-interchange-newline"><blockquote type="cite">On Wed, 9 Apr 2014 23:51:44 +0200<br>Info || Non-Lethal Applications <<a href="mailto:info@non-lethal-applications.com">info@non-lethal-applications.com</a>><br>wrote:<br><br><blockquote type="cite">I’m using libav for my own playback engine and it works like a charm.<br><br>But I have trouble with seeking ...<br>I’d like to pull individual frames from a stream at a given index.<br></blockquote><br>Sounds like a job for <a href="https://github.com/FFMS/ffms2">https://github.com/FFMS/ffms2</a><br><br>It basically takes a frame number, and returns a decoded image.<br></blockquote><div><br></div>Wow, this looks awesome!! </div><div>Exactly what I need, pulling frames of video and audio. Will try immediately!</div><div>Thanks!!</div><div><br><blockquote type="cite"><blockquote type="cite">To do that I’m using the following code:<br><br>int64_t seekTarget = theFrameIndex;<br>int res = avformat_seek_file(pFormatCtx, self.videoStreamIndex, seekTarget, seekTarget, seekTarget, AVSEEK_FLAG_FRAME);<br>. . . <br>while (av_read_frame(pFormatCtx, &packet)>=0)<br>{<br>    int idx = packet.stream_index;<br><br>    if(idx != self.videoStreamIndex)<br>    {<br>        av_free_packet(&packet);<br>        continue;<br>    }<br><br>    int len = avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);<br>    if (len < 0)<br>    {<br>        av_free_packet(&packet);<br>        break;<br>    }     <br><br>    if(!frameFinished)<br>    {<br>        av_free_packet(&packet);<br>        continue;<br>    }<br><br>    presentationTimeStamp = av_frame_get_best_effort_timestamp(pFrame);<br><br>    AVRational timeBase = pFormatCtx->streams[self.videoStreamIndex]->time_base;<br>    float ptsInSeconds = presentationTimeStamp * av_q2d(timeBase);<br>    int frameIndex = (int)(ptsInSeconds * self.videoFrameRate);<br>. . .<br>}<br><br>And that’s how I am pulling the duration that is used to seek:<br><br>float mediaDurationInSecs = pFormatCtx->duration / 1000000.0f;<br>int durationInFrames = (int)(mediaDurationInSecs * self.videoFrameRate);<br><br>The slider used for seeking returns a value from 0-1 which is then multiplied by the duration to get the frame index.<br><br>I’m not getting any errors but the frames returned don’t belong to the frame index provided.<br>It looks like the AVSEEK_FLAG_FRAME doesn’t do what I’d expect.<br></blockquote><br>It doesn't. How reliable seeking is generally depends on the input<br>format. Most times it's not very reliable. Typical media file types<br>like avi, mp4, ts, etc. do not support this kind of seeking at all.<br>Instead, they seek somewhere to the closest key frame. ffms2 does this<br>stuff automatically.<br></blockquote><div><br></div>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).</div><div>H.264 showed a lot of issues …</div><div>It looks like ffms is the way to go for me.</div><div><br><blockquote type="cite"><blockquote type="cite">I would convert the frame index to stream time units but I don’t know why.<br>I’d need a frame duration and I don’t have one at that point…<br><br>I’d appreciate any hint!!<br>Thanks!<br><br></blockquote><br>_______________________________________________<br>Libav-user mailing list<br><a href="mailto:Libav-user@ffmpeg.org">Libav-user@ffmpeg.org</a><br>http://ffmpeg.org/mailman/listinfo/libav-user</blockquote></div><div apple-content-edited="true"><span style="color: rgb(0, 0, 0); font-family: Helvetica;  font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; "><div style="color: rgb(0, 0, 0); font-family: Helvetica;  font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; "><span style="color: rgb(0, 0, 0); font-family: Helvetica;  font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; display: inline !important; float: none; "></span></div>
</span></div>
<br></body></html>