summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Svensson Fors <davidsf@axis.com>2011-09-14 14:46:00 +0200
committerMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>2011-09-14 14:49:36 +0200
commit682ae32f6f8a81e4c3cb164bb285c3d5f1069fa5 (patch)
tree8f1c20b84f6a7c3131854d27b5e4d79de6270474
parentc78048bc25c6b0b7018a442bab24227452b6dd57 (diff)
matroskademux: configurable timestamp gap handling
matroskademux performs segment tricks to skip gaps in streams, notably at start for non 0 based files. There may however be cases when full presentation (including intermediate gaps) is desired, so a property allows to configure as of which gap to act (or not at all). API: GstMatroskaDemux::max-gap-time Fixes #659009.
-rw-r--r--gst/matroska/matroska-demux.c71
-rw-r--r--gst/matroska/matroska-demux.h3
2 files changed, 71 insertions, 3 deletions
diff --git a/gst/matroska/matroska-demux.c b/gst/matroska/matroska-demux.c
index 7fb4071d0..4b39dc929 100644
--- a/gst/matroska/matroska-demux.c
+++ b/gst/matroska/matroska-demux.c
@@ -81,9 +81,12 @@ enum
{
ARG_0,
ARG_METADATA,
- ARG_STREAMINFO
+ ARG_STREAMINFO,
+ ARG_MAX_GAP_TIME
};
+#define DEFAULT_MAX_GAP_TIME (2 * GST_SECOND)
+
static GstStaticPadTemplate sink_templ = GST_STATIC_PAD_TEMPLATE ("sink",
GST_PAD_SINK,
GST_PAD_ALWAYS,
@@ -168,6 +171,12 @@ static void gst_matroska_demux_reset (GstElement * element);
static gboolean perform_seek_to_offset (GstMatroskaDemux * demux,
guint64 offset);
+/* gobject functions */
+static void gst_matroska_demux_set_property (GObject * object,
+ guint prop_id, const GValue * value, GParamSpec * pspec);
+static void gst_matroska_demux_get_property (GObject * object,
+ guint prop_id, GValue * value, GParamSpec * pspec);
+
GType gst_matroska_demux_get_type (void);
GST_BOILERPLATE (GstMatroskaDemux, gst_matroska_demux, GstElement,
GST_TYPE_ELEMENT);
@@ -223,6 +232,15 @@ gst_matroska_demux_class_init (GstMatroskaDemuxClass * klass)
gobject_class->finalize = gst_matroska_demux_finalize;
+ gobject_class->get_property = gst_matroska_demux_get_property;
+ gobject_class->set_property = gst_matroska_demux_set_property;
+
+ g_object_class_install_property (gobject_class, ARG_MAX_GAP_TIME,
+ g_param_spec_uint64 ("max-gap-time", "Maximum gap time",
+ "The demuxer sends out newsegment events for skipping "
+ "gaps longer than this (0 = disabled).", 0, G_MAXUINT64,
+ DEFAULT_MAX_GAP_TIME, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
gstelement_class->change_state =
GST_DEBUG_FUNCPTR (gst_matroska_demux_change_state);
gstelement_class->send_event =
@@ -262,6 +280,9 @@ gst_matroska_demux_init (GstMatroskaDemux * demux,
demux->common.adapter = gst_adapter_new ();
+ /* property defaults */
+ demux->max_gap_time = DEFAULT_MAX_GAP_TIME;
+
/* finish off */
gst_matroska_demux_reset (GST_ELEMENT (demux));
}
@@ -3364,7 +3385,8 @@ gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
/* handle gaps, e.g. non-zero start-time, or an cue index entry
* that landed us with timestamps not quite intended */
GST_OBJECT_LOCK (demux);
- if (GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
+ if (demux->max_gap_time &&
+ GST_CLOCK_TIME_IS_VALID (demux->last_stop_end) &&
demux->common.segment.rate > 0.0) {
GstClockTimeDiff diff;
GstEvent *event1, *event2;
@@ -3373,7 +3395,8 @@ gst_matroska_demux_parse_blockgroup_or_simpleblock (GstMatroskaDemux * demux,
* otherwise if these go back and forth downstream (sinks) increase
* accumulated time and running_time */
diff = GST_CLOCK_DIFF (demux->last_stop_end, lace_time);
- if (diff > 2 * GST_SECOND && lace_time > demux->common.segment.start
+ if (diff > demux->max_gap_time
+ && lace_time > demux->common.segment.start
&& (!GST_CLOCK_TIME_IS_VALID (demux->common.segment.stop)
|| lace_time < demux->common.segment.stop)) {
GST_DEBUG_OBJECT (demux,
@@ -5412,6 +5435,48 @@ gst_matroska_demux_change_state (GstElement * element,
return ret;
}
+static void
+gst_matroska_demux_set_property (GObject * object,
+ guint prop_id, const GValue * value, GParamSpec * pspec)
+{
+ GstMatroskaDemux *demux;
+
+ g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
+ demux = GST_MATROSKA_DEMUX (object);
+
+ switch (prop_id) {
+ case ARG_MAX_GAP_TIME:
+ GST_OBJECT_LOCK (demux);
+ demux->max_gap_time = g_value_get_uint64 (value);
+ GST_OBJECT_UNLOCK (demux);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gst_matroska_demux_get_property (GObject * object,
+ guint prop_id, GValue * value, GParamSpec * pspec)
+{
+ GstMatroskaDemux *demux;
+
+ g_return_if_fail (GST_IS_MATROSKA_DEMUX (object));
+ demux = GST_MATROSKA_DEMUX (object);
+
+ switch (prop_id) {
+ case ARG_MAX_GAP_TIME:
+ GST_OBJECT_LOCK (demux);
+ g_value_set_uint64 (value, demux->max_gap_time);
+ GST_OBJECT_UNLOCK (demux);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
gboolean
gst_matroska_demux_plugin_init (GstPlugin * plugin)
{
diff --git a/gst/matroska/matroska-demux.h b/gst/matroska/matroska-demux.h
index c9ab2fc8e..192189f13 100644
--- a/gst/matroska/matroska-demux.h
+++ b/gst/matroska/matroska-demux.h
@@ -91,6 +91,9 @@ typedef struct _GstMatroskaDemux {
/* reverse playback */
GArray *seek_index;
gint seek_entry;
+
+ /* gap handling */
+ guint64 max_gap_time;
} GstMatroskaDemux;
typedef struct _GstMatroskaDemuxClass {