Add support for seek preroll in AAC and other audio codecs
Closes #452. Change-Id: I0f648c4fa6c861540b050a5b4e9878987c8383e5
This commit is contained in:
parent
9e9833ea63
commit
3cf9b912d8
Binary file not shown.
Binary file not shown.
|
@ -10,8 +10,8 @@
|
|||
<Representation id="0" bandwidth="86874" codecs="opus" mimeType="audio/mp4" audioSamplingRate="48000">
|
||||
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
|
||||
<BaseURL>bear-320x240-vp9-opus-audio.mp4</BaseURL>
|
||||
<SegmentBase indexRange="975-1042" timescale="1000000" presentationTimeOffset="37000">
|
||||
<Initialization range="0-974"/>
|
||||
<SegmentBase indexRange="947-1014" timescale="1000000" presentationTimeOffset="37000">
|
||||
<Initialization range="0-946"/>
|
||||
</SegmentBase>
|
||||
</Representation>
|
||||
</AdaptationSet>
|
||||
|
|
|
@ -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<int16_t>(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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue