7 #include "packager/media/formats/packed_audio/packed_audio_segmenter.h" 11 #include "packager/media/base/id3_tag.h" 12 #include "packager/media/base/media_sample.h" 13 #include "packager/media/codecs/aac_audio_specific_config.h" 14 #include "packager/media/codecs/hls_audio_util.h" 15 #include "packager/status_macros.h" 20 std::string TimestampToString(uint64_t timestamp) {
22 buffer.AppendInt(timestamp);
23 return std::string(buffer.Buffer(), buffer.Buffer() + buffer.Size());
27 PackedAudioSegmenter::PackedAudioSegmenter() =
default;
28 PackedAudioSegmenter::~PackedAudioSegmenter() =
default;
31 const StreamType stream_type = stream_info.stream_type();
32 if (stream_type != StreamType::kStreamAudio) {
33 LOG(ERROR) <<
"PackedAudioSegmenter cannot handle stream type " 35 return Status(error::MUXER_FAILURE,
"Unsupported stream type.");
38 codec_ = stream_info.codec();
39 audio_codec_config_ = stream_info.codec_config();
40 timescale_scale_ = kPackedAudioTimescale / stream_info.time_scale();
42 if (codec_ == kCodecAAC) {
43 adts_converter_ = CreateAdtsConverter();
44 if (!adts_converter_->Parse(audio_codec_config_)) {
45 return Status(error::MUXER_FAILURE,
"Invalid audio codec configuration.");
53 if (sample.is_encrypted() && audio_setup_information_.empty())
54 RETURN_IF_ERROR(EncryptionAudioSetup(sample));
56 if (start_of_new_segment_) {
57 StartNewSegment(sample);
58 start_of_new_segment_ =
false;
61 if (adts_converter_) {
62 std::vector<uint8_t> audio_frame(sample.data(),
63 sample.data() + sample.data_size());
64 if (!adts_converter_->ConvertToADTS(&audio_frame))
65 return Status(error::MUXER_FAILURE,
"Failed to convert to ADTS.");
66 segment_buffer_.AppendArray(audio_frame.data(), audio_frame.size());
68 segment_buffer_.AppendArray(sample.data(), sample.data_size());
74 start_of_new_segment_ =
true;
79 return timescale_scale_;
82 std::unique_ptr<AACAudioSpecificConfig>
83 PackedAudioSegmenter::CreateAdtsConverter() {
87 std::unique_ptr<Id3Tag> PackedAudioSegmenter::CreateId3Tag() {
88 return std::unique_ptr<Id3Tag>(
new Id3Tag);
94 const uint8_t* audio_setup_data = audio_codec_config_.data();
95 size_t audio_setup_data_size = audio_codec_config_.size();
96 if (codec_ == kCodecAC3) {
101 const size_t kSetupDataSize = 10u;
102 if (sample.data_size() < kSetupDataSize) {
103 LOG(ERROR) <<
"Sample is too small for AC3: " << sample.data_size();
104 return Status(error::MUXER_FAILURE,
"Sample is too small for AC3.");
106 audio_setup_data = sample.data();
107 audio_setup_data_size = kSetupDataSize;
111 if (!WriteAudioSetupInformation(codec_, audio_setup_data,
112 audio_setup_data_size, &buffer)) {
113 return Status(error::MUXER_FAILURE,
114 "Failed to write audio setup information.");
116 audio_setup_information_.assign(buffer.
Buffer(),
117 buffer.
Buffer() + buffer.Size());
121 void PackedAudioSegmenter::StartNewSegment(
const MediaSample& sample) {
122 segment_buffer_.Clear();
125 std::unique_ptr<Id3Tag> id3_tag = CreateId3Tag();
126 id3_tag->AddPrivateFrame(kTimestampOwnerIdentifier,
127 TimestampToString(sample.pts() * timescale_scale_));
128 if (!audio_setup_information_.empty()) {
129 id3_tag->AddPrivateFrame(kAudioDescriptionOwnerIdentifier,
130 audio_setup_information_);
132 CHECK(id3_tag->WriteToBuffer(&segment_buffer_));
All the methods that are virtual are virtual for mocking.