From 2e63fa4f1d74a6f730b92811a9aeba0e95f6cbeb Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Sun, 29 Jan 2006 22:55:55 +0000 Subject: [PATCH] gst/elements/gstfdsrc.c: Implement querying. Original commit message from CVS: * gst/elements/gstfdsrc.c: (gst_fdsrc_init), (gst_fdsrc_get_query_types), (gst_fdsrc_get_formats), (gst_fdsrc_srcpad_query): Implement querying. * gst/gstqueue.c: (gst_queue_chain), (gst_queue_get): If we're waiting to be "full enough to start" and EOS comes in, just flow through all data since waiting longer is not going to help us. Fixes hangs on short media files played from network sources. * gst/gsttag.c: (_gst_tag_initialize): * gst/gsttag.h: Add GST_TAG_IMAGE tag. --- ChangeLog | 15 ++++++++++ common | 2 +- gst/elements/gstfdsrc.c | 44 +++++++++++++++++++++++++++++ gst/gstqueue.c | 62 +++++++++++++++++++++++------------------ gst/gsttag.c | 3 ++ gst/gsttag.h | 7 +++++ 6 files changed, 105 insertions(+), 28 deletions(-) diff --git a/ChangeLog b/ChangeLog index e9ce8523b8..73174f17cd 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2006-01-29 Ronald S. Bultje + + * gst/elements/gstfdsrc.c: (gst_fdsrc_init), + (gst_fdsrc_get_query_types), (gst_fdsrc_get_formats), + (gst_fdsrc_srcpad_query): + Implement querying. + * gst/gstqueue.c: (gst_queue_chain), (gst_queue_get): + If we're waiting to be "full enough to start" and EOS comes in, + just flow through all data since waiting longer is not going to + help us. Fixes hangs on short media files played from network + sources. + * gst/gsttag.c: (_gst_tag_initialize): + * gst/gsttag.h: + Add GST_TAG_IMAGE tag. + 2006-01-14 Thomas Vander Stichele * docs/manual/Makefile.am: diff --git a/common b/common index e0b121388e..bc4325349e 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit e0b121388ece524c0b7035a72bddd191d122d8bf +Subproject commit bc4325349e8d0ec90aa5c5e74566880cc2e82527 diff --git a/gst/elements/gstfdsrc.c b/gst/elements/gstfdsrc.c index fdeac10707..a88fb51fb6 100644 --- a/gst/elements/gstfdsrc.c +++ b/gst/elements/gstfdsrc.c @@ -103,6 +103,11 @@ static void gst_fdsrc_set_property (GObject * object, guint prop_id, static void gst_fdsrc_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); +static const GstQueryType *gst_fdsrc_get_query_types (GstPad * pad); +static const GstFormat *gst_fdsrc_get_formats (GstPad * pad); +static gboolean gst_fdsrc_srcpad_query (GstPad * pad, GstQueryType type, + GstFormat * fmt, gint64 * value); + static GstElementStateReturn gst_fdsrc_change_state (GstElement * element); static gboolean gst_fdsrc_release_locks (GstElement * element); static GstData *gst_fdsrc_get (GstPad * pad); @@ -168,6 +173,9 @@ gst_fdsrc_init (GstFdSrc * fdsrc) "src"); gst_pad_set_get_function (fdsrc->srcpad, gst_fdsrc_get); + gst_pad_set_query_function (fdsrc->srcpad, gst_fdsrc_srcpad_query); + gst_pad_set_query_type_function (fdsrc->srcpad, gst_fdsrc_get_query_types); + gst_pad_set_formats_function (fdsrc->srcpad, gst_fdsrc_get_formats); gst_element_add_pad (GST_ELEMENT (fdsrc), fdsrc->srcpad); fdsrc->fd = 0; @@ -178,6 +186,42 @@ gst_fdsrc_init (GstFdSrc * fdsrc) fdsrc->seq = 0; } +static const GstQueryType * +gst_fdsrc_get_query_types (GstPad * pad) +{ + static const GstQueryType types[] = { + GST_QUERY_POSITION, + 0 + }; + + return types; +} + +static const GstFormat * +gst_fdsrc_get_formats (GstPad * pad) +{ + static const GstFormat formats[] = { + GST_FORMAT_BYTES, + 0, + }; + + return formats; +} + +static gboolean +gst_fdsrc_srcpad_query (GstPad * pad, GstQueryType type, + GstFormat * format, gint64 * value) +{ + GstFdSrc *fdsrc = GST_FDSRC (gst_pad_get_parent (pad)); + + if (*format != GST_FORMAT_BYTES || type != GST_QUERY_POSITION) + return FALSE; + + *value = fdsrc->curoffset; + + return TRUE; +} + static GstElementStateReturn gst_fdsrc_change_state (GstElement * element) { diff --git a/gst/gstqueue.c b/gst/gstqueue.c index 0d388cf5a4..1b46973922 100644 --- a/gst/gstqueue.c +++ b/gst/gstqueue.c @@ -59,6 +59,21 @@ GST_DEBUG_CATEGORY_STATIC (queue_dataflow); queue->min_threshold.time, \ queue->max_size.time, \ queue->queue->length) +#define IS_FULL(queue) \ + ((queue->max_size.buffers > 0 && \ + queue->cur_level.buffers >= queue->max_size.buffers) || \ + (queue->max_size.bytes > 0 && \ + queue->cur_level.bytes >= queue->max_size.bytes) || \ + (queue->max_size.time > 0 && \ + queue->cur_level.time >= queue->max_size.time)) +#define IS_EMPTY(queue) \ + (queue->queue->length == 0 || \ + (queue->min_threshold.buffers > 0 && \ + queue->cur_level.buffers < queue->min_threshold.buffers) || \ + (queue->min_threshold.bytes > 0 && \ + queue->cur_level.bytes < queue->min_threshold.bytes) || \ + (queue->min_threshold.time > 0 && \ + queue->cur_level.time < queue->min_threshold.time)) static GstElementDetails gst_queue_details = GST_ELEMENT_DETAILS ("Queue", "Generic", @@ -592,14 +607,10 @@ restart: * and filler events with a duration * We always handle events and they don't count in our statistics. */ if ((GST_IS_BUFFER (data) || - (GST_IS_EVENT (data) && GST_EVENT_TYPE (data) == GST_EVENT_FILLER && + (GST_IS_EVENT (data) && + GST_EVENT_TYPE (data) == GST_EVENT_FILLER && gst_event_filler_get_duration (GST_EVENT (data)) != - GST_CLOCK_TIME_NONE)) && ((queue->max_size.buffers > 0 - && queue->cur_level.buffers >= queue->max_size.buffers) - || (queue->max_size.bytes > 0 - && queue->cur_level.bytes >= queue->max_size.bytes) - || (queue->max_size.time > 0 - && queue->cur_level.time >= queue->max_size.time))) { + GST_CLOCK_TIME_NONE)) && IS_FULL (queue)) { GST_QUEUE_MUTEX_UNLOCK; g_signal_emit (G_OBJECT (queue), gst_queue_signals[SIGNAL_OVERRUN], 0); GST_QUEUE_MUTEX_LOCK; @@ -663,12 +674,7 @@ restart: case GST_QUEUE_NO_LEAK: STATUS (queue, "pre-full wait"); - while ((queue->max_size.buffers > 0 && - queue->cur_level.buffers >= queue->max_size.buffers) || - (queue->max_size.bytes > 0 && - queue->cur_level.bytes >= queue->max_size.bytes) || - (queue->max_size.time > 0 && - queue->cur_level.time >= queue->max_size.time)) { + while (IS_FULL (queue)) { /* if there's a pending state change for this queue * or its manager, switch back to iterator so bottom * half of state change executes */ @@ -793,25 +799,27 @@ restart: /* have to lock for thread-safety */ GST_QUEUE_MUTEX_LOCK; - if (queue->queue->length == 0 || - (queue->min_threshold.buffers > 0 && - queue->cur_level.buffers < queue->min_threshold.buffers) || - (queue->min_threshold.bytes > 0 && - queue->cur_level.bytes < queue->min_threshold.bytes) || - (queue->min_threshold.time > 0 && - queue->cur_level.time < queue->min_threshold.time)) { + if (IS_EMPTY (queue)) { GST_QUEUE_MUTEX_UNLOCK; g_signal_emit (G_OBJECT (queue), gst_queue_signals[SIGNAL_UNDERRUN], 0); GST_QUEUE_MUTEX_LOCK; STATUS (queue, "pre-empty wait"); - while (queue->queue->length == 0 || - (queue->min_threshold.buffers > 0 && - queue->cur_level.buffers < queue->min_threshold.buffers) || - (queue->min_threshold.bytes > 0 && - queue->cur_level.bytes < queue->min_threshold.bytes) || - (queue->min_threshold.time > 0 && - queue->cur_level.time < queue->min_threshold.time)) { + while (IS_EMPTY (queue)) { + /* if there's an EOS in the queue, just run */ + GList *item; + gboolean got_eos = FALSE; + + for (item = queue->queue->head; item != NULL; item = item->next) { + if (GST_IS_EVENT (item->data) && + GST_EVENT_TYPE (item->data) == GST_EVENT_EOS) { + GST_CAT_DEBUG (queue_dataflow, "got eos, exit loop"); + got_eos = TRUE; + break; + } + } + if (got_eos) + break; /* if there's a pending state change for this queue or its * manager, switch back to iterator so bottom half of state * change executes. */ diff --git a/gst/gsttag.c b/gst/gsttag.c index 28ab69fd37..a159e753f9 100644 --- a/gst/gsttag.c +++ b/gst/gsttag.c @@ -25,6 +25,7 @@ #include "gst_private.h" #include "gst-i18n-lib.h" +#include "gstbuffer.h" #include "gsttag.h" #include "gstinfo.h" #include "gstvalue.h" @@ -191,6 +192,8 @@ _gst_tag_initialize (void) gst_tag_register (GST_TAG_LANGUAGE_CODE, GST_TAG_FLAG_META, G_TYPE_STRING, _("language code"), _("language code for this stream, conforming to ISO-639-1"), NULL); + gst_tag_register (GST_TAG_IMAGE, GST_TAG_FLAG_META, GST_TYPE_BUFFER, + _("image"), _("cover art or image for screenshot display"), NULL); } /** diff --git a/gst/gsttag.h b/gst/gsttag.h index f7bca61aba..d7c24cd664 100644 --- a/gst/gsttag.h +++ b/gst/gsttag.h @@ -436,6 +436,13 @@ GstTagList * gst_event_tag_get_list (GstEvent * tag_event); * Language code (ISO-639-1) */ #define GST_TAG_LANGUAGE_CODE "language-code" +/** + * GST_TAG_IMAGE: + * + * Image, such as cover art or screenshot in movie (if explicitely + * supplied in media) + */ +#define GST_TAG_IMAGE "image" G_END_DECLS