[FFmpeg-cvslog] movenc: Make tkhd "enabled" flag QuickTime compatible

John Stebbins git at videolan.org
Fri Aug 23 14:17:26 CEST 2013


ffmpeg | branch: master | John Stebbins <stebbins at jetheaddev.com> | Thu Aug 22 07:25:18 2013 -0700| [30ce289074e88f528965cb57720674a675639737] | committer: Anton Khirnov

movenc: Make tkhd "enabled" flag QuickTime compatible

QuickTime will play multiple audio tracks concurrently if this flag is
set for multiple audio tracks.  And if no subtitle track has this flag
set, QuickTime will show no subtitles in the subtitle menu.

Signed-off-by: Anton Khirnov <anton at khirnov.net>

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=30ce289074e88f528965cb57720674a675639737
---

 libavformat/movenc.c                 |   56 +++++++++++++++++++++++++++++++++-
 libavformat/movenc.h                 |    1 +
 tests/ref/acodec/alac                |    2 +-
 tests/ref/acodec/pcm-s16be           |    2 +-
 tests/ref/acodec/pcm-s24be           |    2 +-
 tests/ref/acodec/pcm-s32be           |    2 +-
 tests/ref/acodec/pcm-s8              |    2 +-
 tests/ref/lavf/mov                   |    2 +-
 tests/ref/vsynth/vsynth1-dnxhd-1080i |    2 +-
 tests/ref/vsynth/vsynth1-mpeg4       |    2 +-
 tests/ref/vsynth/vsynth1-prores      |    2 +-
 tests/ref/vsynth/vsynth1-qtrle       |    2 +-
 tests/ref/vsynth/vsynth1-svq1        |    2 +-
 tests/ref/vsynth/vsynth2-dnxhd-1080i |    2 +-
 tests/ref/vsynth/vsynth2-mpeg4       |    2 +-
 tests/ref/vsynth/vsynth2-prores      |    2 +-
 tests/ref/vsynth/vsynth2-qtrle       |    2 +-
 tests/ref/vsynth/vsynth2-svq1        |    2 +-
 18 files changed, 72 insertions(+), 17 deletions(-)

diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 0c6b09d..577c7e8 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -1391,7 +1391,9 @@ static int mov_write_tkhd_tag(AVIOContext *pb, MOVTrack *track, AVStream *st)
     (version == 1) ? avio_wb32(pb, 104) : avio_wb32(pb, 92); /* size */
     ffio_wfourcc(pb, "tkhd");
     avio_w8(pb, version);
-    avio_wb24(pb, 0xf); /* flags (track enabled) */
+    avio_wb24(pb, (track->flags & MOV_TRACK_ENABLED) ?
+                  MOV_TKHD_FLAG_ENABLED | MOV_TKHD_FLAG_IN_MOVIE :
+                  MOV_TKHD_FLAG_IN_MOVIE);
     if (version == 1) {
         avio_wb64(pb, track->time);
         avio_wb64(pb, track->time);
@@ -3028,6 +3030,56 @@ static int mov_create_chapter_track(AVFormatContext *s, int tracknum)
     return 0;
 }
 
+/*
+ * st->disposition controls the "enabled" flag in the tkhd tag.
+ * QuickTime will not play a track if it is not enabled.  So make sure
+ * that one track of each type (audio, video, subtitle) is enabled.
+ *
+ * Subtitles are special.  For audio and video, setting "enabled" also
+ * makes the track "default" (i.e. it is rendered when played). For
+ * subtitles, an "enabled" subtitle is not rendered by default, but
+ * if no subtitle is enabled, the subtitle menu in QuickTime will be
+ * empty!
+ */
+static void enable_tracks(AVFormatContext *s)
+{
+    MOVMuxContext *mov = s->priv_data;
+    int i;
+    uint8_t enabled[AVMEDIA_TYPE_NB];
+    int first[AVMEDIA_TYPE_NB];
+
+    for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
+        enabled[i] = 0;
+        first[i] = -1;
+    }
+
+    for (i = 0; i < s->nb_streams; i++) {
+        AVStream *st = s->streams[i];
+
+        if (st->codec->codec_type <= AVMEDIA_TYPE_UNKNOWN ||
+            st->codec->codec_type >= AVMEDIA_TYPE_NB)
+            continue;
+
+        if (first[st->codec->codec_type] < 0)
+            first[st->codec->codec_type] = i;
+        if (st->disposition & AV_DISPOSITION_DEFAULT) {
+            mov->tracks[i].flags |= MOV_TRACK_ENABLED;
+            enabled[st->codec->codec_type] = 1;
+        }
+    }
+
+    for (i = 0; i < AVMEDIA_TYPE_NB; i++) {
+        switch (i) {
+        case AVMEDIA_TYPE_VIDEO:
+        case AVMEDIA_TYPE_AUDIO:
+        case AVMEDIA_TYPE_SUBTITLE:
+            if (!enabled[i] && first[i] >= 0)
+                mov->tracks[first[i]].flags |= MOV_TRACK_ENABLED;
+            break;
+        }
+    }
+}
+
 static int mov_write_header(AVFormatContext *s)
 {
     AVIOContext *pb = s->pb;
@@ -3182,6 +3234,8 @@ static int mov_write_header(AVFormatContext *s)
         }
     }
 
+    enable_tracks(s);
+
     if (mov->mode == MODE_ISM) {
         /* If no fragmentation options have been set, set a default. */
         if (!(mov->flags & (FF_MOV_FLAG_FRAG_KEYFRAME |
diff --git a/libavformat/movenc.h b/libavformat/movenc.h
index a6282e1..78001cc 100644
--- a/libavformat/movenc.h
+++ b/libavformat/movenc.h
@@ -85,6 +85,7 @@ typedef struct MOVTrack {
     int         has_keyframes;
 #define MOV_TRACK_CTTS         0x0001
 #define MOV_TRACK_STPS         0x0002
+#define MOV_TRACK_ENABLED      0x0004
     uint32_t    flags;
     int         language;
     int         track_id;
diff --git a/tests/ref/acodec/alac b/tests/ref/acodec/alac
index bb7a202..dde0e36 100644
--- a/tests/ref/acodec/alac
+++ b/tests/ref/acodec/alac
@@ -1,4 +1,4 @@
-8ad790d3a0bbda81cd23c15ab8ba760d *tests/data/fate/acodec-alac.mov
+98cfcf6cf139844ca27d16f1fc64f62c *tests/data/fate/acodec-alac.mov
 389258 tests/data/fate/acodec-alac.mov
 64151e4bcc2b717aa5a8454d424d6a1f *tests/data/fate/acodec-alac.out.wav
 stddev:    0.00 PSNR:999.99 MAXDIFF:    0 bytes:  1058400/  1058400
diff --git a/tests/ref/acodec/pcm-s16be b/tests/ref/acodec/pcm-s16be
index 39c3838..61e5664 100644
--- a/tests/ref/acodec/pcm-s16be
+++ b/tests/ref/acodec/pcm-s16be
@@ -1,4 +1,4 @@
-009a446579dd4cba793723b5e2b93c39 *tests/data/fate/acodec-pcm-s16be.mov
+b650d16f5ac191c41d5fa3657cf4c1ac *tests/data/fate/acodec-pcm-s16be.mov
 1060097 tests/data/fate/acodec-pcm-s16be.mov
 64151e4bcc2b717aa5a8454d424d6a1f *tests/data/fate/acodec-pcm-s16be.out.wav
 stddev:    0.00 PSNR:999.99 MAXDIFF:    0 bytes:  1058400/  1058400
diff --git a/tests/ref/acodec/pcm-s24be b/tests/ref/acodec/pcm-s24be
index 20bc4e0..f673040 100644
--- a/tests/ref/acodec/pcm-s24be
+++ b/tests/ref/acodec/pcm-s24be
@@ -1,4 +1,4 @@
-de27dae0dff0359d8f39449b17d5607f *tests/data/fate/acodec-pcm-s24be.mov
+0bd99d1273fb1fb78055cf97f3efe299 *tests/data/fate/acodec-pcm-s24be.mov
 1589297 tests/data/fate/acodec-pcm-s24be.mov
 64151e4bcc2b717aa5a8454d424d6a1f *tests/data/fate/acodec-pcm-s24be.out.wav
 stddev:    0.00 PSNR:999.99 MAXDIFF:    0 bytes:  1058400/  1058400
diff --git a/tests/ref/acodec/pcm-s32be b/tests/ref/acodec/pcm-s32be
index 302bc1a..1b6dec9 100644
--- a/tests/ref/acodec/pcm-s32be
+++ b/tests/ref/acodec/pcm-s32be
@@ -1,4 +1,4 @@
-2db1e7fe92d4006103691a4b59064dc6 *tests/data/fate/acodec-pcm-s32be.mov
+7ebffb0bd01c02b9953ee5b1e2f47910 *tests/data/fate/acodec-pcm-s32be.mov
 2118497 tests/data/fate/acodec-pcm-s32be.mov
 64151e4bcc2b717aa5a8454d424d6a1f *tests/data/fate/acodec-pcm-s32be.out.wav
 stddev:    0.00 PSNR:999.99 MAXDIFF:    0 bytes:  1058400/  1058400
diff --git a/tests/ref/acodec/pcm-s8 b/tests/ref/acodec/pcm-s8
index f830d2f..c947729 100644
--- a/tests/ref/acodec/pcm-s8
+++ b/tests/ref/acodec/pcm-s8
@@ -1,4 +1,4 @@
-9ee95a7fff38831a1cad3b49c33e6ed9 *tests/data/fate/acodec-pcm-s8.mov
+3b52f563e8e99aa26253eff154980a93 *tests/data/fate/acodec-pcm-s8.mov
 530897 tests/data/fate/acodec-pcm-s8.mov
 651d4eb8d98dfcdda96ae6c43d8f156b *tests/data/fate/acodec-pcm-s8.out.wav
 stddev:  147.89 PSNR: 52.93 MAXDIFF:  255 bytes:  1058400/  1058400
diff --git a/tests/ref/lavf/mov b/tests/ref/lavf/mov
index f73cd4f..f34a006 100644
--- a/tests/ref/lavf/mov
+++ b/tests/ref/lavf/mov
@@ -1,3 +1,3 @@
-8404cccff020ab07fbfe9c713bc98c33 *./tests/data/lavf/lavf.mov
+e46f42ed71a589ac356e9cfad4e1e56a *./tests/data/lavf/lavf.mov
 356797 ./tests/data/lavf/lavf.mov
 ./tests/data/lavf/lavf.mov CRC=0xe3f4950d
diff --git a/tests/ref/vsynth/vsynth1-dnxhd-1080i b/tests/ref/vsynth/vsynth1-dnxhd-1080i
index 3a990c5..8d396e8 100644
--- a/tests/ref/vsynth/vsynth1-dnxhd-1080i
+++ b/tests/ref/vsynth/vsynth1-dnxhd-1080i
@@ -1,4 +1,4 @@
-2412f206f5efcbbcc3f2bba0c86b73d4 *tests/data/fate/vsynth1-dnxhd-1080i.mov
+9e55c9ec332cc6ee002da67de34ca6d1 *tests/data/fate/vsynth1-dnxhd-1080i.mov
 3031875 tests/data/fate/vsynth1-dnxhd-1080i.mov
 34076f61254997c8157eafed1c916472 *tests/data/fate/vsynth1-dnxhd-1080i.out.rawvideo
 stddev:    6.29 PSNR: 32.15 MAXDIFF:   64 bytes:  7603200/   760320
diff --git a/tests/ref/vsynth/vsynth1-mpeg4 b/tests/ref/vsynth/vsynth1-mpeg4
index 9a917d0..38a7294 100644
--- a/tests/ref/vsynth/vsynth1-mpeg4
+++ b/tests/ref/vsynth/vsynth1-mpeg4
@@ -1,4 +1,4 @@
-59a9e2eed314abface66aaf1b45eb8f2 *tests/data/fate/vsynth1-mpeg4.mp4
+dc927acd770e19a97456ecbd4d786938 *tests/data/fate/vsynth1-mpeg4.mp4
 540180 tests/data/fate/vsynth1-mpeg4.mp4
 8828a375448dc5c2215163ba70656f89 *tests/data/fate/vsynth1-mpeg4.out.rawvideo
 stddev:    7.97 PSNR: 30.10 MAXDIFF:  105 bytes:  7603200/  7603200
diff --git a/tests/ref/vsynth/vsynth1-prores b/tests/ref/vsynth/vsynth1-prores
index ac30a6a..12aa758 100644
--- a/tests/ref/vsynth/vsynth1-prores
+++ b/tests/ref/vsynth/vsynth1-prores
@@ -1,4 +1,4 @@
-2566517b15c62887bd94daaab1b1a85b *tests/data/fate/vsynth1-prores.mov
+7dfcca40f50ff1d72541bc095c904784 *tests/data/fate/vsynth1-prores.mov
 3859037 tests/data/fate/vsynth1-prores.mov
 0a4153637d0cc0a88a8bcbf04cfaf8c6 *tests/data/fate/vsynth1-prores.out.rawvideo
 stddev:    3.17 PSNR: 38.09 MAXDIFF:   39 bytes:  7603200/  7603200
diff --git a/tests/ref/vsynth/vsynth1-qtrle b/tests/ref/vsynth/vsynth1-qtrle
index c9c8ccf..4ddd1d8 100644
--- a/tests/ref/vsynth/vsynth1-qtrle
+++ b/tests/ref/vsynth/vsynth1-qtrle
@@ -1,4 +1,4 @@
-7d75328a17e04796a39fe9be3a322946 *tests/data/fate/vsynth1-qtrle.mov
+24650c5b226d054c57be7c06c9220058 *tests/data/fate/vsynth1-qtrle.mov
 15263232 tests/data/fate/vsynth1-qtrle.mov
 243325fb2cae1a9245efd49aff936327 *tests/data/fate/vsynth1-qtrle.out.rawvideo
 stddev:    3.42 PSNR: 37.43 MAXDIFF:   48 bytes:  7603200/  7603200
diff --git a/tests/ref/vsynth/vsynth1-svq1 b/tests/ref/vsynth/vsynth1-svq1
index 0f8a6b2..f610fdc 100644
--- a/tests/ref/vsynth/vsynth1-svq1
+++ b/tests/ref/vsynth/vsynth1-svq1
@@ -1,4 +1,4 @@
-5c9d8734693f3cab57f61e76b5b6da7d *tests/data/fate/vsynth1-svq1.mov
+3c90c6c0c4db7993660cee642de05bb4 *tests/data/fate/vsynth1-svq1.mov
 1334367 tests/data/fate/vsynth1-svq1.mov
 9cc35c54b2c77d36bd7e308b393c1f81 *tests/data/fate/vsynth1-svq1.out.rawvideo
 stddev:    9.58 PSNR: 28.50 MAXDIFF:  210 bytes:  7603200/  7603200
diff --git a/tests/ref/vsynth/vsynth2-dnxhd-1080i b/tests/ref/vsynth/vsynth2-dnxhd-1080i
index 27c79a5..35db6d2 100644
--- a/tests/ref/vsynth/vsynth2-dnxhd-1080i
+++ b/tests/ref/vsynth/vsynth2-dnxhd-1080i
@@ -1,4 +1,4 @@
-65ca6385b565b6ea9a2e28150eef1d46 *tests/data/fate/vsynth2-dnxhd-1080i.mov
+c456f2a7ac9435ea5bfea86bc69c1c41 *tests/data/fate/vsynth2-dnxhd-1080i.mov
 3031875 tests/data/fate/vsynth2-dnxhd-1080i.mov
 42262a2325441b38b3b3c8a42d888e7d *tests/data/fate/vsynth2-dnxhd-1080i.out.rawvideo
 stddev:    1.31 PSNR: 45.77 MAXDIFF:   23 bytes:  7603200/   760320
diff --git a/tests/ref/vsynth/vsynth2-mpeg4 b/tests/ref/vsynth/vsynth2-mpeg4
index 4d96557..a654c13 100644
--- a/tests/ref/vsynth/vsynth2-mpeg4
+++ b/tests/ref/vsynth/vsynth2-mpeg4
@@ -1,4 +1,4 @@
-8c9afbf564008a8ce6719cc3546deae1 *tests/data/fate/vsynth2-mpeg4.mp4
+0282105e98166fac06f7ba9e857cfbfe *tests/data/fate/vsynth2-mpeg4.mp4
 119833 tests/data/fate/vsynth2-mpeg4.mp4
 90a3577850239083a9042bef33c50e85 *tests/data/fate/vsynth2-mpeg4.out.rawvideo
 stddev:    5.34 PSNR: 33.57 MAXDIFF:   83 bytes:  7603200/  7603200
diff --git a/tests/ref/vsynth/vsynth2-prores b/tests/ref/vsynth/vsynth2-prores
index 9a834ed..9d56b95 100644
--- a/tests/ref/vsynth/vsynth2-prores
+++ b/tests/ref/vsynth/vsynth2-prores
@@ -1,4 +1,4 @@
-28755ce05e812adbb8b7c180318ffba8 *tests/data/fate/vsynth2-prores.mov
+7d167fee27e8c34968bbecec282f927a *tests/data/fate/vsynth2-prores.mov
 3884722 tests/data/fate/vsynth2-prores.mov
 ca2f6c1162635dedfa468c90f1fdc0ef *tests/data/fate/vsynth2-prores.out.rawvideo
 stddev:    0.92 PSNR: 48.77 MAXDIFF:   10 bytes:  7603200/  7603200
diff --git a/tests/ref/vsynth/vsynth2-qtrle b/tests/ref/vsynth/vsynth2-qtrle
index ceee854..ac2b557 100644
--- a/tests/ref/vsynth/vsynth2-qtrle
+++ b/tests/ref/vsynth/vsynth2-qtrle
@@ -1,4 +1,4 @@
-4805f35ca6e03b9279cc18f3f7356366 *tests/data/fate/vsynth2-qtrle.mov
+fe3db3dd385b8e5dc43cccc17b50f7f0 *tests/data/fate/vsynth2-qtrle.mov
 14798419 tests/data/fate/vsynth2-qtrle.mov
 b2418e0e3a9a8619b31219cbcf24dc82 *tests/data/fate/vsynth2-qtrle.out.rawvideo
 stddev:    1.26 PSNR: 46.06 MAXDIFF:   13 bytes:  7603200/  7603200
diff --git a/tests/ref/vsynth/vsynth2-svq1 b/tests/ref/vsynth/vsynth2-svq1
index 251f72d..e2af545 100644
--- a/tests/ref/vsynth/vsynth2-svq1
+++ b/tests/ref/vsynth/vsynth2-svq1
@@ -1,4 +1,4 @@
-138ad38281570f1a3b68d63ed896435d *tests/data/fate/vsynth2-svq1.mov
+c15de1e0b0439981dc94b927b1933889 *tests/data/fate/vsynth2-svq1.mov
 766851 tests/data/fate/vsynth2-svq1.mov
 aa03471dac3f49455a33a2b19fda1098 *tests/data/fate/vsynth2-svq1.out.rawvideo
 stddev:    3.23 PSNR: 37.93 MAXDIFF:   61 bytes:  7603200/  7603200



More information about the ffmpeg-cvslog mailing list