Skip to content

Commit

Permalink
[mp2t] Support transition from encrypted buffers to clear buffers
Browse files Browse the repository at this point in the history
Pes with clear stream type may appear after pes with encrypted stream
type, without resetting the decrypt config. In this case, the stream parser
should mark the buffers as clear because the stream type itself already
indicates the buffers in the pes are clear buffers.

EsParser now checks initial encryption scheme for Audio/VideoConfig, so
that the decoder could know the whole stream may contain encrypted
buffers. This is to help the decoder to initialize the secure pipeline
correctly from the start of the playback.

EsParser checks whether there's valid decrypt config to mark whether the
buffers are clear or not. If the pes' stream type is clear, we pass an
empty GetDecryptConfigCB so that EsParser will treat the buffers as
clear buffers.

Bug: internal b/142442975
Test: Test mentioned in the bug.
Change-Id: Ib5a46ea6ef88bd954487fe958808bde6ae8746e8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1912990
Commit-Queue: Yuchen Liu <yucliu@chromium.org>
Reviewed-by: Kongqun Yang <kqyang@chromium.org>
Reviewed-by: Xiaohan Wang <xhwang@chromium.org>
Reviewed-by: Doug Steedman <dougsteed@chromium.org>
Cr-Commit-Position: refs/heads/master@{#716733}
  • Loading branch information
Yuchen Liu authored and Commit Bot committed Nov 19, 2019
1 parent 45a2aeb commit 887260a
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 45 deletions.
16 changes: 6 additions & 10 deletions media/formats/mp2t/es_parser_adts.cc
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ EsParserAdts::EsParserAdts(const NewAudioConfigCB& 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),
init_encryption_scheme_(EncryptionScheme::kUnencrypted),
#endif
sbr_in_mimetype_(sbr_in_mimetype) {
}
Expand All @@ -131,15 +131,13 @@ EsParserAdts::EsParserAdts(const NewAudioConfigCB& new_audio_config_cb,
EsParserAdts::EsParserAdts(const NewAudioConfigCB& new_audio_config_cb,
const EmitBufferCB& emit_buffer_cb,
const GetDecryptConfigCB& get_decrypt_config_cb,
bool use_hls_sample_aes,
EncryptionScheme init_encryption_scheme,
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_, use_hls_sample_aes_);
}
init_encryption_scheme_(init_encryption_scheme),
sbr_in_mimetype_(sbr_in_mimetype) {}
#endif

EsParserAdts::~EsParserAdts() {
Expand Down Expand Up @@ -210,7 +208,7 @@ bool EsParserAdts::ParseFromEsQueue() {
DecodeTimestamp::FromPresentationTime(current_pts));
stream_parser_buffer->set_duration(frame_duration);
#if BUILDFLAG(ENABLE_HLS_SAMPLE_AES)
if (use_hls_sample_aes_) {
if (get_decrypt_config_cb_) {
const DecryptConfig* base_decrypt_config = get_decrypt_config_cb_.Run();
if (base_decrypt_config) {
std::vector<SubsampleEntry> subsamples;
Expand Down Expand Up @@ -262,9 +260,7 @@ bool EsParserAdts::UpdateAudioConfiguration(const uint8_t* adts_header,
: orig_sample_rate;
EncryptionScheme scheme = EncryptionScheme::kUnencrypted;
#if BUILDFLAG(ENABLE_HLS_SAMPLE_AES)
if (use_hls_sample_aes_) {
scheme = EncryptionScheme::kCbcs;
}
scheme = init_encryption_scheme_;
#endif
AudioDecoderConfig audio_decoder_config(
kCodecAAC, kSampleFormatS16, channel_layout, extended_samples_per_second,
Expand Down
6 changes: 3 additions & 3 deletions media/formats/mp2t/es_parser_adts.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class MEDIA_EXPORT EsParserAdts : public EsParser {
EsParserAdts(const NewAudioConfigCB& new_audio_config_cb,
const EmitBufferCB& emit_buffer_cb,
const GetDecryptConfigCB& get_decrypt_config_cb,
bool use_hls_sample_aes,
EncryptionScheme init_encryption_scheme,
bool sbr_in_mimetype);
#endif

Expand Down Expand Up @@ -82,9 +82,9 @@ class MEDIA_EXPORT EsParserAdts : public EsParser {
NewAudioConfigCB new_audio_config_cb_;
EmitBufferCB emit_buffer_cb_;
#if BUILDFLAG(ENABLE_HLS_SAMPLE_AES)
// - to obtain the current decrypt_config. Only called if use_hls_sample_aes_.
// - to obtain the current decrypt_config.
GetDecryptConfigCB get_decrypt_config_cb_;
bool use_hls_sample_aes_;
const EncryptionScheme init_encryption_scheme_;
#endif

// True when AAC SBR extension is signalled in the mimetype
Expand Down
25 changes: 9 additions & 16 deletions media/formats/mp2t/es_parser_h264.cc
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ EsParserH264::EsParserH264(const NewVideoConfigCB& new_video_config_cb,
next_access_unit_pos_(0)
#if BUILDFLAG(ENABLE_HLS_SAMPLE_AES)
,
use_hls_sample_aes_(false),
init_encryption_scheme_(EncryptionScheme::kUnencrypted),
get_decrypt_config_cb_()
#endif
{
Expand All @@ -194,16 +194,14 @@ EsParserH264::EsParserH264(const NewVideoConfigCB& new_video_config_cb,
#if BUILDFLAG(ENABLE_HLS_SAMPLE_AES)
EsParserH264::EsParserH264(const NewVideoConfigCB& new_video_config_cb,
const EmitBufferCB& emit_buffer_cb,
bool use_hls_sample_aes,
EncryptionScheme init_encryption_scheme,
const GetDecryptConfigCB& get_decrypt_config_cb)
: es_adapter_(new_video_config_cb, emit_buffer_cb),
h264_parser_(new H264Parser()),
current_access_unit_pos_(0),
next_access_unit_pos_(0),
use_hls_sample_aes_(use_hls_sample_aes),
get_decrypt_config_cb_(get_decrypt_config_cb) {
DCHECK_EQ(!!get_decrypt_config_cb_, use_hls_sample_aes_);
}
init_encryption_scheme_(init_encryption_scheme),
get_decrypt_config_cb_(get_decrypt_config_cb) {}
#endif

EsParserH264::~EsParserH264() {
Expand Down Expand Up @@ -360,7 +358,7 @@ bool EsParserH264::ParseFromEsQueue() {
#if BUILDFLAG(ENABLE_HLS_SAMPLE_AES)
// With HLS SampleAES, protected blocks in H.264 consist of IDR and non-
// IDR slices that are more than 48 bytes in length.
if (use_hls_sample_aes_ &&
if (get_decrypt_config_cb_ && get_decrypt_config_cb_.Run() &&
nalu.size > kSampleAESMaxUnprotectedNALULength) {
int64_t nal_begin = nalu.data - es;
protected_blocks_.Add(nal_begin, nal_begin + nalu.size);
Expand Down Expand Up @@ -420,10 +418,7 @@ bool EsParserH264::EmitFrame(int64_t access_unit_pos,
return false;
EncryptionScheme scheme = EncryptionScheme::kUnencrypted;
#if BUILDFLAG(ENABLE_HLS_SAMPLE_AES)
if (use_hls_sample_aes_) {
// Note that for SampleAES the (encrypt,skip) pattern is constant.
scheme = EncryptionScheme::kCbcs;
}
scheme = init_encryption_scheme_;
#endif
RCHECK(UpdateVideoDecoderConfig(sps, scheme));
}
Expand All @@ -438,14 +433,12 @@ bool EsParserH264::EmitFrame(int64_t access_unit_pos,

#if BUILDFLAG(ENABLE_HLS_SAMPLE_AES)
const DecryptConfig* base_decrypt_config = nullptr;
if (use_hls_sample_aes_) {
DCHECK(get_decrypt_config_cb_);
if (get_decrypt_config_cb_)
base_decrypt_config = get_decrypt_config_cb_.Run();
}

std::unique_ptr<uint8_t[]> adjusted_au;
std::vector<SubsampleEntry> subsamples;
if (use_hls_sample_aes_ && base_decrypt_config) {
if (base_decrypt_config) {
adjusted_au = AdjustAUForSampleAES(es, &access_unit_size, protected_blocks_,
&subsamples);
protected_blocks_.clear();
Expand All @@ -462,7 +455,7 @@ bool EsParserH264::EmitFrame(int64_t access_unit_pos,
stream_parser_buffer->SetDecodeTimestamp(current_timing_desc.dts);
stream_parser_buffer->set_timestamp(current_timing_desc.pts);
#if BUILDFLAG(ENABLE_HLS_SAMPLE_AES)
if (use_hls_sample_aes_ && base_decrypt_config) {
if (base_decrypt_config) {
switch (base_decrypt_config->encryption_scheme()) {
case EncryptionScheme::kUnencrypted:
// As |base_decrypt_config| is specified, the stream is encrypted,
Expand Down
5 changes: 2 additions & 3 deletions media/formats/mp2t/es_parser_h264.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class MEDIA_EXPORT EsParserH264 : public EsParser {
#if BUILDFLAG(ENABLE_HLS_SAMPLE_AES)
EsParserH264(const NewVideoConfigCB& new_video_config_cb,
const EmitBufferCB& emit_buffer_cb,
bool use_hls_sample_aes,
EncryptionScheme init_encryption_scheme,
const GetDecryptConfigCB& get_decrypt_config_cb);
#endif
~EsParserH264() override;
Expand Down Expand Up @@ -87,9 +87,8 @@ class MEDIA_EXPORT EsParserH264 : public EsParser {
int64_t current_access_unit_pos_;
int64_t next_access_unit_pos_;
#if BUILDFLAG(ENABLE_HLS_SAMPLE_AES)
bool use_hls_sample_aes_;
const EncryptionScheme init_encryption_scheme_;
// Callback to obtain the current decrypt_config.
// Only called if use_hls_sample_aes_ is true.
GetDecryptConfigCB get_decrypt_config_cb_;
Ranges<int> protected_blocks_;
#endif
Expand Down
33 changes: 22 additions & 11 deletions media/formats/mp2t/mp2t_stream_parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -433,28 +433,35 @@ bool Mp2tStreamParser::ShouldForceEncryptedParser() {
}

std::unique_ptr<EsParser> Mp2tStreamParser::CreateEncryptedH264Parser(
int pes_pid) {
int pes_pid,
bool emit_clear_buffers) {
auto on_video_config_changed = base::Bind(
&Mp2tStreamParser::OnVideoConfigChanged, base::Unretained(this), pes_pid);
auto on_emit_video_buffer = base::Bind(&Mp2tStreamParser::OnEmitVideoBuffer,
base::Unretained(this), pes_pid);
auto get_decrypt_config =
base::Bind(&Mp2tStreamParser::GetDecryptConfig, base::Unretained(this));
emit_clear_buffers ? EsParser::GetDecryptConfigCB()
: base::Bind(&Mp2tStreamParser::GetDecryptConfig,
base::Unretained(this));
return std::make_unique<EsParserH264>(
on_video_config_changed, on_emit_video_buffer, true, get_decrypt_config);
on_video_config_changed, on_emit_video_buffer, initial_encryption_scheme_,
get_decrypt_config);
}

std::unique_ptr<EsParser> Mp2tStreamParser::CreateEncryptedAacParser(
int pes_pid) {
int pes_pid,
bool emit_clear_buffers) {
auto on_audio_config_changed = base::Bind(
&Mp2tStreamParser::OnAudioConfigChanged, base::Unretained(this), pes_pid);
auto on_emit_audio_buffer = base::Bind(&Mp2tStreamParser::OnEmitAudioBuffer,
base::Unretained(this), pes_pid);
auto get_decrypt_config =
base::Bind(&Mp2tStreamParser::GetDecryptConfig, base::Unretained(this));
emit_clear_buffers ? EsParser::GetDecryptConfigCB()
: base::Bind(&Mp2tStreamParser::GetDecryptConfig,
base::Unretained(this));
return std::make_unique<EsParserAdts>(
on_audio_config_changed, on_emit_audio_buffer, get_decrypt_config, true,
sbr_in_mimetype_);
on_audio_config_changed, on_emit_audio_buffer, get_decrypt_config,
initial_encryption_scheme_, sbr_in_mimetype_);
}
#endif

Expand All @@ -478,7 +485,8 @@ void Mp2tStreamParser::RegisterPes(int pes_pid,
is_audio = false;
#if BUILDFLAG(ENABLE_HLS_SAMPLE_AES)
if (ShouldForceEncryptedParser()) {
es_parser = CreateEncryptedH264Parser(pes_pid);
es_parser =
CreateEncryptedH264Parser(pes_pid, true /* emit_clear_buffers */);
break;
}
#endif
Expand All @@ -488,7 +496,8 @@ void Mp2tStreamParser::RegisterPes(int pes_pid,
case kStreamTypeAAC:
#if BUILDFLAG(ENABLE_HLS_SAMPLE_AES)
if (ShouldForceEncryptedParser()) {
es_parser = CreateEncryptedAacParser(pes_pid);
es_parser =
CreateEncryptedAacParser(pes_pid, true /* emit_clear_buffers */);
break;
}
#endif
Expand All @@ -505,7 +514,8 @@ void Mp2tStreamParser::RegisterPes(int pes_pid,
if (descriptors.HasPrivateDataIndicator(
kSampleAESPrivateDataIndicatorAVC)) {
is_audio = false;
es_parser = CreateEncryptedH264Parser(pes_pid);
es_parser =
CreateEncryptedH264Parser(pes_pid, false /* emit_clear_buffers */);
} else {
VLOG(2) << "HLS: stream_type in PMT indicates AVC with Sample-AES, but "
<< "corresponding private data indicator is not present.";
Expand All @@ -515,7 +525,8 @@ void Mp2tStreamParser::RegisterPes(int pes_pid,
case kStreamTypeAACWithSampleAES:
if (descriptors.HasPrivateDataIndicator(
kSampleAESPrivateDataIndicatorAAC)) {
es_parser = CreateEncryptedAacParser(pes_pid);
es_parser =
CreateEncryptedAacParser(pes_pid, false /* emit_clear_buffers */);
} else {
VLOG(2) << "HLS: stream_type in PMT indicates AAC with Sample-AES, but "
<< "corresponding private data indicator is not present.";
Expand Down
6 changes: 4 additions & 2 deletions media/formats/mp2t/mp2t_stream_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,10 @@ class MEDIA_EXPORT Mp2tStreamParser : public StreamParser {

#if BUILDFLAG(ENABLE_HLS_SAMPLE_AES)
bool ShouldForceEncryptedParser();
std::unique_ptr<EsParser> CreateEncryptedH264Parser(int pes_pid);
std::unique_ptr<EsParser> CreateEncryptedAacParser(int pes_pid);
std::unique_ptr<EsParser> CreateEncryptedH264Parser(int pes_pid,
bool emit_clear_buffers);
std::unique_ptr<EsParser> CreateEncryptedAacParser(int pes_pid,
bool emit_clear_buffers);

std::unique_ptr<PidState> MakeCatPidState();
void UnregisterCat();
Expand Down

0 comments on commit 887260a

Please sign in to comment.