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); }