Skip to content

Commit

Permalink
media: Support updated CDM_11 that supports ColorSpace
Browse files Browse the repository at this point in the history
Conversion code is added to support multiple CDM interfaces that use
different version of cdm::VideoDecoderConfig and cdm::VideoFrame.

Bug: 854943
Change-Id: I235c12805aea3191f8a5153c9a124f6fe3b26a31
Reviewed-on: https://chromium-review.googlesource.com/1227489
Commit-Queue: Xiaohan Wang <xhwang@chromium.org>
Reviewed-by: Fredrik Hubinette <hubbe@chromium.org>
Cr-Commit-Position: refs/heads/master@{#591940}
  • Loading branch information
xhwang-chromium authored and Commit Bot committed Sep 18, 2018
1 parent da8cf24 commit 106f5d9
Show file tree
Hide file tree
Showing 17 changed files with 297 additions and 127 deletions.
2 changes: 1 addition & 1 deletion DEPS
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ deps = {
},

'src/media/cdm/api':
Var('chromium_git') + '/chromium/cdm.git' + '@' + '2c580d1532f354556c05b09512e64eeab938b01e',
Var('chromium_git') + '/chromium/cdm.git' + '@' + '6f92d7c0e62b135511744ce6bcf0dd2ff364df09',

'src/native_client': {
'url': Var('chromium_git') + '/native_client/src/native_client.git' + '@' + Var('nacl_revision'),
Expand Down
28 changes: 27 additions & 1 deletion media/cdm/cdm_adapter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "base/logging.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/numerics/safe_conversions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
Expand All @@ -35,6 +36,7 @@
#include "media/cdm/cdm_auxiliary_helper.h"
#include "media/cdm/cdm_helpers.h"
#include "media/cdm/cdm_wrapper.h"
#include "ui/gfx/color_space.h"
#include "ui/gfx/geometry/rect.h"
#include "url/origin.h"

Expand Down Expand Up @@ -239,6 +241,29 @@ cdm::VideoFormat ToCdmVideoFormat(VideoPixelFormat format) {
}
}

cdm::ColorRange ToCdmColorRange(gfx::ColorSpace::RangeID range) {
switch (range) {
case gfx::ColorSpace::RangeID::LIMITED:
return cdm::ColorRange::kLimited;
case gfx::ColorSpace::RangeID::FULL:
return cdm::ColorRange::kFull;
case gfx::ColorSpace::RangeID::DERIVED:
return cdm::ColorRange::kDerived;
default:
DVLOG(1) << "Invalid color range";
return cdm::ColorRange::kInvalid;
}
}

cdm::ColorSpace ToCdmColorSpace(const VideoColorSpace& color_space) {
// Cast is okay because both VideoColorSpace and cdm::ColorSpace follow the
// standard ISO 23001-8:2016.
return {base::checked_cast<uint8_t>(color_space.primaries),
base::checked_cast<uint8_t>(color_space.transfer),
base::checked_cast<uint8_t>(color_space.matrix),
ToCdmColorRange(color_space.range)};
}

cdm::StreamType ToCdmStreamType(Decryptor::StreamType stream_type) {
switch (stream_type) {
case Decryptor::kAudio:
Expand Down Expand Up @@ -791,10 +816,11 @@ void CdmAdapter::InitializeVideoDecoder(const VideoDecoderConfig& config,
DCHECK(task_runner_->BelongsToCurrentThread());
DCHECK(video_init_cb_.is_null());

cdm::VideoDecoderConfig_2 cdm_decoder_config = {};
cdm::VideoDecoderConfig_3 cdm_decoder_config = {};
cdm_decoder_config.codec = ToCdmVideoCodec(config.codec());
cdm_decoder_config.profile = ToCdmVideoCodecProfile(config.profile());
cdm_decoder_config.format = ToCdmVideoFormat(config.format());
cdm_decoder_config.color_space = ToCdmColorSpace(config.color_space_info());
cdm_decoder_config.coded_size.width = config.coded_size().width();
cdm_decoder_config.coded_size.height = config.coded_size().height();
cdm_decoder_config.extra_data =
Expand Down
57 changes: 46 additions & 11 deletions media/cdm/cdm_helpers.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,32 @@
#include "media/cdm/cdm_helpers.h"

#include "base/logging.h"
#include "ui/gfx/color_space.h"

namespace media {

namespace {

// See ISO 23001-8:2016, section 7. Value 2 means "Unspecified".
constexpr cdm::ColorSpace kUnspecifiedColorSpace = {2, 2, 2,
cdm::ColorRange::kInvalid};

gfx::ColorSpace::RangeID ToGfxColorSpaceRange(cdm::ColorRange range) {
switch (range) {
case cdm::ColorRange::kLimited:
return gfx::ColorSpace::RangeID::LIMITED;
case cdm::ColorRange::kFull:
return gfx::ColorSpace::RangeID::FULL;
case cdm::ColorRange::kDerived:
return gfx::ColorSpace::RangeID::DERIVED;
default:
DVLOG(1) << "Invalid color range";
return gfx::ColorSpace::RangeID::INVALID;
}
}

} // namespace

DecryptedBlockImpl::DecryptedBlockImpl() : buffer_(nullptr), timestamp_(0) {}

DecryptedBlockImpl::~DecryptedBlockImpl() {
Expand All @@ -32,8 +55,11 @@ int64_t DecryptedBlockImpl::Timestamp() const {
}

VideoFrameImpl::VideoFrameImpl()
: format_(cdm::kUnknownVideoFormat), frame_buffer_(nullptr), timestamp_(0) {
for (uint32_t i = 0; i < kMaxPlanes; ++i) {
: format_(cdm::kUnknownVideoFormat),
color_space_(kUnspecifiedColorSpace),
frame_buffer_(nullptr),
timestamp_(0) {
for (uint32_t i = 0; i < cdm::kMaxPlanes; ++i) {
plane_offsets_[i] = 0;
strides_[i] = 0;
}
Expand Down Expand Up @@ -68,24 +94,23 @@ cdm::Buffer* VideoFrameImpl::FrameBuffer() {
return frame_buffer_;
}

void VideoFrameImpl::SetPlaneOffset(cdm::VideoFrame::VideoPlane plane,
uint32_t offset) {
DCHECK(plane < kMaxPlanes);
void VideoFrameImpl::SetPlaneOffset(cdm::VideoPlane plane, uint32_t offset) {
DCHECK(plane < cdm::kMaxPlanes);
plane_offsets_[plane] = offset;
}

uint32_t VideoFrameImpl::PlaneOffset(VideoPlane plane) {
DCHECK(plane < kMaxPlanes);
uint32_t VideoFrameImpl::PlaneOffset(cdm::VideoPlane plane) {
DCHECK(plane < cdm::kMaxPlanes);
return plane_offsets_[plane];
}

void VideoFrameImpl::SetStride(VideoPlane plane, uint32_t stride) {
DCHECK(plane < kMaxPlanes);
void VideoFrameImpl::SetStride(cdm::VideoPlane plane, uint32_t stride) {
DCHECK(plane < cdm::kMaxPlanes);
strides_[plane] = stride;
}

uint32_t VideoFrameImpl::Stride(VideoPlane plane) {
DCHECK(plane < kMaxPlanes);
uint32_t VideoFrameImpl::Stride(cdm::VideoPlane plane) {
DCHECK(plane < cdm::kMaxPlanes);
return strides_[plane];
}

Expand All @@ -97,6 +122,16 @@ int64_t VideoFrameImpl::Timestamp() const {
return timestamp_;
}

void VideoFrameImpl::SetColorSpace(cdm::ColorSpace color_space) {
color_space_ = color_space;
}

media::VideoColorSpace VideoFrameImpl::MediaColorSpace() const {
return media::VideoColorSpace(
color_space_.primary_id, color_space_.transfer_id, color_space_.matrix_id,
ToGfxColorSpaceRange(color_space_.range));
}

AudioFramesImpl::AudioFramesImpl()
: buffer_(nullptr), format_(cdm::kUnknownAudioFormat) {}

Expand Down
26 changes: 18 additions & 8 deletions media/cdm/cdm_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "media/base/media_export.h"
#include "media/base/video_color_space.h"
#include "media/cdm/api/content_decryption_module.h"
#include "ui/gfx/geometry/size.h"

Expand All @@ -36,25 +37,32 @@ class DecryptedBlockImpl : public cdm::DecryptedBlock {
DISALLOW_COPY_AND_ASSIGN(DecryptedBlockImpl);
};

class MEDIA_EXPORT VideoFrameImpl : public cdm::VideoFrame {
class MEDIA_EXPORT VideoFrameImpl : public cdm::VideoFrame,
public cdm::VideoFrame_2 {
public:
VideoFrameImpl();
~VideoFrameImpl() override;

// cdm::VideoFrame implementation.
// cdm::VideoFrame and cdm::VideoFrame_2 common implementation.
void SetFormat(cdm::VideoFormat format) final;
cdm::VideoFormat Format() const final;
void SetSize(cdm::Size size) final;
cdm::Size Size() const final;
void SetFrameBuffer(cdm::Buffer* frame_buffer) final;
cdm::Buffer* FrameBuffer() final;
void SetPlaneOffset(cdm::VideoFrame::VideoPlane plane, uint32_t offset) final;
uint32_t PlaneOffset(VideoPlane plane) final;
void SetStride(VideoPlane plane, uint32_t stride) final;
uint32_t Stride(VideoPlane plane) final;
void SetPlaneOffset(cdm::VideoPlane plane, uint32_t offset) final;
uint32_t PlaneOffset(cdm::VideoPlane plane) final;
void SetStride(cdm::VideoPlane plane, uint32_t stride) final;
uint32_t Stride(cdm::VideoPlane plane) final;
void SetTimestamp(int64_t timestamp) final;
int64_t Timestamp() const final;

// cdm::VideoFrame_2 specific implementation.
void SetColorSpace(cdm::ColorSpace color_space) final;

// Helper functions to get the ColorSpace.
media::VideoColorSpace MediaColorSpace() const;

// Create a media::VideoFrame based on the data contained in this object.
// |natural_size| is the visible portion of the video frame, and is
// provided separately as it comes from the configuration, not the CDM.
Expand All @@ -71,19 +79,21 @@ class MEDIA_EXPORT VideoFrameImpl : public cdm::VideoFrame {
// The video buffer format.
cdm::VideoFormat format_;

cdm::ColorSpace color_space_;

// Width and height of the video frame.
cdm::Size size_;

// The video frame buffer.
cdm::Buffer* frame_buffer_;

// Array of data pointers to each plane in the video frame buffer.
uint32_t plane_offsets_[kMaxPlanes];
uint32_t plane_offsets_[cdm::kMaxPlanes];

// Array of strides for each plane, typically greater or equal to the width
// of the surface divided by the horizontal sampling period. Note that
// strides can be negative.
uint32_t strides_[kMaxPlanes];
uint32_t strides_[cdm::kMaxPlanes];

// Presentation timestamp in microseconds.
int64_t timestamp_;
Expand Down
38 changes: 30 additions & 8 deletions media/cdm/cdm_wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "base/macros.h"
#include "media/base/media_switches.h"
#include "media/cdm/api/content_decryption_module.h"
#include "media/cdm/cdm_helpers.h"
#include "media/cdm/supported_cdm_versions.h"

namespace media {
Expand All @@ -39,11 +40,22 @@ cdm::AudioDecoderConfig_1 ToAudioDecoderConfig_1(
}

cdm::VideoDecoderConfig_1 ToVideoDecoderConfig_1(
const cdm::VideoDecoderConfig_2& config) {
const cdm::VideoDecoderConfig_3& config) {
return {config.codec, config.profile, config.format,
config.coded_size, config.extra_data, config.extra_data_size};
}

cdm::VideoDecoderConfig_2 ToVideoDecoderConfig_2(
const cdm::VideoDecoderConfig_3& config) {
return {config.codec,
config.profile,
config.format,
config.coded_size,
config.extra_data,
config.extra_data_size,
config.encryption_scheme};
}

cdm::InputBuffer_1 ToInputBuffer_1(const cdm::InputBuffer_2& buffer) {
return {buffer.data, buffer.data_size,
buffer.key_id, buffer.key_id_size,
Expand Down Expand Up @@ -141,12 +153,12 @@ class CdmWrapper {
virtual cdm::Status InitializeAudioDecoder(
const cdm::AudioDecoderConfig_2& audio_decoder_config) = 0;
virtual cdm::Status InitializeVideoDecoder(
const cdm::VideoDecoderConfig_2& video_decoder_config) = 0;
const cdm::VideoDecoderConfig_3& video_decoder_config) = 0;
virtual void DeinitializeDecoder(cdm::StreamType decoder_type) = 0;
virtual void ResetDecoder(cdm::StreamType decoder_type) = 0;
virtual cdm::Status DecryptAndDecodeFrame(
const cdm::InputBuffer_2& encrypted_buffer,
cdm::VideoFrame* video_frame) = 0;
media::VideoFrameImpl* video_frame) = 0;
virtual cdm::Status DecryptAndDecodeSamples(
const cdm::InputBuffer_2& encrypted_buffer,
cdm::AudioFrames* audio_frames) = 0;
Expand Down Expand Up @@ -268,7 +280,7 @@ class CdmWrapperImpl : public CdmWrapper {
}

cdm::Status InitializeVideoDecoder(
const cdm::VideoDecoderConfig_2& video_decoder_config) override {
const cdm::VideoDecoderConfig_3& video_decoder_config) override {
return cdm_->InitializeVideoDecoder(video_decoder_config);
}

Expand All @@ -280,8 +292,9 @@ class CdmWrapperImpl : public CdmWrapper {
cdm_->ResetDecoder(decoder_type);
}

cdm::Status DecryptAndDecodeFrame(const cdm::InputBuffer_2& encrypted_buffer,
cdm::VideoFrame* video_frame) override {
cdm::Status DecryptAndDecodeFrame(
const cdm::InputBuffer_2& encrypted_buffer,
media::VideoFrameImpl* video_frame) override {
return cdm_->DecryptAndDecodeFrame(encrypted_buffer, video_frame);
}

Expand Down Expand Up @@ -341,7 +354,7 @@ cdm::Status CdmWrapperImpl<9>::InitializeAudioDecoder(

template <>
cdm::Status CdmWrapperImpl<9>::InitializeVideoDecoder(
const cdm::VideoDecoderConfig_2& video_decoder_config) {
const cdm::VideoDecoderConfig_3& video_decoder_config) {
if (!IsEncryptionSchemeSupportedByLegacyCdms(
video_decoder_config.encryption_scheme))
return cdm::kInitializationError;
Expand All @@ -364,7 +377,7 @@ cdm::Status CdmWrapperImpl<9>::Decrypt(
template <>
cdm::Status CdmWrapperImpl<9>::DecryptAndDecodeFrame(
const cdm::InputBuffer_2& encrypted_buffer,
cdm::VideoFrame* video_frame) {
media::VideoFrameImpl* video_frame) {
if (!IsEncryptionSchemeSupportedByLegacyCdms(
encrypted_buffer.encryption_scheme))
return cdm::kDecryptError;
Expand All @@ -385,6 +398,15 @@ cdm::Status CdmWrapperImpl<9>::DecryptAndDecodeSamples(
audio_frames);
}

// Specialization for cdm::ContentDecryptionModule_10 methods.

template <>
cdm::Status CdmWrapperImpl<10>::InitializeVideoDecoder(
const cdm::VideoDecoderConfig_3& video_decoder_config) {
return cdm_->InitializeVideoDecoder(
ToVideoDecoderConfig_2(video_decoder_config));
}

// static
CdmWrapper* CdmWrapper::Create(CreateCdmFunc create_cdm_func,
const char* key_system,
Expand Down
2 changes: 1 addition & 1 deletion media/cdm/library_cdm/clear_key_cdm/cdm_video_decoder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ namespace media {

std::unique_ptr<CdmVideoDecoder> CreateVideoDecoder(
CdmHostProxy* cdm_host_proxy,
const cdm::VideoDecoderConfig_2& config) {
const cdm::VideoDecoderConfig_3& config) {
std::unique_ptr<CdmVideoDecoder> video_decoder;

#if defined(CLEAR_KEY_CDM_USE_LIBVPX_DECODER)
Expand Down
8 changes: 5 additions & 3 deletions media/cdm/library_cdm/clear_key_cdm/cdm_video_decoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@ class CdmHostProxy;

class CdmVideoDecoder {
public:
using CdmVideoFrame = cdm::VideoFrame_2;

virtual ~CdmVideoDecoder() {}
virtual bool Initialize(const cdm::VideoDecoderConfig_2& config) = 0;
virtual bool Initialize(const cdm::VideoDecoderConfig_3& config) = 0;
virtual void Deinitialize() = 0;
virtual void Reset() = 0;
virtual bool is_initialized() const = 0;
Expand All @@ -33,15 +35,15 @@ class CdmVideoDecoder {
virtual cdm::Status DecodeFrame(const uint8_t* compressed_frame,
int32_t compressed_frame_size,
int64_t timestamp,
cdm::VideoFrame* decoded_frame) = 0;
CdmVideoFrame* decoded_frame) = 0;
};

// Initializes the appropriate video decoder based on build flags and the value
// of |config.codec|. Returns a scoped_ptr containing a non-null initialized
// CdmVideoDecoder pointer upon success.
std::unique_ptr<CdmVideoDecoder> CreateVideoDecoder(
CdmHostProxy* cdm_host_proxy,
const cdm::VideoDecoderConfig_2& config);
const cdm::VideoDecoderConfig_3& config);

} // namespace media

Expand Down
Loading

0 comments on commit 106f5d9

Please sign in to comment.