Chromium Code Reviews| Index: media/formats/mp2t/es_parser_adts.cc |
| diff --git a/media/formats/mp2t/es_parser_adts.cc b/media/formats/mp2t/es_parser_adts.cc |
| index da04cedb61e7d87d591c88c0ac67ed8da45a14a9..a037207e2fd049fc62cd19c450eccb648c34b422 100644 |
| --- a/media/formats/mp2t/es_parser_adts.cc |
| +++ b/media/formats/mp2t/es_parser_adts.cc |
| @@ -13,6 +13,7 @@ |
| #include "media/base/audio_timestamp_helper.h" |
| #include "media/base/bit_reader.h" |
| #include "media/base/channel_layout.h" |
| +#include "media/base/media_util.h" |
| #include "media/base/stream_parser_buffer.h" |
| #include "media/base/timestamp_constants.h" |
| #include "media/formats/common/offset_byte_queue.h" |
| @@ -28,6 +29,11 @@ static int ExtractAdtsFrameSize(const uint8_t* adts_header) { |
| ((static_cast<int>(adts_header[3]) & 0x3) << 11)); |
| } |
| +static int AdtsHeaderSize(const uint8_t* adts_header) { |
| + // protection absent bit: set to 1 if there is no CRC and 0 if there is CRC |
| + return (adts_header[1] & 0x1) ? kADTSHeaderSizeNoCrc : kADTSHeaderSizeWithCrc; |
| +} |
| + |
| // Return true if buf corresponds to an ADTS syncword. |
| // |buf| size must be at least 2. |
| static bool isAdtsSyncWord(const uint8_t* buf) { |
| @@ -44,6 +50,7 @@ struct EsParserAdts::AdtsFrame { |
| // Frame size; |
| int size; |
| + int header_size; |
| // Frame offset in the ES queue. |
| int64_t queue_offset; |
| @@ -68,6 +75,7 @@ bool EsParserAdts::LookForAdtsFrame(AdtsFrame* adts_frame) { |
| // Too short to be an ADTS frame. |
| continue; |
| } |
| + int header_size = AdtsHeaderSize(cur_buf); |
| int remaining_size = es_size - offset; |
| if (remaining_size < frame_size) { |
| @@ -87,6 +95,7 @@ bool EsParserAdts::LookForAdtsFrame(AdtsFrame* adts_frame) { |
| es_queue_->Peek(&adts_frame->data, &es_size); |
| adts_frame->queue_offset = es_queue_->head(); |
| adts_frame->size = frame_size; |
| + adts_frame->header_size = header_size; |
| DVLOG(LOG_LEVEL_ES) |
| << "ADTS syncword @ pos=" << adts_frame->queue_offset |
| << " frame_size=" << adts_frame->size; |
| @@ -105,18 +114,61 @@ void EsParserAdts::SkipAdtsFrame(const AdtsFrame& adts_frame) { |
| es_queue_->Pop(adts_frame.size); |
| } |
| -EsParserAdts::EsParserAdts( |
| - const NewAudioConfigCB& new_audio_config_cb, |
| - const EmitBufferCB& emit_buffer_cb, |
| - bool sbr_in_mimetype) |
| - : new_audio_config_cb_(new_audio_config_cb), |
| - emit_buffer_cb_(emit_buffer_cb), |
| - sbr_in_mimetype_(sbr_in_mimetype) { |
| +EsParserAdts::EsParserAdts(const NewAudioConfigCB& new_audio_config_cb, |
| + const EmitBufferCB& emit_buffer_cb, |
| + bool sbr_in_mimetype) |
| + : new_audio_config_cb_(new_audio_config_cb), |
| + emit_buffer_cb_(emit_buffer_cb), |
| +#if BUILDFLAG(ENABLE_HLS_SAMPLE_AES) |
| + get_decrypt_config_cb_(), |
| + use_hls_sample_aes_(false), |
| +#endif |
| + sbr_in_mimetype_(sbr_in_mimetype) { |
| } |
| +#if BUILDFLAG(ENABLE_HLS_SAMPLE_AES) |
| +EsParserAdts::EsParserAdts(const NewAudioConfigCB& new_audio_config_cb, |
| + const EmitBufferCB& emit_buffer_cb, |
| + const GetDecryptConfigCB& get_decrypt_config_cb, |
| + bool use_hls_sample_aes, |
| + bool sbr_in_mimetype) |
| + : new_audio_config_cb_(new_audio_config_cb), |
| + emit_buffer_cb_(emit_buffer_cb), |
| + get_decrypt_config_cb_(get_decrypt_config_cb), |
| + use_hls_sample_aes_(use_hls_sample_aes), |
|
ddorwin
2016/04/12 00:40:47
DCHECK_EQ(get_decrypt_config_cb_, use_hls_sample_a
dougsteed
2016/05/08 23:18:44
Done.
|
| + sbr_in_mimetype_(sbr_in_mimetype) {} |
| +#endif |
| + |
| EsParserAdts::~EsParserAdts() { |
| } |
| +#if BUILDFLAG(ENABLE_HLS_SAMPLE_AES) |
| +void EsParserAdts::CalculateSubsamplesForAdtsFrame( |
| + const AdtsFrame& adts_frame, |
| + std::vector<SubsampleEntry>* subsamples) { |
| + DCHECK(subsamples); |
| + subsamples->clear(); |
| + int data_size = adts_frame.size - adts_frame.header_size; |
| + int residue = data_size % 16; |
| + int clear_bytes = adts_frame.header_size; |
| + int encrypted_bytes = 0; |
| + if (data_size <= 16) { |
| + clear_bytes += data_size; |
| + residue = 0; |
| + } else { |
| + clear_bytes += 16; |
| + encrypted_bytes = adts_frame.size - clear_bytes - residue; |
| + } |
| + SubsampleEntry subsample(clear_bytes, encrypted_bytes); |
| + subsamples->push_back(subsample); |
| + if (residue) { |
| + subsample.clear_bytes = residue; |
| + subsample.cypher_bytes = 0; |
| + subsamples->push_back(subsample); |
| + } |
| +} |
| +#endif |
| + |
| bool EsParserAdts::ParseFromEsQueue() { |
| // Look for every ADTS frame in the ES buffer. |
| AdtsFrame adts_frame; |
| @@ -156,6 +208,18 @@ bool EsParserAdts::ParseFromEsQueue() { |
| stream_parser_buffer->SetDecodeTimestamp( |
| DecodeTimestamp::FromPresentationTime(current_pts)); |
| stream_parser_buffer->set_duration(frame_duration); |
| +#if BUILDFLAG(ENABLE_HLS_SAMPLE_AES) |
| + if (use_hls_sample_aes_) { |
| + const DecryptConfig* base_decrypt_config = get_decrypt_config_cb_.Run(); |
| + RCHECK(base_decrypt_config); |
| + std::vector<SubsampleEntry> subsamples; |
| + CalculateSubsamplesForAdtsFrame(adts_frame, &subsamples); |
| + scoped_ptr<DecryptConfig> decrypt_config( |
| + new DecryptConfig(base_decrypt_config->key_id(), |
| + base_decrypt_config->iv(), subsamples)); |
| + stream_parser_buffer->set_decrypt_config(std::move(decrypt_config)); |
| + } |
| +#endif |
| emit_buffer_cb_.Run(stream_parser_buffer); |
| // Update the PTS of the next frame. |
| @@ -177,7 +241,15 @@ void EsParserAdts::ResetInternal() { |
| bool EsParserAdts::UpdateAudioConfiguration(const uint8_t* adts_header) { |
| AudioDecoderConfig audio_decoder_config; |
| - if (!ParseAdtsHeader(adts_header, sbr_in_mimetype_, &audio_decoder_config)) |
| + EncryptionScheme scheme = Unencrypted(); |
| +#if BUILDFLAG(ENABLE_HLS_SAMPLE_AES) |
| + if (use_hls_sample_aes_) { |
| + scheme = EncryptionScheme(EncryptionScheme::CIPHER_MODE_AES_CBC, |
| + EncryptionScheme::Pattern()); |
| + } |
| +#endif |
| + if (!ParseAdtsHeader(adts_header, sbr_in_mimetype_, scheme, |
| + &audio_decoder_config)) |
| return false; |
| if (!audio_decoder_config.Matches(last_audio_decoder_config_)) { |