matroskademux: also consider BlockNumber indicated in index when seeking

This commit is contained in:
Mark Nauwelaerts 2009-12-16 12:48:02 +01:00
parent 900ff7247e
commit c9a0d2339e
2 changed files with 37 additions and 0 deletions

View file

@ -402,6 +402,7 @@ gst_matroska_demux_reset (GstElement * element)
gst_segment_init (&demux->segment, GST_FORMAT_TIME); gst_segment_init (&demux->segment, GST_FORMAT_TIME);
demux->duration = -1; demux->duration = -1;
demux->last_stop_end = GST_CLOCK_TIME_NONE; demux->last_stop_end = GST_CLOCK_TIME_NONE;
demux->seek_block = 0;
demux->offset = 0; demux->offset = 0;
demux->cluster_time = GST_CLOCK_TIME_NONE; demux->cluster_time = GST_CLOCK_TIME_NONE;
@ -2302,6 +2303,7 @@ gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux,
context->last_flow = GST_FLOW_OK; context->last_flow = GST_FLOW_OK;
} }
demux->segment.last_stop = entry->time; demux->segment.last_stop = entry->time;
demux->seek_block = entry->block;
/* restart our task since it might have been stopped when we did the /* restart our task since it might have been stopped when we did the
* flush. */ * flush. */
@ -2562,6 +2564,12 @@ gst_matroska_demux_parse_index_cuetrack (GstMatroskaDemux * demux,
GST_DEBUG_OBJECT (demux, "CueBlockNumber: %" G_GUINT64_FORMAT, num); GST_DEBUG_OBJECT (demux, "CueBlockNumber: %" G_GUINT64_FORMAT, num);
idx.block = num; idx.block = num;
/* mild sanity check, disregard strange cases ... */
if (idx.block > G_MAXUINT16) {
GST_DEBUG_OBJECT (demux, "... looks suspicious, ignoring");
idx.block = 1;
}
break; break;
} }
@ -4518,6 +4526,22 @@ done:
return ret; return ret;
} }
/* return FALSE if block(group) should be skipped (due to a seek) */
static inline gboolean
gst_matroska_demux_seek_block (GstMatroskaDemux * demux)
{
if (G_UNLIKELY (demux->seek_block)) {
if (!(--demux->seek_block)) {
return TRUE;
} else {
GST_LOG_OBJECT (demux, "should skip block due to seek");
return FALSE;
}
} else {
return TRUE;
}
}
static GstFlowReturn static GstFlowReturn
gst_matroska_demux_parse_cluster (GstMatroskaDemux * demux) gst_matroska_demux_parse_cluster (GstMatroskaDemux * demux)
{ {
@ -4559,6 +4583,8 @@ gst_matroska_demux_parse_cluster (GstMatroskaDemux * demux)
/* a group of blocks inside a cluster */ /* a group of blocks inside a cluster */
case GST_MATROSKA_ID_BLOCKGROUP: case GST_MATROSKA_ID_BLOCKGROUP:
if (!gst_matroska_demux_seek_block (demux))
goto skip;
DEBUG_ELEMENT_START (demux, ebml, "BlockGroup"); DEBUG_ELEMENT_START (demux, ebml, "BlockGroup");
if ((ret = gst_ebml_read_master (ebml, &id)) == GST_FLOW_OK) { if ((ret = gst_ebml_read_master (ebml, &id)) == GST_FLOW_OK) {
ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux, ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
@ -4569,6 +4595,8 @@ gst_matroska_demux_parse_cluster (GstMatroskaDemux * demux)
case GST_MATROSKA_ID_SIMPLEBLOCK: case GST_MATROSKA_ID_SIMPLEBLOCK:
{ {
if (!gst_matroska_demux_seek_block (demux))
goto skip;
DEBUG_ELEMENT_START (demux, ebml, "SimpleBlock"); DEBUG_ELEMENT_START (demux, ebml, "SimpleBlock");
ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux, ret = gst_matroska_demux_parse_blockgroup_or_simpleblock (demux,
cluster_time, cluster_offset, TRUE); cluster_time, cluster_offset, TRUE);
@ -4583,6 +4611,7 @@ gst_matroska_demux_parse_cluster (GstMatroskaDemux * demux)
case GST_MATROSKA_ID_PREVSIZE: case GST_MATROSKA_ID_PREVSIZE:
case GST_MATROSKA_ID_ENCRYPTEDBLOCK: case GST_MATROSKA_ID_ENCRYPTEDBLOCK:
case GST_MATROSKA_ID_SILENTTRACKS: case GST_MATROSKA_ID_SILENTTRACKS:
skip:
GST_DEBUG ("Skipping Cluster subelement 0x%x - ignoring", id); GST_DEBUG ("Skipping Cluster subelement 0x%x - ignoring", id);
ret = gst_ebml_read_skip (ebml); ret = gst_ebml_read_skip (ebml);
break; break;
@ -4610,6 +4639,13 @@ gst_matroska_demux_parse_cluster (GstMatroskaDemux * demux)
DEBUG_ELEMENT_STOP (demux, ebml, "Cluster", ret); DEBUG_ELEMENT_STOP (demux, ebml, "Cluster", ret);
if (G_UNLIKELY (demux->seek_block)) {
GST_DEBUG_OBJECT (demux, "seek target block %" G_GUINT64_FORMAT
" not found in Cluster, trying next Cluster's first block instead",
demux->seek_block);
demux->seek_block = 0;
}
return ret; return ret;
} }

View file

@ -72,6 +72,7 @@ typedef struct _GstMatroskaDemux {
/* state */ /* state */
GstMatroskaDemuxState state; GstMatroskaDemuxState state;
guint level_up; guint level_up;
guint64 seek_block;
/* did we parse cues/tracks/segmentinfo already? */ /* did we parse cues/tracks/segmentinfo already? */
gboolean index_parsed; gboolean index_parsed;