| 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 3a31f1eb199296496e41f26f2fc145ce54d0d218..2ba520cf481d48e95593c67b5bb9bf88c1a0221e 100644
|
| --- a/media/formats/mp2t/es_parser_adts.cc
|
| +++ b/media/formats/mp2t/es_parser_adts.cc
|
| @@ -28,6 +28,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 +49,7 @@ struct EsParserAdts::AdtsFrame {
|
|
|
| // Frame size;
|
| int size;
|
| + int header_size;
|
|
|
| // Frame offset in the ES queue.
|
| int64_t queue_offset;
|
| @@ -68,6 +74,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 +94,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 +113,63 @@ 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),
|
| + sbr_in_mimetype_(sbr_in_mimetype) {
|
| + DCHECK_EQ(!get_decrypt_config_cb_.is_null(), use_hls_sample_aes_);
|
| }
|
| +#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;
|
| @@ -154,6 +207,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);
|
| + std::unique_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.
|
| @@ -191,10 +256,16 @@ bool EsParserAdts::UpdateAudioConfiguration(const uint8_t* adts_header,
|
| const int extended_samples_per_second =
|
| sbr_in_mimetype_ ? std::min(2 * orig_sample_rate, 48000)
|
| : orig_sample_rate;
|
| -
|
| + EncryptionScheme scheme = Unencrypted();
|
| +#if BUILDFLAG(ENABLE_HLS_SAMPLE_AES)
|
| + if (use_hls_sample_aes_) {
|
| + scheme = EncryptionScheme(EncryptionScheme::CIPHER_MODE_AES_CBC,
|
| + EncryptionScheme::Pattern());
|
| + }
|
| +#endif
|
| AudioDecoderConfig audio_decoder_config(
|
| kCodecAAC, kSampleFormatS16, channel_layout, extended_samples_per_second,
|
| - extra_data, Unencrypted());
|
| + extra_data, scheme);
|
|
|
| if (!audio_decoder_config.Matches(last_audio_decoder_config_)) {
|
| DVLOG(1) << "Sampling frequency: "
|
|
|