diff --git a/gst/gstpipeline.c b/gst/gstpipeline.c index c17c759731..eb55a5f080 100644 --- a/gst/gstpipeline.c +++ b/gst/gstpipeline.c @@ -402,7 +402,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 diff --git a/libs/gst/base/gstbaseparse.c b/libs/gst/base/gstbaseparse.c index 13a599f875..7bf533f1ff 100644 --- a/libs/gst/base/gstbaseparse.c +++ b/libs/gst/base/gstbaseparse.c @@ -459,6 +459,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 @@ -488,10 +492,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; diff --git a/libs/gst/base/gstcollectpads2.c b/libs/gst/base/gstcollectpads2.c index 3741f7cf16..649e72ae2f 100644 --- a/libs/gst/base/gstcollectpads2.c +++ b/libs/gst/base/gstcollectpads2.c @@ -403,6 +403,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 @@ -1489,6 +1531,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; diff --git a/libs/gst/base/gstcollectpads2.h b/libs/gst/base/gstcollectpads2.h index 52d4736802..8625e733d9 100644 --- a/libs/gst/base/gstcollectpads2.h +++ b/libs/gst/base/gstcollectpads2.h @@ -383,6 +383,11 @@ GstBuffer* gst_collect_pads2_take_buffer (GstCollectPads2 * pads, GstColl 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 diff --git a/plugins/elements/gstfilesrc.c b/plugins/elements/gstfilesrc.c index 1e35ab4731..3471a90fb3 100644 --- a/plugins/elements/gstfilesrc.c +++ b/plugins/elements/gstfilesrc.c @@ -329,6 +329,7 @@ gst_file_src_fill (GstBaseSrc * basesrc, guint64 offset, guint length, GstBuffer * buf) { GstFileSrc *src; + guint to_read, bytes_read; int ret; guint8 *data; @@ -346,29 +347,33 @@ gst_file_src_fill (GstBaseSrc * basesrc, guint64 offset, guint length, data = gst_buffer_map (buf, NULL, NULL, GST_MAP_WRITE); - GST_LOG_OBJECT (src, "Reading %d bytes at offset 0x%" G_GINT64_MODIFIER "x", - length, offset); + bytes_read = 0; + to_read = length; + while (to_read > 0) { + GST_LOG_OBJECT (src, "Reading %d bytes at offset 0x%" G_GINT64_MODIFIER "x", + to_read, offset + bytes_read); + errno = 0; + ret = read (src->fd, data + bytes_read, to_read); + if (G_UNLIKELY (ret < 0)) { + if (errno == EAGAIN || errno == EINTR) + continue; + goto could_not_read; + } - ret = read (src->fd, data, length); - if (G_UNLIKELY (ret < 0)) - goto could_not_read; + /* files should eos if they read 0 and more was requested */ + if (G_UNLIKELY (ret == 0)) + goto eos; - /* seekable regular files should have given us what we expected */ - if (G_UNLIKELY ((guint) ret < length && src->seekable)) - goto unexpected_eos; + to_read -= ret; + bytes_read += ret; - /* other files should eos if they read 0 and more was requested */ - if (G_UNLIKELY (ret == 0)) - goto eos; + src->read_position += ret; + } - length = ret; - - gst_buffer_unmap (buf, data, length); + gst_buffer_unmap (buf, data, bytes_read); GST_BUFFER_OFFSET (buf) = offset; - GST_BUFFER_OFFSET_END (buf) = offset + length; - - src->read_position += length; + GST_BUFFER_OFFSET_END (buf) = offset + bytes_read; return GST_FLOW_OK; @@ -384,16 +389,9 @@ could_not_read: gst_buffer_unmap (buf, data, 0); return GST_FLOW_ERROR; } -unexpected_eos: - { - GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), - ("unexpected end of file.")); - gst_buffer_unmap (buf, data, 0); - return GST_FLOW_ERROR; - } eos: { - GST_DEBUG ("non-regular file hits EOS"); + GST_DEBUG ("EOS"); gst_buffer_unmap (buf, data, 0); return GST_FLOW_EOS; } diff --git a/win32/common/libgstbase.def b/win32/common/libgstbase.def index 0f554f6ee4..0e4a563bfa 100644 --- a/win32/common/libgstbase.def +++ b/win32/common/libgstbase.def @@ -212,6 +212,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