From 8e19b6a4d42af2f3a74bdf7df3c2f4ea67c09317 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Fri, 17 Jan 2003 20:41:04 +0000 Subject: [PATCH] - Error after configurable number of buffers Original commit message from CVS: - Error after configurable number of buffers --- gst/gsttypefind.c | 86 +++++++++++++++++++++++++++++++++++++---------- gst/gsttypefind.h | 13 ++++--- 2 files changed, 76 insertions(+), 23 deletions(-) diff --git a/gst/gsttypefind.c b/gst/gsttypefind.c index ccffac8acc..c5d9d7b903 100644 --- a/gst/gsttypefind.c +++ b/gst/gsttypefind.c @@ -22,13 +22,11 @@ #include "gst_private.h" - #include "gsttype.h" - #include "gstlog.h" #include "gsttypefind.h" -/* #define GST_DEBUG_ENABLED */ +#define DEFAULT_MAX_BUFFERS 1 GstElementDetails gst_type_find_details = { "TypeFind", @@ -51,6 +49,7 @@ enum { enum { ARG_0, ARG_CAPS, + ARG_MAX_BUFFERS, }; @@ -65,6 +64,8 @@ static void gst_type_find_get_property (GObject *object, guint prop_id, GParamSpec *pspec); static void gst_type_find_chain (GstPad *pad, GstBuffer *buf); +static GstElementStateReturn + gst_type_find_change_state (GstElement *element); static GstElementClass *parent_class = NULL; static guint gst_type_find_signals[LAST_SIGNAL] = { 0 }; @@ -96,22 +97,31 @@ static void gst_type_find_class_init (GstTypeFindClass *klass) { GObjectClass *gobject_class; + GstElementClass *gstelement_class; gobject_class = (GObjectClass*)klass; + gstelement_class = (GstElementClass*)klass; parent_class = g_type_class_ref (GST_TYPE_ELEMENT); - g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_CAPS, - g_param_spec_pointer("caps", "Caps", "Found capabilities", G_PARAM_READABLE)); + g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_CAPS, + g_param_spec_pointer ("caps", "Caps", "Found capabilities", G_PARAM_READABLE)); + g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MAX_BUFFERS, + g_param_spec_int ("max_buffers", + "Max Buffers", + "Maximal amount of buffers before giving en error (0 == unlimited)", + 0, G_MAXINT, DEFAULT_MAX_BUFFERS, G_PARAM_READWRITE)); gst_type_find_signals[HAVE_TYPE] = - g_signal_new ("have_type", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, + g_signal_new ("have_type", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstTypeFindClass, have_type), NULL, NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER); gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_type_find_set_property); gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_type_find_get_property); + + gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_type_find_change_state); } static void @@ -120,6 +130,10 @@ gst_type_find_init (GstTypeFind *typefind) typefind->sinkpad = gst_pad_new ("sink", GST_PAD_SINK); gst_element_add_pad (GST_ELEMENT (typefind), typefind->sinkpad); gst_pad_set_chain_function (typefind->sinkpad, gst_type_find_chain); + + typefind->num_buffer = 0; + typefind->max_buffers = DEFAULT_MAX_BUFFERS; + typefind->caps = NULL; } static void @@ -133,7 +147,11 @@ gst_type_find_set_property (GObject *object, guint prop_id, typefind = GST_TYPE_FIND (object); switch (prop_id) { + case ARG_MAX_BUFFERS: + typefind->max_buffers = g_value_get_int (value); + break; default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } @@ -150,9 +168,13 @@ gst_type_find_get_property (GObject *object, guint prop_id, switch (prop_id) { case ARG_CAPS: - g_value_set_pointer(value, typefind->caps); + g_value_set_pointer (value, typefind->caps); + break; + case ARG_MAX_BUFFERS: + g_value_set_int (value, typefind->max_buffers); break; default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } @@ -161,18 +183,17 @@ static void gst_type_find_chain (GstPad *pad, GstBuffer *buf) { GstTypeFind *typefind; - GList *type_list; + const GList *type_list; GstType *type; - g_return_if_fail (pad != NULL); g_return_if_fail (GST_IS_PAD (pad)); - g_return_if_fail (buf != NULL); typefind = GST_TYPE_FIND (GST_OBJECT_PARENT (pad)); + GST_DEBUG (0,"got buffer of %d bytes in '%s'", GST_BUFFER_SIZE (buf), GST_OBJECT_NAME (typefind)); - type_list = (GList *) gst_type_get_list (); + type_list = gst_type_get_list (); while (type_list) { GSList *factories; @@ -197,24 +218,53 @@ gst_type_find_chain (GstPad *pad, GstBuffer *buf) } { - /* int oldstate = GST_STATE(typefind);*/ gst_object_ref (GST_OBJECT (typefind)); g_signal_emit (G_OBJECT (typefind), gst_type_find_signals[HAVE_TYPE], 0, typefind->caps); -/* if (GST_STATE(typefind) != oldstate) { - GST_DEBUG(0, "state changed during signal, aborting"); - gst_element_interrupt (GST_ELEMENT (typefind)); - } */ gst_object_unref (GST_OBJECT (typefind)); - goto end; } } factories = g_slist_next (factories); } - type_list = g_list_next (type_list); } + + typefind->num_buffer++; + end: gst_buffer_unref (buf); + + if (typefind->num_buffer >= typefind->max_buffers) { + gst_element_error (GST_ELEMENT (typefind), + "typefind could not determine type after %d buffers", typefind->num_buffer); + } +} + +static GstElementStateReturn +gst_type_find_change_state (GstElement *element) +{ + GstTypeFind *typefind; + GstElementStateReturn ret; + + typefind = GST_TYPE_FIND (element); + + switch (GST_STATE_TRANSITION (element)) { + case GST_STATE_NULL_TO_READY: + break; + case GST_STATE_READY_TO_PAUSED: + typefind->num_buffer = 0; + gst_caps_unref (typefind->caps); + typefind->caps = NULL; + break; + case GST_STATE_PAUSED_TO_PLAYING: + case GST_STATE_PLAYING_TO_PAUSED: + case GST_STATE_PAUSED_TO_READY: + case GST_STATE_READY_TO_NULL: + break; + } + + ret = GST_ELEMENT_CLASS (parent_class)->change_state (element); + + return ret; } diff --git a/gst/gsttypefind.h b/gst/gsttypefind.h index dd65b276e7..e584a82397 100644 --- a/gst/gsttypefind.h +++ b/gst/gsttypefind.h @@ -43,18 +43,21 @@ typedef struct _GstTypeFind GstTypeFind; typedef struct _GstTypeFindClass GstTypeFindClass; struct _GstTypeFind { - GstElement element; + GstElement element; - GstPad *sinkpad; + GstPad *sinkpad; - GstCaps *caps; + GstCaps *caps; + + gint num_buffer; + gint max_buffers; }; struct _GstTypeFindClass { - GstElementClass parent_class; + GstElementClass parent_class; /* signals */ - void (*have_type) (GstElement *element); + void (*have_type) (GstElement *element); }; GType gst_type_find_get_type (void);