summaryrefslogtreecommitdiffstats
path: root/chromecast
diff options
context:
space:
mode:
authordougsteed <dougsteed@chromium.org>2016-03-11 16:04:30 -0800
committerCommit bot <commit-bot@chromium.org>2016-03-12 00:05:22 +0000
commit8d5275f7bbb6f79c83829a7931f1500128ef3f8f (patch)
tree06d53aa908b22da47f819afbf815aa941f709ef9 /chromecast
parentc5bf1a9a84aadcf927f94e806f4647d65e3da2c1 (diff)
downloadchromium_src-8d5275f7bbb6f79c83829a7931f1500128ef3f8f.zip
chromium_src-8d5275f7bbb6f79c83829a7931f1500128ef3f8f.tar.gz
chromium_src-8d5275f7bbb6f79c83829a7931f1500128ef3f8f.tar.bz2
media config: expand is_encrypted to a struct.
Provide more complete encryption metadata, rather than just a bool. EncryptionScheme also allows specification of the mode and the pattern, as will be allowed by CENC (ISO's Common Encryption standard), 3rd Edition. BUG=568326 Committed: https://crrev.com/c9d2206c62f65e29b141e08df2b2dcb88f54162f Cr-Commit-Position: refs/heads/master@{#380710} Review URL: https://codereview.chromium.org/1490613005 Cr-Commit-Position: refs/heads/master@{#380791}
Diffstat (limited to 'chromecast')
-rw-r--r--chromecast/common/media/cma_param_traits.cc71
-rw-r--r--chromecast/common/media/cma_param_traits.h10
-rw-r--r--chromecast/common/media/cma_param_traits_macros.h2
-rw-r--r--chromecast/media/audio/cast_audio_output_stream.cc1
-rw-r--r--chromecast/media/audio/cast_audio_output_stream_unittest.cc2
-rw-r--r--chromecast/media/cma/backend/audio_video_pipeline_device_unittest.cc5
-rw-r--r--chromecast/media/cma/base/decoder_config_adapter.cc67
-rw-r--r--chromecast/media/cma/base/demuxer_stream_for_test.cc2
-rw-r--r--chromecast/media/cma/ipc_streamer/BUILD.gn2
-rw-r--r--chromecast/media/cma/ipc_streamer/audio_decoder_config_marshaller.cc9
-rw-r--r--chromecast/media/cma/ipc_streamer/encryption_scheme_marshaller.cc54
-rw-r--r--chromecast/media/cma/ipc_streamer/encryption_scheme_marshaller.h27
-rw-r--r--chromecast/media/cma/ipc_streamer/video_decoder_config_marshaller.cc9
-rw-r--r--chromecast/media/cma/pipeline/audio_decoder_software_wrapper.cc4
-rw-r--r--chromecast/media/cma/pipeline/audio_video_pipeline_impl_unittest.cc4
-rw-r--r--chromecast/media/cma/test/mock_frame_provider.cc4
-rw-r--r--chromecast/media/media.gyp2
-rw-r--r--chromecast/public/media/decoder_config.h83
18 files changed, 318 insertions, 40 deletions
diff --git a/chromecast/common/media/cma_param_traits.cc b/chromecast/common/media/cma_param_traits.cc
index f27043d..f0ddc49 100644
--- a/chromecast/common/media/cma_param_traits.cc
+++ b/chromecast/common/media/cma_param_traits.cc
@@ -12,6 +12,7 @@
#include "content/public/common/common_param_traits.h"
#include "ipc/ipc_message_macros.h"
#include "media/base/audio_decoder_config.h"
+#include "media/base/encryption_scheme.h"
#include "media/base/video_decoder_config.h"
#include "ui/gfx/ipc/gfx_param_traits.h"
@@ -29,6 +30,16 @@ IPC_ENUM_TRAITS_MAX_VALUE(media::VideoPixelFormat, media::PIXEL_FORMAT_MAX)
namespace IPC {
+template <>
+struct ParamTraits<media::EncryptionScheme::Pattern> {
+ typedef media::EncryptionScheme::Pattern param_type;
+ static void Write(base::Pickle* m, const param_type& p);
+ static bool Read(const base::Pickle* m, base::PickleIterator* iter,
+ param_type* r);
+ static void Log(const param_type& p, std::string* l);
+};
+
+
void ParamTraits<media::AudioDecoderConfig>::Write(
base::Pickle* m,
const media::AudioDecoderConfig& p) {
@@ -36,7 +47,7 @@ void ParamTraits<media::AudioDecoderConfig>::Write(
WriteParam(m, p.sample_format());
WriteParam(m, p.channel_layout());
WriteParam(m, p.samples_per_second());
- WriteParam(m, p.is_encrypted());
+ WriteParam(m, p.encryption_scheme());
WriteParam(m, p.extra_data());
}
@@ -48,15 +59,17 @@ bool ParamTraits<media::AudioDecoderConfig>::Read(
media::SampleFormat sample_format;
media::ChannelLayout channel_layout;
int samples_per_second;
- bool is_encrypted;
+ media::EncryptionScheme encryption_scheme;
std::vector<uint8_t> extra_data;
if (!ReadParam(m, iter, &codec) || !ReadParam(m, iter, &sample_format) ||
!ReadParam(m, iter, &channel_layout) ||
!ReadParam(m, iter, &samples_per_second) ||
- !ReadParam(m, iter, &is_encrypted) || !ReadParam(m, iter, &extra_data))
+ !ReadParam(m, iter, &encryption_scheme) ||
+ !ReadParam(m, iter, &extra_data))
return false;
*r = media::AudioDecoderConfig(codec, sample_format, channel_layout,
- samples_per_second, extra_data, is_encrypted);
+ samples_per_second, extra_data,
+ encryption_scheme);
return true;
}
@@ -75,7 +88,7 @@ void ParamTraits<media::VideoDecoderConfig>::Write(
WriteParam(m, p.coded_size());
WriteParam(m, p.visible_rect());
WriteParam(m, p.natural_size());
- WriteParam(m, p.is_encrypted());
+ WriteParam(m, p.encryption_scheme());
WriteParam(m, p.extra_data());
}
@@ -90,17 +103,18 @@ bool ParamTraits<media::VideoDecoderConfig>::Read(
gfx::Size coded_size;
gfx::Rect visible_rect;
gfx::Size natural_size;
- bool is_encrypted;
+ media::EncryptionScheme encryption_scheme;
std::vector<uint8_t> extra_data;
if (!ReadParam(m, iter, &codec) || !ReadParam(m, iter, &profile) ||
!ReadParam(m, iter, &format) || !ReadParam(m, iter, &color_space) ||
!ReadParam(m, iter, &coded_size) || !ReadParam(m, iter, &visible_rect) ||
!ReadParam(m, iter, &natural_size) ||
- !ReadParam(m, iter, &is_encrypted) || !ReadParam(m, iter, &extra_data))
+ !ReadParam(m, iter, &encryption_scheme) ||
+ !ReadParam(m, iter, &extra_data))
return false;
*r = media::VideoDecoderConfig(codec, profile, format, color_space,
coded_size, visible_rect, natural_size,
- extra_data, is_encrypted);
+ extra_data, encryption_scheme);
return true;
}
@@ -109,4 +123,45 @@ void ParamTraits<media::VideoDecoderConfig>::Log(
l->append(base::StringPrintf("<VideoDecoderConfig>"));
}
+void ParamTraits<media::EncryptionScheme>::Write(
+ base::Pickle* m, const param_type& p) {
+ WriteParam(m, p.mode());
+ WriteParam(m, p.pattern());
+}
+
+bool ParamTraits<media::EncryptionScheme>::Read(
+ const base::Pickle* m, base::PickleIterator* iter, param_type* r) {
+ media::EncryptionScheme::CipherMode mode;
+ media::EncryptionScheme::Pattern pattern;
+ if (!ReadParam(m, iter, &mode) || !ReadParam(m, iter, &pattern))
+ return false;
+ *r = media::EncryptionScheme(mode, pattern);
+ return true;
+}
+
+void ParamTraits<media::EncryptionScheme>::Log(
+ const param_type& p, std::string* l) {
+ l->append(base::StringPrintf("<EncryptionScheme>"));
+}
+
+void ParamTraits<media::EncryptionScheme::Pattern>::Write(
+ base::Pickle* m, const param_type& p) {
+ WriteParam(m, p.encrypt_blocks());
+ WriteParam(m, p.skip_blocks());
+}
+
+bool ParamTraits<media::EncryptionScheme::Pattern>::Read(
+ const base::Pickle* m, base::PickleIterator* iter, param_type* r) {
+ uint32_t encrypt_blocks, skip_blocks;
+ if (!ReadParam(m, iter, &encrypt_blocks) || !ReadParam(m, iter, &skip_blocks))
+ return false;
+ *r = media::EncryptionScheme::Pattern(encrypt_blocks, skip_blocks);
+ return true;
+}
+
+void ParamTraits<media::EncryptionScheme::Pattern>::Log(
+ const param_type& p, std::string* l) {
+ l->append(base::StringPrintf("<Pattern>"));
+}
+
} // namespace IPC
diff --git a/chromecast/common/media/cma_param_traits.h b/chromecast/common/media/cma_param_traits.h
index c8609a5..879bbf1 100644
--- a/chromecast/common/media/cma_param_traits.h
+++ b/chromecast/common/media/cma_param_traits.h
@@ -10,6 +10,7 @@
namespace media {
class AudioDecoderConfig;
class VideoDecoderConfig;
+class EncryptionScheme;
}
namespace IPC {
@@ -34,6 +35,15 @@ struct ParamTraits<media::VideoDecoderConfig> {
static void Log(const param_type& p, std::string* l);
};
+template <>
+struct ParamTraits<media::EncryptionScheme> {
+ typedef media::EncryptionScheme param_type;
+ static void Write(base::Pickle* m, const param_type& p);
+ static bool Read(const base::Pickle* m, base::PickleIterator* iter,
+ param_type* r);
+ static void Log(const param_type& p, std::string* l);
+};
+
} // namespace IPC
#endif // CHROMECAST_COMMON_MEDIA_CMA_PARAM_TRAITS_H_
diff --git a/chromecast/common/media/cma_param_traits_macros.h b/chromecast/common/media/cma_param_traits_macros.h
index a25e53f..2aae996 100644
--- a/chromecast/common/media/cma_param_traits_macros.h
+++ b/chromecast/common/media/cma_param_traits_macros.h
@@ -44,6 +44,8 @@ IPC_ENUM_TRAITS_MIN_MAX_VALUE(media::VideoCodec,
media::VideoCodec::kUnknownVideoCodec,
media::VideoCodec::kVideoCodecMax)
IPC_ENUM_TRAITS_MAX_VALUE(media::ColorSpace, media::COLOR_SPACE_MAX)
+IPC_ENUM_TRAITS_MAX_VALUE(media::EncryptionScheme::CipherMode,
+ media::EncryptionScheme::CIPHER_MODE_MAX);
IPC_STRUCT_TRAITS_BEGIN(media::PipelineStatistics)
IPC_STRUCT_TRAITS_MEMBER(audio_bytes_decoded)
diff --git a/chromecast/media/audio/cast_audio_output_stream.cc b/chromecast/media/audio/cast_audio_output_stream.cc
index ec415d7..fc91d50 100644
--- a/chromecast/media/audio/cast_audio_output_stream.cc
+++ b/chromecast/media/audio/cast_audio_output_stream.cc
@@ -47,7 +47,6 @@ MediaPipelineBackend::AudioDecoder* InitializeBackend(
audio_config.bytes_per_channel = audio_params.bits_per_sample() / 8;
audio_config.channel_number = audio_params.channels();
audio_config.samples_per_second = audio_params.sample_rate();
- audio_config.is_encrypted = false;
if (!decoder->SetConfig(audio_config))
return nullptr;
diff --git a/chromecast/media/audio/cast_audio_output_stream_unittest.cc b/chromecast/media/audio/cast_audio_output_stream_unittest.cc
index a8ad0f0..8402a6a 100644
--- a/chromecast/media/audio/cast_audio_output_stream_unittest.cc
+++ b/chromecast/media/audio/cast_audio_output_stream_unittest.cc
@@ -385,7 +385,7 @@ TEST_F(CastAudioOutputStreamTest, Format) {
const AudioConfig& audio_config = audio_decoder->config();
EXPECT_EQ(kCodecPCM, audio_config.codec);
EXPECT_EQ(kSampleFormatS16, audio_config.sample_format);
- EXPECT_FALSE(audio_config.is_encrypted);
+ EXPECT_FALSE(audio_config.encryption_scheme.is_encrypted());
CloseStream(stream);
}
diff --git a/chromecast/media/cma/backend/audio_video_pipeline_device_unittest.cc b/chromecast/media/cma/backend/audio_video_pipeline_device_unittest.cc
index 8cc5c03..c78af4a 100644
--- a/chromecast/media/cma/backend/audio_video_pipeline_device_unittest.cc
+++ b/chromecast/media/cma/backend/audio_video_pipeline_device_unittest.cc
@@ -35,6 +35,7 @@
#include "media/base/audio_decoder_config.h"
#include "media/base/audio_timestamp_helper.h"
#include "media/base/decoder_buffer.h"
+#include "media/base/encryption_scheme.h"
#include "media/base/video_decoder_config.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -68,7 +69,7 @@ VideoConfig DefaultVideoConfig() {
default_config.codec = kCodecH264;
default_config.profile = kH264Main;
default_config.additional_config = nullptr;
- default_config.is_encrypted = false;
+ default_config.encryption_scheme = Unencrypted();
return default_config;
}
@@ -564,7 +565,7 @@ scoped_ptr<BufferFeeder> BufferFeeder::LoadVideo(MediaPipelineBackend* backend,
video_config.codec = kCodecH264;
video_config.profile = kH264Main;
video_config.additional_config = nullptr;
- video_config.is_encrypted = false;
+ video_config.encryption_scheme = Unencrypted();
} else {
base::FilePath file_path = GetTestDataFilePath(filename);
DemuxResult demux_result = FFmpegDemuxForTest(file_path, false /* audio */);
diff --git a/chromecast/media/cma/base/decoder_config_adapter.cc b/chromecast/media/cma/base/decoder_config_adapter.cc
index 3a8ab39..24e8b41 100644
--- a/chromecast/media/cma/base/decoder_config_adapter.cc
+++ b/chromecast/media/cma/base/decoder_config_adapter.cc
@@ -85,7 +85,7 @@ VideoCodec ToVideoCodec(const ::media::VideoCodec video_codec) {
// Converts ::media::VideoCodecProfile to chromecast::media::VideoProfile.
VideoProfile ToVideoProfile(const ::media::VideoCodecProfile codec_profile) {
- switch(codec_profile) {
+ switch (codec_profile) {
case ::media::H264PROFILE_BASELINE:
return kH264Baseline;
case ::media::H264PROFILE_MAIN:
@@ -183,6 +183,62 @@ VideoProfile ToVideoProfile(const ::media::VideoCodecProfile codec_profile) {
}
}
+::media::EncryptionScheme::CipherMode ToMediaCipherMode(
+ EncryptionScheme::CipherMode mode) {
+ switch (mode) {
+ case EncryptionScheme::CIPHER_MODE_UNENCRYPTED:
+ return ::media::EncryptionScheme::CIPHER_MODE_UNENCRYPTED;
+ case EncryptionScheme::CIPHER_MODE_AES_CTR:
+ return ::media::EncryptionScheme::CIPHER_MODE_AES_CTR;
+ case EncryptionScheme::CIPHER_MODE_AES_CBC:
+ return ::media::EncryptionScheme::CIPHER_MODE_AES_CBC;
+ default:
+ NOTREACHED();
+ return ::media::EncryptionScheme::CIPHER_MODE_UNENCRYPTED;
+ }
+}
+
+EncryptionScheme::CipherMode ToCipherMode(
+ ::media::EncryptionScheme::CipherMode mode) {
+ switch (mode) {
+ case ::media::EncryptionScheme::CIPHER_MODE_UNENCRYPTED:
+ return EncryptionScheme::CIPHER_MODE_UNENCRYPTED;
+ case ::media::EncryptionScheme::CIPHER_MODE_AES_CTR:
+ return EncryptionScheme::CIPHER_MODE_AES_CTR;
+ case ::media::EncryptionScheme::CIPHER_MODE_AES_CBC:
+ return EncryptionScheme::CIPHER_MODE_AES_CBC;
+ default:
+ NOTREACHED();
+ return EncryptionScheme::CIPHER_MODE_UNENCRYPTED;
+ }
+}
+
+EncryptionScheme::Pattern ToPatternSpec(
+ const ::media::EncryptionScheme::Pattern& pattern) {
+ return EncryptionScheme::Pattern(
+ pattern.encrypt_blocks(), pattern.skip_blocks());
+}
+
+::media::EncryptionScheme::Pattern ToMediaPatternSpec(
+ const EncryptionScheme::Pattern& pattern) {
+ return ::media::EncryptionScheme::Pattern(
+ pattern.encrypt_blocks, pattern.skip_blocks);
+}
+
+EncryptionScheme ToEncryptionScheme(
+ const ::media::EncryptionScheme& scheme) {
+ return EncryptionScheme(
+ ToCipherMode(scheme.mode()),
+ ToPatternSpec(scheme.pattern()));
+}
+
+::media::EncryptionScheme ToMediaEncryptionScheme(
+ const EncryptionScheme& scheme) {
+ return ::media::EncryptionScheme(
+ ToMediaCipherMode(scheme.mode),
+ ToMediaPatternSpec(scheme.pattern));
+}
+
} // namespace
// static
@@ -201,7 +257,8 @@ AudioConfig DecoderConfigAdapter::ToCastAudioConfig(
::media::ChannelLayoutToChannelCount(config.channel_layout()),
audio_config.samples_per_second = config.samples_per_second();
audio_config.extra_data = config.extra_data();
- audio_config.is_encrypted = config.is_encrypted();
+ audio_config.encryption_scheme = ToEncryptionScheme(
+ config.encryption_scheme());
return audio_config;
}
@@ -212,7 +269,8 @@ AudioConfig DecoderConfigAdapter::ToCastAudioConfig(
ToMediaAudioCodec(config.codec),
ToMediaSampleFormat(config.sample_format),
ToMediaChannelLayout(config.channel_number), config.samples_per_second,
- config.extra_data, config.is_encrypted);
+ config.extra_data,
+ ToMediaEncryptionScheme(config.encryption_scheme));
}
// static
@@ -228,7 +286,8 @@ VideoConfig DecoderConfigAdapter::ToCastVideoConfig(
video_config.codec = ToVideoCodec(config.codec());
video_config.profile = ToVideoProfile(config.profile());
video_config.extra_data = config.extra_data();
- video_config.is_encrypted = config.is_encrypted();
+ video_config.encryption_scheme = ToEncryptionScheme(
+ config.encryption_scheme());
return video_config;
}
diff --git a/chromecast/media/cma/base/demuxer_stream_for_test.cc b/chromecast/media/cma/base/demuxer_stream_for_test.cc
index 9942545..32ee27b 100644
--- a/chromecast/media/cma/base/demuxer_stream_for_test.cc
+++ b/chromecast/media/cma/base/demuxer_stream_for_test.cc
@@ -63,7 +63,7 @@ void DemuxerStreamForTest::Read(const ReadCB& read_cb) {
visible_rect,
natural_size,
::media::EmptyExtraData(),
- false);
+ ::media::Unencrypted());
}
::media::DemuxerStream::Type DemuxerStreamForTest::type() const {
diff --git a/chromecast/media/cma/ipc_streamer/BUILD.gn b/chromecast/media/cma/ipc_streamer/BUILD.gn
index a3429d6..7d25f45 100644
--- a/chromecast/media/cma/ipc_streamer/BUILD.gn
+++ b/chromecast/media/cma/ipc_streamer/BUILD.gn
@@ -14,6 +14,8 @@ source_set("ipc_streamer") {
"decoder_buffer_base_marshaller.h",
"decrypt_config_marshaller.cc",
"decrypt_config_marshaller.h",
+ "encryption_scheme_marshaller.cc",
+ "encryption_scheme_marshaller.h",
"video_decoder_config_marshaller.cc",
"video_decoder_config_marshaller.h",
]
diff --git a/chromecast/media/cma/ipc_streamer/audio_decoder_config_marshaller.cc b/chromecast/media/cma/ipc_streamer/audio_decoder_config_marshaller.cc
index 2798c6b..031571a 100644
--- a/chromecast/media/cma/ipc_streamer/audio_decoder_config_marshaller.cc
+++ b/chromecast/media/cma/ipc_streamer/audio_decoder_config_marshaller.cc
@@ -11,6 +11,7 @@
#include "base/logging.h"
#include "chromecast/media/cma/ipc/media_message.h"
+#include "chromecast/media/cma/ipc_streamer/encryption_scheme_marshaller.h"
#include "media/base/audio_decoder_config.h"
namespace chromecast {
@@ -27,7 +28,7 @@ void AudioDecoderConfigMarshaller::Write(
CHECK(msg->WritePod(config.channel_layout()));
CHECK(msg->WritePod(config.samples_per_second()));
CHECK(msg->WritePod(config.sample_format()));
- CHECK(msg->WritePod(config.is_encrypted()));
+ EncryptionSchemeMarshaller::Write(config.encryption_scheme(), msg);
CHECK(msg->WritePod(config.extra_data().size()));
if (!config.extra_data().empty())
CHECK(msg->WriteBuffer(&config.extra_data()[0],
@@ -41,15 +42,15 @@ void AudioDecoderConfigMarshaller::Write(
::media::SampleFormat sample_format;
::media::ChannelLayout channel_layout;
int samples_per_second;
- bool is_encrypted;
size_t extra_data_size;
std::vector<uint8_t> extra_data;
+ ::media::EncryptionScheme encryption_scheme;
CHECK(msg->ReadPod(&codec));
CHECK(msg->ReadPod(&channel_layout));
CHECK(msg->ReadPod(&samples_per_second));
CHECK(msg->ReadPod(&sample_format));
- CHECK(msg->ReadPod(&is_encrypted));
+ encryption_scheme = EncryptionSchemeMarshaller::Read(msg);
CHECK(msg->ReadPod(&extra_data_size));
CHECK_GE(codec, ::media::kUnknownAudioCodec);
@@ -67,7 +68,7 @@ void AudioDecoderConfigMarshaller::Write(
return ::media::AudioDecoderConfig(
codec, sample_format,
channel_layout, samples_per_second,
- extra_data, is_encrypted);
+ extra_data, encryption_scheme);
}
} // namespace media
diff --git a/chromecast/media/cma/ipc_streamer/encryption_scheme_marshaller.cc b/chromecast/media/cma/ipc_streamer/encryption_scheme_marshaller.cc
new file mode 100644
index 0000000..a88cfc5
--- /dev/null
+++ b/chromecast/media/cma/ipc_streamer/encryption_scheme_marshaller.cc
@@ -0,0 +1,54 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chromecast/media/cma/ipc_streamer/encryption_scheme_marshaller.h"
+
+#include <stdint.h>
+
+#include "base/logging.h"
+#include "chromecast/media/cma/ipc/media_message.h"
+
+namespace chromecast {
+namespace media {
+
+namespace {
+
+class PatternSpecMarshaller {
+ public:
+ static void Write(const ::media::EncryptionScheme::Pattern& pattern,
+ MediaMessage* msg) {
+ CHECK(msg->WritePod(pattern.encrypt_blocks()));
+ CHECK(msg->WritePod(pattern.skip_blocks()));
+ }
+
+ static ::media::EncryptionScheme::Pattern Read(MediaMessage* msg) {
+ uint32_t encrypt_blocks;
+ uint32_t skip_blocks;
+ CHECK(msg->ReadPod(&encrypt_blocks));
+ CHECK(msg->ReadPod(&skip_blocks));
+ return ::media::EncryptionScheme::Pattern(encrypt_blocks, skip_blocks);
+ }
+};
+
+} // namespace
+
+// static
+void EncryptionSchemeMarshaller::Write(
+ const ::media::EncryptionScheme& encryption_scheme,
+ MediaMessage* msg) {
+ CHECK(msg->WritePod(encryption_scheme.mode()));
+ PatternSpecMarshaller::Write(encryption_scheme.pattern(), msg);
+}
+
+// static
+::media::EncryptionScheme EncryptionSchemeMarshaller::Read(MediaMessage* msg) {
+ ::media::EncryptionScheme::CipherMode mode;
+ ::media::EncryptionScheme::Pattern pattern;
+ CHECK(msg->ReadPod(&mode));
+ pattern = PatternSpecMarshaller::Read(msg);
+ return ::media::EncryptionScheme(mode, pattern);
+}
+
+} // namespace media
+} // namespace chromecast
diff --git a/chromecast/media/cma/ipc_streamer/encryption_scheme_marshaller.h b/chromecast/media/cma/ipc_streamer/encryption_scheme_marshaller.h
new file mode 100644
index 0000000..0b3371b
--- /dev/null
+++ b/chromecast/media/cma/ipc_streamer/encryption_scheme_marshaller.h
@@ -0,0 +1,27 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROMECAST_MEDIA_CMA_IPC_STREAMER_ENCRYPTION_SCHEME_MARSHALLER_H_
+#define CHROMECAST_MEDIA_CMA_IPC_STREAMER_ENCRYPTION_SCHEME_MARSHALLER_H_
+
+#include "media/base/encryption_scheme.h"
+
+namespace chromecast {
+namespace media {
+class MediaMessage;
+
+class EncryptionSchemeMarshaller {
+ public:
+ // Writes the serialized structure of |encryption_scheme| into |msg|.
+ static void Write(
+ const ::media::EncryptionScheme& encryption_scheme, MediaMessage* msg);
+
+ // Returns an EncryptionScheme from its serialized structure.
+ static ::media::EncryptionScheme Read(MediaMessage* msg);
+};
+
+} // namespace media
+} // namespace chromecast
+
+#endif // CHROMECAST_MEDIA_CMA_IPC_STREAMER_ENCRYPTION_SCHEME_MARSHALLER_H_
diff --git a/chromecast/media/cma/ipc_streamer/video_decoder_config_marshaller.cc b/chromecast/media/cma/ipc_streamer/video_decoder_config_marshaller.cc
index b2e9aaa..a471eb6 100644
--- a/chromecast/media/cma/ipc_streamer/video_decoder_config_marshaller.cc
+++ b/chromecast/media/cma/ipc_streamer/video_decoder_config_marshaller.cc
@@ -11,6 +11,7 @@
#include "base/logging.h"
#include "chromecast/media/cma/ipc/media_message.h"
+#include "chromecast/media/cma/ipc_streamer/encryption_scheme_marshaller.h"
#include "media/base/video_decoder_config.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"
@@ -67,7 +68,7 @@ void VideoDecoderConfigMarshaller::Write(
SizeMarshaller::Write(config.coded_size(), msg);
RectMarshaller::Write(config.visible_rect(), msg);
SizeMarshaller::Write(config.natural_size(), msg);
- CHECK(msg->WritePod(config.is_encrypted()));
+ EncryptionSchemeMarshaller::Write(config.encryption_scheme(), msg);
CHECK(msg->WritePod(config.extra_data().size()));
if (!config.extra_data().empty())
CHECK(msg->WriteBuffer(&config.extra_data()[0],
@@ -84,8 +85,8 @@ void VideoDecoderConfigMarshaller::Write(
gfx::Size coded_size;
gfx::Rect visible_rect;
gfx::Size natural_size;
- bool is_encrypted;
size_t extra_data_size;
+ ::media::EncryptionScheme encryption_scheme;
std::vector<uint8_t> extra_data;
CHECK(msg->ReadPod(&codec));
@@ -95,7 +96,7 @@ void VideoDecoderConfigMarshaller::Write(
coded_size = SizeMarshaller::Read(msg);
visible_rect = RectMarshaller::Read(msg);
natural_size = SizeMarshaller::Read(msg);
- CHECK(msg->ReadPod(&is_encrypted));
+ encryption_scheme = EncryptionSchemeMarshaller::Read(msg);
CHECK(msg->ReadPod(&extra_data_size));
CHECK_GE(codec, ::media::kUnknownVideoCodec);
@@ -115,7 +116,7 @@ void VideoDecoderConfigMarshaller::Write(
return ::media::VideoDecoderConfig(
codec, profile, format, color_space,
coded_size, visible_rect, natural_size,
- extra_data, is_encrypted);
+ extra_data, encryption_scheme);
}
} // namespace media
diff --git a/chromecast/media/cma/pipeline/audio_decoder_software_wrapper.cc b/chromecast/media/cma/pipeline/audio_decoder_software_wrapper.cc
index 4b15bcc..a1cdf95 100644
--- a/chromecast/media/cma/pipeline/audio_decoder_software_wrapper.cc
+++ b/chromecast/media/cma/pipeline/audio_decoder_software_wrapper.cc
@@ -59,7 +59,7 @@ bool AudioDecoderSoftwareWrapper::SetConfig(const AudioConfig& config) {
return true;
}
- if (config.is_encrypted || !CreateSoftwareDecoder(config))
+ if (config.is_encrypted() || !CreateSoftwareDecoder(config))
return false;
output_config_.codec = media::kCodecPCM;
@@ -67,7 +67,7 @@ bool AudioDecoderSoftwareWrapper::SetConfig(const AudioConfig& config) {
output_config_.channel_number = 2;
output_config_.bytes_per_channel = 2;
output_config_.samples_per_second = config.samples_per_second;
- output_config_.is_encrypted = false;
+ output_config_.encryption_scheme = Unencrypted();
return backend_decoder_->SetConfig(output_config_);
}
diff --git a/chromecast/media/cma/pipeline/audio_video_pipeline_impl_unittest.cc b/chromecast/media/cma/pipeline/audio_video_pipeline_impl_unittest.cc
index bd747dd..eba1961 100644
--- a/chromecast/media/cma/pipeline/audio_video_pipeline_impl_unittest.cc
+++ b/chromecast/media/cma/pipeline/audio_video_pipeline_impl_unittest.cc
@@ -66,7 +66,7 @@ class AudioVideoPipelineImplTest
::media::AudioDecoderConfig audio_config(
::media::kCodecMP3, ::media::kSampleFormatS16,
::media::CHANNEL_LAYOUT_STEREO, 44100, ::media::EmptyExtraData(),
- false);
+ ::media::Unencrypted());
AvPipelineClient client;
client.eos_cb = base::Bind(&AudioVideoPipelineImplTest::OnEos,
base::Unretained(this), STREAM_AUDIO);
@@ -80,7 +80,7 @@ class AudioVideoPipelineImplTest
::media::kCodecH264, ::media::H264PROFILE_MAIN,
::media::PIXEL_FORMAT_I420, ::media::COLOR_SPACE_UNSPECIFIED,
gfx::Size(640, 480), gfx::Rect(0, 0, 640, 480), gfx::Size(640, 480),
- ::media::EmptyExtraData(), false));
+ ::media::EmptyExtraData(), ::media::Unencrypted()));
VideoPipelineClient client;
client.av_pipeline_client.eos_cb =
base::Bind(&AudioVideoPipelineImplTest::OnEos, base::Unretained(this),
diff --git a/chromecast/media/cma/test/mock_frame_provider.cc b/chromecast/media/cma/test/mock_frame_provider.cc
index fdab889..16d6393 100644
--- a/chromecast/media/cma/test/mock_frame_provider.cc
+++ b/chromecast/media/cma/test/mock_frame_provider.cc
@@ -82,7 +82,7 @@ void MockFrameProvider::DoRead(const ReadCB& read_cb) {
::media::kCodecH264, ::media::VIDEO_CODEC_PROFILE_UNKNOWN,
::media::PIXEL_FORMAT_YV12, ::media::COLOR_SPACE_UNSPECIFIED,
coded_size, visible_rect, natural_size, ::media::EmptyExtraData(),
- false);
+ ::media::Unencrypted());
audio_config = ::media::AudioDecoderConfig(
::media::kCodecAAC,
@@ -90,7 +90,7 @@ void MockFrameProvider::DoRead(const ReadCB& read_cb) {
::media::CHANNEL_LAYOUT_STEREO,
44100,
::media::EmptyExtraData(),
- false);
+ ::media::Unencrypted());
}
read_cb.Run(buffer, audio_config, video_config);
diff --git a/chromecast/media/media.gyp b/chromecast/media/media.gyp
index 6cabfc7..077ea0c 100644
--- a/chromecast/media/media.gyp
+++ b/chromecast/media/media.gyp
@@ -229,6 +229,8 @@
'cma/ipc_streamer/decoder_buffer_base_marshaller.h',
'cma/ipc_streamer/decrypt_config_marshaller.cc',
'cma/ipc_streamer/decrypt_config_marshaller.h',
+ 'cma/ipc_streamer/encryption_scheme_marshaller.cc',
+ 'cma/ipc_streamer/encryption_scheme_marshaller.h',
'cma/ipc_streamer/video_decoder_config_marshaller.cc',
'cma/ipc_streamer/video_decoder_config_marshaller.h',
],
diff --git a/chromecast/public/media/decoder_config.h b/chromecast/public/media/decoder_config.h
index 261b3f1..b82c5c1 100644
--- a/chromecast/public/media/decoder_config.h
+++ b/chromecast/public/media/decoder_config.h
@@ -93,13 +93,78 @@ enum VideoProfile {
kVideoProfileMax = kDolbyVisionNonCompatible_BL_EL_MD,
};
-// TODO(erickung): Remove constructor once CMA backend implementation does't
+// Specification of whether and how the stream is encrypted (in whole or part).
+struct EncryptionScheme {
+ // Algorithm and mode that was used to encrypt the stream.
+ enum CipherMode {
+ CIPHER_MODE_UNENCRYPTED,
+ CIPHER_MODE_AES_CTR,
+ CIPHER_MODE_AES_CBC
+ };
+
+ // CENC 3rd Edition adds pattern encryption, through two new protection
+ // schemes: 'cens' (with AES-CTR) and 'cbcs' (with AES-CBC).
+ // The pattern applies independently to each 'encrypted' part of the frame (as
+ // defined by the relevant subsample entries), and reduces further the
+ // actual encryption applied through a repeating pattern of (encrypt:skip)
+ // 16 byte blocks. For example, in a (1:9) pattern, the first block is
+ // encrypted, and the next nine are skipped. This pattern is applied
+ // repeatedly until the end of the last 16-byte block in the subsample.
+ // Any remaining bytes are left clear.
+ // If either of encrypt_blocks or skip_blocks is 0, pattern encryption is
+ // disabled.
+ struct Pattern {
+ Pattern() {}
+ Pattern(uint32_t encrypt_blocks, uint32_t skip_blocks);
+ ~Pattern() {}
+ bool IsInEffect() const;
+
+ uint32_t encrypt_blocks = 0;
+ uint32_t skip_blocks = 0;
+ };
+
+ EncryptionScheme() {}
+ EncryptionScheme(CipherMode mode, const Pattern& pattern);
+ ~EncryptionScheme() {}
+ bool is_encrypted() const { return mode != CIPHER_MODE_UNENCRYPTED; }
+
+ CipherMode mode = CIPHER_MODE_UNENCRYPTED;
+ Pattern pattern;
+};
+
+inline EncryptionScheme::Pattern::Pattern(uint32_t encrypt_blocks,
+ uint32_t skip_blocks)
+ : encrypt_blocks(encrypt_blocks), skip_blocks(skip_blocks) {
+}
+
+inline bool EncryptionScheme::Pattern::IsInEffect() const {
+ return encrypt_blocks != 0 && skip_blocks != 0;
+}
+
+inline EncryptionScheme::EncryptionScheme(CipherMode mode,
+ const Pattern& pattern)
+ : mode(mode), pattern(pattern) {
+}
+
+inline EncryptionScheme Unencrypted() {
+ return EncryptionScheme();
+}
+
+inline EncryptionScheme AesCtrEncryptionScheme() {
+ return EncryptionScheme(EncryptionScheme::CIPHER_MODE_AES_CTR,
+ EncryptionScheme::Pattern());
+}
+
+
+// TODO(erickung): Remove constructor once CMA backend implementation doesn't
// create a new object to reset the configuration and use IsValidConfig() to
// determine if the configuration is still valid or not.
struct AudioConfig {
AudioConfig();
~AudioConfig();
+ bool is_encrypted() const { return encryption_scheme.is_encrypted(); }
+
// Stream id.
StreamId id;
// Audio codec.
@@ -114,8 +179,8 @@ struct AudioConfig {
int samples_per_second;
// Extra data buffer for certain codec initialization.
std::vector<uint8_t> extra_data;
- // content is encrypted or not.
- bool is_encrypted;
+ // Encryption scheme (if any) used for the content.
+ EncryptionScheme encryption_scheme;
};
inline AudioConfig::AudioConfig()
@@ -124,8 +189,7 @@ inline AudioConfig::AudioConfig()
sample_format(kUnknownSampleFormat),
bytes_per_channel(0),
channel_number(0),
- samples_per_second(0),
- is_encrypted(false) {
+ samples_per_second(0) {
}
inline AudioConfig::~AudioConfig() {
@@ -138,6 +202,8 @@ struct VideoConfig {
VideoConfig();
~VideoConfig();
+ bool is_encrypted() const { return encryption_scheme.is_encrypted(); }
+
// Stream Id.
StreamId id;
// Video codec.
@@ -150,16 +216,15 @@ struct VideoConfig {
VideoConfig* additional_config;
// Extra data buffer for certain codec initialization.
std::vector<uint8_t> extra_data;
- // content is encrypted or not.
- bool is_encrypted;
+ // Encryption scheme (if any) used for the content.
+ EncryptionScheme encryption_scheme;
};
inline VideoConfig::VideoConfig()
: id(kPrimary),
codec(kVideoCodecUnknown),
profile(kVideoProfileUnknown),
- additional_config(nullptr),
- is_encrypted(false) {
+ additional_config(nullptr) {
}
inline VideoConfig::~VideoConfig() {