Merge the tizen patch based on 1.12.2
[platform/upstream/gstreamer.git] / plugins / elements / gsttypefindelement.c
index d4d2e81..0d8f092 100644 (file)
@@ -20,6 +20,7 @@
  */
 /**
  * SECTION:element-typefind
+ * @title: typefind
  *
  * Determines the media-type of a stream. It applies typefind functions in the
  * order of their rank. Once the type has been detected it sets its src pad caps
@@ -97,7 +98,14 @@ GST_STATIC_PAD_TEMPLATE ("src",
 
 /* Require at least 2kB of data before we attempt typefinding in chain-mode.
  * 128kB is massive overkill for the maximum, but doesn't do any harm */
+#ifdef TIZEN_PROFILE_TV
+/* TV demuxer needs 4*1024 as min size to match demuxer, if not
+ * sometimes can't find correct demuxer
+ */
+#define TYPE_FIND_MIN_SIZE   (4*1024)
+#else
 #define TYPE_FIND_MIN_SIZE   (2*1024)
+#endif
 #define TYPE_FIND_MAX_SIZE (128*1024)
 
 /* TypeFind signals and args */
@@ -179,6 +187,10 @@ gst_type_find_element_have_type (GstTypeFindElement * typefind,
   GST_INFO_OBJECT (typefind, "found caps %" GST_PTR_FORMAT ", probability=%u",
       caps, probability);
 
+  /* Do nothing if downstream is pulling from us */
+  if (GST_PAD_MODE (typefind->src) == GST_PAD_MODE_PULL)
+    return;
+
   GST_OBJECT_LOCK (typefind);
 
   /* Now actually send the CAPS event downstream.
@@ -193,9 +205,7 @@ gst_type_find_element_have_type (GstTypeFindElement * typefind,
     GstCaps *event_caps;
 
     gst_event_parse_caps (event, &event_caps);
-    if (caps == event_caps) {
-      event = event;
-    } else {
+    if (caps != event_caps) {
       gst_event_unref (event);
       event = gst_event_new_caps (caps);
     }
@@ -203,9 +213,6 @@ gst_type_find_element_have_type (GstTypeFindElement * typefind,
     event = gst_event_new_caps (caps);
   }
 
-  if (typefind->caps)
-    gst_caps_unref (typefind->caps);
-  typefind->caps = gst_caps_ref (caps);
   GST_OBJECT_UNLOCK (typefind);
 
   gst_pad_push_event (typefind->src, event);
@@ -217,6 +224,15 @@ gst_type_find_element_emit_have_type (GstTypeFindElement * typefind,
 {
   GstEvent *event;
 
+  /* Update caps field immediatly so that caps queries and properties can be
+   * honored in all "have-type" signal handlers.
+   */
+  GST_OBJECT_LOCK (typefind);
+  if (typefind->caps)
+    gst_caps_unref (typefind->caps);
+  typefind->caps = gst_caps_ref (caps);
+  GST_OBJECT_UNLOCK (typefind);
+
   /* Only store the caps event at this point. We give signal handlers
    * the chance to look at the caps before they are sent downstream.
    * They are only forwarded downstream later in the default signal
@@ -442,6 +458,8 @@ gst_type_find_handle_src_query (GstPad * pad, GstObject * parent,
       switch (format) {
         case GST_FORMAT_BYTES:
           peer_pos -= gst_adapter_available (typefind->adapter);
+          if (peer_pos < 0)     /* Clamp result to 0 */
+            peer_pos = 0;
           break;
         default:
           /* FIXME */
@@ -548,6 +566,7 @@ gst_type_find_element_src_event (GstPad * pad, GstObject * parent,
 
   if (typefind->mode != MODE_NORMAL) {
     /* need to do more? */
+    GST_LOG_OBJECT (typefind, "Still typefinding. Not passing event upstream");
     gst_event_unref (event);
     return FALSE;
   }
@@ -773,6 +792,8 @@ gst_type_find_element_setcaps (GstTypeFindElement * typefind, GstCaps * caps)
   if (gst_caps_is_any (caps))
     return TRUE;
 
+  /* Set to MODE_NORMAL before emitting have-type, in case it triggers a seek */
+  typefind->mode = MODE_NORMAL;
   gst_type_find_element_emit_have_type (typefind, GST_TYPE_FIND_MAXIMUM, caps);
 
   /* Shortcircuit typefinding if we get caps */
@@ -957,6 +978,8 @@ gst_type_find_element_chain_do_typefinding (GstTypeFindElement * typefind,
 
   /* probability is good enough too, so let's make it known ... emiting this
    * signal calls our object handler which sets the caps. */
+  /* Set to MODE_NORMAL before emitting have-type, in case it triggers a seek */
+  typefind->mode = MODE_NORMAL;
   gst_type_find_element_emit_have_type (typefind, probability, caps);
 
   /* .. and send out the accumulated data */
@@ -1148,8 +1171,9 @@ gst_type_find_element_loop (GstPad * pad)
     }
 
     GST_DEBUG ("Emiting found caps %" GST_PTR_FORMAT, found_caps);
-    gst_type_find_element_emit_have_type (typefind, probability, found_caps);
+    /* Set to MODE_NORMAL before emitting have-type, in case it triggers a seek */
     typefind->mode = MODE_NORMAL;
+    gst_type_find_element_emit_have_type (typefind, probability, found_caps);
     gst_caps_unref (found_caps);
   } else if (typefind->mode == MODE_NORMAL) {
     GstBuffer *outbuf = NULL;
@@ -1208,8 +1232,7 @@ pause:
       }
     } else if (ret == GST_FLOW_NOT_LINKED || ret < GST_FLOW_EOS) {
       /* for fatal errors we post an error message */
-      GST_ELEMENT_ERROR (typefind, STREAM, FAILED, (NULL),
-          ("stream stopped, reason %s", reason));
+      GST_ELEMENT_FLOW_ERROR (typefind, ret);
       push_eos = TRUE;
     }
     if (push_eos) {
@@ -1265,7 +1288,6 @@ gst_type_find_element_activate_sink (GstPad * pad, GstObject * parent)
 {
   GstQuery *query;
   gboolean pull_mode;
-  GstSchedulingFlags sched_flags;
 
   query = gst_query_new_scheduling ();
 
@@ -1274,10 +1296,8 @@ gst_type_find_element_activate_sink (GstPad * pad, GstObject * parent)
     goto typefind_push;
   }
 
-  gst_query_parse_scheduling (query, &sched_flags, NULL, NULL, NULL);
-
-  pull_mode = gst_query_has_scheduling_mode (query, GST_PAD_MODE_PULL)
-      && ((sched_flags & GST_SCHEDULING_FLAG_SEEKABLE) != 0);
+  pull_mode = gst_query_has_scheduling_mode_with_flags (query,
+      GST_PAD_MODE_PULL, GST_SCHEDULING_FLAG_SEEKABLE);
 
   gst_query_unref (query);