OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "media/formats/mp2t/es_parser_adts.h" | 5 #include "media/formats/mp2t/es_parser_adts.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/strings/string_number_conversions.h" | 11 #include "base/strings/string_number_conversions.h" |
12 #include "media/base/audio_timestamp_helper.h" | 12 #include "media/base/audio_timestamp_helper.h" |
13 #include "media/base/bit_reader.h" | 13 #include "media/base/bit_reader.h" |
14 #include "media/base/channel_layout.h" | 14 #include "media/base/channel_layout.h" |
15 #include "media/base/decrypt_config.h" | |
15 #include "media/base/encryption_scheme.h" | 16 #include "media/base/encryption_scheme.h" |
16 #include "media/base/stream_parser_buffer.h" | 17 #include "media/base/stream_parser_buffer.h" |
17 #include "media/base/timestamp_constants.h" | 18 #include "media/base/timestamp_constants.h" |
18 #include "media/formats/common/offset_byte_queue.h" | 19 #include "media/formats/common/offset_byte_queue.h" |
19 #include "media/formats/mp2t/mp2t_common.h" | 20 #include "media/formats/mp2t/mp2t_common.h" |
20 #include "media/formats/mpeg/adts_constants.h" | 21 #include "media/formats/mpeg/adts_constants.h" |
21 | 22 |
22 namespace media { | 23 namespace media { |
23 | 24 |
24 static int ExtractAdtsFrameSize(const uint8* adts_header) { | 25 static int ExtractAdtsFrameSize(const uint8* adts_header) { |
25 return ((static_cast<int>(adts_header[5]) >> 5) | | 26 return ((static_cast<int>(adts_header[5]) >> 5) | |
26 (static_cast<int>(adts_header[4]) << 3) | | 27 (static_cast<int>(adts_header[4]) << 3) | |
27 ((static_cast<int>(adts_header[3]) & 0x3) << 11)); | 28 ((static_cast<int>(adts_header[3]) & 0x3) << 11)); |
28 } | 29 } |
29 | 30 |
31 static int AdtsHeaderSize(const uint8* adts_header) { | |
32 // protection absent bit: set to 1 if there is no CRC and 0 if there is CRC | |
33 return (adts_header[1] & 0x1) ? kADTSHeaderSizeNoCrc : kADTSHeaderSizeWithCrc; | |
34 } | |
35 | |
30 static size_t ExtractAdtsFrequencyIndex(const uint8* adts_header) { | 36 static size_t ExtractAdtsFrequencyIndex(const uint8* adts_header) { |
31 return ((adts_header[2] >> 2) & 0xf); | 37 return ((adts_header[2] >> 2) & 0xf); |
32 } | 38 } |
33 | 39 |
34 static size_t ExtractAdtsChannelConfig(const uint8* adts_header) { | 40 static size_t ExtractAdtsChannelConfig(const uint8* adts_header) { |
35 return (((adts_header[3] >> 6) & 0x3) | | 41 return (((adts_header[3] >> 6) & 0x3) | |
36 ((adts_header[2] & 0x1) << 2)); | 42 ((adts_header[2] & 0x1) << 2)); |
37 } | 43 } |
38 | 44 |
39 // Return true if buf corresponds to an ADTS syncword. | 45 // Return true if buf corresponds to an ADTS syncword. |
40 // |buf| size must be at least 2. | 46 // |buf| size must be at least 2. |
41 static bool isAdtsSyncWord(const uint8* buf) { | 47 static bool isAdtsSyncWord(const uint8* buf) { |
42 // The first 12 bits must be 1. | 48 // The first 12 bits must be 1. |
43 // The layer field (2 bits) must be set to 0. | 49 // The layer field (2 bits) must be set to 0. |
44 return (buf[0] == 0xff) && ((buf[1] & 0xf6) == 0xf0); | 50 return (buf[0] == 0xff) && ((buf[1] & 0xf6) == 0xf0); |
45 } | 51 } |
46 | 52 |
47 namespace mp2t { | 53 namespace mp2t { |
48 | 54 |
49 struct EsParserAdts::AdtsFrame { | 55 struct EsParserAdts::AdtsFrame { |
50 // Pointer to the ES data. | 56 // Pointer to the ES data. |
51 const uint8* data; | 57 const uint8* data; |
52 | 58 |
53 // Frame size; | 59 // Frame size; |
54 int size; | 60 int size; |
61 int header_size; | |
55 | 62 |
56 // Frame offset in the ES queue. | 63 // Frame offset in the ES queue. |
57 int64 queue_offset; | 64 int64 queue_offset; |
58 }; | 65 }; |
59 | 66 |
60 bool EsParserAdts::LookForAdtsFrame(AdtsFrame* adts_frame) { | 67 bool EsParserAdts::LookForAdtsFrame(AdtsFrame* adts_frame) { |
61 int es_size; | 68 int es_size; |
62 const uint8* es; | 69 const uint8* es; |
63 es_queue_->Peek(&es, &es_size); | 70 es_queue_->Peek(&es, &es_size); |
64 | 71 |
65 int max_offset = es_size - kADTSHeaderMinSize; | 72 int max_offset = es_size - kADTSHeaderMinSize; |
66 if (max_offset <= 0) | 73 if (max_offset <= 0) |
67 return false; | 74 return false; |
68 | 75 |
69 for (int offset = 0; offset < max_offset; offset++) { | 76 for (int offset = 0; offset < max_offset; offset++) { |
70 const uint8* cur_buf = &es[offset]; | 77 const uint8* cur_buf = &es[offset]; |
71 if (!isAdtsSyncWord(cur_buf)) | 78 if (!isAdtsSyncWord(cur_buf)) |
72 continue; | 79 continue; |
73 | 80 |
74 int frame_size = ExtractAdtsFrameSize(cur_buf); | 81 int frame_size = ExtractAdtsFrameSize(cur_buf); |
75 if (frame_size < kADTSHeaderMinSize) { | 82 if (frame_size < kADTSHeaderMinSize) { |
76 // Too short to be an ADTS frame. | 83 // Too short to be an ADTS frame. |
77 continue; | 84 continue; |
78 } | 85 } |
86 int header_size = AdtsHeaderSize(cur_buf); | |
79 | 87 |
80 int remaining_size = es_size - offset; | 88 int remaining_size = es_size - offset; |
81 if (remaining_size < frame_size) { | 89 if (remaining_size < frame_size) { |
82 // Not a full frame: will resume when we have more data. | 90 // Not a full frame: will resume when we have more data. |
83 es_queue_->Pop(offset); | 91 es_queue_->Pop(offset); |
84 return false; | 92 return false; |
85 } | 93 } |
86 | 94 |
87 // Check whether there is another frame | 95 // Check whether there is another frame |
88 // |size| apart from the current one. | 96 // |size| apart from the current one. |
89 if (remaining_size >= frame_size + 2 && | 97 if (remaining_size >= frame_size + 2 && |
90 !isAdtsSyncWord(&cur_buf[frame_size])) { | 98 !isAdtsSyncWord(&cur_buf[frame_size])) { |
91 continue; | 99 continue; |
92 } | 100 } |
93 | 101 |
94 es_queue_->Pop(offset); | 102 es_queue_->Pop(offset); |
95 es_queue_->Peek(&adts_frame->data, &es_size); | 103 es_queue_->Peek(&adts_frame->data, &es_size); |
96 adts_frame->queue_offset = es_queue_->head(); | 104 adts_frame->queue_offset = es_queue_->head(); |
97 adts_frame->size = frame_size; | 105 adts_frame->size = frame_size; |
106 adts_frame->header_size = header_size; | |
98 DVLOG(LOG_LEVEL_ES) | 107 DVLOG(LOG_LEVEL_ES) |
99 << "ADTS syncword @ pos=" << adts_frame->queue_offset | 108 << "ADTS syncword @ pos=" << adts_frame->queue_offset |
100 << " frame_size=" << adts_frame->size; | 109 << " frame_size=" << adts_frame->size; |
101 DVLOG(LOG_LEVEL_ES) | 110 DVLOG(LOG_LEVEL_ES) |
102 << "ADTS header: " | 111 << "ADTS header: " |
103 << base::HexEncode(adts_frame->data, kADTSHeaderMinSize); | 112 << base::HexEncode(adts_frame->data, kADTSHeaderMinSize); |
104 return true; | 113 return true; |
105 } | 114 } |
106 | 115 |
107 es_queue_->Pop(max_offset); | 116 es_queue_->Pop(max_offset); |
108 return false; | 117 return false; |
109 } | 118 } |
110 | 119 |
111 void EsParserAdts::SkipAdtsFrame(const AdtsFrame& adts_frame) { | 120 void EsParserAdts::SkipAdtsFrame(const AdtsFrame& adts_frame) { |
112 DCHECK_EQ(adts_frame.queue_offset, es_queue_->head()); | 121 DCHECK_EQ(adts_frame.queue_offset, es_queue_->head()); |
113 es_queue_->Pop(adts_frame.size); | 122 es_queue_->Pop(adts_frame.size); |
114 } | 123 } |
115 | 124 |
116 EsParserAdts::EsParserAdts( | 125 EsParserAdts::EsParserAdts(const NewAudioConfigCB& new_audio_config_cb, |
117 const NewAudioConfigCB& new_audio_config_cb, | 126 const EmitBufferCB& emit_buffer_cb, |
118 const EmitBufferCB& emit_buffer_cb, | 127 bool sbr_in_mimetype) |
119 bool sbr_in_mimetype) | 128 : new_audio_config_cb_(new_audio_config_cb), |
120 : new_audio_config_cb_(new_audio_config_cb), | 129 emit_buffer_cb_(emit_buffer_cb), |
121 emit_buffer_cb_(emit_buffer_cb), | 130 #ifdef ENABLE_HLS_SAMPLE_AES |
122 sbr_in_mimetype_(sbr_in_mimetype) { | 131 get_decrypt_config_cb_(GetDecryptConfigCB()), |
yucliu1
2015/12/11 19:55:31
Maybe simply get_decrypt_config_cb_()?
dougsteed
2015/12/14 22:51:46
Done.
| |
132 use_hls_sample_aes_(false), | |
133 #endif | |
134 sbr_in_mimetype_(sbr_in_mimetype) { | |
123 } | 135 } |
124 | 136 |
137 #ifdef ENABLE_HLS_SAMPLE_AES | |
138 EsParserAdts::EsParserAdts(const NewAudioConfigCB& new_audio_config_cb, | |
139 const EmitBufferCB& emit_buffer_cb, | |
140 const GetDecryptConfigCB get_decrypt_config_cb, | |
yucliu1
2015/12/11 19:55:31
const GetDecryptConfigCB&
dougsteed
2015/12/14 22:51:46
Done.
| |
141 bool use_hls_sample_aes, | |
142 bool sbr_in_mimetype) | |
143 : new_audio_config_cb_(new_audio_config_cb), | |
144 emit_buffer_cb_(emit_buffer_cb), | |
145 get_decrypt_config_cb_(get_decrypt_config_cb), | |
146 use_hls_sample_aes_(use_hls_sample_aes), | |
147 sbr_in_mimetype_(sbr_in_mimetype) {} | |
148 #endif | |
149 | |
125 EsParserAdts::~EsParserAdts() { | 150 EsParserAdts::~EsParserAdts() { |
126 } | 151 } |
127 | 152 |
153 #ifdef ENABLE_HLS_SAMPLE_AES | |
154 void EsParserAdts::CalculateSubsamplesForAdtsFrame( | |
155 const AdtsFrame& adts_frame, | |
156 std::vector<SubsampleEntry>* subsamples) { | |
157 DCHECK(subsamples); | |
158 subsamples->clear(); | |
159 int data_size = adts_frame.size - adts_frame.header_size; | |
160 int residue = data_size % 16; | |
161 int clear_bytes = adts_frame.header_size; | |
162 int encrypted_bytes = 0; | |
163 if (data_size <= 16) { | |
164 clear_bytes += data_size; | |
165 residue = 0; | |
166 } else { | |
167 clear_bytes += 16; | |
168 encrypted_bytes = adts_frame.size - clear_bytes - residue; | |
169 } | |
170 SubsampleEntry subsample(clear_bytes, encrypted_bytes); | |
171 subsamples->push_back(subsample); | |
172 if (residue) { | |
173 subsample.clear_bytes = residue; | |
174 subsample.cypher_bytes = 0; | |
175 subsamples->push_back(subsample); | |
176 } | |
177 } | |
178 #endif | |
179 | |
128 bool EsParserAdts::ParseFromEsQueue() { | 180 bool EsParserAdts::ParseFromEsQueue() { |
129 // Look for every ADTS frame in the ES buffer. | 181 // Look for every ADTS frame in the ES buffer. |
130 AdtsFrame adts_frame; | 182 AdtsFrame adts_frame; |
131 while (LookForAdtsFrame(&adts_frame)) { | 183 while (LookForAdtsFrame(&adts_frame)) { |
132 // Update the audio configuration if needed. | 184 // Update the audio configuration if needed. |
133 DCHECK_GE(adts_frame.size, kADTSHeaderMinSize); | 185 DCHECK_GE(adts_frame.size, kADTSHeaderMinSize); |
134 if (!UpdateAudioConfiguration(adts_frame.data)) | 186 if (!UpdateAudioConfiguration(adts_frame.data)) |
135 return false; | 187 return false; |
136 | 188 |
137 // Get the PTS & the duration of this access unit. | 189 // Get the PTS & the duration of this access unit. |
(...skipping 19 matching lines...) Expand all Loading... | |
157 scoped_refptr<StreamParserBuffer> stream_parser_buffer = | 209 scoped_refptr<StreamParserBuffer> stream_parser_buffer = |
158 StreamParserBuffer::CopyFrom( | 210 StreamParserBuffer::CopyFrom( |
159 adts_frame.data, | 211 adts_frame.data, |
160 adts_frame.size, | 212 adts_frame.size, |
161 is_key_frame, | 213 is_key_frame, |
162 DemuxerStream::AUDIO, 0); | 214 DemuxerStream::AUDIO, 0); |
163 stream_parser_buffer->set_timestamp(current_pts); | 215 stream_parser_buffer->set_timestamp(current_pts); |
164 stream_parser_buffer->SetDecodeTimestamp( | 216 stream_parser_buffer->SetDecodeTimestamp( |
165 DecodeTimestamp::FromPresentationTime(current_pts)); | 217 DecodeTimestamp::FromPresentationTime(current_pts)); |
166 stream_parser_buffer->set_duration(frame_duration); | 218 stream_parser_buffer->set_duration(frame_duration); |
219 #ifdef ENABLE_HLS_SAMPLE_AES | |
220 if (use_hls_sample_aes_) { | |
221 const DecryptConfig& base_decrypt_config = get_decrypt_config_cb_.Run(); | |
222 std::vector<SubsampleEntry> subsamples; | |
223 CalculateSubsamplesForAdtsFrame(adts_frame, &subsamples); | |
224 scoped_ptr<DecryptConfig> decrypt_config(new DecryptConfig( | |
225 base_decrypt_config.key_id(), base_decrypt_config.iv(), subsamples)); | |
226 stream_parser_buffer->set_decrypt_config(decrypt_config.Pass()); | |
227 } | |
228 #endif | |
167 emit_buffer_cb_.Run(stream_parser_buffer); | 229 emit_buffer_cb_.Run(stream_parser_buffer); |
168 | 230 |
169 // Update the PTS of the next frame. | 231 // Update the PTS of the next frame. |
170 audio_timestamp_helper_->AddFrames(kSamplesPerAACFrame); | 232 audio_timestamp_helper_->AddFrames(kSamplesPerAACFrame); |
171 | 233 |
172 // Skip the current frame. | 234 // Skip the current frame. |
173 SkipAdtsFrame(adts_frame); | 235 SkipAdtsFrame(adts_frame); |
174 } | 236 } |
175 | 237 |
176 return true; | 238 return true; |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
220 ((adts_profile + 1) << 11) + | 282 ((adts_profile + 1) << 11) + |
221 // frequency_index is [0..13], per early out above. | 283 // frequency_index is [0..13], per early out above. |
222 (frequency_index << 7) + | 284 (frequency_index << 7) + |
223 // channel_configuration is [0..7], per early out above. | 285 // channel_configuration is [0..7], per early out above. |
224 (channel_configuration << 3)); | 286 (channel_configuration << 3)); |
225 std::vector<uint8_t> extra_data; | 287 std::vector<uint8_t> extra_data; |
226 extra_data.push_back(static_cast<uint8>(extra_data_int >> 8)); | 288 extra_data.push_back(static_cast<uint8>(extra_data_int >> 8)); |
227 extra_data.push_back(static_cast<uint8>(extra_data_int & 0xff)); | 289 extra_data.push_back(static_cast<uint8>(extra_data_int & 0xff)); |
228 | 290 |
229 EncryptionScheme scheme(false); | 291 EncryptionScheme scheme(false); |
230 | 292 #ifdef ENABLE_HLS_SAMPLE_AES |
293 if (use_hls_sample_aes_) { | |
294 scheme = EncryptionScheme(kCipherModeAesCbc); | |
295 } | |
296 #endif | |
231 AudioDecoderConfig audio_decoder_config( | 297 AudioDecoderConfig audio_decoder_config( |
232 kCodecAAC, kSampleFormatS16, | 298 kCodecAAC, kSampleFormatS16, |
233 kADTSChannelLayoutTable[channel_configuration], | 299 kADTSChannelLayoutTable[channel_configuration], |
234 extended_samples_per_second, extra_data, scheme); | 300 extended_samples_per_second, extra_data, scheme); |
235 | 301 |
236 if (!audio_decoder_config.Matches(last_audio_decoder_config_)) { | 302 if (!audio_decoder_config.Matches(last_audio_decoder_config_)) { |
237 DVLOG(1) << "Sampling frequency: " << samples_per_second; | 303 DVLOG(1) << "Sampling frequency: " << samples_per_second; |
238 DVLOG(1) << "Extended sampling frequency: " << extended_samples_per_second; | 304 DVLOG(1) << "Extended sampling frequency: " << extended_samples_per_second; |
239 DVLOG(1) << "Channel config: " << channel_configuration; | 305 DVLOG(1) << "Channel config: " << channel_configuration; |
240 DVLOG(1) << "Adts profile: " << adts_profile; | 306 DVLOG(1) << "Adts profile: " << adts_profile; |
(...skipping 11 matching lines...) Expand all Loading... | |
252 // Audio config notification. | 318 // Audio config notification. |
253 last_audio_decoder_config_ = audio_decoder_config; | 319 last_audio_decoder_config_ = audio_decoder_config; |
254 new_audio_config_cb_.Run(audio_decoder_config); | 320 new_audio_config_cb_.Run(audio_decoder_config); |
255 } | 321 } |
256 | 322 |
257 return true; | 323 return true; |
258 } | 324 } |
259 | 325 |
260 } // namespace mp2t | 326 } // namespace mp2t |
261 } // namespace media | 327 } // namespace media |
OLD | NEW |