diff --git a/gst/autoplug/gstspideridentity.c b/gst/autoplug/gstspideridentity.c index 4f7fd5d290..49bb4d81ed 100644 --- a/gst/autoplug/gstspideridentity.c +++ b/gst/autoplug/gstspideridentity.c @@ -430,7 +430,8 @@ spider_find_peek (gpointer data, gint64 offset, guint size) return NULL; } } -void spider_find_suggest (gpointer data, guint probability, GstCaps *caps) +static void +spider_find_suggest (gpointer data, guint probability, GstCaps *caps) { SpiderTypeFind *find = (SpiderTypeFind *) data; G_GNUC_UNUSED gchar *caps_str; @@ -459,6 +460,7 @@ gst_spider_identity_sink_loop_type_finding (GstSpiderIdentity *ident) data = gst_pad_pull (ident->sink); } + find.buffer = GST_BUFFER (data); /* maybe there are already valid caps now? */ if ((find.caps = gst_pad_get_caps (ident->sink)) != NULL) { gst_caps_ref (find.caps); /* it's unrefed later below */ @@ -468,7 +470,6 @@ gst_spider_identity_sink_loop_type_finding (GstSpiderIdentity *ident) /* now do the actual typefinding with the supplied buffer */ type_list = gst_type_find_factory_get_list (); - find.buffer = GST_BUFFER (data); find.best_probability = 0; find.caps = NULL; gst_find.data = &find; diff --git a/gst/elements/gstbufferstore.c b/gst/elements/gstbufferstore.c index 035e722200..38e6c9e341 100644 --- a/gst/elements/gstbufferstore.c +++ b/gst/elements/gstbufferstore.c @@ -143,7 +143,7 @@ gst_buffer_store_add_buffer_func (GstBufferStore *store, GstBuffer *buffer) GST_LOG_OBJECT (store, "adding buffer %p with invalid offset and size %u", buffer, GST_BUFFER_SIZE (buffer)); gst_data_ref (GST_DATA (buffer)); - g_list_append (store->buffers, buffer); + store->buffers = g_list_append (store->buffers, buffer); return TRUE; } else { /* both list and buffer have valid offsets, we can really go wild */ @@ -326,6 +326,8 @@ gst_buffer_store_get_buffer (GstBufferStore *store, guint64 offset, guint size) current, offset, size); ret = current; gst_data_ref (GST_DATA (ret)); + GST_LOG_OBJECT (store, "refcount %d", + GST_DATA_REFCOUNT_VALUE(ret)); break; } else if (cur_offset + GST_BUFFER_SIZE (current) > offset) { if (cur_offset + GST_BUFFER_SIZE (current) >= offset + size) { diff --git a/gst/elements/gsttypefind.c b/gst/elements/gsttypefind.c index b383b03750..d5a7f3db0e 100644 --- a/gst/elements/gsttypefind.c +++ b/gst/elements/gsttypefind.c @@ -19,6 +19,8 @@ * Boston, MA 02111-1307, USA. */ +/* FIXME: need a better solution for non-seekable streams */ + /* way of operation: * 1) get a list of all typefind functions sorted best to worst * 2) if all elements have been called with all requested data goto 8 @@ -99,6 +101,11 @@ static void gst_type_find_element_get_property (GObject * object, GValue * value, GParamSpec * pspec); +static const GstEventMask * + gst_type_find_element_src_event_mask (GstPad * pad); +static gboolean gst_type_find_element_src_event (GstPad * pad, + GstEvent * event); + static void gst_type_find_element_chain (GstPad * sinkpad, GstData * data); static GstElementStateReturn @@ -197,6 +204,8 @@ gst_type_find_element_init (GTypeInstance *instance, gpointer g_class) /* srcpad */ typefind->src = gst_pad_new_from_template ( GST_PAD_TEMPLATE_GET (type_find_element_src_factory), "src"); + gst_pad_set_event_function (typefind->src, gst_type_find_element_src_event); + gst_pad_set_event_mask_function (typefind->src, gst_type_find_element_src_event_mask); gst_element_add_pad (GST_ELEMENT (typefind), typefind->src); typefind->caps = NULL; @@ -268,6 +277,29 @@ gst_type_find_element_get_property (GObject *object, guint prop_id, break; } } +static const GstEventMask * +gst_type_find_element_src_event_mask (GstPad *pad) +{ + static const GstEventMask mask[] = { + { GST_EVENT_SEEK, GST_SEEK_METHOD_SET | GST_SEEK_METHOD_CUR | GST_SEEK_METHOD_END | GST_SEEK_FLAG_FLUSH}, + /* add more if you want, event masks suck and need to die anyway */ + { 0, } + }; + + return mask; +} +static gboolean +gst_type_find_element_src_event (GstPad *pad, GstEvent *event) +{ + GstTypeFindElement *typefind = GST_TYPE_FIND_ELEMENT (GST_PAD_PARENT (pad)); + + if (typefind->mode == MODE_TYPEFIND) { + /* need to do more? */ + gst_data_unref (GST_DATA (event)); + return FALSE; + } + return gst_pad_event_default (pad, event); +} static void start_typefinding (GstTypeFindElement *typefind) { @@ -279,32 +311,14 @@ start_typefinding (GstTypeFindElement *typefind) typefind->stream_length = 0; } static void -stop_typefinding (GstTypeFindElement *typefind) -{ - /* stop all typefinding and set mode back to normal */ - gboolean push_cached_buffers = gst_element_get_state (GST_ELEMENT (typefind)) == GST_STATE_PLAYING; - - g_assert (typefind->possibilities == NULL); - - GST_LOG_OBJECT (typefind, "stopping typefinding%s", push_cached_buffers ? " and pushing cached buffers" : ""); - typefind->mode = MODE_NORMAL; - - if (push_cached_buffers) { - GstBuffer *buffer; - guint size = gst_buffer_store_get_size (typefind->store, 0); - if (size && (buffer = gst_buffer_store_get_buffer (typefind->store, 0, size))) { - gst_pad_push (typefind->src, GST_DATA (buffer)); - } else { - size = 0; - } - gst_pad_send_event (GST_PAD_PEER (typefind->sink), - gst_event_new_seek (GST_SEEK_METHOD_SET, size)); - } - gst_buffer_store_clear (typefind->store); -} -static void gst_type_find_element_handle_event (GstPad *pad, GstEvent *event) { + GstTypeFindElement *typefind = GST_TYPE_FIND_ELEMENT (GST_PAD_PARENT (pad)); + + if (typefind->mode == MODE_TYPEFIND) { + /* need to do more? */ + gst_data_unref (GST_DATA (event)); + } gst_pad_event_default (pad, event); } typedef struct { @@ -333,6 +347,40 @@ free_entry (TypeFindEntry *entry) gst_caps_unref (entry->caps); g_free (entry); } +static void +stop_typefinding (GstTypeFindElement *typefind) +{ + /* stop all typefinding and set mode back to normal */ + gboolean push_cached_buffers = gst_element_get_state (GST_ELEMENT (typefind)) == GST_STATE_PLAYING; + + GST_LOG_OBJECT (typefind, "stopping typefinding%s", push_cached_buffers ? " and pushing cached buffers" : ""); + if (typefind->possibilities != NULL) { + /* this can only happen on PAUSED => READY */ + GST_LOG_OBJECT (typefind, "freeing remaining %u typefind functions", g_list_length (typefind->possibilities)); + g_assert (push_cached_buffers == FALSE); + g_list_foreach (typefind->possibilities, (GFunc) free_entry, NULL); + g_list_free (typefind->possibilities); + typefind->possibilities = NULL; + } + + typefind->mode = MODE_NORMAL; + + if (push_cached_buffers) { + GstBuffer *buffer; + guint size = gst_buffer_store_get_size (typefind->store, 0); + if (size && (buffer = gst_buffer_store_get_buffer (typefind->store, 0, size))) { + gst_pad_push (typefind->src, GST_DATA (buffer)); + } else { + size = 0; + } + GST_LOG_OBJECT (typefind, "seeking back to current position %u", size); + if (!gst_pad_send_event (GST_PAD_PEER (typefind->sink), + gst_event_new_seek (GST_SEEK_METHOD_SET | GST_FORMAT_BYTES, size))) { + GST_WARNING_OBJECT (typefind, "could not seek to required position %u, hope for the best", size); + } + } + gst_buffer_store_clear (typefind->store); +} static guint64 find_element_get_length (gpointer data) { diff --git a/gst/elements/gsttypefindelement.c b/gst/elements/gsttypefindelement.c index b383b03750..d5a7f3db0e 100644 --- a/gst/elements/gsttypefindelement.c +++ b/gst/elements/gsttypefindelement.c @@ -19,6 +19,8 @@ * Boston, MA 02111-1307, USA. */ +/* FIXME: need a better solution for non-seekable streams */ + /* way of operation: * 1) get a list of all typefind functions sorted best to worst * 2) if all elements have been called with all requested data goto 8 @@ -99,6 +101,11 @@ static void gst_type_find_element_get_property (GObject * object, GValue * value, GParamSpec * pspec); +static const GstEventMask * + gst_type_find_element_src_event_mask (GstPad * pad); +static gboolean gst_type_find_element_src_event (GstPad * pad, + GstEvent * event); + static void gst_type_find_element_chain (GstPad * sinkpad, GstData * data); static GstElementStateReturn @@ -197,6 +204,8 @@ gst_type_find_element_init (GTypeInstance *instance, gpointer g_class) /* srcpad */ typefind->src = gst_pad_new_from_template ( GST_PAD_TEMPLATE_GET (type_find_element_src_factory), "src"); + gst_pad_set_event_function (typefind->src, gst_type_find_element_src_event); + gst_pad_set_event_mask_function (typefind->src, gst_type_find_element_src_event_mask); gst_element_add_pad (GST_ELEMENT (typefind), typefind->src); typefind->caps = NULL; @@ -268,6 +277,29 @@ gst_type_find_element_get_property (GObject *object, guint prop_id, break; } } +static const GstEventMask * +gst_type_find_element_src_event_mask (GstPad *pad) +{ + static const GstEventMask mask[] = { + { GST_EVENT_SEEK, GST_SEEK_METHOD_SET | GST_SEEK_METHOD_CUR | GST_SEEK_METHOD_END | GST_SEEK_FLAG_FLUSH}, + /* add more if you want, event masks suck and need to die anyway */ + { 0, } + }; + + return mask; +} +static gboolean +gst_type_find_element_src_event (GstPad *pad, GstEvent *event) +{ + GstTypeFindElement *typefind = GST_TYPE_FIND_ELEMENT (GST_PAD_PARENT (pad)); + + if (typefind->mode == MODE_TYPEFIND) { + /* need to do more? */ + gst_data_unref (GST_DATA (event)); + return FALSE; + } + return gst_pad_event_default (pad, event); +} static void start_typefinding (GstTypeFindElement *typefind) { @@ -279,32 +311,14 @@ start_typefinding (GstTypeFindElement *typefind) typefind->stream_length = 0; } static void -stop_typefinding (GstTypeFindElement *typefind) -{ - /* stop all typefinding and set mode back to normal */ - gboolean push_cached_buffers = gst_element_get_state (GST_ELEMENT (typefind)) == GST_STATE_PLAYING; - - g_assert (typefind->possibilities == NULL); - - GST_LOG_OBJECT (typefind, "stopping typefinding%s", push_cached_buffers ? " and pushing cached buffers" : ""); - typefind->mode = MODE_NORMAL; - - if (push_cached_buffers) { - GstBuffer *buffer; - guint size = gst_buffer_store_get_size (typefind->store, 0); - if (size && (buffer = gst_buffer_store_get_buffer (typefind->store, 0, size))) { - gst_pad_push (typefind->src, GST_DATA (buffer)); - } else { - size = 0; - } - gst_pad_send_event (GST_PAD_PEER (typefind->sink), - gst_event_new_seek (GST_SEEK_METHOD_SET, size)); - } - gst_buffer_store_clear (typefind->store); -} -static void gst_type_find_element_handle_event (GstPad *pad, GstEvent *event) { + GstTypeFindElement *typefind = GST_TYPE_FIND_ELEMENT (GST_PAD_PARENT (pad)); + + if (typefind->mode == MODE_TYPEFIND) { + /* need to do more? */ + gst_data_unref (GST_DATA (event)); + } gst_pad_event_default (pad, event); } typedef struct { @@ -333,6 +347,40 @@ free_entry (TypeFindEntry *entry) gst_caps_unref (entry->caps); g_free (entry); } +static void +stop_typefinding (GstTypeFindElement *typefind) +{ + /* stop all typefinding and set mode back to normal */ + gboolean push_cached_buffers = gst_element_get_state (GST_ELEMENT (typefind)) == GST_STATE_PLAYING; + + GST_LOG_OBJECT (typefind, "stopping typefinding%s", push_cached_buffers ? " and pushing cached buffers" : ""); + if (typefind->possibilities != NULL) { + /* this can only happen on PAUSED => READY */ + GST_LOG_OBJECT (typefind, "freeing remaining %u typefind functions", g_list_length (typefind->possibilities)); + g_assert (push_cached_buffers == FALSE); + g_list_foreach (typefind->possibilities, (GFunc) free_entry, NULL); + g_list_free (typefind->possibilities); + typefind->possibilities = NULL; + } + + typefind->mode = MODE_NORMAL; + + if (push_cached_buffers) { + GstBuffer *buffer; + guint size = gst_buffer_store_get_size (typefind->store, 0); + if (size && (buffer = gst_buffer_store_get_buffer (typefind->store, 0, size))) { + gst_pad_push (typefind->src, GST_DATA (buffer)); + } else { + size = 0; + } + GST_LOG_OBJECT (typefind, "seeking back to current position %u", size); + if (!gst_pad_send_event (GST_PAD_PEER (typefind->sink), + gst_event_new_seek (GST_SEEK_METHOD_SET | GST_FORMAT_BYTES, size))) { + GST_WARNING_OBJECT (typefind, "could not seek to required position %u, hope for the best", size); + } + } + gst_buffer_store_clear (typefind->store); +} static guint64 find_element_get_length (gpointer data) { diff --git a/libs/gst/bytestream/bytestream.c b/libs/gst/bytestream/bytestream.c index 06e1259d9f..8476806d13 100644 --- a/libs/gst/bytestream/bytestream.c +++ b/libs/gst/bytestream/bytestream.c @@ -78,8 +78,6 @@ gst_bytestream_new (GstPad * pad) { GstByteStream *bs = g_new (GstByteStream, 1); - GST_DEBUG_CATEGORY_INIT (debug_bs, "bytestream", 0, "bytestream library"); - bs->pad = pad; gst_bytestream_init (bs); @@ -750,6 +748,8 @@ gst_bytestream_print_status (GstByteStream * bs) static gboolean plugin_init (GModule *module, GstPlugin *plugin) { + GST_DEBUG_CATEGORY_INIT (debug_bs, "bytestream", 0, "bytestream library"); + gst_plugin_set_longname (plugin, "GstByteStream: a byte-oriented layer on top of buffer-passing"); return TRUE; } diff --git a/plugins/elements/gstbufferstore.c b/plugins/elements/gstbufferstore.c index 035e722200..38e6c9e341 100644 --- a/plugins/elements/gstbufferstore.c +++ b/plugins/elements/gstbufferstore.c @@ -143,7 +143,7 @@ gst_buffer_store_add_buffer_func (GstBufferStore *store, GstBuffer *buffer) GST_LOG_OBJECT (store, "adding buffer %p with invalid offset and size %u", buffer, GST_BUFFER_SIZE (buffer)); gst_data_ref (GST_DATA (buffer)); - g_list_append (store->buffers, buffer); + store->buffers = g_list_append (store->buffers, buffer); return TRUE; } else { /* both list and buffer have valid offsets, we can really go wild */ @@ -326,6 +326,8 @@ gst_buffer_store_get_buffer (GstBufferStore *store, guint64 offset, guint size) current, offset, size); ret = current; gst_data_ref (GST_DATA (ret)); + GST_LOG_OBJECT (store, "refcount %d", + GST_DATA_REFCOUNT_VALUE(ret)); break; } else if (cur_offset + GST_BUFFER_SIZE (current) > offset) { if (cur_offset + GST_BUFFER_SIZE (current) >= offset + size) { diff --git a/plugins/elements/gsttypefind.c b/plugins/elements/gsttypefind.c index b383b03750..d5a7f3db0e 100644 --- a/plugins/elements/gsttypefind.c +++ b/plugins/elements/gsttypefind.c @@ -19,6 +19,8 @@ * Boston, MA 02111-1307, USA. */ +/* FIXME: need a better solution for non-seekable streams */ + /* way of operation: * 1) get a list of all typefind functions sorted best to worst * 2) if all elements have been called with all requested data goto 8 @@ -99,6 +101,11 @@ static void gst_type_find_element_get_property (GObject * object, GValue * value, GParamSpec * pspec); +static const GstEventMask * + gst_type_find_element_src_event_mask (GstPad * pad); +static gboolean gst_type_find_element_src_event (GstPad * pad, + GstEvent * event); + static void gst_type_find_element_chain (GstPad * sinkpad, GstData * data); static GstElementStateReturn @@ -197,6 +204,8 @@ gst_type_find_element_init (GTypeInstance *instance, gpointer g_class) /* srcpad */ typefind->src = gst_pad_new_from_template ( GST_PAD_TEMPLATE_GET (type_find_element_src_factory), "src"); + gst_pad_set_event_function (typefind->src, gst_type_find_element_src_event); + gst_pad_set_event_mask_function (typefind->src, gst_type_find_element_src_event_mask); gst_element_add_pad (GST_ELEMENT (typefind), typefind->src); typefind->caps = NULL; @@ -268,6 +277,29 @@ gst_type_find_element_get_property (GObject *object, guint prop_id, break; } } +static const GstEventMask * +gst_type_find_element_src_event_mask (GstPad *pad) +{ + static const GstEventMask mask[] = { + { GST_EVENT_SEEK, GST_SEEK_METHOD_SET | GST_SEEK_METHOD_CUR | GST_SEEK_METHOD_END | GST_SEEK_FLAG_FLUSH}, + /* add more if you want, event masks suck and need to die anyway */ + { 0, } + }; + + return mask; +} +static gboolean +gst_type_find_element_src_event (GstPad *pad, GstEvent *event) +{ + GstTypeFindElement *typefind = GST_TYPE_FIND_ELEMENT (GST_PAD_PARENT (pad)); + + if (typefind->mode == MODE_TYPEFIND) { + /* need to do more? */ + gst_data_unref (GST_DATA (event)); + return FALSE; + } + return gst_pad_event_default (pad, event); +} static void start_typefinding (GstTypeFindElement *typefind) { @@ -279,32 +311,14 @@ start_typefinding (GstTypeFindElement *typefind) typefind->stream_length = 0; } static void -stop_typefinding (GstTypeFindElement *typefind) -{ - /* stop all typefinding and set mode back to normal */ - gboolean push_cached_buffers = gst_element_get_state (GST_ELEMENT (typefind)) == GST_STATE_PLAYING; - - g_assert (typefind->possibilities == NULL); - - GST_LOG_OBJECT (typefind, "stopping typefinding%s", push_cached_buffers ? " and pushing cached buffers" : ""); - typefind->mode = MODE_NORMAL; - - if (push_cached_buffers) { - GstBuffer *buffer; - guint size = gst_buffer_store_get_size (typefind->store, 0); - if (size && (buffer = gst_buffer_store_get_buffer (typefind->store, 0, size))) { - gst_pad_push (typefind->src, GST_DATA (buffer)); - } else { - size = 0; - } - gst_pad_send_event (GST_PAD_PEER (typefind->sink), - gst_event_new_seek (GST_SEEK_METHOD_SET, size)); - } - gst_buffer_store_clear (typefind->store); -} -static void gst_type_find_element_handle_event (GstPad *pad, GstEvent *event) { + GstTypeFindElement *typefind = GST_TYPE_FIND_ELEMENT (GST_PAD_PARENT (pad)); + + if (typefind->mode == MODE_TYPEFIND) { + /* need to do more? */ + gst_data_unref (GST_DATA (event)); + } gst_pad_event_default (pad, event); } typedef struct { @@ -333,6 +347,40 @@ free_entry (TypeFindEntry *entry) gst_caps_unref (entry->caps); g_free (entry); } +static void +stop_typefinding (GstTypeFindElement *typefind) +{ + /* stop all typefinding and set mode back to normal */ + gboolean push_cached_buffers = gst_element_get_state (GST_ELEMENT (typefind)) == GST_STATE_PLAYING; + + GST_LOG_OBJECT (typefind, "stopping typefinding%s", push_cached_buffers ? " and pushing cached buffers" : ""); + if (typefind->possibilities != NULL) { + /* this can only happen on PAUSED => READY */ + GST_LOG_OBJECT (typefind, "freeing remaining %u typefind functions", g_list_length (typefind->possibilities)); + g_assert (push_cached_buffers == FALSE); + g_list_foreach (typefind->possibilities, (GFunc) free_entry, NULL); + g_list_free (typefind->possibilities); + typefind->possibilities = NULL; + } + + typefind->mode = MODE_NORMAL; + + if (push_cached_buffers) { + GstBuffer *buffer; + guint size = gst_buffer_store_get_size (typefind->store, 0); + if (size && (buffer = gst_buffer_store_get_buffer (typefind->store, 0, size))) { + gst_pad_push (typefind->src, GST_DATA (buffer)); + } else { + size = 0; + } + GST_LOG_OBJECT (typefind, "seeking back to current position %u", size); + if (!gst_pad_send_event (GST_PAD_PEER (typefind->sink), + gst_event_new_seek (GST_SEEK_METHOD_SET | GST_FORMAT_BYTES, size))) { + GST_WARNING_OBJECT (typefind, "could not seek to required position %u, hope for the best", size); + } + } + gst_buffer_store_clear (typefind->store); +} static guint64 find_element_get_length (gpointer data) { diff --git a/plugins/elements/gsttypefindelement.c b/plugins/elements/gsttypefindelement.c index b383b03750..d5a7f3db0e 100644 --- a/plugins/elements/gsttypefindelement.c +++ b/plugins/elements/gsttypefindelement.c @@ -19,6 +19,8 @@ * Boston, MA 02111-1307, USA. */ +/* FIXME: need a better solution for non-seekable streams */ + /* way of operation: * 1) get a list of all typefind functions sorted best to worst * 2) if all elements have been called with all requested data goto 8 @@ -99,6 +101,11 @@ static void gst_type_find_element_get_property (GObject * object, GValue * value, GParamSpec * pspec); +static const GstEventMask * + gst_type_find_element_src_event_mask (GstPad * pad); +static gboolean gst_type_find_element_src_event (GstPad * pad, + GstEvent * event); + static void gst_type_find_element_chain (GstPad * sinkpad, GstData * data); static GstElementStateReturn @@ -197,6 +204,8 @@ gst_type_find_element_init (GTypeInstance *instance, gpointer g_class) /* srcpad */ typefind->src = gst_pad_new_from_template ( GST_PAD_TEMPLATE_GET (type_find_element_src_factory), "src"); + gst_pad_set_event_function (typefind->src, gst_type_find_element_src_event); + gst_pad_set_event_mask_function (typefind->src, gst_type_find_element_src_event_mask); gst_element_add_pad (GST_ELEMENT (typefind), typefind->src); typefind->caps = NULL; @@ -268,6 +277,29 @@ gst_type_find_element_get_property (GObject *object, guint prop_id, break; } } +static const GstEventMask * +gst_type_find_element_src_event_mask (GstPad *pad) +{ + static const GstEventMask mask[] = { + { GST_EVENT_SEEK, GST_SEEK_METHOD_SET | GST_SEEK_METHOD_CUR | GST_SEEK_METHOD_END | GST_SEEK_FLAG_FLUSH}, + /* add more if you want, event masks suck and need to die anyway */ + { 0, } + }; + + return mask; +} +static gboolean +gst_type_find_element_src_event (GstPad *pad, GstEvent *event) +{ + GstTypeFindElement *typefind = GST_TYPE_FIND_ELEMENT (GST_PAD_PARENT (pad)); + + if (typefind->mode == MODE_TYPEFIND) { + /* need to do more? */ + gst_data_unref (GST_DATA (event)); + return FALSE; + } + return gst_pad_event_default (pad, event); +} static void start_typefinding (GstTypeFindElement *typefind) { @@ -279,32 +311,14 @@ start_typefinding (GstTypeFindElement *typefind) typefind->stream_length = 0; } static void -stop_typefinding (GstTypeFindElement *typefind) -{ - /* stop all typefinding and set mode back to normal */ - gboolean push_cached_buffers = gst_element_get_state (GST_ELEMENT (typefind)) == GST_STATE_PLAYING; - - g_assert (typefind->possibilities == NULL); - - GST_LOG_OBJECT (typefind, "stopping typefinding%s", push_cached_buffers ? " and pushing cached buffers" : ""); - typefind->mode = MODE_NORMAL; - - if (push_cached_buffers) { - GstBuffer *buffer; - guint size = gst_buffer_store_get_size (typefind->store, 0); - if (size && (buffer = gst_buffer_store_get_buffer (typefind->store, 0, size))) { - gst_pad_push (typefind->src, GST_DATA (buffer)); - } else { - size = 0; - } - gst_pad_send_event (GST_PAD_PEER (typefind->sink), - gst_event_new_seek (GST_SEEK_METHOD_SET, size)); - } - gst_buffer_store_clear (typefind->store); -} -static void gst_type_find_element_handle_event (GstPad *pad, GstEvent *event) { + GstTypeFindElement *typefind = GST_TYPE_FIND_ELEMENT (GST_PAD_PARENT (pad)); + + if (typefind->mode == MODE_TYPEFIND) { + /* need to do more? */ + gst_data_unref (GST_DATA (event)); + } gst_pad_event_default (pad, event); } typedef struct { @@ -333,6 +347,40 @@ free_entry (TypeFindEntry *entry) gst_caps_unref (entry->caps); g_free (entry); } +static void +stop_typefinding (GstTypeFindElement *typefind) +{ + /* stop all typefinding and set mode back to normal */ + gboolean push_cached_buffers = gst_element_get_state (GST_ELEMENT (typefind)) == GST_STATE_PLAYING; + + GST_LOG_OBJECT (typefind, "stopping typefinding%s", push_cached_buffers ? " and pushing cached buffers" : ""); + if (typefind->possibilities != NULL) { + /* this can only happen on PAUSED => READY */ + GST_LOG_OBJECT (typefind, "freeing remaining %u typefind functions", g_list_length (typefind->possibilities)); + g_assert (push_cached_buffers == FALSE); + g_list_foreach (typefind->possibilities, (GFunc) free_entry, NULL); + g_list_free (typefind->possibilities); + typefind->possibilities = NULL; + } + + typefind->mode = MODE_NORMAL; + + if (push_cached_buffers) { + GstBuffer *buffer; + guint size = gst_buffer_store_get_size (typefind->store, 0); + if (size && (buffer = gst_buffer_store_get_buffer (typefind->store, 0, size))) { + gst_pad_push (typefind->src, GST_DATA (buffer)); + } else { + size = 0; + } + GST_LOG_OBJECT (typefind, "seeking back to current position %u", size); + if (!gst_pad_send_event (GST_PAD_PEER (typefind->sink), + gst_event_new_seek (GST_SEEK_METHOD_SET | GST_FORMAT_BYTES, size))) { + GST_WARNING_OBJECT (typefind, "could not seek to required position %u, hope for the best", size); + } + } + gst_buffer_store_clear (typefind->store); +} static guint64 find_element_get_length (gpointer data) {