Merge branch 'master' into 0.11
[platform/upstream/gstreamer.git] / gst / isomp4 / qtdemux.c
index 02d1ebd..784648e 100644 (file)
@@ -33,7 +33,7 @@
  * <refsect2>
  * <title>Example launch line</title>
  * |[
- * gst-launch filesrc location=test.mov ! qtdemux name=demux  demux.audio_00 ! decodebin ! audioconvert ! audioresample ! autoaudiosink   demux.video_00 ! queue ! decodebin ! ffmpegcolorspace ! videoscale ! autovideosink
+ * gst-launch filesrc location=test.mov ! qtdemux name=demux  demux.audio_0 ! decodebin ! audioconvert ! audioresample ! autoaudiosink   demux.video_0 ! queue ! decodebin ! ffmpegcolorspace ! videoscale ! autovideosink
  * ]| Play (parse and decode) a .mov file and try to output it to
  * an automatically detected soundcard and videosink. If the MOV file contains
  * compressed audio or video data, this will only work if you have the
@@ -367,19 +367,19 @@ static GstStaticPadTemplate gst_qtdemux_sink_template =
     );
 
 static GstStaticPadTemplate gst_qtdemux_videosrc_template =
-GST_STATIC_PAD_TEMPLATE ("video_%02d",
+GST_STATIC_PAD_TEMPLATE ("video_%u",
     GST_PAD_SRC,
     GST_PAD_SOMETIMES,
     GST_STATIC_CAPS_ANY);
 
 static GstStaticPadTemplate gst_qtdemux_audiosrc_template =
-GST_STATIC_PAD_TEMPLATE ("audio_%02d",
+GST_STATIC_PAD_TEMPLATE ("audio_%u",
     GST_PAD_SRC,
     GST_PAD_SOMETIMES,
     GST_STATIC_CAPS_ANY);
 
 static GstStaticPadTemplate gst_qtdemux_subsrc_template =
-GST_STATIC_PAD_TEMPLATE ("subtitle_%02d",
+GST_STATIC_PAD_TEMPLATE ("subtitle_%u",
     GST_PAD_SRC,
     GST_PAD_SOMETIMES,
     GST_STATIC_CAPS_ANY);
@@ -678,21 +678,6 @@ done:
 }
 #endif
 
-static const GstQueryType *
-gst_qtdemux_get_src_query_types (GstPad * pad)
-{
-  static const GstQueryType src_types[] = {
-    GST_QUERY_POSITION,
-    GST_QUERY_DURATION,
-    GST_QUERY_CONVERT,
-    GST_QUERY_FORMATS,
-    GST_QUERY_SEEKING,
-    0
-  };
-
-  return src_types;
-}
-
 static gboolean
 gst_qtdemux_get_duration (GstQTDemux * qtdemux, gint64 * duration)
 {
@@ -4995,7 +4980,7 @@ gst_qtdemux_add_stream (GstQTDemux * qtdemux,
   gst_segment_init (&stream->segment, GST_FORMAT_TIME);
 
   if (stream->subtype == FOURCC_vide) {
-    gchar *name = g_strdup_printf ("video_%02d", qtdemux->n_video_streams);
+    gchar *name = g_strdup_printf ("video_%u", qtdemux->n_video_streams);
 
     stream->pad =
         gst_pad_new_from_static_template (&gst_qtdemux_videosrc_template, name);
@@ -5111,7 +5096,7 @@ gst_qtdemux_add_stream (GstQTDemux * qtdemux,
     }
     qtdemux->n_video_streams++;
   } else if (stream->subtype == FOURCC_soun) {
-    gchar *name = g_strdup_printf ("audio_%02d", qtdemux->n_audio_streams);
+    gchar *name = g_strdup_printf ("audio_%u", qtdemux->n_audio_streams);
 
     stream->pad =
         gst_pad_new_from_static_template (&gst_qtdemux_audiosrc_template, name);
@@ -5125,7 +5110,7 @@ gst_qtdemux_add_stream (GstQTDemux * qtdemux,
   } else if (stream->subtype == FOURCC_strm) {
     GST_DEBUG_OBJECT (qtdemux, "stream type, not creating pad");
   } else if (stream->subtype == FOURCC_subp || stream->subtype == FOURCC_text) {
-    gchar *name = g_strdup_printf ("subtitle_%02d", qtdemux->n_sub_streams);
+    gchar *name = g_strdup_printf ("subtitle_%u", qtdemux->n_sub_streams);
 
     stream->pad =
         gst_pad_new_from_static_template (&gst_qtdemux_subsrc_template, name);
@@ -5141,8 +5126,6 @@ gst_qtdemux_add_stream (GstQTDemux * qtdemux,
 
     gst_pad_use_fixed_caps (stream->pad);
     gst_pad_set_event_function (stream->pad, gst_qtdemux_handle_src_event);
-    gst_pad_set_query_type_function (stream->pad,
-        gst_qtdemux_get_src_query_types);
     gst_pad_set_query_function (stream->pad, gst_qtdemux_handle_src_query);
 
     GST_DEBUG_OBJECT (qtdemux, "setting caps %" GST_PTR_FORMAT, stream->caps);
@@ -5323,7 +5306,7 @@ qtdemux_stbl_init (GstQTDemux * qtdemux, QtDemuxStream * stream, GNode * stbl)
   /* sync sample atom */
   stream->stps_present = FALSE;
   if ((stream->stss_present =
-          !!qtdemux_tree_get_child_by_type_full (stbl, FOURCC_stss,
+          ! !qtdemux_tree_get_child_by_type_full (stbl, FOURCC_stss,
               &stream->stss) ? TRUE : FALSE) == TRUE) {
     /* copy atom data into a new buffer for later use */
     stream->stss.data = g_memdup (stream->stss.data, stream->stss.size);
@@ -5341,7 +5324,7 @@ qtdemux_stbl_init (GstQTDemux * qtdemux, QtDemuxStream * stream, GNode * stbl)
 
     /* partial sync sample atom */
     if ((stream->stps_present =
-            !!qtdemux_tree_get_child_by_type_full (stbl, FOURCC_stps,
+            ! !qtdemux_tree_get_child_by_type_full (stbl, FOURCC_stps,
                 &stream->stps) ? TRUE : FALSE) == TRUE) {
       /* copy atom data into a new buffer for later use */
       stream->stps.data = g_memdup (stream->stps.data, stream->stps.size);
@@ -5460,7 +5443,7 @@ qtdemux_stbl_init (GstQTDemux * qtdemux, QtDemuxStream * stream, GNode * stbl)
 
   /* composition time-to-sample */
   if ((stream->ctts_present =
-          !!qtdemux_tree_get_child_by_type_full (stbl, FOURCC_ctts,
+          ! !qtdemux_tree_get_child_by_type_full (stbl, FOURCC_ctts,
               &stream->ctts) ? TRUE : FALSE) == TRUE) {
     /* copy atom data into a new buffer for later use */
     stream->ctts.data = g_memdup (stream->ctts.data, stream->ctts.size);
@@ -6494,7 +6477,7 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
     stream->caps =
         qtdemux_video_caps (qtdemux, stream, fourcc, stsd_data, &codec);
     if (codec) {
-      list = gst_tag_list_new ();
+      list = gst_tag_list_new_empty ();
       gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
           GST_TAG_VIDEO_CODEC, codec, NULL);
       g_free (codec);
@@ -6588,7 +6571,7 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
                 }
 
                 if (!list)
-                  list = gst_tag_list_new ();
+                  list = gst_tag_list_new_empty ();
 
                 if (max_bitrate > 0 && max_bitrate < G_MAXUINT32) {
                   gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
@@ -7151,7 +7134,7 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
       GstStructure *s;
       gint bitrate = 0;
 
-      list = gst_tag_list_new ();
+      list = gst_tag_list_new_empty ();
       gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
           GST_TAG_AUDIO_CODEC, codec, NULL);
       g_free (codec);
@@ -7313,7 +7296,7 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
             if ((len - 0x34) > 8 &&
                 (bitrate = qtdemux_parse_amr_bitrate (buf, amrwb))) {
               if (!list)
-                list = gst_tag_list_new ();
+                list = gst_tag_list_new_empty ();
               gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
                   GST_TAG_MAXIMUM_BITRATE, bitrate, NULL);
             }
@@ -7350,7 +7333,7 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
     stream->caps =
         qtdemux_sub_caps (qtdemux, stream, fourcc, stsd_data, &codec);
     if (codec) {
-      list = gst_tag_list_new ();
+      list = gst_tag_list_new_empty ();
       gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
           GST_TAG_SUBTITLE_CODEC, codec, NULL);
       g_free (codec);
@@ -7462,7 +7445,7 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
     const gchar *lang_code;
 
     if (!list)
-      list = gst_tag_list_new ();
+      list = gst_tag_list_new_empty ();
 
     /* convert ISO 639-2 code to ISO 639-1 */
     lang_code = gst_tag_get_language_code (stream->lang_id);
@@ -7605,7 +7588,7 @@ gst_qtdemux_guess_bitrate (GstQTDemux * qtdemux)
       ", Stream bitrate = %u", sys_bitrate, bitrate);
 
   if (!stream->pending_tags)
-    stream->pending_tags = gst_tag_list_new ();
+    stream->pending_tags = gst_tag_list_new_empty ();
 
   gst_tag_list_add (stream->pending_tags, GST_TAG_MERGE_REPLACE,
       GST_TAG_BITRATE, bitrate, NULL);
@@ -8569,7 +8552,7 @@ qtdemux_parse_udta (GstQTDemux * qtdemux, GNode * udta)
 
   GST_DEBUG_OBJECT (qtdemux, "new tag list");
   if (!qtdemux->tag_list)
-    qtdemux->tag_list = gst_tag_list_new ();
+    qtdemux->tag_list = gst_tag_list_new_empty ();
 
   i = 0;
   while (i < G_N_ELEMENTS (add_funcs)) {
@@ -8787,7 +8770,7 @@ qtdemux_add_container_format (GstQTDemux * qtdemux, GstTagList * tags)
   const gchar *fmt;
 
   if (tags == NULL)
-    tags = gst_tag_list_new ();
+    tags = gst_tag_list_new_empty ();
 
   if (qtdemux->major_brand == FOURCC_mjp2)
     fmt = "Motion JPEG 2000";
@@ -8848,8 +8831,16 @@ qtdemux_parse_tree (GstQTDemux * qtdemux)
   /* Moving qt creation time (secs since 1904) to unix time */
   if (creation_time != 0) {
     if (creation_time > QTDEMUX_SECONDS_FROM_1904_TO_1970) {
+      GTimeVal now;
+
       creation_time -= QTDEMUX_SECONDS_FROM_1904_TO_1970;
-      datetime = gst_date_time_new_from_unix_epoch_local_time (creation_time);
+      /* some data cleansing sanity */
+      g_get_current_time (&now);
+      if (now.tv_sec + 24 * 3600 < creation_time) {
+        GST_DEBUG_OBJECT (qtdemux, "discarding bogus future creation time");
+      } else {
+        datetime = gst_date_time_new_from_unix_epoch_local_time (creation_time);
+      }
     } else {
       GST_WARNING_OBJECT (qtdemux, "Can't handle datetimes before 1970 yet, "
           "please file a bug at http://bugzilla.gnome.org");
@@ -8857,7 +8848,7 @@ qtdemux_parse_tree (GstQTDemux * qtdemux)
   }
   if (datetime) {
     if (!qtdemux->tag_list)
-      qtdemux->tag_list = gst_tag_list_new ();
+      qtdemux->tag_list = gst_tag_list_new_empty ();
 
     /* Use KEEP as explicit tags should have a higher priority than mvhd tag */
     gst_tag_list_add (qtdemux->tag_list, GST_TAG_MERGE_KEEP, GST_TAG_DATE_TIME,
@@ -8885,8 +8876,13 @@ qtdemux_parse_tree (GstQTDemux * qtdemux)
 
   /* set duration in the segment info */
   gst_qtdemux_get_duration (qtdemux, &duration);
-  if (duration)
+  if (duration) {
     qtdemux->segment.duration = duration;
+    /* also do not exceed duration; stop is set that way post seek anyway,
+     * and segment activation falls back to duration,
+     * whereas loop only checks stop, so let's align this here as well */
+    qtdemux->segment.stop = duration;
+  }
 
   /* parse all traks */
   trak = qtdemux_tree_get_child_by_type (qtdemux->moov_node, FOURCC_trak);