basesrc: use segment start if DTS for first buffer is unset
[platform/upstream/gstreamer.git] / tools / gst-launch.c
index b616c8a..a8ab1cd 100644 (file)
@@ -63,9 +63,6 @@ static gboolean messages = FALSE;
 static gboolean is_live = FALSE;
 static gboolean waiting_eos = FALSE;
 
-G_LOCK_DEFINE_STATIC (context);
-static GstContext *context = NULL;
-
 /* convenience macro so we don't have to litter the code with if(!quiet) */
 #define PRINT if(!quiet)g_print
 
@@ -338,11 +335,13 @@ print_tag (const GstTagList * list, const gchar * tag, gpointer unused)
   count = gst_tag_list_get_tag_size (list, tag);
 
   for (i = 0; i < count; i++) {
-    gchar *str;
+    gchar *str = NULL;
 
     if (gst_tag_get_type (tag) == G_TYPE_STRING) {
-      if (!gst_tag_list_get_string_index (list, tag, i, &str))
+      if (!gst_tag_list_get_string_index (list, tag, i, &str)) {
+        g_warning ("Couldn't fetch string for %s tag", tag);
         g_assert_not_reached ();
+      }
     } else if (gst_tag_get_type (tag) == GST_TYPE_SAMPLE) {
       GstSample *sample = NULL;
 
@@ -365,6 +364,9 @@ print_tag (const GstTagList * list, const gchar * tag, gpointer unused)
         } else {
           str = g_strdup ("NULL buffer");
         }
+      } else {
+        g_warning ("Couldn't fetch sample for %s tag", tag);
+        g_assert_not_reached ();
       }
     } else if (gst_tag_get_type (tag) == GST_TYPE_DATE_TIME) {
       GstDateTime *dt = NULL;
@@ -395,13 +397,10 @@ print_tag (const GstTagList * list, const gchar * tag, gpointer unused)
           g_strdup_value_contents (gst_tag_list_get_value_index (list, tag, i));
     }
 
-    if (i == 0) {
-      PRINT ("%16s: %s\n", gst_tag_get_nick (tag), str);
-    } else {
-      PRINT ("%16s: %s\n", "", str);
+    if (str) {
+      PRINT ("%16s: %s\n", i == 0 ? gst_tag_get_nick (tag) : "", str);
+      g_free (str);
     }
-
-    g_free (str);
   }
 }
 
@@ -413,7 +412,8 @@ print_tag_foreach (const GstTagList * tags, const gchar * tag,
   gchar *str;
   gint depth = GPOINTER_TO_INT (user_data);
 
-  gst_tag_list_copy_value (&val, tags, tag);
+  if (!gst_tag_list_copy_value (&val, tags, tag))
+    return;
 
   if (G_VALUE_HOLDS_STRING (&val))
     str = g_value_dup_string (&val);
@@ -462,6 +462,10 @@ print_toc_entry (gpointer data, gpointer user_data)
 }
 
 #ifdef G_OS_UNIX
+static guint signal_watch_id;
+#endif
+
+#ifdef G_OS_UNIX
 /* As the interrupt handler is dispatched from GMainContext as a GSourceFunc
  * handler, we can react to this by posting a message. */
 static gboolean
@@ -478,23 +482,12 @@ intr_handler (gpointer user_data)
               "message", G_TYPE_STRING, "Pipeline interrupted", NULL)));
 
   /* remove signal handler */
+  signal_watch_id = 0;
   return FALSE;
 }
 
 #endif /* G_OS_UNIX */
 
-static gboolean
-merge_structures (GQuark field_id, const GValue * value, gpointer user_data)
-{
-  GstStructure *s2 = user_data;
-
-  /* Copy all fields that are not set yet */
-  if (!gst_structure_id_has_field (s2, field_id))
-    gst_structure_id_set_value (s2, field_id, value);
-
-  return TRUE;
-}
-
 /* returns ELR_ERROR if there was an error
  * or ELR_INTERRUPT if we caught a keyboard interrupt
  * or ELR_NO_ERROR otherwise. */
@@ -502,9 +495,6 @@ static EventLoopResult
 event_loop (GstElement * pipeline, gboolean blocking, gboolean do_progress,
     GstState target_state)
 {
-#ifdef G_OS_UNIX
-  guint signal_watch_id;
-#endif
   GstBus *bus;
   GstMessage *message = NULL;
   EventLoopResult res = ELR_NO_ERROR;
@@ -808,26 +798,20 @@ event_loop (GstElement * pipeline, gboolean blocking, gboolean do_progress,
         break;
       }
       case GST_MESSAGE_HAVE_CONTEXT:{
-        GstContext *context_new;
+        GstContext *context;
+        const gchar *context_type;
         gchar *context_str;
 
-        gst_message_parse_have_context (message, &context_new);
+        gst_message_parse_have_context (message, &context);
 
+        context_type = gst_context_get_context_type (context);
         context_str =
-            gst_structure_to_string (gst_context_get_structure (context_new));
-        PRINT (_("Got context from element '%s': %s\n"),
-            GST_ELEMENT_NAME (GST_MESSAGE_SRC (message)), context_str);
+            gst_structure_to_string (gst_context_get_structure (context));
+        PRINT (_("Got context from element '%s': %s=%s\n"),
+            GST_ELEMENT_NAME (GST_MESSAGE_SRC (message)), context_type,
+            context_str);
         g_free (context_str);
-        gst_context_unref (context_new);
-
-        /* The contexts were merged in the sync handler already, here
-         * now just print them and propagate the merged context to the
-         * complete pipeline */
-        G_LOCK (context);
-        context_new = gst_context_ref (context_new);
-        G_UNLOCK (context);
-        gst_element_set_context (pipeline, context_new);
-        gst_context_unref (context_new);
+        gst_context_unref (context);
         break;
       }
       default:
@@ -845,7 +829,8 @@ exit:
       gst_message_unref (message);
     gst_object_unref (bus);
 #ifdef G_OS_UNIX
-    g_source_remove (signal_watch_id);
+    if (signal_watch_id > 0)
+      g_source_remove (signal_watch_id);
 #endif
     return res;
   }
@@ -887,49 +872,7 @@ bus_sync_handler (GstBus * bus, GstMessage * message, gpointer data)
 
         g_free (state_transition_name);
       }
-    case GST_MESSAGE_NEED_CONTEXT:{
-      G_LOCK (context);
-      /* We could filter something here, but instead we can also just pass the complete
-       * context knowledge we have to the element. If we have what it needs, it will be
-       * happy, otherwise we can't do anything else anyway */
-      if (context)
-        gst_element_set_context (GST_ELEMENT_CAST (GST_MESSAGE_SRC (message)),
-            context);
-      G_UNLOCK (context);
-
       break;
-    }
-    case GST_MESSAGE_HAVE_CONTEXT:{
-      GstContext *context_new;
-
-      gst_message_parse_have_context (message, &context_new);
-
-      /* Merge the contexts here as soon as possible and not
-       * in the async bus handler, in case something asks for
-       * a specific context before the async bus handler is run.
-       *
-       * Don't set the context on the complete pipeline here as it
-       * might deadlock, but do that from the async bus handler
-       * instead.
-       */
-      G_LOCK (context);
-      if (context) {
-        const GstStructure *s1;
-        GstStructure *s2;
-
-        /* Merge structures */
-        context = gst_context_make_writable (context);
-        s1 = gst_context_get_structure (context_new);
-        s2 = gst_context_writable_structure (context);
-        gst_structure_foreach (s1, merge_structures, s2);
-      } else {
-        /* Copy over the context */
-        gst_context_replace (&context, context_new);
-      }
-      gst_context_unref (context_new);
-      G_UNLOCK (context);
-      break;
-    }
     default:
       break;
   }
@@ -1105,6 +1048,7 @@ main (int argc, char *argv[])
         caught_error = event_loop (pipeline, TRUE, TRUE, GST_STATE_PAUSED);
         if (caught_error) {
           g_printerr (_("ERROR: pipeline doesn't want to preroll.\n"));
+          res = caught_error;
           goto end;
         }
         state = GST_STATE_PAUSED;
@@ -1118,6 +1062,7 @@ main (int argc, char *argv[])
 
     if (caught_error) {
       g_printerr (_("ERROR: pipeline doesn't want to preroll.\n"));
+      res = caught_error;
     } else {
       GstClockTime tfthen, tfnow;
       GstClockTimeDiff diff;
@@ -1166,10 +1111,12 @@ main (int argc, char *argv[])
           } else if (caught_error == ELR_INTERRUPT) {
             PRINT (_
                 ("Interrupt while waiting for EOS - stopping pipeline...\n"));
+            res = caught_error;
             break;
           } else if (caught_error == ELR_ERROR) {
             if (!ignore_errors) {
               PRINT (_("An error happened while waiting for EOS\n"));
+              res = caught_error;
               break;
             }
           }
@@ -1213,7 +1160,6 @@ main (int argc, char *argv[])
 
   PRINT (_("Freeing pipeline ...\n"));
   gst_object_unref (pipeline);
-  gst_context_replace (&context, NULL);
 
   gst_deinit ();