1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "media/formats/mp2t/es_parser_adts.h"
6 
7 #include <stddef.h>
8 
9 #include <vector>
10 
11 #include "base/logging.h"
12 #include "base/optional.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "media/base/audio_timestamp_helper.h"
15 #include "media/base/bit_reader.h"
16 #include "media/base/channel_layout.h"
17 #include "media/base/encryption_pattern.h"
18 #include "media/base/media_util.h"
19 #include "media/base/stream_parser_buffer.h"
20 #include "media/base/timestamp_constants.h"
21 #include "media/formats/common/offset_byte_queue.h"
22 #include "media/formats/mp2t/mp2t_common.h"
23 #include "media/formats/mpeg/adts_constants.h"
24 
25 namespace media {
26 
ExtractAdtsFrameSize(const uint8_t * adts_header)27 static int ExtractAdtsFrameSize(const uint8_t* adts_header) {
28   return ((static_cast<int>(adts_header[5]) >> 5) |
29           (static_cast<int>(adts_header[4]) << 3) |
30           ((static_cast<int>(adts_header[3]) & 0x3) << 11));
31 }
32 
AdtsHeaderSize(const uint8_t * adts_header)33 static int AdtsHeaderSize(const uint8_t* adts_header) {
34   // protection absent bit: set to 1 if there is no CRC and 0 if there is CRC
35   return (adts_header[1] & 0x1) ? kADTSHeaderSizeNoCrc : kADTSHeaderSizeWithCrc;
36 }
37 
38 // Return true if buf corresponds to an ADTS syncword.
39 // |buf| size must be at least 2.
isAdtsSyncWord(const uint8_t * buf)40 static bool isAdtsSyncWord(const uint8_t* buf) {
41   // The first 12 bits must be 1.
42   // The layer field (2 bits) must be set to 0.
43   return (buf[0] == 0xff) && ((buf[1] & 0xf6) == 0xf0);
44 }
45 
46 namespace mp2t {
47 
48 struct EsParserAdts::AdtsFrame {
49   // Pointer to the ES data.
50   const uint8_t* data;
51 
52   // Frame size;
53   int size;
54   int header_size;
55 
56   // Frame offset in the ES queue.
57   int64_t queue_offset;
58 };
59 
LookForAdtsFrame(AdtsFrame * adts_frame)60 bool EsParserAdts::LookForAdtsFrame(AdtsFrame* adts_frame) {
61   int es_size;
62   const uint8_t* es;
63   es_queue_->Peek(&es, &es_size);
64 
65   int _max_offset = es_size - kADTSHeaderMinSize;
66   if (_max_offset <= 0)
67     return false;
68 
69   for (int offset = 0; offset < _max_offset; offset++) {
70     const uint8_t* cur_buf = &es[offset];
71     if (!isAdtsSyncWord(cur_buf))
72       continue;
73 
74     int frame_size = ExtractAdtsFrameSize(cur_buf);
75     if (frame_size < kADTSHeaderMinSize) {
76       // Too short to be an ADTS frame.
77       continue;
78     }
79     int header_size = AdtsHeaderSize(cur_buf);
80 
81     int remaining_size = es_size - offset;
82     if (remaining_size < frame_size) {
83       // Not a full frame: will resume when we have more data.
84       es_queue_->Pop(offset);
85       return false;
86     }
87 
88     // Check whether there is another frame
89     // |size| apart from the current one.
90     if (remaining_size >= frame_size + 2 &&
91         !isAdtsSyncWord(&cur_buf[frame_size])) {
92       continue;
93     }
94 
95     es_queue_->Pop(offset);
96     es_queue_->Peek(&adts_frame->data, &es_size);
97     adts_frame->queue_offset = es_queue_->head();
98     adts_frame->size = frame_size;
99     adts_frame->header_size = header_size;
100     DVLOG(LOG_LEVEL_ES)
101         << "ADTS syncword @ pos=" << adts_frame->queue_offset
102         << " frame_size=" << adts_frame->size;
103     DVLOG(LOG_LEVEL_ES)
104         << "ADTS header: "
105         << base::HexEncode(adts_frame->data, kADTSHeaderMinSize);
106     return true;
107   }
108 
109   es_queue_->Pop(_max_offset);
110   return false;
111 }
112 
SkipAdtsFrame(const AdtsFrame & adts_frame)113 void EsParserAdts::SkipAdtsFrame(const AdtsFrame& adts_frame) {
114   DCHECK_EQ(adts_frame.queue_offset, es_queue_->head());
115   es_queue_->Pop(adts_frame.size);
116 }
117 
EsParserAdts(NewAudioConfigCB new_audio_config_cb,EmitBufferCB emit_buffer_cb,bool sbr_in_mimetype)118 EsParserAdts::EsParserAdts(NewAudioConfigCB new_audio_config_cb,
119                            EmitBufferCB emit_buffer_cb,
120                            bool sbr_in_mimetype)
121     : new_audio_config_cb_(std::move(new_audio_config_cb)),
122       emit_buffer_cb_(std::move(emit_buffer_cb)),
123 #if BUILDFLAG(ENABLE_HLS_SAMPLE_AES)
124       get_decrypt_config_cb_(),
125       init_encryption_scheme_(EncryptionScheme::kUnencrypted),
126 #endif
127       sbr_in_mimetype_(sbr_in_mimetype) {
128 }
129 
130 #if BUILDFLAG(ENABLE_HLS_SAMPLE_AES)
EsParserAdts(NewAudioConfigCB new_audio_config_cb,EmitBufferCB emit_buffer_cb,GetDecryptConfigCB get_decrypt_config_cb,EncryptionScheme init_encryption_scheme,bool sbr_in_mimetype)131 EsParserAdts::EsParserAdts(NewAudioConfigCB new_audio_config_cb,
132                            EmitBufferCB emit_buffer_cb,
133                            GetDecryptConfigCB get_decrypt_config_cb,
134                            EncryptionScheme init_encryption_scheme,
135                            bool sbr_in_mimetype)
136     : new_audio_config_cb_(std::move(new_audio_config_cb)),
137       emit_buffer_cb_(std::move(emit_buffer_cb)),
138       get_decrypt_config_cb_(std::move(get_decrypt_config_cb)),
139       init_encryption_scheme_(init_encryption_scheme),
140       sbr_in_mimetype_(sbr_in_mimetype) {}
141 #endif
142 
~EsParserAdts()143 EsParserAdts::~EsParserAdts() {
144 }
145 
146 #if BUILDFLAG(ENABLE_HLS_SAMPLE_AES)
CalculateSubsamplesForAdtsFrame(const AdtsFrame & adts_frame,std::vector<SubsampleEntry> * subsamples)147 void EsParserAdts::CalculateSubsamplesForAdtsFrame(
148     const AdtsFrame& adts_frame,
149     std::vector<SubsampleEntry>* subsamples) {
150   DCHECK(subsamples);
151   subsamples->clear();
152   int data_size = adts_frame.size - adts_frame.header_size;
153   int residue = data_size % 16;
154   int clear_bytes = adts_frame.header_size;
155   int encrypted_bytes = 0;
156   if (data_size <= 16) {
157     clear_bytes += data_size;
158     residue = 0;
159   } else {
160     clear_bytes += 16;
161     encrypted_bytes = adts_frame.size - clear_bytes - residue;
162   }
163   SubsampleEntry subsample(clear_bytes, encrypted_bytes);
164   subsamples->push_back(subsample);
165   if (residue) {
166     subsample.clear_bytes = residue;
167     subsample.cypher_bytes = 0;
168     subsamples->push_back(subsample);
169   }
170 }
171 #endif
172 
ParseFromEsQueue()173 bool EsParserAdts::ParseFromEsQueue() {
174   // Look for every ADTS frame in the ES buffer.
175   AdtsFrame adts_frame;
176   while (LookForAdtsFrame(&adts_frame)) {
177     // Update the audio configuration if needed.
178     DCHECK_GE(adts_frame.size, kADTSHeaderMinSize);
179     if (!UpdateAudioConfiguration(adts_frame.data, adts_frame.size))
180       return false;
181 
182     // Get the PTS & the duration of this access unit.
183     TimingDesc current_timing_desc =
184         GetTimingDescriptor(adts_frame.queue_offset);
185     if (current_timing_desc.pts != kNoTimestamp)
186       audio_timestamp_helper_->SetBaseTimestamp(current_timing_desc.pts);
187 
188     if (audio_timestamp_helper_->base_timestamp() == kNoTimestamp) {
189       DVLOG(1) << "Skipping audio frame with unknown timestamp";
190       SkipAdtsFrame(adts_frame);
191       continue;
192     }
193     base::TimeDelta current_pts = audio_timestamp_helper_->GetTimestamp();
194     base::TimeDelta frame_duration =
195         audio_timestamp_helper_->GetFrameDuration(kSamplesPerAACFrame);
196 
197     // Emit an audio frame.
198     bool is_key_frame = true;
199 
200     // TODO(wolenetz/acolwell): Validate and use a common cross-parser TrackId
201     // type and allow multiple audio tracks. See https://crbug.com/341581.
202     scoped_refptr<StreamParserBuffer> stream_parser_buffer =
203         StreamParserBuffer::CopyFrom(adts_frame.data, adts_frame.size,
204                                      is_key_frame, DemuxerStream::AUDIO,
205                                      kMp2tAudioTrackId);
206     stream_parser_buffer->set_timestamp(current_pts);
207     stream_parser_buffer->SetDecodeTimestamp(
208         DecodeTimestamp::FromPresentationTime(current_pts));
209     stream_parser_buffer->set_duration(frame_duration);
210 #if BUILDFLAG(ENABLE_HLS_SAMPLE_AES)
211     if (get_decrypt_config_cb_) {
212       const DecryptConfig* base_decrypt_config = get_decrypt_config_cb_.Run();
213       if (base_decrypt_config) {
214         std::vector<SubsampleEntry> subsamples;
215         CalculateSubsamplesForAdtsFrame(adts_frame, &subsamples);
216         stream_parser_buffer->set_decrypt_config(
217             std::make_unique<DecryptConfig>(
218                 base_decrypt_config->encryption_scheme(),
219                 base_decrypt_config->key_id(), base_decrypt_config->iv(),
220                 subsamples, EncryptionPattern()));
221       }
222     }
223 #endif
224     emit_buffer_cb_.Run(stream_parser_buffer);
225 
226     // Update the PTS of the next frame.
227     audio_timestamp_helper_->AddFrames(kSamplesPerAACFrame);
228 
229     // Skip the current frame.
230     SkipAdtsFrame(adts_frame);
231   }
232 
233   return true;
234 }
235 
Flush()236 void EsParserAdts::Flush() {
237 }
238 
ResetInternal()239 void EsParserAdts::ResetInternal() {
240   last_audio_decoder_config_ = AudioDecoderConfig();
241 }
242 
UpdateAudioConfiguration(const uint8_t * adts_header,int size)243 bool EsParserAdts::UpdateAudioConfiguration(const uint8_t* adts_header,
244                                             int size) {
245   int orig_sample_rate;
246   ChannelLayout channel_layout;
247   std::vector<uint8_t> extra_data;
248   if (adts_parser_.ParseFrameHeader(adts_header, size, nullptr,
249                                     &orig_sample_rate, &channel_layout, nullptr,
250                                     nullptr, &extra_data) <= 0) {
251     return false;
252   }
253 
254   // The following code is written according to ISO 14496 Part 3 Table 1.11 and
255   // Table 1.22. (Table 1.11 refers to the capping to 48000, Table 1.22 refers
256   // to SBR doubling the AAC sample rate.)
257   // TODO(damienv) : Extend sample rate cap to 96kHz for Level 5 content.
258   const int extended_samples_per_second =
259       sbr_in_mimetype_ ? std::min(2 * orig_sample_rate, 48000)
260                        : orig_sample_rate;
261   EncryptionScheme scheme = EncryptionScheme::kUnencrypted;
262 #if BUILDFLAG(ENABLE_HLS_SAMPLE_AES)
263   scheme = init_encryption_scheme_;
264 #endif
265   AudioDecoderConfig audio_decoder_config(
266       kCodecAAC, kSampleFormatS16, channel_layout, extended_samples_per_second,
267       extra_data, scheme);
268 
269   if (!audio_decoder_config.IsValidConfig()) {
270     DVLOG(1) << "Invalid config: "
271              << audio_decoder_config.AsHumanReadableString();
272     return false;
273   }
274 
275   if (!audio_decoder_config.Matches(last_audio_decoder_config_)) {
276     DVLOG(1) << "Sampling frequency: "
277              << audio_decoder_config.samples_per_second()
278              << " SBR=" << sbr_in_mimetype_;
279     DVLOG(1) << "Channel layout: "
280              << ChannelLayoutToString(audio_decoder_config.channel_layout());
281 
282     // For AAC audio with SBR (Spectral Band Replication) the sampling rate is
283     // doubled above, but AudioTimestampHelper should still use the original
284     // sample rate to compute audio timestamps and durations correctly.
285 
286     // Reset the timestamp helper to use a new time scale.
287     if (audio_timestamp_helper_ &&
288         audio_timestamp_helper_->base_timestamp() != kNoTimestamp) {
289       base::TimeDelta base_timestamp = audio_timestamp_helper_->GetTimestamp();
290       audio_timestamp_helper_.reset(new AudioTimestampHelper(orig_sample_rate));
291       audio_timestamp_helper_->SetBaseTimestamp(base_timestamp);
292     } else {
293       audio_timestamp_helper_.reset(new AudioTimestampHelper(orig_sample_rate));
294     }
295     // Audio config notification.
296     last_audio_decoder_config_ = audio_decoder_config;
297     new_audio_config_cb_.Run(audio_decoder_config);
298   }
299 
300   return true;
301 }
302 
303 }  // namespace mp2t
304 }  // namespace media
305