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.
This commit is contained in:
Ronald S. Bultje 2006-01-29 22:55:55 +00:00
parent 25c0f073ba
commit 2e63fa4f1d
6 changed files with 105 additions and 28 deletions

View file

@ -1,3 +1,18 @@
2006-01-29 Ronald S. Bultje <rbultje@ronald.bitfreak.net>
* 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 <thomas at apestaart dot org>
* docs/manual/Makefile.am:

2
common

@ -1 +1 @@
Subproject commit e0b121388ece524c0b7035a72bddd191d122d8bf
Subproject commit bc4325349e8d0ec90aa5c5e74566880cc2e82527

View file

@ -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)
{

View file

@ -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. */

View file

@ -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);
}
/**

View file

@ -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