<html><head>

    
  <style>pre,code,address {
  margin: 0px;
}
h1,h2,h3,h4,h5,h6 {
  margin-top: 0.2em;
  margin-bottom: 0.2em;
}
ol,ul {
  margin-top: 0em;
  margin-bottom: 0em;
}
blockquote {
  margin-top: 0em;
  margin-bottom: 0em;
}
</style></head>
  <body><div>Le vendredi 12 janvier 2024 à 16:50 +0000, Will McElderry via gstreamer-devel a écrit :</div><blockquote type="cite" style="margin:0 0 0 .8ex; border-left:2px #729fcf solid;padding-left:1ex"><div> </div><p>Hi All,</p><div> </div><p><br> </p><div> </div><p>TLDR version:</p><div> </div><p>I am trying to accurately seek to a known frame in a video file (usually an MP4 with an h264 stream inside captured from an RTSP camera).<br> </p></blockquote><div>This can only be performed if the source media have a fixed frame rate, just be aware.</div><blockquote type="cite" style="margin:0 0 0 .8ex; border-left:2px #729fcf solid;padding-left:1ex"><div> </div><p>[1] Is Buffer.pts in Segment time, and need mapping to stream time with 'Segment.to_stream_time(Buffer.pts)' ?</p></blockquote><div><br></div><div>Yes.</div><div><br></div><blockquote type="cite" style="margin:0 0 0 .8ex; border-left:2px #729fcf solid;padding-left:1ex"><div> </div><p>[2] Should Pipeline.seek( ... buffer_time ... ) mean the next frame I receive is the Buffer I saw at that stream time?</p><div> </div><p>    (using a file src, pipeline does support seeking, details of '...'  in seek function given below if useful)</p></blockquote><div><br></div><div>Seek time is always in stream time. You'll have to use the seeking flag "GST_SEEK_FLAG_ACCURATE" to obtain the exact frame. In this context, demuxers will make extra effort to ensure the first frame match as closely as possible the requested stream time.</div><div><br></div><div>Nicolas</div><div><br></div><blockquote type="cite" style="margin:0 0 0 .8ex; border-left:2px #729fcf solid;padding-left:1ex"><div> </div><p><br></p><div> </div><p>Thanks!</p><div> </div><p>Will.<br> </p><div> </div><p><br> </p><div> </div><p><u>Verbose context:</u><br> </p><div> </div><p></p><div> </div><p></p><div> </div><p>I am working with some legacy code and have been asked to make it seek accurately to a specific frame. However things are not working as I'd expect.</p><div> </div><p>I'd love some feedback on my understanding, pointers to make things work or knowledgeable person to confirm if this could be an issue!</p><div> <br> </div><p>From comments </p><div> </div><p>    <a href="https://gstreamer.freedesktop.org/documentation/application-development/advanced/clocks.html?gi-language=python#buffer-streamtime">here</a>    (The buffer stream-time, ... [is] calculated from the buffer timestamps and the preceding <code>SEGMENT</code> event.)<br> </p><div> </div><p>and</p><div> </div><p>    <a href="https://gstreamer.freedesktop.org/documentation/gstreamer/gstsegment.html?gi-language=python#gst_segment_to_stream_time">here</a>    (Gst.Segment.to_stream_time ... is typically used ... to operate on the stream time of the buffers it receives)</p><div> </div><p>I believe Buffer.pts is in Segment time.  Is that correct?</p><div> </div><p>(I cannot see where it explicitly stated anywhere what time it's in, so I could be easily wrong!)</p><div> </div><p><br> </p><div> </div><p>Building on that understanding, I'm trying to obtain the <b>stream time</b> of a frame from a video that is provided to an appsink with 'pull_preroll()' with the following method:<br> </p><div> </div><p>    seg = sample.get_segment()</p><div> </div><p>    buf = sample.get_buffer()</p><div> </div><p>    stream_time = seg.to_stream_time( buf.pts )<br> </p><div> </div><p><br> </p><div> </div><p>I then attempt to seek to a known frame's <b>stream time</b> I've obtained using the method above with:</p><div> </div><p>    pipeline.seek(<br>         1.0, Gst.Format.TIME,</p><div> </div><p>        Gst.SeekFlags.ACCURATE | Gst.SeekFlags.FLUSH,</p><div> </div><p>        Gst.SeekType.SET, target_time,</p><div> </div><p>        Gst.SeekType.NONE, 0<br>     )</p><div> </div><p>   await_async_done()<br> </p><div> </div><p>However, I do not get the frame I started with (sometimes I do, but generally it's one or two out, usually prior to the frame I anticipate).  I've tried adding an 'epsilon' value to see if it is a rounding issue, but that doesn't seem to apply either.<br> </p><div> </div><p>Can anyone make any comments or recommendations?</p></blockquote><div>Seeking to get a specific frame without some Format.FRAME (in theory DEFAULT for video should be frame, but this is largely unimplemented since we don't track frame numbers, and most container don't do that either). A slower, but more accurate alternative is to use step operations (see <span style="font-family: Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace; font-size: 13px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); background-color: rgb(245, 242, 240);">gst_event_new_step()).</span></div><blockquote type="cite" style="margin:0 0 0 .8ex; border-left:2px #729fcf solid;padding-left:1ex"><div> </div><p><br> </p><div> </div><p>Thanks!</p><div> </div><p><br> </p><div> </div><p>Will.</p><div> </div><p><br> </p><div> </div><p><br> </p><div> </div><p>P.S.</p><div> </div><p>I've also tried the following based on seeking by Buffers, but it doesn't seem to work with my pipeline.  From docs I read I think this is not unexpected...<br> </p><div> </div><p>    pipeline.seek(<br>         1.0, Gst.Format.Buffers,</p><div> </div><p>        Gst.SeekFlags.ACCURATE | Gst.SeekFlags.FLUSH,</p><div> </div><p>        Gst.SeekType.SET, target_frame_index,</p><div> </div><p>        Gst.SeekType.NONE, 0<br>     )</p><div> </div><p></p><div> </div></blockquote><div><br></div><div><span></span></div></body></html>