summaryrefslogtreecommitdiffstats
path: root/gst
diff options
context:
space:
mode:
authorWim Taymans <wim.taymans@gmail.com>2007-04-11 09:53:38 +0000
committerWim Taymans <wim.taymans@gmail.com>2007-04-11 09:53:38 +0000
commit54260af4c9042d98531907c3a149eea03b5283cd (patch)
treeb3a8f0237b90f9b724bd384e5a4afbb2bc164147 /gst
parent8db0d2bcab91315deaf53f97fb8e3213d7e6ff6d (diff)
downloadgst-plugins-bad-54260af4c9042d98531907c3a149eea03b5283cd.tar.gz
gst-plugins-bad-54260af4c9042d98531907c3a149eea03b5283cd.tar.bz2
gst-plugins-bad-54260af4c9042d98531907c3a149eea03b5283cd.zip
gst/qtdemux/: Handle version 1 mdhd atoms to get extended precision durations.
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.
Diffstat (limited to 'gst')
-rw-r--r--gst/qtdemux/qtdemux.c37
-rw-r--r--gst/qtdemux/qtdemux_dump.c36
2 files changed, 52 insertions, 21 deletions
diff --git a/gst/qtdemux/qtdemux.c b/gst/qtdemux/qtdemux.c
index aca5bd32..1cd0f3b8 100644
--- a/gst/qtdemux/qtdemux.c
+++ b/gst/qtdemux/qtdemux.c
@@ -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);
diff --git a/gst/qtdemux/qtdemux_dump.c b/gst/qtdemux/qtdemux_dump.c
index 357a5b15..391d67a0 100644
--- a/gst/qtdemux/qtdemux_dump.c
+++ b/gst/qtdemux/qtdemux_dump.c
@@ -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