gst/qtdemux/: Handle version 1 mdhd atoms to get extended precision durations.
authorWim Taymans <wim.taymans@gmail.com>
Wed, 11 Apr 2007 09:53:38 +0000 (09:53 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Wed, 11 Apr 2007 09:53:38 +0000 (09:53 +0000)
Original commit message from CVS:
* gst/qtdemux/qtdemux.c: (gst_qtdemux_get_duration),
(qtdemux_parse_samples), (qtdemux_parse_segments),
(qtdemux_parse_trak), (qtdemux_parse_tree):
* gst/qtdemux/qtdemux_dump.c: (qtdemux_dump_mdhd):
Handle version 1 mdhd atoms to get extended precision durations.
Fixes #426972.

ChangeLog
gst/qtdemux/qtdemux.c
gst/qtdemux/qtdemux_dump.c

index 51b44db..adaafd6 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2007-04-11  Wim Taymans  <wim@fluendo.com>
+
+       * gst/qtdemux/qtdemux.c: (gst_qtdemux_get_duration),
+       (qtdemux_parse_samples), (qtdemux_parse_segments),
+       (qtdemux_parse_trak), (qtdemux_parse_tree):
+       * gst/qtdemux/qtdemux_dump.c: (qtdemux_dump_mdhd):
+       Handle version 1 mdhd atoms to get extended precision durations.
+       Fixes #426972.
+
 2007-04-10  Wim Taymans  <wim@fluendo.com>
 
        * gst/rtpmanager/.cvsignore:
index aca5bd3..1cd0f3b 100644 (file)
@@ -116,8 +116,8 @@ struct _QtDemuxStream
   guint32 fourcc;
 
   /* duration/scale */
-  guint32 duration;             /* in timescale */
-  guint32 timescale;
+  guint64 duration;             /* in timescale */
+  guint64 timescale;
 
   /* our samples */
   guint32 n_samples;
@@ -401,7 +401,7 @@ gst_qtdemux_get_duration (GstQTDemux * qtdemux, gint64 * duration)
 
   if (qtdemux->duration != 0) {
     if (qtdemux->duration != G_MAXINT32 && qtdemux->timescale != 0) {
-      *duration = gst_util_uint64_scale_int (qtdemux->duration,
+      *duration = gst_util_uint64_scale (qtdemux->duration,
           GST_SECOND, qtdemux->timescale);
     }
   }
@@ -2385,8 +2385,7 @@ qtdemux_parse_samples (GstQTDemux * qtdemux, QtDemuxStream * stream,
           stream->min_duration = duration;
         /* add non-scaled values to avoid rounding errors */
         time += duration;
-        timestamp = gst_util_uint64_scale_int (time,
-            GST_SECOND, stream->timescale);
+        timestamp = gst_util_uint64_scale (time, GST_SECOND, stream->timescale);
         samples[index].duration = timestamp - samples[index].timestamp;
 
         index++;
@@ -2481,7 +2480,7 @@ qtdemux_parse_samples (GstQTDemux * qtdemux, QtDemuxStream * stream,
         samples[j].timestamp = timestamp;
         sample_index += samples_per_chunk;
 
-        timestamp = gst_util_uint64_scale_int (sample_index,
+        timestamp = gst_util_uint64_scale (sample_index,
             GST_SECOND, stream->timescale);
         samples[j].duration = timestamp - samples[j].timestamp;
 
@@ -2572,12 +2571,12 @@ qtdemux_parse_segments (GstQTDemux * qtdemux, QtDemuxStream * stream,
       segment->time = stime;
       /* add non scaled values so we don't cause roundoff errors */
       time += duration;
-      stime = gst_util_uint64_scale_int (time, GST_SECOND, qtdemux->timescale);
+      stime = gst_util_uint64_scale (time, GST_SECOND, qtdemux->timescale);
       segment->stop_time = stime;
       segment->duration = stime - segment->time;
       /* media_time expressed in stream timescale */
       segment->media_start =
-          gst_util_uint64_scale_int (media_time, GST_SECOND, stream->timescale);
+          gst_util_uint64_scale (media_time, GST_SECOND, stream->timescale);
       segment->media_stop = segment->media_start + segment->duration;
       segment->rate = QT_FP32 (buffer + 24 + i * 12);
 
@@ -2636,6 +2635,7 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
   GstTagList *list = NULL;
   const gchar *codec = NULL;
   const guint8 *stsd_data;
+  guint32 version;
 
   /* new streams always need a discont */
   stream = g_new0 (QtDemuxStream, 1);
@@ -2657,11 +2657,20 @@ qtdemux_parse_trak (GstQTDemux * qtdemux, GNode * trak)
   if (!(mdhd = qtdemux_tree_get_child_by_type (mdia, FOURCC_mdhd)))
     goto corrupt_file;
 
-  stream->timescale = QT_UINT32 ((guint8 *) mdhd->data + 20);
-  stream->duration = QT_UINT32 ((guint8 *) mdhd->data + 24);
+  version = QT_UINT32 ((guint8 *) mdhd->data + 8);
+  GST_LOG_OBJECT (qtdemux, "track version/flags: %08x", version);
+  if (version == 0x01000000) {
+    stream->timescale = QT_UINT32 ((guint8 *) mdhd->data + 28);
+    stream->duration = QT_UINT64 ((guint8 *) mdhd->data + 32);
+  } else {
+    stream->timescale = QT_UINT32 ((guint8 *) mdhd->data + 20);
+    stream->duration = QT_UINT32 ((guint8 *) mdhd->data + 24);
+  }
 
-  GST_LOG_OBJECT (qtdemux, "track timescale: %d", stream->timescale);
-  GST_LOG_OBJECT (qtdemux, "track duration: %d", stream->duration);
+  GST_LOG_OBJECT (qtdemux, "track timescale: %" G_GUINT64_FORMAT,
+      stream->timescale);
+  GST_LOG_OBJECT (qtdemux, "track duration: %" G_GUINT64_FORMAT,
+      stream->duration);
 
   if (qtdemux->duration != G_MAXINT32 && stream->duration != G_MAXINT32) {
     guint64 tdur1, tdur2;
@@ -3501,8 +3510,8 @@ qtdemux_parse_tree (GstQTDemux * qtdemux)
   qtdemux->timescale = QT_UINT32 ((guint8 *) mvhd->data + 20);
   qtdemux->duration = QT_UINT32 ((guint8 *) mvhd->data + 24);
 
-  GST_INFO_OBJECT (qtdemux, "timescale: %d", qtdemux->timescale);
-  GST_INFO_OBJECT (qtdemux, "duration: %d", qtdemux->duration);
+  GST_INFO_OBJECT (qtdemux, "timescale: %u", qtdemux->timescale);
+  GST_INFO_OBJECT (qtdemux, "duration: %u", qtdemux->duration);
 
   /* set duration in the segment info */
   gst_qtdemux_get_duration (qtdemux, &duration);
index 357a5b1..391d67a 100644 (file)
@@ -83,14 +83,36 @@ qtdemux_dump_elst (GstQTDemux * qtdemux, guint8 * buffer, int depth)
 void
 qtdemux_dump_mdhd (GstQTDemux * qtdemux, guint8 * buffer, int depth)
 {
-  GST_LOG ("%*s  version/flags: %08x", depth, "", QT_UINT32 (buffer + 8));
-  GST_LOG ("%*s  creation time: %u", depth, "", QT_UINT32 (buffer + 12));
-  GST_LOG ("%*s  modify time:   %u", depth, "", QT_UINT32 (buffer + 16));
-  GST_LOG ("%*s  time scale:    1/%u sec", depth, "", QT_UINT32 (buffer + 20));
-  GST_LOG ("%*s  duration:      %u", depth, "", QT_UINT32 (buffer + 24));
-  GST_LOG ("%*s  language:      %u", depth, "", QT_UINT16 (buffer + 28));
-  GST_LOG ("%*s  quality:       %u", depth, "", QT_UINT16 (buffer + 30));
+  guint32 version;
+  guint64 duration, ctime, mtime;
+  guint32 time_scale;
+  guint16 language, quality;
+
+  version = QT_UINT32 (buffer + 8);
+  GST_LOG ("%*s  version/flags: %08x", depth, "", version);
+
+  if (version == 0x01000000) {
+    ctime = QT_UINT64 (buffer + 12);
+    mtime = QT_UINT64 (buffer + 20);
+    time_scale = QT_UINT32 (buffer + 28);
+    duration = QT_UINT64 (buffer + 32);
+    language = QT_UINT16 (buffer + 40);
+    quality = QT_UINT16 (buffer + 42);
+  } else {
+    ctime = QT_UINT32 (buffer + 12);
+    mtime = QT_UINT32 (buffer + 16);
+    time_scale = QT_UINT32 (buffer + 20);
+    duration = QT_UINT32 (buffer + 24);
+    language = QT_UINT16 (buffer + 28);
+    quality = QT_UINT16 (buffer + 30);
+  }
 
+  GST_LOG ("%*s  creation time: %" G_GUINT64_FORMAT, depth, "", ctime);
+  GST_LOG ("%*s  modify time:   %" G_GUINT64_FORMAT, depth, "", mtime);
+  GST_LOG ("%*s  time scale:    1/%u sec", depth, "", time_scale);
+  GST_LOG ("%*s  duration:      %" G_GUINT64_FORMAT, depth, "", duration);
+  GST_LOG ("%*s  language:      %u", depth, "", language);
+  GST_LOG ("%*s  quality:       %u", depth, "", quality);
 }
 
 void