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">
|
<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"/>
|
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
|
||||||
<BaseURL>bear-320x240-vp9-opus-audio.mp4</BaseURL>
|
<BaseURL>bear-320x240-vp9-opus-audio.mp4</BaseURL>
|
||||||
<SegmentBase indexRange="975-1042" timescale="1000000" presentationTimeOffset="37000">
|
<SegmentBase indexRange="947-1014" timescale="1000000" presentationTimeOffset="37000">
|
||||||
<Initialization range="0-974"/>
|
<Initialization range="0-946"/>
|
||||||
</SegmentBase>
|
</SegmentBase>
|
||||||
</Representation>
|
</Representation>
|
||||||
</AdaptationSet>
|
</AdaptationSet>
|
||||||
|
|
|
@ -135,6 +135,16 @@ void GenerateSinf(FourCC old_type,
|
||||||
track_encryption.default_kid = encryption_config.key_id;
|
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
|
} // namespace
|
||||||
|
|
||||||
MP4Muxer::MP4Muxer(const MuxerOptions& options) : Muxer(options) {}
|
MP4Muxer::MP4Muxer(const MuxerOptions& options) : Muxer(options) {}
|
||||||
|
@ -497,34 +507,16 @@ bool MP4Muxer::GenerateAudioTrak(const AudioStreamInfo* audio_info,
|
||||||
entry.format = FOURCC_enca;
|
entry.format = FOURCC_enca;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Opus requires at least one sample group description box and at least one
|
if (audio_info->seek_preroll_ns() > 0) {
|
||||||
// sample to group box with grouping type 'roll' within sample table box.
|
|
||||||
if (audio_info->codec() == kCodecOpus) {
|
|
||||||
sample_table.sample_group_descriptions.resize(1);
|
sample_table.sample_group_descriptions.resize(1);
|
||||||
SampleGroupDescription& sample_group_description =
|
SampleGroupDescription& sample_group_description =
|
||||||
sample_table.sample_group_descriptions.back();
|
sample_table.sample_group_descriptions.back();
|
||||||
sample_group_description.grouping_type = FOURCC_roll;
|
sample_group_description.grouping_type = FOURCC_roll;
|
||||||
sample_group_description.audio_roll_recovery_entries.resize(1);
|
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 =
|
sample_group_description.audio_roll_recovery_entries[0].roll_distance =
|
||||||
(0 - (audio_info->seek_preroll_ns() * audio.samplerate +
|
GetRollDistance(audio_info->seek_preroll_ns(), audio.samplerate);
|
||||||
kNanosecondsPerSecond / 2)) /
|
// sample to group box is not allowed in the init segment per CMAF
|
||||||
kNanosecondsPerSecond;
|
// specification. It is put in the fragment instead.
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue