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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 840190d..92d923e 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -136,6 +136,54 @@ static int mov_write_stco_tag(AVIOContext *pb, MOVTrack *track)
return update_size(pb, pos);
}
+static int mov_write_sgpd_tag(AVIOContext *pb, int16_t roll)
+{
+ int64_t pos = avio_tell(pb);
+ avio_wb32(pb, 0); /* size */
+
+ ffio_wfourcc(pb, "sgpd");
+ avio_w8(pb, 1); /* version */
+ avio_w8(pb, 0); /* flags (1) */
+ avio_wb16(pb, 0); /* flags (2) */
+ ffio_wfourcc(pb, "roll"); /* grouping type */
+ avio_wb32(pb, 2); /* table entry length */
+ avio_wb32(pb, 1); /* table entry count */
+
+ /* table data, roll distance
+ * i.e. number of audio frames to pre-roll after a seek */
+ avio_wb16(pb, roll);
+
+ return update_size(pb, pos);
+}
+
+static int mov_write_sbgp_tag(AVIOContext *pb, MOVTrack *track)
+{
+ int count = 0;
+ int i;
+ int64_t pos;
+
+ for (i = 0; i < track->entry; i++)
+ {
+ count += track->cluster[i].entries;
+ }
+
+ pos = avio_tell(pb);
+ avio_wb32(pb, 0); /* size */
+
+ ffio_wfourcc(pb, "sbgp"); /* atom name */
+ avio_wb32(pb, 0); /* version & flags */
+ ffio_wfourcc(pb, "roll"); /* grouping type */
+ avio_wb32(pb, 1); /* table entry count */
+
+ /* table data */
+ avio_wb32(pb, count);
+ /* sgpd table index, index values are 1 based
+ * we write 'roll' sample group at index 1 */
+ avio_wb32(pb, 1);
+
+ return update_size(pb, pos);
+}
+
/* Sample size atom */
static int mov_write_stsz_tag(AVIOContext *pb, MOVTrack *track)
{
@@ -1277,6 +1325,16 @@ static int mov_write_stbl_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *tra
mov_write_stsc_tag(pb, track);
mov_write_stsz_tag(pb, track);
mov_write_stco_tag(pb, track);
+
+ /* Add sgpd and sbgp tags for AAC tracks
+ * Apple documentation says they use this as a flag to indicate
+ * that AAC encoder delay is explicitely set in the edit list */
+ if (track->par->codec_id == AV_CODEC_ID_AAC)
+ {
+ mov_write_sgpd_tag(pb, -1);
+ mov_write_sbgp_tag(pb, track);
+ }
+
return update_size(pb, pos);
}
|