diff options
-rw-r--r-- | ChangeLog | 14 | ||||
-rw-r--r-- | gst/qtdemux/qtdemux.c | 34 | ||||
-rw-r--r-- | gst/qtdemux/qtdemux_dump.c | 20 | ||||
-rw-r--r-- | gst/qtdemux/qtdemux_dump.h | 1 | ||||
-rw-r--r-- | gst/qtdemux/qtdemux_fourcc.h | 1 | ||||
-rw-r--r-- | gst/qtdemux/qtdemux_types.c | 1 |
6 files changed, 67 insertions, 4 deletions
@@ -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 = |