summaryrefslogtreecommitdiffstats
path: root/contrib/ffmpeg/A10-mp4-track-enable.patch
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/ffmpeg/A10-mp4-track-enable.patch')
-rw-r--r--contrib/ffmpeg/A10-mp4-track-enable.patch142
1 files changed, 142 insertions, 0 deletions
diff --git a/contrib/ffmpeg/A10-mp4-track-enable.patch b/contrib/ffmpeg/A10-mp4-track-enable.patch
new file mode 100644
index 000000000..282326157
--- /dev/null
+++ b/contrib/ffmpeg/A10-mp4-track-enable.patch
@@ -0,0 +1,142 @@
+From 25a0ee27bb5d2bb46781ea4a2a3c88581ad75fde Mon Sep 17 00:00:00 2001
+From: John Stebbins <[email protected]>
+Date: Fri, 10 May 2013 09:16:08 -0700
+Subject: [PATCH 8/9] 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.
+---
+ libavformat/mov.c | 4 +++-
+ libavformat/movenc.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++-
+ libavformat/movenc.h | 1 +
+ 3 files changed, 63 insertions(+), 2 deletions(-)
+
+diff --git a/libavformat/mov.c b/libavformat/mov.c
+index 7fe0548..cb0e395 100644
+--- a/libavformat/mov.c
++++ b/libavformat/mov.c
+@@ -2129,6 +2129,7 @@ static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+ AVStream *st;
+ MOVStreamContext *sc;
+ int version;
++ int flags;
+
+ if (c->fc->nb_streams < 1)
+ return 0;
+@@ -2136,13 +2137,14 @@ static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
+ sc = st->priv_data;
+
+ version = avio_r8(pb);
+- avio_rb24(pb); /* flags */
++ flags = avio_rb24(pb); /* flags */
+ /*
+ MOV_TRACK_ENABLED 0x0001
+ MOV_TRACK_IN_MOVIE 0x0002
+ MOV_TRACK_IN_PREVIEW 0x0004
+ MOV_TRACK_IN_POSTER 0x0008
+ */
++ st->disposition |= (flags & 0x1) ? AV_DISPOSITION_DEFAULT : 0;
+
+ if (version == 1) {
+ avio_rb64(pb);
+diff --git a/libavformat/movenc.c b/libavformat/movenc.c
+index 2f6c003..bc77a6f 100644
+--- a/libavformat/movenc.c
++++ b/libavformat/movenc.c
+@@ -1387,7 +1387,13 @@ 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) ? 0x3 : 0x2); /* flags */
++ /*
++ MOV_TRACK_ENABLED 0x0001
++ MOV_TRACK_IN_MOVIE 0x0002
++ MOV_TRACK_IN_PREVIEW 0x0004
++ MOV_TRACK_IN_POSTER 0x0008
++ */
+ if (version == 1) {
+ avio_wb64(pb, track->time);
+ avio_wb64(pb, track->time);
+@@ -3003,6 +3009,56 @@ static void mov_create_chapter_track(AVFormatContext *s, int tracknum)
+ }
+ }
+
++// 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;
++ default:
++ break;
++ }
++ }
++}
++
+ static int mov_write_header(AVFormatContext *s)
+ {
+ AVIOContext *pb = s->pb;
+@@ -3156,6 +3212,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 3ea0dd5..9bb8a78 100644
+--- a/libavformat/movenc.h
++++ b/libavformat/movenc.h
+@@ -84,6 +84,7 @@ typedef struct MOVIndex {
+ 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;
+--
+1.8.1.4
+