This recordes the number of AAC frames that must be decoded before valid
audio is decoded.
It also signals to Apple tools that the encoder delay is explicitly set
in the edit list. If the roll sample group is omitted, Apply tools will
apply an implicit rule to remove encoder delay which would result in
removing the delay twice.
---
libavformat/movenc.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++
tests/ref/fate/movenc | 32 +++++++++++++-------------
2 files changed, 79 insertions(+), 16 deletions(-)
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 4d351b7..a26dcf7 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)
{
@@ -1260,6 +1308,7 @@ static int mov_write_dref_tag(AVIOContext *pb)
static int mov_write_stbl_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack
*track)
{
+ MOVMuxContext *mov = s->priv_data;
int64_t pos = avio_tell(pb);
avio_wb32(pb, 0); /* size */
ffio_wfourcc(pb, "stbl");
@@ -1277,6 +1326,20 @@ 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);
+
+ if (track->par->codec_id == AV_CODEC_ID_AAC && mov->use_editlist &&
+ track->start_dts != AV_NOPTS_VALUE &&
+ (track->start_dts < 0 || track->par->initial_padding > 0)) {
+ /* 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 this is omitted, Apple tools will apply an implicit
+ * rule to remove encoder delay samples, which results in
+ * removal of 2 * delay and A/V desync. */
+ mov_write_sgpd_tag(pb, -1);
+ mov_write_sbgp_tag(pb, track);
+ }
+
return update_size(pb, pos);
}
diff --git a/tests/ref/fate/movenc b/tests/ref/fate/movenc
index a0a1700..05a171d 100644
--- a/tests/ref/fate/movenc
+++ b/tests/ref/fate/movenc
@@ -4,10 +4,10 @@ write_data len 496, time 1000000, type sync atom moof
write_data len 110, time nopts, type trailer atom -
07cee26b35b140ae50268c3083e2d880 2449 non-empty-moov
write_data len 36, time nopts, type header atom ftyp
-write_data len 2135, time nopts, type header atom -
+write_data len 2189, time nopts, type header atom -
write_data len 616, time 966667, type sync atom moof
write_data len 110, time nopts, type trailer atom -
-c3c47c2c9566cb410e0832c37f4f8527 2897 non-empty-moov-elst
+6548a2ff72e337dfc1da35482ff6d244 2951 non-empty-moov-elst
write_data len 36, time nopts, type header atom ftyp
write_data len 2055, time nopts, type header atom -
write_data len 616, time 1000000, type sync atom moof
@@ -44,11 +44,11 @@ write_data len 500, time 0, type sync atom moof
write_data len 496, time 1000000, type sync atom moof
write_data len 148, time nopts, type trailer atom -
89ea214e1d1079556164664eea9a7884 2327 delay-moov
-write_data len 1255, time nopts, type header atom ftyp
+write_data len 1309, time nopts, type header atom ftyp
write_data len 620, time -33333, type sync atom moof
write_data len 616, time 966667, type sync atom moof
write_data len 148, time nopts, type trailer atom -
-8fd78a5a91d73a735da53ac02f844177 2639 delay-moov-elst
+795a3f0c76a0e9bc4ac1e3405e1d42cd 2693 delay-moov-elst
write_data len 1183, time nopts, type header atom ftyp
write_data len 596, time 0, type sync atom moof
write_data len 67, time nopts, type trailer atom -
@@ -97,39 +97,39 @@ fdc08ccfb9ca1a7a63a8e82a99e28e83 1207
delay-moov-elst-init-discont
write_data len 704, time 966667, type sync atom sidx
41afdc44b0e376fae49a730afe0c53c2 704 delay-moov-elst-second-frag-discont
write_data len 110, time nopts, type trailer atom -
-write_data len 1243, time nopts, type header atom ftyp
-57c113cd2baf7b231355eee6980fb6b5 1243 delay-moov-elst-signal-init
+write_data len 1297, time nopts, type header atom ftyp
+9b76e16f7f7835b18b461ac2797f10eb 1297 delay-moov-elst-signal-init
write_data len 708, time -33333, type sync atom sidx
write_data len 704, time 966667, type sync atom sidx
13b8487a4f004ec9f1db543aee1e5e18 704 delay-moov-elst-signal-second-frag
write_data len 148, time nopts, type trailer atom -
-write_data len 1243, time nopts, type header atom ftyp
-57c113cd2baf7b231355eee6980fb6b5 1243 delay-moov-elst-signal-init-discont
+write_data len 1297, time nopts, type header atom ftyp
+9b76e16f7f7835b18b461ac2797f10eb 1297 delay-moov-elst-signal-init-discont
write_data len 704, time 966667, type sync atom sidx
13b8487a4f004ec9f1db543aee1e5e18 704 delay-moov-elst-signal-second-frag-discont
write_data len 110, time nopts, type trailer atom -
-write_data len 1243, time nopts, type header atom ftyp
+write_data len 1297, time nopts, type header atom ftyp
write_data len 1552, time -333333, type sync atom sidx
write_data len 704, time 5166667, type sync atom sidx
write_data len 148, time nopts, type trailer atom -
-5e676152714f9478b5f74ce67cd7ed60 3647 vfr
-write_data len 1243, time nopts, type header atom ftyp
+2d775976518508c7ea633cbe64cd75d2 3701 vfr
+write_data len 1297, time nopts, type header atom ftyp
write_data len 1552, time -333333, type sync atom sidx
write_data len 704, time 5166667, type sync atom sidx
write_data len 148, time nopts, type trailer atom -
-5e676152714f9478b5f74ce67cd7ed60 3647 vfr-noduration
-write_data len 1255, time nopts, type header atom ftyp
+2d775976518508c7ea633cbe64cd75d2 3701 vfr-noduration
+write_data len 1309, time nopts, type header atom ftyp
write_data len 1500, time -333333, type sync atom moof
write_data len 620, time nopts, type unknown atom -
write_data len 1500, time 9666667, type sync atom moof
write_data len 664, time nopts, type unknown atom -
write_data len 148, time nopts, type trailer atom -
-03766894d839e5fcb1edb88498d812f7 5687 large_frag
-write_data len 1255, time nopts, type header atom ftyp
+a4b05f1a8273dc7bb4f46744717f9ca9 5741 large_frag
+write_data len 1309, time nopts, type header atom ftyp
write_data len 508, time -33333, type sync atom moof
write_data len 372, time 800000, type boundary atom moof
write_data len 328, time 1266667, type boundary atom moof
write_data len 476, time 1566667, type sync atom moof
write_data len 340, time 2233333, type boundary atom moof
write_data len 262, time nopts, type trailer atom -
-a4280bdc23af2c4334ec2da3fa946d3a 3541 vfr-noduration-interleave
+e605de9fc384d64aacee5ea6844539e6 3595 vfr-noduration-interleave
--
2.9.3
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel