From f4040d3f6b0fabda92fbbb624cf11f13ff2c164f Mon Sep 17 00:00:00 2001 From: Matej Knopp Date: Mon, 14 Nov 2011 02:26:31 +0100 Subject: [PATCH 1/9] baseparse: Clear queued frames with other queues --- libs/gst/base/gstbaseparse.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libs/gst/base/gstbaseparse.c b/libs/gst/base/gstbaseparse.c index 9da9b49a02..64ba62fd20 100644 --- a/libs/gst/base/gstbaseparse.c +++ b/libs/gst/base/gstbaseparse.c @@ -456,6 +456,10 @@ gst_base_parse_clear_queues (GstBaseParse * parse) g_list_free (parse->priv->detect_buffers); parse->priv->detect_buffers = NULL; parse->priv->detect_buffers_size = 0; + + g_queue_foreach (&parse->priv->queued_frames, + (GFunc) gst_base_parse_frame_free, NULL); + g_queue_clear (&parse->priv->queued_frames); } static void @@ -485,10 +489,6 @@ gst_base_parse_finalize (GObject * object) g_list_free (parse->priv->pending_events); parse->priv->pending_events = NULL; - g_queue_foreach (&parse->priv->queued_frames, - (GFunc) gst_base_parse_frame_free, NULL); - g_queue_clear (&parse->priv->queued_frames); - if (parse->priv->index) { gst_object_unref (parse->priv->index); parse->priv->index = NULL; From 431fc714c927381e359c07a8599b8b2bc301f415 Mon Sep 17 00:00:00 2001 From: Vincent Penquerc'h Date: Mon, 12 Dec 2011 13:05:36 +0000 Subject: [PATCH 2/9] filesrc: do not mistake short reads for EOS While local filesystems will usually not cause short reads, this may happen on seekable files on some remote filesystems. Instead, loop till we get the requested amount of data, or an actual EOS (ie, 0 bytes). https://bugzilla.gnome.org/show_bug.cgi?id=665921 --- plugins/elements/gstfilesrc.c | 44 +++++++++++++++++------------------ 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/plugins/elements/gstfilesrc.c b/plugins/elements/gstfilesrc.c index f8dbfe2c4c..d2b88c6329 100644 --- a/plugins/elements/gstfilesrc.c +++ b/plugins/elements/gstfilesrc.c @@ -800,6 +800,7 @@ gst_file_src_create_read (GstFileSrc * src, guint64 offset, guint length, { int ret; GstBuffer *buf; + guint64 woffset; if (G_UNLIKELY (src->read_position != offset)) { off_t res; @@ -818,27 +819,31 @@ gst_file_src_create_read (GstFileSrc * src, guint64 offset, guint length, } /* No need to read anything if length is 0 */ - if (length > 0) { + GST_BUFFER_SIZE (buf) = 0; + GST_BUFFER_OFFSET (buf) = offset; + GST_BUFFER_OFFSET_END (buf) = offset; + woffset = 0; + while (length > 0) { GST_LOG_OBJECT (src, "Reading %d bytes at offset 0x%" G_GINT64_MODIFIER "x", - length, offset); - ret = read (src->fd, GST_BUFFER_DATA (buf), length); - if (G_UNLIKELY (ret < 0)) + length, offset + woffset); + errno = 0; + ret = read (src->fd, GST_BUFFER_DATA (buf) + woffset, length); + if (G_UNLIKELY (ret < 0)) { + if (errno == EAGAIN || errno == EINTR) + continue; goto could_not_read; + } - /* seekable regular files should have given us what we expected */ - if (G_UNLIKELY ((guint) ret < length && src->seekable)) - goto unexpected_eos; - - /* other files should eos if they read 0 and more was requested */ - if (G_UNLIKELY (ret == 0 && length > 0)) + /* files should eos if they read 0 and more was requested */ + if (G_UNLIKELY (ret == 0)) goto eos; - length = ret; - GST_BUFFER_SIZE (buf) = length; - GST_BUFFER_OFFSET (buf) = offset; - GST_BUFFER_OFFSET_END (buf) = offset + length; + length -= ret; + woffset += ret; + GST_BUFFER_SIZE (buf) += ret; + GST_BUFFER_OFFSET_END (buf) += ret; - src->read_position += length; + src->read_position += ret; } *buffer = buf; @@ -857,16 +862,9 @@ could_not_read: gst_buffer_unref (buf); return GST_FLOW_ERROR; } -unexpected_eos: - { - GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), - ("unexpected end of file.")); - gst_buffer_unref (buf); - return GST_FLOW_ERROR; - } eos: { - GST_DEBUG ("non-regular file hits EOS"); + GST_DEBUG ("EOS"); gst_buffer_unref (buf); return GST_FLOW_UNEXPECTED; } From 26e8e336ccf5742f47a816c5a17d8f3b0f491f17 Mon Sep 17 00:00:00 2001 From: Stefan Sauer Date: Thu, 15 Dec 2011 16:06:30 +0100 Subject: [PATCH 3/9] controller: user the parent_class vars from G_DEFINE_TYPE --- libs/gst/controller/gstinterpolationcontrolsource.c | 8 +++----- libs/gst/controller/gstlfocontrolsource.c | 7 ++----- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/libs/gst/controller/gstinterpolationcontrolsource.c b/libs/gst/controller/gstinterpolationcontrolsource.c index 2bdefeb8c6..1dd0a89fa3 100644 --- a/libs/gst/controller/gstinterpolationcontrolsource.c +++ b/libs/gst/controller/gstinterpolationcontrolsource.c @@ -51,8 +51,6 @@ GST_DEBUG_CATEGORY_EXTERN (GST_CAT_DEFAULT); G_DEFINE_TYPE (GstInterpolationControlSource, gst_interpolation_control_source, GST_TYPE_CONTROL_SOURCE); -static GObjectClass *parent_class = NULL; - /* * gst_control_point_free: * @prop: the object to free @@ -672,13 +670,14 @@ gst_interpolation_control_source_finalize (GObject * obj) gst_interpolation_control_source_reset (self); g_mutex_unlock (self->lock); g_mutex_free (self->lock); - G_OBJECT_CLASS (parent_class)->finalize (obj); + G_OBJECT_CLASS (gst_interpolation_control_source_parent_class)->finalize + (obj); } static void gst_interpolation_control_source_dispose (GObject * obj) { - G_OBJECT_CLASS (parent_class)->dispose (obj); + G_OBJECT_CLASS (gst_interpolation_control_source_parent_class)->dispose (obj); } static void @@ -688,7 +687,6 @@ gst_interpolation_control_source_class_init (GstInterpolationControlSourceClass GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GstControlSourceClass *csource_class = GST_CONTROL_SOURCE_CLASS (klass); - parent_class = g_type_class_peek_parent (klass); g_type_class_add_private (klass, sizeof (GstInterpolationControlSourcePrivate)); diff --git a/libs/gst/controller/gstlfocontrolsource.c b/libs/gst/controller/gstlfocontrolsource.c index 61396875d6..f462fdd6f9 100644 --- a/libs/gst/controller/gstlfocontrolsource.c +++ b/libs/gst/controller/gstlfocontrolsource.c @@ -608,8 +608,6 @@ gst_lfo_waveform_get_type (void) G_DEFINE_TYPE (GstLFOControlSource, gst_lfo_control_source, GST_TYPE_CONTROL_SOURCE); -static GObjectClass *parent_class = NULL; - static void gst_lfo_control_source_reset (GstLFOControlSource * self) { @@ -953,13 +951,13 @@ gst_lfo_control_source_finalize (GObject * obj) self->lock = NULL; } - G_OBJECT_CLASS (parent_class)->finalize (obj); + G_OBJECT_CLASS (gst_lfo_control_source_parent_class)->finalize (obj); } static void gst_lfo_control_source_dispose (GObject * obj) { - G_OBJECT_CLASS (parent_class)->dispose (obj); + G_OBJECT_CLASS (gst_lfo_control_source_parent_class)->dispose (obj); } static void @@ -1084,7 +1082,6 @@ gst_lfo_control_source_class_init (GstLFOControlSourceClass * klass) GObjectClass *gobject_class = G_OBJECT_CLASS (klass); GstControlSourceClass *csource_class = GST_CONTROL_SOURCE_CLASS (klass); - parent_class = g_type_class_peek_parent (klass); g_type_class_add_private (klass, sizeof (GstLFOControlSourcePrivate)); gobject_class->finalize = gst_lfo_control_source_finalize; From eb79c0a835f72eadc8c5ae82c7ced18333262dc5 Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Thu, 15 Dec 2011 14:31:05 +0100 Subject: [PATCH 4/9] collectpads2: delay collecting buffer if a pad newly set waiting ... as commented; make code correspond to it (again). --- libs/gst/base/gstcollectpads2.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libs/gst/base/gstcollectpads2.c b/libs/gst/base/gstcollectpads2.c index 0505da6028..932e3c903a 100644 --- a/libs/gst/base/gstcollectpads2.c +++ b/libs/gst/base/gstcollectpads2.c @@ -1527,6 +1527,7 @@ gst_collect_pads2_default_collected (GstCollectPads2 * pads, gpointer user_data) * so give another thread a chance to deliver a possibly * older buffer; don't charge on yet with the current oldest */ ret = GST_FLOW_OK; + goto done; } best = pads->earliest_data; From b3886b793544664de93e23286109dfb21ba0f5eb Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Mon, 19 Dec 2011 12:33:18 +0100 Subject: [PATCH 5/9] basetransform: suggestion compatible with upstream is not much of a suggestion ... in that upstream is already complying with that suggestion. Fixes #666174. --- libs/gst/base/gstbasetransform.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libs/gst/base/gstbasetransform.c b/libs/gst/base/gstbasetransform.c index 9f9c935897..4408ef2f8c 100644 --- a/libs/gst/base/gstbasetransform.c +++ b/libs/gst/base/gstbasetransform.c @@ -1866,7 +1866,8 @@ gst_base_transform_buffer_alloc (GstPad * pad, guint64 offset, guint size, } else { /* if we have a suggestion, pretend we got these as input */ GST_OBJECT_LOCK (pad); - if (priv->sink_suggest && !gst_caps_is_equal (caps, priv->sink_suggest)) { + if (priv->sink_suggest && + !gst_caps_can_intersect (caps, priv->sink_suggest)) { sink_suggest = gst_caps_ref (priv->sink_suggest); size_suggest = priv->size_suggest; GST_DEBUG_OBJECT (trans, "have suggestion %p %" GST_PTR_FORMAT " size %u", From 78565da18b1d5219b81728a3f63974a4071ef46f Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Mon, 19 Dec 2011 17:38:18 +0100 Subject: [PATCH 6/9] basetransform: do not delay sparse stream newsegment updates --- libs/gst/base/gstbasetransform.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/libs/gst/base/gstbasetransform.c b/libs/gst/base/gstbasetransform.c index 4408ef2f8c..dfaa359c80 100644 --- a/libs/gst/base/gstbasetransform.c +++ b/libs/gst/base/gstbasetransform.c @@ -2220,6 +2220,19 @@ gst_base_transform_sink_event (GstPad * pad, GstEvent * event) } else { delay = GST_EVENT_IS_SERIALIZED (event) && !caps_set && GST_EVENT_TYPE (event) != GST_EVENT_EOS; + + /* do not stall sparse stream update newsegment events */ + if (delay && (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT)) { + gboolean update; + + gst_event_parse_new_segment_full (event, &update, NULL, NULL, NULL, + NULL, NULL, NULL); + if (update) { + GST_DEBUG_OBJECT (trans, "update segment; triggering delayed events"); + delay = FALSE; + caps_set = TRUE; + } + } } if (delay) { From 28e9d735bbcf989b52062b0b299de1b2e1bb6aa8 Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Fri, 16 Dec 2011 17:59:22 +0100 Subject: [PATCH 7/9] collectpads2: add convenience clipping function ... which also converts to running time; useful for typical muxer. --- libs/gst/base/gstcollectpads2.c | 42 +++++++++++++++++++++++++++++++++ libs/gst/base/gstcollectpads2.h | 5 ++++ 2 files changed, 47 insertions(+) diff --git a/libs/gst/base/gstcollectpads2.c b/libs/gst/base/gstcollectpads2.c index 932e3c903a..3e51a0c615 100644 --- a/libs/gst/base/gstcollectpads2.c +++ b/libs/gst/base/gstcollectpads2.c @@ -401,6 +401,48 @@ gst_collect_pads2_set_event_function (GstCollectPads2 * pads, GST_OBJECT_UNLOCK (pads); } +/** +* gst_collect_pads2_clip_running: +* @pads: the collectspads to use +* @cdata: collect data of corrsponding pad +* @buf: buffer being clipped +* @outbuf: output buffer with running time, or NULL if clipped +* @user_data: user data (unused) +* +* Convenience clipping function that converts incoming buffer's timestamp +* to running time, or clips the buffer if outside configured segment. +* +* Since: 0.10.37 +*/ +GstFlowReturn +gst_collect_pads2_clip_running_time (GstCollectPads2 * pads, + GstCollectData2 * cdata, GstBuffer * buf, GstBuffer ** outbuf, + gpointer user_data) +{ + GstClockTime time; + + *outbuf = buf; + time = GST_BUFFER_TIMESTAMP (buf); + + /* invalid left alone and passed */ + if (G_LIKELY (GST_CLOCK_TIME_IS_VALID (time))) { + time = gst_segment_to_running_time (&cdata->segment, GST_FORMAT_TIME, time); + if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (time))) { + GST_DEBUG_OBJECT (cdata->pad, "clipping buffer on pad outside segment"); + gst_buffer_unref (buf); + *outbuf = NULL; + } else { + GST_LOG_OBJECT (cdata->pad, "buffer ts %" GST_TIME_FORMAT " -> %" + GST_TIME_FORMAT " running time", + GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)), GST_TIME_ARGS (time)); + *outbuf = gst_buffer_make_metadata_writable (buf); + GST_BUFFER_TIMESTAMP (*outbuf) = time; + } + } + + return GST_FLOW_OK; +} + /** * gst_collect_pads2_set_clip_function: * @pads: the collectspads to use diff --git a/libs/gst/base/gstcollectpads2.h b/libs/gst/base/gstcollectpads2.h index 208b547dc8..7890e7ae35 100644 --- a/libs/gst/base/gstcollectpads2.h +++ b/libs/gst/base/gstcollectpads2.h @@ -380,6 +380,11 @@ GstBuffer* gst_collect_pads2_take_buffer (GstCollectPads2 * pads, GstCollectData void gst_collect_pads2_set_waiting (GstCollectPads2 *pads, GstCollectData2 *data, gboolean waiting); +/* convenience helper */ +GstFlowReturn gst_collect_pads2_clip_running_time (GstCollectPads2 * pads, + GstCollectData2 * cdata, GstBuffer * buf, GstBuffer ** outbuf, + gpointer user_data); + G_END_DECLS From 434b5093ba2e36512a62e9865e840e411aeb087f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Mon, 19 Dec 2011 20:57:44 +0000 Subject: [PATCH 8/9] win32: add new collectpads2 function to .def file --- win32/common/libgstbase.def | 1 + 1 file changed, 1 insertion(+) diff --git a/win32/common/libgstbase.def b/win32/common/libgstbase.def index e68c0e976d..806ba6c76f 100644 --- a/win32/common/libgstbase.def +++ b/win32/common/libgstbase.def @@ -210,6 +210,7 @@ EXPORTS gst_collect_pads2_add_pad gst_collect_pads2_add_pad_full gst_collect_pads2_available + gst_collect_pads2_clip_running_time gst_collect_pads2_collect gst_collect_pads2_collect_range gst_collect_pads2_flush From f2d76b7e7b1af42963e3c252fcce9f5ac7911ce4 Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Fri, 2 Dec 2011 14:10:32 +0100 Subject: [PATCH 9/9] pipeline: only have a top-level pipeline do pipeline management Fixes #665390. --- gst/gstpipeline.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gst/gstpipeline.c b/gst/gstpipeline.c index b032c2f982..8612ae3e40 100644 --- a/gst/gstpipeline.c +++ b/gst/gstpipeline.c @@ -408,7 +408,9 @@ gst_pipeline_change_state (GstElement * element, GstStateChange transition) /* running time changed, either with a PAUSED or a flush, we need to check * if there is a new clock & update the base time */ - if (update_clock || last_start_time != start_time) { + /* only do this for top-level, however */ + if (GST_OBJECT_PARENT (element) == NULL && + (update_clock || last_start_time != start_time)) { GST_DEBUG_OBJECT (pipeline, "Need to update start_time"); /* when going to PLAYING, select a clock when needed. If we just got