From 3cf9b912d8217a7339faa47470e07c1820f25ed2 Mon Sep 17 00:00:00 2001 From: KongQun Yang Date: Tue, 21 Aug 2018 15:52:09 -0700 Subject: [PATCH] Add support for seek preroll in AAC and other audio codecs Closes #452. Change-Id: I0f648c4fa6c861540b050a5b4e9878987c8383e5 --- .../bear-320x240-vp9-opus-audio.mp4 | Bin 28355 -> 28327 bytes ...ecrypted-bear-320x240-vp9-opus-audio-0.mp4 | Bin 27350 -> 27322 bytes .../opus-vp9-mp4-with-encryption/output.mpd | 4 +- packager/media/formats/mp4/mp4_muxer.cc | 36 +++++++----------- 4 files changed, 16 insertions(+), 24 deletions(-) diff --git a/packager/app/test/testdata/opus-vp9-mp4-with-encryption/bear-320x240-vp9-opus-audio.mp4 b/packager/app/test/testdata/opus-vp9-mp4-with-encryption/bear-320x240-vp9-opus-audio.mp4 index 646ae1c3299b2ab0c1a87df514c1d10a33c78587..db1cc3a4aee57baaca48c20c7022d825a78f68ab 100644 GIT binary patch delta 60 zcmV-C0K@;o-2tcF0gxjLlWlKrb^rhXY;AUvkO3BvMBM=?lOh3Q0mYMs0aO8SliL9+ S0W`A*0xkgp@c^?^18{4Qh!gDq delta 88 zcmZ2}m+|mj#tF*Y>vQw-%NQ6Ka&pTiPhb?A=yI3Qb+Qs;GULO^ZHys|J(F)UYBL6G lW@pl4lzYtyR47xNlwJU&8H)0Aa)1;ghz$gco6VUEvH|}b7ykeN diff --git a/packager/app/test/testdata/opus-vp9-mp4-with-encryption/decrypted-bear-320x240-vp9-opus-audio-0.mp4 b/packager/app/test/testdata/opus-vp9-mp4-with-encryption/decrypted-bear-320x240-vp9-opus-audio-0.mp4 index 54a091c00c5537994dd50d283ab1c4541a23dab3..4332c1ac88197c6f45afb6e78b832d1d7ec558d5 100644 GIT binary patch delta 60 zcmV-C0K@;*)d9NI0gxjL*lllbb^rhXY;AUvkO3BvMBM?RlOh3Q0X~z40aF41>66<5 SD*>&O2Lh)8@c^^T0t#rfh!v9n delta 88 zcmdmWmGRnD#tF*YUvl&F%NQ6Ka&pTiPhb?A=yI2F-()4mWX7n;ZH&Q8jI5JyGio!Q moXpO&T<)n5P@zn5QhEW9W+=+f$pKP~AT|&%Zr;Gel>q=D2N bear-320x240-vp9-opus-audio.mp4 - - + + diff --git a/packager/media/formats/mp4/mp4_muxer.cc b/packager/media/formats/mp4/mp4_muxer.cc index 319727c75d..3c4309e6c3 100644 --- a/packager/media/formats/mp4/mp4_muxer.cc +++ b/packager/media/formats/mp4/mp4_muxer.cc @@ -135,6 +135,16 @@ void GenerateSinf(FourCC old_type, track_encryption.default_kid = encryption_config.key_id; } +// The roll distance is expressed in sample units and always takes negative +// values. +int16_t GetRollDistance(uint64_t seek_preroll_ns, uint32_t sampling_frequency) { + const double kNanosecondsPerSecond = 1000000000; + const double preroll_in_samples = + seek_preroll_ns / kNanosecondsPerSecond * sampling_frequency; + // Round to closest integer. + return -static_cast(preroll_in_samples + 0.5); +} + } // namespace MP4Muxer::MP4Muxer(const MuxerOptions& options) : Muxer(options) {} @@ -497,34 +507,16 @@ bool MP4Muxer::GenerateAudioTrak(const AudioStreamInfo* audio_info, entry.format = FOURCC_enca; } - // Opus requires at least one sample group description box and at least one - // sample to group box with grouping type 'roll' within sample table box. - if (audio_info->codec() == kCodecOpus) { + if (audio_info->seek_preroll_ns() > 0) { sample_table.sample_group_descriptions.resize(1); SampleGroupDescription& sample_group_description = sample_table.sample_group_descriptions.back(); sample_group_description.grouping_type = FOURCC_roll; sample_group_description.audio_roll_recovery_entries.resize(1); - // The roll distance is expressed in sample units and always takes negative - // values. - const uint64_t kNanosecondsPerSecond = 1000000000ull; sample_group_description.audio_roll_recovery_entries[0].roll_distance = - (0 - (audio_info->seek_preroll_ns() * audio.samplerate + - kNanosecondsPerSecond / 2)) / - kNanosecondsPerSecond; - - sample_table.sample_to_groups.resize(1); - SampleToGroup& sample_to_group = sample_table.sample_to_groups.back(); - sample_to_group.grouping_type = FOURCC_roll; - - sample_to_group.entries.resize(1); - SampleToGroupEntry& sample_to_group_entry = sample_to_group.entries.back(); - // All samples are in track fragments. - sample_to_group_entry.sample_count = 0; - sample_to_group_entry.group_description_index = - SampleToGroupEntry::kTrackGroupDescriptionIndexBase + 1; - } else if (audio_info->seek_preroll_ns() != 0) { - LOG(WARNING) << "Unexpected seek preroll for codec " << audio_info->codec(); + GetRollDistance(audio_info->seek_preroll_ns(), audio.samplerate); + // sample to group box is not allowed in the init segment per CMAF + // specification. It is put in the fragment instead. } return true; }