mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-24 01:00:37 +00:00
oggdemux: Make bisecting fully accurate
When bisecting after an earliest time has been found, we need to only consider the stream for which the earliest time was found. Before, the following scenario could be and was encountered: a) Find the earliest time for stream X b) bisect and find a page which granuletime is indeed < target, but contains another stream. c) decide to seek at the wrong offset, sometimes inferior to the real one, in which case the error was undected or d) the offset was superior, and thus the actual target keyframe was not processed, and packets were skipped waiting for a granulepos. https://bugzilla.gnome.org/show_bug.cgi?id=700537
This commit is contained in:
parent
affd9f37aa
commit
905fe0f4ca
1 changed files with 11 additions and 3 deletions
|
@ -2695,7 +2695,7 @@ gst_ogg_demux_activate_chain (GstOggDemux * ogg, GstOggChain * chain,
|
||||||
static gboolean
|
static gboolean
|
||||||
do_binary_search (GstOggDemux * ogg, GstOggChain * chain, gint64 begin,
|
do_binary_search (GstOggDemux * ogg, GstOggChain * chain, gint64 begin,
|
||||||
gint64 end, gint64 begintime, gint64 endtime, gint64 target,
|
gint64 end, gint64 begintime, gint64 endtime, gint64 target,
|
||||||
gint64 * offset)
|
gint64 * offset, gboolean only_serial_no, gint serialno)
|
||||||
{
|
{
|
||||||
gint64 best;
|
gint64 best;
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
|
@ -2769,6 +2769,11 @@ do_binary_search (GstOggDemux * ogg, GstOggChain * chain, gint64 begin,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Avoid seeking to an incorrect granuletime by only considering
|
||||||
|
the stream for which we found the earliest time */
|
||||||
|
if (only_serial_no && ogg_page_serialno (&og) != serialno)
|
||||||
|
continue;
|
||||||
|
|
||||||
/* get the stream */
|
/* get the stream */
|
||||||
pad = gst_ogg_chain_get_stream (chain, ogg_page_serialno (&og));
|
pad = gst_ogg_chain_get_stream (chain, ogg_page_serialno (&og));
|
||||||
if (pad == NULL || pad->map.is_skeleton)
|
if (pad == NULL || pad->map.is_skeleton)
|
||||||
|
@ -2887,6 +2892,7 @@ gst_ogg_demux_do_seek (GstOggDemux * ogg, GstSegment * segment,
|
||||||
gint64 result = 0;
|
gint64 result = 0;
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
gint i, pending;
|
gint i, pending;
|
||||||
|
gint serialno = 0;
|
||||||
|
|
||||||
position = segment->position;
|
position = segment->position;
|
||||||
|
|
||||||
|
@ -2985,8 +2991,10 @@ gst_ogg_demux_do_seek (GstOggDemux * ogg, GstSegment * segment,
|
||||||
/* collect smallest value */
|
/* collect smallest value */
|
||||||
if (keyframe_time != -1) {
|
if (keyframe_time != -1) {
|
||||||
keyframe_time += begintime;
|
keyframe_time += begintime;
|
||||||
if (keyframe_time < keytarget)
|
if (keyframe_time < keytarget) {
|
||||||
|
serialno = pad->map.serialno;
|
||||||
keytarget = keyframe_time;
|
keytarget = keyframe_time;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
next:
|
next:
|
||||||
|
@ -3005,7 +3013,7 @@ gst_ogg_demux_do_seek (GstOggDemux * ogg, GstSegment * segment,
|
||||||
|
|
||||||
/* last step, seek to the location of the keyframe */
|
/* last step, seek to the location of the keyframe */
|
||||||
if (!do_binary_search (ogg, chain, begin, end, begintime, endtime,
|
if (!do_binary_search (ogg, chain, begin, end, begintime, endtime,
|
||||||
keytarget, &best))
|
keytarget, &best, TRUE, serialno))
|
||||||
goto seek_error;
|
goto seek_error;
|
||||||
} else {
|
} else {
|
||||||
/* seek back to previous position */
|
/* seek back to previous position */
|
||||||
|
|
Loading…
Reference in a new issue