summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEdward Hervey <bilboed@bilboed.com>2007-03-28 15:17:27 +0000
committerEdward Hervey <bilboed@bilboed.com>2007-03-28 15:17:27 +0000
commitab589bff3e975300c0f9f26b534078155c1989ea (patch)
treefd9e49f4a888dcbcb4f60b971c2dce2de01676b5
parent8f5fb88b5ac1b80dc0ab8190a2da26f2c23f31f2 (diff)
gst/qtdemux/: Process 'ctts' atoms, which are present in AVC ISO files (.mov files with h264 video).
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
m---------common0
-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, 53 insertions, 4 deletions
diff --git a/common b/common
-Subproject dec151d15512e4cca2dcdd36d9c6c4a2185760e
+Subproject 57d4a1587556bd42c850601773c662211694c5a
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 =