mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 11:45:25 +00:00
dashdemux: Keep track of the PTS, not the SIDX index position between representations
There is no guarantee that the index positions are the same between representations, and assuming this easily causes us to get into invalid index positions.
This commit is contained in:
parent
b84f530a9a
commit
b76a2200de
2 changed files with 81 additions and 21 deletions
|
@ -1134,7 +1134,9 @@ gst_dash_demux_stream_update_fragment_info (GstAdaptiveDemuxStream * stream)
|
||||||
gst_dash_demux_stream_update_headers_info (stream);
|
gst_dash_demux_stream_update_headers_info (stream);
|
||||||
dashstream->sidx_base_offset = stream->fragment.index_range_end + 1;
|
dashstream->sidx_base_offset = stream->fragment.index_range_end + 1;
|
||||||
/* sidx entries may not be available in here */
|
/* sidx entries may not be available in here */
|
||||||
if (dashstream->sidx_index != 0 && SIDX (dashstream)->entries) {
|
if (dashstream->sidx_position != 0
|
||||||
|
&& dashstream->sidx_position != GST_CLOCK_TIME_NONE
|
||||||
|
&& SIDX (dashstream)->entries) {
|
||||||
/* request only the index to be downloaded as we need to reposition the
|
/* request only the index to be downloaded as we need to reposition the
|
||||||
* stream to a subsegment */
|
* stream to a subsegment */
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
|
@ -1204,7 +1206,9 @@ gst_dash_demux_stream_update_fragment_info (GstAdaptiveDemuxStream * stream)
|
||||||
stream->fragment.uri = fragment.uri;
|
stream->fragment.uri = fragment.uri;
|
||||||
/* If mpd does not specify indexRange (i.e., null index_uri),
|
/* If mpd does not specify indexRange (i.e., null index_uri),
|
||||||
* sidx entries may not be available until download it */
|
* sidx entries may not be available until download it */
|
||||||
if (isombff && dashstream->sidx_index != 0 && SIDX (dashstream)->entries) {
|
if (isombff && dashstream->sidx_position != 0
|
||||||
|
&& dashstream->sidx_position != GST_CLOCK_TIME_NONE
|
||||||
|
&& SIDX (dashstream)->entries) {
|
||||||
GstSidxBoxEntry *entry = SIDX_CURRENT_ENTRY (dashstream);
|
GstSidxBoxEntry *entry = SIDX_CURRENT_ENTRY (dashstream);
|
||||||
stream->fragment.range_start =
|
stream->fragment.range_start =
|
||||||
dashstream->sidx_base_offset + entry->offset;
|
dashstream->sidx_base_offset + entry->offset;
|
||||||
|
@ -1292,13 +1296,14 @@ gst_dash_demux_stream_sidx_seek (GstDashDemuxStream * dashstream,
|
||||||
}
|
}
|
||||||
|
|
||||||
sidx->entry_index = idx;
|
sidx->entry_index = idx;
|
||||||
dashstream->sidx_index = idx;
|
if (idx == sidx->entries_count)
|
||||||
|
dashstream->sidx_position =
|
||||||
|
sidx->entries[idx - 1].pts + sidx->entries[idx - 1].duration;
|
||||||
|
else
|
||||||
|
dashstream->sidx_position = sidx->entries[idx].pts;
|
||||||
|
|
||||||
if (final_ts) {
|
if (final_ts) {
|
||||||
if (idx == sidx->entries_count)
|
*final_ts = dashstream->sidx_position;
|
||||||
*final_ts = sidx->entries[idx].pts + sidx->entries[idx].duration;
|
|
||||||
else
|
|
||||||
*final_ts = sidx->entries[idx].pts;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1332,6 +1337,7 @@ gst_dash_demux_stream_seek (GstAdaptiveDemuxStream * stream, gboolean forward,
|
||||||
gst_isoff_sidx_parser_clear (&dashstream->sidx_parser);
|
gst_isoff_sidx_parser_clear (&dashstream->sidx_parser);
|
||||||
gst_isoff_sidx_parser_init (&dashstream->sidx_parser);
|
gst_isoff_sidx_parser_init (&dashstream->sidx_parser);
|
||||||
dashstream->sidx_base_offset = 0;
|
dashstream->sidx_base_offset = 0;
|
||||||
|
dashstream->sidx_position = GST_CLOCK_TIME_NONE;
|
||||||
if (dashstream->sidx_adapter)
|
if (dashstream->sidx_adapter)
|
||||||
gst_adapter_clear (dashstream->sidx_adapter);
|
gst_adapter_clear (dashstream->sidx_adapter);
|
||||||
}
|
}
|
||||||
|
@ -1434,16 +1440,24 @@ gst_dash_demux_stream_advance_subfragment (GstAdaptiveDemuxStream * stream)
|
||||||
|
|
||||||
if (dashstream->sidx_parser.status == GST_ISOFF_SIDX_PARSER_FINISHED) {
|
if (dashstream->sidx_parser.status == GST_ISOFF_SIDX_PARSER_FINISHED) {
|
||||||
if (stream->demux->segment.rate > 0.0) {
|
if (stream->demux->segment.rate > 0.0) {
|
||||||
sidx->entry_index++;
|
gint idx = ++sidx->entry_index;
|
||||||
if (sidx->entry_index < sidx->entries_count) {
|
if (idx < sidx->entries_count) {
|
||||||
fragment_finished = FALSE;
|
fragment_finished = FALSE;
|
||||||
}
|
}
|
||||||
dashstream->sidx_index++;
|
|
||||||
|
if (idx == sidx->entries_count)
|
||||||
|
dashstream->sidx_position =
|
||||||
|
sidx->entries[idx - 1].pts + sidx->entries[idx - 1].duration;
|
||||||
|
else
|
||||||
|
dashstream->sidx_position = sidx->entries[idx].pts;
|
||||||
} else {
|
} else {
|
||||||
sidx->entry_index--;
|
gint idx = --sidx->entry_index;
|
||||||
dashstream->sidx_index--;
|
|
||||||
if (sidx->entry_index >= 0) {
|
if (idx >= 0) {
|
||||||
fragment_finished = FALSE;
|
fragment_finished = FALSE;
|
||||||
|
dashstream->sidx_position = sidx->entries[idx].pts;
|
||||||
|
} else {
|
||||||
|
dashstream->sidx_position = GST_CLOCK_TIME_NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1485,6 +1499,8 @@ gst_dash_demux_clear_pending_stream_data (GstDashDemux * dashdemux,
|
||||||
gst_isoff_sidx_parser_init (&dashstream->sidx_parser);
|
gst_isoff_sidx_parser_init (&dashstream->sidx_parser);
|
||||||
if (dashstream->sidx_adapter)
|
if (dashstream->sidx_adapter)
|
||||||
gst_adapter_clear (dashstream->sidx_adapter);
|
gst_adapter_clear (dashstream->sidx_adapter);
|
||||||
|
dashstream->sidx_base_offset = 0;
|
||||||
|
dashstream->sidx_position = GST_CLOCK_TIME_NONE;
|
||||||
|
|
||||||
/* Reset ISOBMFF box parsing state */
|
/* Reset ISOBMFF box parsing state */
|
||||||
if (dashstream->isobmff_adapter)
|
if (dashstream->isobmff_adapter)
|
||||||
|
@ -1542,7 +1558,7 @@ gst_dash_demux_stream_advance_fragment (GstAdaptiveDemuxStream * stream)
|
||||||
gst_isoff_sidx_parser_clear (&dashstream->sidx_parser);
|
gst_isoff_sidx_parser_clear (&dashstream->sidx_parser);
|
||||||
gst_isoff_sidx_parser_init (&dashstream->sidx_parser);
|
gst_isoff_sidx_parser_init (&dashstream->sidx_parser);
|
||||||
dashstream->sidx_base_offset = 0;
|
dashstream->sidx_base_offset = 0;
|
||||||
dashstream->sidx_index = 0;
|
dashstream->sidx_position = GST_CLOCK_TIME_NONE;
|
||||||
if (dashstream->sidx_adapter)
|
if (dashstream->sidx_adapter)
|
||||||
gst_adapter_clear (dashstream->sidx_adapter);
|
gst_adapter_clear (dashstream->sidx_adapter);
|
||||||
|
|
||||||
|
@ -1619,13 +1635,25 @@ gst_dash_demux_stream_select_bitrate (GstAdaptiveDemuxStream * stream,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret) {
|
if (ret) {
|
||||||
gst_dash_demux_clear_pending_stream_data (demux, dashstream);
|
if (gst_mpd_client_has_isoff_ondemand_profile (demux->client)
|
||||||
|
&& SIDX (dashstream)->entries) {
|
||||||
if (gst_mpd_client_has_isoff_ondemand_profile (demux->client)) {
|
|
||||||
/* store our current position to change to the same one in a different
|
/* store our current position to change to the same one in a different
|
||||||
* representation if needed */
|
* representation if needed */
|
||||||
dashstream->sidx_index = SIDX (dashstream)->entry_index;
|
if (SIDX (dashstream)->entry_index < SIDX (dashstream)->entries_count)
|
||||||
|
dashstream->sidx_position = SIDX_CURRENT_ENTRY (dashstream)->pts;
|
||||||
|
else if (SIDX (dashstream)->entry_index >=
|
||||||
|
SIDX (dashstream)->entries_count)
|
||||||
|
dashstream->sidx_position =
|
||||||
|
SIDX_ENTRY (dashstream,
|
||||||
|
SIDX (dashstream)->entries_count - 1)->pts + SIDX_ENTRY (dashstream,
|
||||||
|
SIDX (dashstream)->entries_count - 1)->duration;
|
||||||
|
else
|
||||||
|
dashstream->sidx_position = GST_CLOCK_TIME_NONE;
|
||||||
|
} else {
|
||||||
|
dashstream->sidx_position = GST_CLOCK_TIME_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gst_dash_demux_clear_pending_stream_data (demux, dashstream);
|
||||||
}
|
}
|
||||||
|
|
||||||
end:
|
end:
|
||||||
|
@ -2254,7 +2282,23 @@ gst_dash_demux_parse_isobmff (GstAdaptiveDemux * demux,
|
||||||
/* push buffer up to sidx box, and do pending stream seek */
|
/* push buffer up to sidx box, and do pending stream seek */
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
SIDX (dash_stream)->entry_index = dash_stream->sidx_index;
|
gint idx = 0;
|
||||||
|
|
||||||
|
if (dash_stream->sidx_position == GST_CLOCK_TIME_NONE) {
|
||||||
|
idx = 0;
|
||||||
|
} else {
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
/* Set sidx index to the highest entry that is smaller than our
|
||||||
|
* remembered position */
|
||||||
|
for (i = 0; i < SIDX (dash_stream)->entries_count; i++) {
|
||||||
|
idx = i;
|
||||||
|
if (SIDX_ENTRY (dash_stream, i)->pts + SIDX_ENTRY (dash_stream,
|
||||||
|
i)->duration > dash_stream->sidx_position)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SIDX (dash_stream)->entry_index = idx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -2714,7 +2758,23 @@ gst_dash_demux_data_received (GstAdaptiveDemux * demux,
|
||||||
NULL);
|
NULL);
|
||||||
dash_stream->pending_seek_ts = GST_CLOCK_TIME_NONE;
|
dash_stream->pending_seek_ts = GST_CLOCK_TIME_NONE;
|
||||||
} else {
|
} else {
|
||||||
SIDX (dash_stream)->entry_index = dash_stream->sidx_index;
|
gint idx = 0;
|
||||||
|
|
||||||
|
if (dash_stream->sidx_position == GST_CLOCK_TIME_NONE) {
|
||||||
|
idx = 0;
|
||||||
|
} else {
|
||||||
|
gint i;
|
||||||
|
|
||||||
|
/* Set sidx index to the highest entry that is smaller than our
|
||||||
|
* remembered position */
|
||||||
|
for (i = 0; i < SIDX (dash_stream)->entries_count; i++) {
|
||||||
|
idx = i;
|
||||||
|
if (SIDX_ENTRY (dash_stream, i)->pts + SIDX_ENTRY (dash_stream,
|
||||||
|
i)->duration > dash_stream->sidx_position)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SIDX (dash_stream)->entry_index = idx;
|
||||||
}
|
}
|
||||||
} else if (consumed < available) {
|
} else if (consumed < available) {
|
||||||
GstBuffer *pending;
|
GstBuffer *pending;
|
||||||
|
|
|
@ -69,7 +69,7 @@ struct _GstDashDemuxStream
|
||||||
/* index parsing */
|
/* index parsing */
|
||||||
GstAdapter *sidx_adapter;
|
GstAdapter *sidx_adapter;
|
||||||
GstSidxParser sidx_parser;
|
GstSidxParser sidx_parser;
|
||||||
gint sidx_index;
|
GstClockTime sidx_position;
|
||||||
gint64 sidx_base_offset;
|
gint64 sidx_base_offset;
|
||||||
GstClockTime pending_seek_ts;
|
GstClockTime pending_seek_ts;
|
||||||
/* sidx offset tracking */
|
/* sidx offset tracking */
|
||||||
|
|
Loading…
Reference in a new issue