| 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: " | 
|  |