summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog14
-rw-r--r--gst/qtdemux/qtdemux.c34
-rw-r--r--gst/qtdemux/qtdemux_dump.c20
-rw-r--r--gst/qtdemux/qtdemux_dump.h1
-rw-r--r--gst/qtdemux/qtdemux_fourcc.h1
-rw-r--r--gst/qtdemux/qtdemux_types.c1
6 files changed, 67 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index 33dfc40f..f5d54055 100644
--- 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
diff --git a/gst/qtdemux/qtdemux.c b/gst/qtdemux/qtdemux.c
index 3b527fac..aca5bd32 100644
--- a/gst/qtdemux/qtdemux.c
+++ b/gst/qtdemux/qtdemux.c
@@ -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;
diff --git a/gst/qtdemux/qtdemux_dump.c b/gst/qtdemux/qtdemux_dump.c
index 561b20d0..357a5b15 100644
--- a/gst/qtdemux/qtdemux_dump.c
+++ b/gst/qtdemux/qtdemux_dump.c
@@ -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;
diff --git a/gst/qtdemux/qtdemux_dump.h b/gst/qtdemux/qtdemux_dump.h
index ce26acc3..adfbeae4 100644
--- a/gst/qtdemux/qtdemux_dump.h
+++ b/gst/qtdemux/qtdemux_dump.h
@@ -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);
diff --git a/gst/qtdemux/qtdemux_fourcc.h b/gst/qtdemux/qtdemux_fourcc.h
index 8dbb3ebd..c196768a 100644
--- a/gst/qtdemux/qtdemux_fourcc.h
+++ b/gst/qtdemux/qtdemux_fourcc.h
@@ -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
diff --git a/gst/qtdemux/qtdemux_types.c b/gst/qtdemux/qtdemux_types.c
index a8bd5415..76813b06 100644
--- a/gst/qtdemux/qtdemux_types.c
+++ b/gst/qtdemux/qtdemux_types.c
@@ -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 =