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