gstreamer_core/plugins/elements/gsttypefindelement.c
branchRCL_3
changeset 29 567bb019e3e3
parent 0 0e761a78d257
child 30 7e817e7e631c
equal deleted inserted replaced
6:9b2c3c7a1a9c 29:567bb019e3e3
    16  * You should have received a copy of the GNU Library General Public
    16  * You should have received a copy of the GNU Library General Public
    17  * License along with this library; if not, write to the
    17  * License along with this library; if not, write to the
    18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    19  * Boston, MA 02111-1307, USA.
    19  * Boston, MA 02111-1307, USA.
    20  */
    20  */
       
    21 /**
       
    22  * SECTION:element-typefind
       
    23  *
       
    24  * Determines the media-type of a stream. It applies typefind functions in the
       
    25  * order of their rank. One the type has been deteted it sets its src pad caps
       
    26  * to the found media type.
       
    27  *
       
    28  * Plugins can register custom typefinders by using #GstTypeFindFactory.
       
    29  */
    21 
    30 
    22 /* FIXME: need a better solution for non-seekable streams */
    31 /* FIXME: need a better solution for non-seekable streams */
    23 
    32 
    24 /* way of operation:
    33 /* way of operation:
    25  * 1) get a list of all typefind functions sorted best to worst
    34  * 1) get a list of all typefind functions sorted best to worst
    26  * 2) if all elements have been called with all requested data goto 8
    35  * 2) if all elements have been called with all requested data goto 8
    27  * 3) call all functions once with all available data
    36  * 3) call all functions once with all available data
    28  * 4) if a function returns a value >= ARG_MAXIMUM goto 8
    37  * 4) if a function returns a value >= PROP_MAXIMUM goto 8
    29  * 5) all functions with a result > ARG_MINIMUM or functions that did not get
    38  * 5) all functions with a result > PROP_MINIMUM or functions that did not get
    30  *    all requested data (where peek returned NULL) stay in list
    39  *    all requested data (where peek returned NULL) stay in list
    31  * 6) seek to requested offset of best function that still has open data
    40  * 6) seek to requested offset of best function that still has open data
    32  *    requests
    41  *    requests
    33  * 7) goto 2
    42  * 7) goto 2
    34  * 8) take best available result and use its caps
    43  * 8) take best available result and use its caps
    48  */
    57  */
    49 
    58 
    50 #ifdef HAVE_CONFIG_H
    59 #ifdef HAVE_CONFIG_H
    51 #  include "config.h"
    60 #  include "config.h"
    52 #endif
    61 #endif
    53 #ifdef __SYMBIAN32__
       
    54 #include <gst_global.h>
       
    55 #endif
       
    56 
    62 
    57 #include "gsttypefindelement.h"
    63 #include "gsttypefindelement.h"
    58 #include "gst/gst_private.h"
    64 #include "gst/gst_private.h"
    59 #include "gst/gst-i18n-lib.h"
    65 #include "gst/gst-i18n-lib.h"
    60 #include "gst/base/gsttypefindhelper.h"
    66 #include "gst/base/gsttypefindhelper.h"
    90   HAVE_TYPE,
    96   HAVE_TYPE,
    91   LAST_SIGNAL
    97   LAST_SIGNAL
    92 };
    98 };
    93 enum
    99 enum
    94 {
   100 {
    95   ARG_0,
   101   PROP_0,
    96   ARG_CAPS,
   102   PROP_CAPS,
    97   ARG_MINIMUM,
   103   PROP_MINIMUM,
    98   ARG_MAXIMUM
   104   PROP_MAXIMUM,
       
   105   PROP_FORCE_CAPS,
       
   106   PROP_LAST
    99 };
   107 };
   100 enum
   108 enum
   101 {
   109 {
   102   MODE_NORMAL,                  /* act as identity */
   110   MODE_NORMAL,                  /* act as identity */
   103   MODE_TYPEFIND,                /* do typefinding  */
   111   MODE_TYPEFIND,                /* do typefinding  */
   152 gst_type_find_element_have_type (GstTypeFindElement * typefind,
   160 gst_type_find_element_have_type (GstTypeFindElement * typefind,
   153     guint probability, const GstCaps * caps)
   161     guint probability, const GstCaps * caps)
   154 {
   162 {
   155   g_assert (caps != NULL);
   163   g_assert (caps != NULL);
   156 
   164 
   157   GST_INFO_OBJECT (typefind, "found caps %" GST_PTR_FORMAT, caps);
   165   GST_INFO_OBJECT (typefind, "found caps %" GST_PTR_FORMAT ", probability=%u",
       
   166       caps, probability);
   158   if (typefind->caps)
   167   if (typefind->caps)
   159     gst_caps_unref (typefind->caps);
   168     gst_caps_unref (typefind->caps);
   160   typefind->caps = gst_caps_copy (caps);
   169   typefind->caps = gst_caps_copy (caps);
   161   gst_pad_set_caps (typefind->src, (GstCaps *) caps);
   170   gst_pad_set_caps (typefind->src, (GstCaps *) caps);
   162 }
   171 }
   189       GST_DEBUG_FUNCPTR (gst_type_find_element_get_property);
   198       GST_DEBUG_FUNCPTR (gst_type_find_element_get_property);
   190   gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_type_find_element_dispose);
   199   gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_type_find_element_dispose);
   191 
   200 
   192   typefind_class->have_type = gst_type_find_element_have_type;
   201   typefind_class->have_type = gst_type_find_element_have_type;
   193 
   202 
   194   g_object_class_install_property (gobject_class, ARG_CAPS,
   203   g_object_class_install_property (gobject_class, PROP_CAPS,
   195       g_param_spec_boxed ("caps", _("caps"),
   204       g_param_spec_boxed ("caps", _("caps"),
   196           _("detected capabilities in stream"), gst_caps_get_type (),
   205           _("detected capabilities in stream"), gst_caps_get_type (),
   197           G_PARAM_READABLE));
   206           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
   198   g_object_class_install_property (gobject_class, ARG_MINIMUM,
   207   g_object_class_install_property (gobject_class, PROP_MINIMUM,
   199       g_param_spec_uint ("minimum", _("minimum"),
   208       g_param_spec_uint ("minimum", _("minimum"),
   200           "minimum probability required to accept caps", GST_TYPE_FIND_MINIMUM,
   209           "minimum probability required to accept caps", GST_TYPE_FIND_MINIMUM,
   201           GST_TYPE_FIND_MAXIMUM, GST_TYPE_FIND_MINIMUM, G_PARAM_READWRITE));
   210           GST_TYPE_FIND_MAXIMUM, GST_TYPE_FIND_MINIMUM,
   202   g_object_class_install_property (gobject_class, ARG_MAXIMUM,
   211           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
       
   212   g_object_class_install_property (gobject_class, PROP_MAXIMUM,
   203       g_param_spec_uint ("maximum", _("maximum"),
   213       g_param_spec_uint ("maximum", _("maximum"),
   204           "probability to stop typefinding (deprecated; non-functional)",
   214           "probability to stop typefinding (deprecated; non-functional)",
   205           GST_TYPE_FIND_MINIMUM, GST_TYPE_FIND_MAXIMUM, GST_TYPE_FIND_MAXIMUM,
   215           GST_TYPE_FIND_MINIMUM, GST_TYPE_FIND_MAXIMUM, GST_TYPE_FIND_MAXIMUM,
   206           G_PARAM_READWRITE));
   216           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
       
   217   g_object_class_install_property (gobject_class, PROP_FORCE_CAPS,
       
   218       g_param_spec_boxed ("force-caps", _("force caps"),
       
   219           _("force caps without doing a typefind"), gst_caps_get_type (),
       
   220           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
   207   /**
   221   /**
   208    * GstTypeFindElement::have-type:
   222    * GstTypeFindElement::have-type:
   209    * @typefind: the typefind instance
   223    * @typefind: the typefind instance
   210    * @probability: the probability of the type found
   224    * @probability: the probability of the type found
   211    * @caps: the caps of the type found
   225    * @caps: the caps of the type found
   220       G_TYPE_UINT, GST_TYPE_CAPS | G_SIGNAL_TYPE_STATIC_SCOPE);
   234       G_TYPE_UINT, GST_TYPE_CAPS | G_SIGNAL_TYPE_STATIC_SCOPE);
   221 
   235 
   222   gstelement_class->change_state =
   236   gstelement_class->change_state =
   223       GST_DEBUG_FUNCPTR (gst_type_find_element_change_state);
   237       GST_DEBUG_FUNCPTR (gst_type_find_element_change_state);
   224 }
   238 }
       
   239 
   225 static void
   240 static void
   226 gst_type_find_element_init (GstTypeFindElement * typefind,
   241 gst_type_find_element_init (GstTypeFindElement * typefind,
   227     GstTypeFindElementClass * g_class)
   242     GstTypeFindElementClass * g_class)
   228 {
   243 {
   229   /* sinkpad */
   244   /* sinkpad */
   263   typefind->min_probability = 1;
   278   typefind->min_probability = 1;
   264   typefind->max_probability = GST_TYPE_FIND_MAXIMUM;
   279   typefind->max_probability = GST_TYPE_FIND_MAXIMUM;
   265 
   280 
   266   typefind->store = NULL;
   281   typefind->store = NULL;
   267 }
   282 }
       
   283 
   268 static void
   284 static void
   269 gst_type_find_element_dispose (GObject * object)
   285 gst_type_find_element_dispose (GObject * object)
   270 {
   286 {
   271   GstTypeFindElement *typefind = GST_TYPE_FIND_ELEMENT (object);
   287   GstTypeFindElement *typefind = GST_TYPE_FIND_ELEMENT (object);
   272 
       
   273   G_OBJECT_CLASS (parent_class)->dispose (object);
       
   274 
   288 
   275   if (typefind->store) {
   289   if (typefind->store) {
   276     gst_buffer_unref (typefind->store);
   290     gst_buffer_unref (typefind->store);
   277     typefind->store = NULL;
   291     typefind->store = NULL;
   278   }
   292   }
   279 }
   293   if (typefind->force_caps) {
       
   294     gst_caps_unref (typefind->force_caps);
       
   295     typefind->force_caps = NULL;
       
   296   }
       
   297 
       
   298   G_OBJECT_CLASS (parent_class)->dispose (object);
       
   299 }
       
   300 
   280 static void
   301 static void
   281 gst_type_find_element_set_property (GObject * object, guint prop_id,
   302 gst_type_find_element_set_property (GObject * object, guint prop_id,
   282     const GValue * value, GParamSpec * pspec)
   303     const GValue * value, GParamSpec * pspec)
   283 {
   304 {
   284   GstTypeFindElement *typefind;
   305   GstTypeFindElement *typefind;
   285 
   306 
   286   typefind = GST_TYPE_FIND_ELEMENT (object);
   307   typefind = GST_TYPE_FIND_ELEMENT (object);
   287 
   308 
   288   switch (prop_id) {
   309   switch (prop_id) {
   289     case ARG_MINIMUM:
   310     case PROP_MINIMUM:
   290       typefind->min_probability = g_value_get_uint (value);
   311       typefind->min_probability = g_value_get_uint (value);
   291       break;
   312       break;
   292     case ARG_MAXIMUM:
   313     case PROP_MAXIMUM:
   293       typefind->max_probability = g_value_get_uint (value);
   314       typefind->max_probability = g_value_get_uint (value);
       
   315       break;
       
   316     case PROP_FORCE_CAPS:
       
   317       GST_OBJECT_LOCK (typefind);
       
   318       if (typefind->force_caps)
       
   319         gst_caps_unref (typefind->force_caps);
       
   320       typefind->force_caps = g_value_dup_boxed (value);
       
   321       GST_OBJECT_UNLOCK (typefind);
   294       break;
   322       break;
   295     default:
   323     default:
   296       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
   324       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
   297       break;
   325       break;
   298   }
   326   }
   299 }
   327 }
       
   328 
   300 static void
   329 static void
   301 gst_type_find_element_get_property (GObject * object, guint prop_id,
   330 gst_type_find_element_get_property (GObject * object, guint prop_id,
   302     GValue * value, GParamSpec * pspec)
   331     GValue * value, GParamSpec * pspec)
   303 {
   332 {
   304   GstTypeFindElement *typefind;
   333   GstTypeFindElement *typefind;
   305 
   334 
   306   typefind = GST_TYPE_FIND_ELEMENT (object);
   335   typefind = GST_TYPE_FIND_ELEMENT (object);
   307 
   336 
   308   switch (prop_id) {
   337   switch (prop_id) {
   309     case ARG_CAPS:
   338     case PROP_CAPS:
   310       g_value_set_boxed (value, typefind->caps);
   339       g_value_set_boxed (value, typefind->caps);
   311       break;
   340       break;
   312     case ARG_MINIMUM:
   341     case PROP_MINIMUM:
   313       g_value_set_uint (value, typefind->min_probability);
   342       g_value_set_uint (value, typefind->min_probability);
   314       break;
   343       break;
   315     case ARG_MAXIMUM:
   344     case PROP_MAXIMUM:
   316       g_value_set_uint (value, typefind->max_probability);
   345       g_value_set_uint (value, typefind->max_probability);
       
   346       break;
       
   347     case PROP_FORCE_CAPS:
       
   348       GST_OBJECT_LOCK (typefind);
       
   349       g_value_set_boxed (value, typefind->force_caps);
       
   350       GST_OBJECT_UNLOCK (typefind);
   317       break;
   351       break;
   318     default:
   352     default:
   319       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
   353       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
   320       break;
   354       break;
   321   }
   355   }
   350       gst_query_parse_position (query, &format, &peer_pos);
   384       gst_query_parse_position (query, &format, &peer_pos);
   351 
   385 
   352       /* FIXME: this code assumes that there's no discont in the queue */
   386       /* FIXME: this code assumes that there's no discont in the queue */
   353       switch (format) {
   387       switch (format) {
   354         case GST_FORMAT_BYTES:
   388         case GST_FORMAT_BYTES:
   355           peer_pos -= typefind->store->size;
   389           peer_pos -= GST_BUFFER_SIZE (typefind->store);
   356           break;
   390           break;
   357         default:
   391         default:
   358           /* FIXME */
   392           /* FIXME */
   359           break;
   393           break;
   360       }
   394       }
   394   if (typefind->mode != MODE_NORMAL) {
   428   if (typefind->mode != MODE_NORMAL) {
   395     /* need to do more? */
   429     /* need to do more? */
   396     gst_mini_object_unref (GST_MINI_OBJECT (event));
   430     gst_mini_object_unref (GST_MINI_OBJECT (event));
   397     return FALSE;
   431     return FALSE;
   398   }
   432   }
   399   return gst_pad_event_default (pad, event);
   433   return gst_pad_push_event (typefind->sink, event);
   400 }
   434 }
   401 
   435 
   402 static void
   436 static void
   403 start_typefinding (GstTypeFindElement * typefind)
   437 start_typefinding (GstTypeFindElement * typefind)
   404 {
   438 {
   496                 (_("Stream contains no data.")),
   530                 (_("Stream contains no data.")),
   497                 ("Can't typefind empty stream"));
   531                 ("Can't typefind empty stream"));
   498           }
   532           }
   499 
   533 
   500           stop_typefinding (typefind);
   534           stop_typefinding (typefind);
   501           res = gst_pad_event_default (pad, event);
   535           res = gst_pad_push_event (typefind->src, event);
   502           break;
   536           break;
   503         }
   537         }
       
   538         case GST_EVENT_FLUSH_STOP:
       
   539           g_list_foreach (typefind->cached_events,
       
   540               (GFunc) gst_mini_object_unref, NULL);
       
   541           g_list_free (typefind->cached_events);
       
   542           typefind->cached_events = NULL;
       
   543           gst_buffer_replace (&typefind->store, NULL);
       
   544           /* fall through */
       
   545         case GST_EVENT_FLUSH_START:
       
   546           res = gst_pad_push_event (typefind->src, event);
       
   547           break;
   504         default:
   548         default:
   505           GST_DEBUG_OBJECT (typefind, "Saving %s event to send later",
   549           GST_DEBUG_OBJECT (typefind, "Saving %s event to send later",
   506               GST_EVENT_TYPE_NAME (event));
   550               GST_EVENT_TYPE_NAME (event));
   507           typefind->cached_events =
   551           typefind->cached_events =
   508               g_list_append (typefind->cached_events, event);
   552               g_list_append (typefind->cached_events, event);
   509           res = TRUE;
   553           res = TRUE;
   510           break;
   554           break;
   511       }
   555       }
   512       break;
   556       break;
   513     case MODE_NORMAL:
   557     case MODE_NORMAL:
   514       res = gst_pad_event_default (pad, event);
   558       res = gst_pad_push_event (typefind->src, event);
   515       break;
   559       break;
   516     case MODE_ERROR:
   560     case MODE_ERROR:
   517       break;
   561       break;
   518     default:
   562     default:
   519       g_assert_not_reached ();
   563       g_assert_not_reached ();
   566       typefind->store = NULL;
   610       typefind->store = NULL;
   567     }
   611     }
   568   }
   612   }
   569 
   613 
   570   return TRUE;
   614   return TRUE;
       
   615 }
       
   616 
       
   617 static GstCaps *
       
   618 gst_type_find_guess_by_extension (GstTypeFindElement * typefind, GstPad * pad,
       
   619     GstTypeFindProbability * probability)
       
   620 {
       
   621   GstQuery *query;
       
   622   gchar *uri;
       
   623   size_t len;
       
   624   gint find;
       
   625   GstCaps *caps;
       
   626 
       
   627   query = gst_query_new_uri ();
       
   628 
       
   629   /* try getting the caps with an uri query and from the extension */
       
   630   if (!gst_pad_peer_query (pad, query))
       
   631     goto peer_query_failed;
       
   632 
       
   633   gst_query_parse_uri (query, &uri);
       
   634   if (uri == NULL)
       
   635     goto no_uri;
       
   636 
       
   637   GST_DEBUG_OBJECT (typefind, "finding extension of %s", uri);
       
   638 
       
   639   /* find the extension on the uri, this is everything after a '.' */
       
   640   len = strlen (uri);
       
   641   find = len - 1;
       
   642 
       
   643   while (find >= 0) {
       
   644     if (uri[find] == '.')
       
   645       break;
       
   646     find--;
       
   647   }
       
   648   if (find < 0)
       
   649     goto no_extension;
       
   650 
       
   651   GST_DEBUG_OBJECT (typefind, "found extension %s", &uri[find + 1]);
       
   652 
       
   653   caps =
       
   654       gst_type_find_helper_for_extension (GST_OBJECT_CAST (typefind),
       
   655       &uri[find + 1]);
       
   656   if (caps)
       
   657     *probability = GST_TYPE_FIND_MAXIMUM;
       
   658 
       
   659   gst_query_unref (query);
       
   660 
       
   661   return caps;
       
   662 
       
   663   /* ERRORS */
       
   664 peer_query_failed:
       
   665   {
       
   666     GST_WARNING_OBJECT (typefind, "failed to query peer uri");
       
   667     gst_query_unref (query);
       
   668     return NULL;
       
   669   }
       
   670 no_uri:
       
   671   {
       
   672     GST_WARNING_OBJECT (typefind, "could not parse the peer uri");
       
   673     gst_query_unref (query);
       
   674     return NULL;
       
   675   }
       
   676 no_extension:
       
   677   {
       
   678     GST_WARNING_OBJECT (typefind, "could not find uri extension in %s", uri);
       
   679     gst_query_unref (query);
       
   680     return NULL;
       
   681   }
   571 }
   682 }
   572 
   683 
   573 static GstFlowReturn
   684 static GstFlowReturn
   574 gst_type_find_element_chain (GstPad * pad, GstBuffer * buffer)
   685 gst_type_find_element_chain (GstPad * pad, GstBuffer * buffer)
   575 {
   686 {
   703   GstCaps *found_caps = NULL;
   814   GstCaps *found_caps = NULL;
   704   GstTypeFindElement *typefind;
   815   GstTypeFindElement *typefind;
   705 
   816 
   706   typefind = GST_TYPE_FIND_ELEMENT (GST_OBJECT_PARENT (pad));
   817   typefind = GST_TYPE_FIND_ELEMENT (GST_OBJECT_PARENT (pad));
   707 
   818 
       
   819   /* if we have force caps, use those */
       
   820   if (typefind->force_caps) {
       
   821     found_caps = gst_caps_ref (typefind->force_caps);
       
   822     probability = GST_TYPE_FIND_MAXIMUM;
       
   823     goto done;
       
   824   }
       
   825 
   708   /* 1. try to activate in pull mode. if not, switch to push and succeed.
   826   /* 1. try to activate in pull mode. if not, switch to push and succeed.
   709      2. try to pull type find.
   827      2. try to pull type find.
   710      3. deactivate pull mode.
   828      3. deactivate pull mode.
   711      4. src pad might have been activated push by the state change. deactivate.
   829      4. src pad might have been activated push by the state change. deactivate.
   712      5. if we didn't find any caps, fail.
   830      5. if we didn't find any caps, try getting the uri extension by doing an uri
   713      6. emit have-type; maybe the app connected the source pad to something.
   831      query.
   714      7. if the sink pad is activated, we are in pull mode. succeed.
   832      6. if we didn't find any caps, fail.
       
   833      7. emit have-type; maybe the app connected the source pad to something.
       
   834      8. if the sink pad is activated, we are in pull mode. succeed.
   715      otherwise activate both pads in push mode and succeed.
   835      otherwise activate both pads in push mode and succeed.
   716    */
   836    */
   717 
   837 
   718   /* 1 */
   838   /* 1 */
   719   if (!gst_pad_check_pull_range (pad) || !gst_pad_activate_pull (pad, TRUE)) {
   839   if (!gst_pad_check_pull_range (pad) || !gst_pad_activate_pull (pad, TRUE)) {
   730       gint64 size;
   850       gint64 size;
   731       GstFormat format = GST_FORMAT_BYTES;
   851       GstFormat format = GST_FORMAT_BYTES;
   732 
   852 
   733       if (!gst_pad_query_duration (peer, &format, &size)) {
   853       if (!gst_pad_query_duration (peer, &format, &size)) {
   734         GST_WARNING_OBJECT (typefind, "Could not query upstream length!");
   854         GST_WARNING_OBJECT (typefind, "Could not query upstream length!");
       
   855         gst_object_unref (peer);
   735         return FALSE;
   856         return FALSE;
   736       }
   857       }
   737 
   858 
   738       if (size > 0) {
   859       /* the size if 0, we cannot continue */
   739         found_caps = gst_type_find_helper_get_range (GST_OBJECT_CAST (peer),
   860       if (size == 0) {
   740             (GstTypeFindHelperGetRangeFunction) (GST_PAD_GETRANGEFUNC (peer)),
       
   741             (guint64) size, &probability);
       
   742       } else {
       
   743         /* keep message in sync with message in sink event handler */
   861         /* keep message in sync with message in sink event handler */
   744         GST_ELEMENT_ERROR (typefind, STREAM, TYPE_NOT_FOUND,
   862         GST_ELEMENT_ERROR (typefind, STREAM, TYPE_NOT_FOUND,
   745             (_("Stream contains no data.")), ("Can't typefind empty stream"));
   863             (_("Stream contains no data.")), ("Can't typefind empty stream"));
       
   864         gst_object_unref (peer);
       
   865         return FALSE;
   746       }
   866       }
       
   867 
       
   868       found_caps = gst_type_find_helper_get_range (GST_OBJECT_CAST (peer),
       
   869           (GstTypeFindHelperGetRangeFunction) (GST_PAD_GETRANGEFUNC (peer)),
       
   870           (guint64) size, &probability);
   747 
   871 
   748       gst_object_unref (peer);
   872       gst_object_unref (peer);
   749     }
   873     }
   750   }
   874   }
   751 
   875 
   754 
   878 
   755   /* 4 */
   879   /* 4 */
   756   gst_pad_activate_push (typefind->src, FALSE);
   880   gst_pad_activate_push (typefind->src, FALSE);
   757 
   881 
   758   /* 5 */
   882   /* 5 */
       
   883   if (!found_caps || probability < typefind->min_probability) {
       
   884     found_caps = gst_type_find_guess_by_extension (typefind, pad, &probability);
       
   885   }
       
   886 
       
   887   /* 6 */
   759   if (!found_caps || probability < typefind->min_probability) {
   888   if (!found_caps || probability < typefind->min_probability) {
   760     GST_ELEMENT_ERROR (typefind, STREAM, TYPE_NOT_FOUND, (NULL), (NULL));
   889     GST_ELEMENT_ERROR (typefind, STREAM, TYPE_NOT_FOUND, (NULL), (NULL));
   761     gst_caps_replace (&found_caps, NULL);
   890     gst_caps_replace (&found_caps, NULL);
   762     return FALSE;
   891     return FALSE;
   763   }
   892   }
   764 
   893 
   765   /* 6 */
   894 done:
       
   895   /* 7 */
   766   g_signal_emit (typefind, gst_type_find_element_signals[HAVE_TYPE],
   896   g_signal_emit (typefind, gst_type_find_element_signals[HAVE_TYPE],
   767       0, probability, found_caps);
   897       0, probability, found_caps);
   768   gst_caps_unref (found_caps);
   898   gst_caps_unref (found_caps);
   769   typefind->mode = MODE_NORMAL;
   899   typefind->mode = MODE_NORMAL;
   770 
   900 
   771   /* 7 */
   901   /* 8 */
   772   if (gst_pad_is_active (pad))
   902   if (gst_pad_is_active (pad))
   773     return TRUE;
   903     return TRUE;
   774   else {
   904   else {
   775     gboolean ret;
   905     gboolean ret;
   776 
   906 
   794 
   924 
   795   switch (transition) {
   925   switch (transition) {
   796     case GST_STATE_CHANGE_PAUSED_TO_READY:
   926     case GST_STATE_CHANGE_PAUSED_TO_READY:
   797     case GST_STATE_CHANGE_READY_TO_NULL:
   927     case GST_STATE_CHANGE_READY_TO_NULL:
   798       gst_caps_replace (&typefind->caps, NULL);
   928       gst_caps_replace (&typefind->caps, NULL);
       
   929 
   799       g_list_foreach (typefind->cached_events,
   930       g_list_foreach (typefind->cached_events,
   800           (GFunc) gst_mini_object_unref, NULL);
   931           (GFunc) gst_mini_object_unref, NULL);
   801       g_list_free (typefind->cached_events);
   932       g_list_free (typefind->cached_events);
   802       typefind->cached_events = NULL;
   933       typefind->cached_events = NULL;
   803       break;
   934       break;