gst/qtdemux/: Process 'ctts' atoms, which are present in AVC ISO files (.mov files...
authorEdward Hervey <bilboed@bilboed.com>
Wed, 28 Mar 2007 15:17:27 +0000 (15:17 +0000)
committerEdward Hervey <bilboed@bilboed.com>
Wed, 28 Mar 2007 15:17:27 +0000 (15:17 +0000)
Original commit message from CVS:
* gst/qtdemux/qtdemux.c: (gst_qtdemux_prepare_current_sample),
(gst_qtdemux_chain), (qtdemux_parse_samples):
* gst/qtdemux/qtdemux_dump.c: (qtdemux_dump_ctts):
* gst/qtdemux/qtdemux_dump.h:
* gst/qtdemux/qtdemux_fourcc.h:
* gst/qtdemux/qtdemux_types.c:
Process 'ctts' atoms, which are present in AVC ISO files (.mov files
with h264 video).
Use the offset present in 'ctts' to calculate the PTS for each packet
and set the PTS on outgoing buffers.
Fixes #423283

ChangeLog
gst/qtdemux/qtdemux.c
gst/qtdemux/qtdemux_dump.c
gst/qtdemux/qtdemux_dump.h
gst/qtdemux/qtdemux_fourcc.h
gst/qtdemux/qtdemux_types.c

index 33dfc40..f5d5405 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2007-03-28  Edward Hervey  <edward@fluendo.com>
+
+       * gst/qtdemux/qtdemux.c: (gst_qtdemux_prepare_current_sample),
+       (gst_qtdemux_chain), (qtdemux_parse_samples):
+       * gst/qtdemux/qtdemux_dump.c: (qtdemux_dump_ctts):
+       * gst/qtdemux/qtdemux_dump.h:
+       * gst/qtdemux/qtdemux_fourcc.h:
+       * gst/qtdemux/qtdemux_types.c:
+       Process 'ctts' atoms, which are present in AVC ISO files (.mov files
+       with h264 video).
+       Use the offset present in 'ctts' to calculate the PTS for each packet
+       and set the PTS on outgoing buffers.
+       Fixes #423283
+
 2007-03-27  Julien MOUTTE  <julien@moutte.net>
 
        * ext/xvid/gstxviddec.c: (gst_xviddec_chain): Add some
index 3b527fa..aca5bd3 100644 (file)
@@ -88,6 +88,7 @@ struct _QtDemuxSample
   guint32 chunk;
   guint32 size;
   guint64 offset;
+  GstClockTimeDiff pts_offset;  /* Add this value to timestamp to get the pts */
   guint64 timestamp;            /* In GstClockTime */
   guint64 duration;             /* in GstClockTime */
   gboolean keyframe;            /* TRUE when this packet is a keyframe */
@@ -1147,9 +1148,9 @@ gst_qtdemux_prepare_current_sample (GstQTDemux * qtdemux,
   /* now get the info for the sample we're at */
   sample = &stream->samples[stream->sample_index];
 
+  *timestamp = sample->timestamp + sample->pts_offset;
   *offset = sample->offset;
   *size = sample->size;
-  *timestamp = sample->timestamp;
   *duration = sample->duration;
   *keyframe = stream->all_keyframe || sample->keyframe;
 
@@ -1687,9 +1688,15 @@ gst_qtdemux_chain (GstPad * sinkpad, GstBuffer * inbuf)
         GST_DEBUG_OBJECT (demux, "stream : %" GST_FOURCC_FORMAT,
             GST_FOURCC_ARGS (stream->fourcc));
 
-        GST_BUFFER_TIMESTAMP (outbuf) =
-            stream->samples[stream->sample_index].timestamp;
-        demux->last_ts = GST_BUFFER_TIMESTAMP (outbuf);
+        if (stream->samples[stream->sample_index].pts_offset) {
+          demux->last_ts = stream->samples[stream->sample_index].timestamp;
+          GST_BUFFER_TIMESTAMP (outbuf) = demux->last_ts +
+              stream->samples[stream->sample_index].pts_offset;
+        } else {
+          GST_BUFFER_TIMESTAMP (outbuf) =
+              stream->samples[stream->sample_index].timestamp;
+          demux->last_ts = GST_BUFFER_TIMESTAMP (outbuf);
+        }
         GST_BUFFER_DURATION (outbuf) =
             stream->samples[stream->sample_index].duration;
 
@@ -2265,6 +2272,7 @@ qtdemux_parse_samples (GstQTDemux * qtdemux, QtDemuxStream * stream,
   GNode *co64;
   GNode *stts;
   GNode *stss;
+  GNode *ctts;
   const guint8 *stsc_data, *stsz_data, *stco_data;
   int sample_size;
   int sample_index;
@@ -2481,6 +2489,24 @@ qtdemux_parse_samples (GstQTDemux * qtdemux, QtDemuxStream * stream,
       }
     }
   }
+
+  /* composition time to sample */
+  if ((ctts = qtdemux_tree_get_child_by_type (stbl, FOURCC_ctts))) {
+    const guint8 *ctts_data = (const guint8 *) ctts->data;
+    guint32 n_entries = QT_UINT32 (ctts_data + 12);
+    guint32 count;
+    gint32 soffset;
+
+    /* Fill in the pts_offsets */
+    for (i = 0, j = 0; (j < stream->n_samples) && (i < n_entries); i++) {
+      count = QT_UINT32 (ctts_data + 16 + i * 8);
+      soffset = QT_UINT32 (ctts_data + 20 + i * 8);
+      for (k = 0; k < count; k++, j++) {
+        /* we operate with very small soffset values here, it shouldn't overflow */
+        samples[j].pts_offset = soffset * GST_SECOND / stream->timescale;
+      }
+    }
+  }
 done:
   return TRUE;
 
index 561b20d..357a5b1 100644 (file)
@@ -298,6 +298,26 @@ qtdemux_dump_stco (GstQTDemux * qtdemux, guint8 * buffer, int depth)
 }
 
 void
+qtdemux_dump_ctts (GstQTDemux * qtdemux, guint8 * buffer, int depth)
+{
+  int i;
+  int n;
+  int offset;
+
+  GST_LOG ("%*s  version/flags: %08x", depth, "", QT_UINT32 (buffer + 8));
+  n = QT_UINT32 (buffer + 12);
+  GST_LOG ("%*s  n entries:     %d", depth, "", n);
+  offset = 16;
+  for (i = 0; i < n; i++) {
+    GST_LOG ("%*s    sample count :%8d offset: %8d",
+        depth, "", QT_UINT32 (buffer + offset),
+        QT_UINT32 (buffer + offset + 4));
+
+    offset += 8;
+  }
+}
+
+void
 qtdemux_dump_co64 (GstQTDemux * qtdemux, guint8 * buffer, int depth)
 {
   //int i;
index ce26acc..adfbeae 100644 (file)
@@ -41,6 +41,7 @@ void qtdemux_dump_stco (GstQTDemux * qtdemux, guint8 * buffer, int depth);
 void qtdemux_dump_co64 (GstQTDemux * qtdemux, guint8 * buffer, int depth);
 void qtdemux_dump_dcom (GstQTDemux * qtdemux, guint8 * buffer, int depth);
 void qtdemux_dump_cmvd (GstQTDemux * qtdemux, guint8 * buffer, int depth);
+void qtdemux_dump_ctts (GstQTDemux * qtdemux, guint8 * buffer, int depth);
 void qtdemux_dump_unknown (GstQTDemux * qtdemux, guint8 * buffer, int depth);
 
 void qtdemux_node_dump (GstQTDemux * qtdemux, GNode * node);
index 8dbb3eb..c196768 100644 (file)
@@ -126,6 +126,7 @@ G_BEGIN_DECLS
 #define FOURCC_alis     GST_MAKE_FOURCC('a','l','i','s')
 #define FOURCC_url_     GST_MAKE_FOURCC('u','r','l',' ')
 #define FOURCC_frma     GST_MAKE_FOURCC('f','r','m','a')
+#define FOURCC_ctts    GST_MAKE_FOURCC('c','t','t','s')
 
 G_END_DECLS
 
index a8bd541..76813b0 100644 (file)
@@ -107,6 +107,7 @@ static const QtNodeType qt_node_types[] = {
   {FOURCC_rmda, "rmda", QT_FLAG_CONTAINER,},
   {FOURCC_rdrf, "rdrf", 0,},
   {FOURCC__gen, "Custom Genre", QT_FLAG_CONTAINER,},
+  {FOURCC_ctts, "Composition time to sample", 0, qtdemux_dump_ctts},
   {0, "unknown", 0,},
 };
 static const int n_qt_node_types =