summaryrefslogtreecommitdiffstats
path: root/contrib/ffmpeg/A07-mp4-chapters.patch
blob: 0fec0eaf97d95fd248d14d460b03b55207c64641 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
From 36bdd52964ef68532eea50a81431c0c4c9f329e5 Mon Sep 17 00:00:00 2001
From: John Stebbins <jstebbins.hb@gmail.com>
Date: Fri, 10 May 2013 08:51:46 -0700
Subject: [PATCH 4/9] movenc: Allow chapters to be written in trailer

This allows creation of frame accurate chapter marks from sources
like DVD and BD where the precise chapter location is not known until
the chapter mark has been reached during reading.
---
 libavformat/movenc.c | 19 ++++++++++++++++---
 1 file changed, 16 insertions(+), 3 deletions(-)

diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 496158c..f41f8d7 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -3038,7 +3038,7 @@ static int mov_write_header(AVFormatContext *s)
     }
 
     mov->nb_streams = s->nb_streams;
-    if (mov->mode & (MODE_MOV|MODE_IPOD) && s->nb_chapters)
+    if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters)
         mov->chapter_track = mov->nb_streams++;
 
     if (mov->flags & FF_MOV_FLAG_RTP_HINT) {
@@ -3053,7 +3053,9 @@ static int mov_write_header(AVFormatContext *s)
         }
     }
 
-    mov->tracks = av_mallocz(mov->nb_streams*sizeof(*mov->tracks));
+    // Reserve an extra stream for chapters for the case where chapters
+    // are written in the trailer
+    mov->tracks = av_mallocz((mov->nb_streams+1)*sizeof(*mov->tracks));
     if (!mov->tracks)
         return AVERROR(ENOMEM);
 
@@ -3189,8 +3191,19 @@ static int mov_write_trailer(AVFormatContext *s)
     AVIOContext *pb = s->pb;
     int res = 0;
     int i;
+    int64_t moov_pos;
+
+    // If there were no chapters when the header was written, but there
+    // are chapters now, write them in the trailer.  This only works
+    // when we are not doing fragments.
+    if (!mov->chapter_track && !(mov->flags & FF_MOV_FLAG_FRAGMENT)) {
+        if (mov->mode & (MODE_MP4|MODE_MOV|MODE_IPOD) && s->nb_chapters) {
+            mov->chapter_track = mov->nb_streams++;
+            mov_create_chapter_track(s, mov->chapter_track);
+        }
+    }
 
-    int64_t moov_pos = avio_tell(pb);
+    moov_pos = avio_tell(pb);
 
     if (!(mov->flags & FF_MOV_FLAG_FRAGMENT)) {
         /* Write size of mdat tag */
-- 
1.8.1.4