diff options
author | Sebastian Dröge <slomo@circular-chaos.org> | 2008-07-02 09:51:16 +0000 |
---|---|---|
committer | Sebastian Dröge <slomo@circular-chaos.org> | 2008-07-02 09:51:16 +0000 |
commit | 33e0d064a5c223bc4c39e7861e22c77e2b0da5fd (patch) | |
tree | d98ec2db775593a68d125bbbf666779db16c7e30 /gst | |
parent | 2c38fcd1e6d59ab4c87e1e6eada50cf769db66d4 (diff) |
gst/matroska/matroska-demux.c: Handle position and duration query in DEFAULT format if the pad's track has a default ...
Original commit message from CVS:
* gst/matroska/matroska-demux.c: (gst_matroska_demux_class_init),
(gst_matroska_demux_add_stream), (gst_matroska_demux_query),
(gst_matroska_demux_element_query),
(gst_matroska_demux_handle_src_query),
(gst_matroska_demux_handle_seek_event):
Handle position and duration query in DEFAULT format if the
pad's track has a default frame duration set.
Fix seeking now that the segment's duration doesn't contain the
(possibly wrong or inaccurate) duration of the Matroska file.
Diffstat (limited to 'gst')
-rw-r--r-- | gst/matroska/matroska-demux.c | 101 |
1 files changed, 69 insertions, 32 deletions
diff --git a/gst/matroska/matroska-demux.c b/gst/matroska/matroska-demux.c index a9dbed55..ff3f7f40 100644 --- a/gst/matroska/matroska-demux.c +++ b/gst/matroska/matroska-demux.c @@ -116,6 +116,9 @@ static void gst_matroska_demux_loop (GstPad * pad); static gboolean gst_matroska_demux_element_send_event (GstElement * element, GstEvent * event); +static gboolean gst_matroska_demux_element_query (GstElement * element, + GstQuery * query); + /* pad functions */ static gboolean gst_matroska_demux_sink_activate_pull (GstPad * sinkpad, gboolean active); @@ -183,6 +186,8 @@ gst_matroska_demux_class_init (GstMatroskaDemuxClass * klass) GST_DEBUG_FUNCPTR (gst_matroska_demux_change_state); gstelement_class->send_event = GST_DEBUG_FUNCPTR (gst_matroska_demux_element_send_event); + gstelement_class->query = + GST_DEBUG_FUNCPTR (gst_matroska_demux_element_query); } static void @@ -1472,6 +1477,8 @@ gst_matroska_demux_add_stream (GstMatroskaDemux * demux) context->pending_tags = list; + gst_pad_set_element_private (context->pad, context); + gst_pad_use_fixed_caps (context->pad); gst_pad_set_caps (context->pad, context->caps); gst_pad_set_active (context->pad, TRUE); @@ -1496,17 +1503,16 @@ gst_matroska_demux_get_src_query_types (GstPad * pad) } static gboolean -gst_matroska_demux_handle_src_query (GstPad * pad, GstQuery * query) +gst_matroska_demux_query (GstMatroskaDemux * demux, GstPad * pad, + GstQuery * query) { - GstMatroskaDemux *demux; - gboolean res = FALSE; + GstMatroskaTrackContext *context = NULL; - demux = GST_MATROSKA_DEMUX (gst_pad_get_parent (pad)); + if (pad) { + context = gst_pad_get_element_private (pad); + } - /* FIXME: do queries on the Tracks, not on the Segment. - * Convert between time and frames if we know the duration - * of one frame for the track */ switch (GST_QUERY_TYPE (query)) { case GST_QUERY_POSITION: { @@ -1514,15 +1520,25 @@ gst_matroska_demux_handle_src_query (GstPad * pad, GstQuery * query) gst_query_parse_position (query, &format, NULL); - if (format != GST_FORMAT_TIME) { - GST_DEBUG ("only query position on TIME is supported"); - break; + if (format == GST_FORMAT_TIME) { + GST_OBJECT_LOCK (demux); + if (context) + gst_query_set_position (query, GST_FORMAT_TIME, context->pos); + else + gst_query_set_position (query, GST_FORMAT_TIME, + demux->segment.last_stop); + GST_OBJECT_UNLOCK (demux); + } else if (format == GST_FORMAT_DEFAULT && context + && context->default_duration) { + GST_OBJECT_LOCK (demux); + gst_query_set_position (query, GST_FORMAT_DEFAULT, + context->pos / context->default_duration); + GST_OBJECT_UNLOCK (demux); + } else { + GST_DEBUG_OBJECT (demux, + "only position query in TIME and DEFAULT format is supported"); } - GST_OBJECT_LOCK (demux); - gst_query_set_position (query, GST_FORMAT_TIME, demux->segment.last_stop); - GST_OBJECT_UNLOCK (demux); - res = TRUE; break; } @@ -1532,15 +1548,21 @@ gst_matroska_demux_handle_src_query (GstPad * pad, GstQuery * query) gst_query_parse_duration (query, &format, NULL); - if (format != GST_FORMAT_TIME) { - GST_DEBUG ("only query duration on TIME is supported"); - break; + if (format == GST_FORMAT_TIME) { + GST_OBJECT_LOCK (demux); + gst_query_set_duration (query, GST_FORMAT_TIME, demux->duration); + GST_OBJECT_UNLOCK (demux); + } else if (format == GST_FORMAT_DEFAULT && context + && context->default_duration) { + GST_OBJECT_LOCK (demux); + gst_query_set_duration (query, GST_FORMAT_DEFAULT, + demux->duration / context->default_duration); + GST_OBJECT_UNLOCK (demux); + } else { + GST_DEBUG_OBJECT (demux, + "only duration query in TIME and DEFAULT format is supported"); } - GST_OBJECT_LOCK (demux); - gst_query_set_duration (query, GST_FORMAT_TIME, demux->duration); - GST_OBJECT_UNLOCK (demux); - res = TRUE; break; } @@ -1550,10 +1572,27 @@ gst_matroska_demux_handle_src_query (GstPad * pad, GstQuery * query) break; } - gst_object_unref (demux); return res; } +static gboolean +gst_matroska_demux_element_query (GstElement * element, GstQuery * query) +{ + return gst_matroska_demux_query (GST_MATROSKA_DEMUX (element), NULL, query); +} + +static gboolean +gst_matroska_demux_handle_src_query (GstPad * pad, GstQuery * query) +{ + gboolean ret; + GstMatroskaDemux *demux = GST_MATROSKA_DEMUX (gst_pad_get_parent (pad)); + + ret = gst_matroska_demux_query (demux, pad, query); + + gst_object_unref (demux); + + return ret; +} static GstMatroskaIndex * gst_matroskademux_do_index_seek (GstMatroskaDemux * demux, gint64 seek_pos, @@ -1729,28 +1768,26 @@ gst_matroska_demux_handle_seek_event (GstMatroskaDemux * demux, /* if nothing configured, play complete file */ if (!GST_CLOCK_TIME_IS_VALID (cur)) cur = 0; - if (!GST_CLOCK_TIME_IS_VALID (stop)) - stop = demux->segment.duration; /* prevent some calculations and comparisons involving INVALID */ segment_start = demux->segment.start; segment_stop = demux->segment.stop; if (!GST_CLOCK_TIME_IS_VALID (segment_start)) segment_start = 0; - if (!GST_CLOCK_TIME_IS_VALID (segment_stop)) - segment_stop = demux->segment.duration; if (cur_type == GST_SEEK_TYPE_SET) segment_start = cur; else if (cur_type == GST_SEEK_TYPE_CUR) segment_start += cur; - if (stop_type == GST_SEEK_TYPE_SET) + if (stop_type == GST_SEEK_TYPE_SET) { segment_stop = stop; - else if (stop_type == GST_SEEK_TYPE_CUR) - segment_stop += stop; - - segment_start = CLAMP (segment_start, 0, demux->segment.duration); - segment_stop = CLAMP (segment_stop, 0, demux->segment.duration); + } else if (stop_type == GST_SEEK_TYPE_CUR) { + if (GST_CLOCK_TIME_IS_VALID (segment_stop) + && GST_CLOCK_TIME_IS_VALID (stop)) + segment_stop += stop; + else + segment_stop = -1; + } GST_DEBUG ("New segment positions: %" GST_TIME_FORMAT "-%" GST_TIME_FORMAT, GST_TIME_ARGS (segment_start), GST_TIME_ARGS (segment_stop)); |