Bug 1944456 - Update Chromium CDM headers to revision 06395a2863cb1ebdb47617a995b73f95c14fe120. r=media-playback-reviewers,frontend-codestyle-reviewers,padenot

Differential Revision: https://phabricator.services.mozilla.com/D235875
This commit is contained in:
Andrew Osmond
2025-01-29 15:53:48 +00:00
parent 627989de17
commit 71fe8eb9b8
11 changed files with 464 additions and 197 deletions

View File

@@ -82,7 +82,6 @@ dom/media/gmp/rlz/.*
dom/media/gmp/widevine-adapter/content_decryption_module.h dom/media/gmp/widevine-adapter/content_decryption_module.h
dom/media/gmp/widevine-adapter/content_decryption_module_export.h dom/media/gmp/widevine-adapter/content_decryption_module_export.h
dom/media/gmp/widevine-adapter/content_decryption_module_ext.h dom/media/gmp/widevine-adapter/content_decryption_module_ext.h
dom/media/gmp/widevine-adapter/content_decryption_module_proxy.h
dom/media/platforms/ffmpeg/ffmpeg57/.* dom/media/platforms/ffmpeg/ffmpeg57/.*
dom/media/platforms/ffmpeg/ffmpeg58/.* dom/media/platforms/ffmpeg/ffmpeg58/.*
dom/media/platforms/ffmpeg/ffmpeg59/.* dom/media/platforms/ffmpeg/ffmpeg59/.*

View File

@@ -1273,7 +1273,6 @@ dom/media/gmp/rlz/
dom/media/gmp/widevine-adapter/content_decryption_module_export.h dom/media/gmp/widevine-adapter/content_decryption_module_export.h
dom/media/gmp/widevine-adapter/content_decryption_module_ext.h dom/media/gmp/widevine-adapter/content_decryption_module_ext.h
dom/media/gmp/widevine-adapter/content_decryption_module.h dom/media/gmp/widevine-adapter/content_decryption_module.h
dom/media/gmp/widevine-adapter/content_decryption_module_proxy.h
dom/media/platforms/ffmpeg/ffmpeg57/ dom/media/platforms/ffmpeg/ffmpeg57/
dom/media/platforms/ffmpeg/ffmpeg58/ dom/media/platforms/ffmpeg/ffmpeg58/
dom/media/platforms/ffmpeg/ffmpeg59/ dom/media/platforms/ffmpeg/ffmpeg59/

View File

@@ -783,12 +783,12 @@ void ChromiumCDMChild::ReturnOutput(WidevineVideoFrame& aFrame) {
output.mFormat() = static_cast<cdm::VideoFormat>(aFrame.Format()); output.mFormat() = static_cast<cdm::VideoFormat>(aFrame.Format());
output.mImageWidth() = aFrame.Size().width; output.mImageWidth() = aFrame.Size().width;
output.mImageHeight() = aFrame.Size().height; output.mImageHeight() = aFrame.Size().height;
output.mYPlane() = {aFrame.PlaneOffset(cdm::VideoPlane::kYPlane), output.mYPlane() = {aFrame.PlaneOffset(cdm::kYPlane),
aFrame.Stride(cdm::VideoPlane::kYPlane)}; aFrame.Stride(cdm::kYPlane)};
output.mUPlane() = {aFrame.PlaneOffset(cdm::VideoPlane::kUPlane), output.mUPlane() = {aFrame.PlaneOffset(cdm::kUPlane),
aFrame.Stride(cdm::VideoPlane::kUPlane)}; aFrame.Stride(cdm::kUPlane)};
output.mVPlane() = {aFrame.PlaneOffset(cdm::VideoPlane::kVPlane), output.mVPlane() = {aFrame.PlaneOffset(cdm::kVPlane),
aFrame.Stride(cdm::VideoPlane::kVPlane)}; aFrame.Stride(cdm::kVPlane)};
output.mTimestamp() = aFrame.Timestamp(); output.mTimestamp() = aFrame.Timestamp();
uint64_t duration = 0; uint64_t duration = 0;

View File

@@ -62,10 +62,6 @@ EXPORTS += [
"GMPVideoHost.h", "GMPVideoHost.h",
"GMPVideoi420FrameImpl.h", "GMPVideoi420FrameImpl.h",
"GMPVideoPlaneImpl.h", "GMPVideoPlaneImpl.h",
"widevine-adapter/content_decryption_module.h",
"widevine-adapter/content_decryption_module_export.h",
"widevine-adapter/content_decryption_module_ext.h",
"widevine-adapter/content_decryption_module_proxy.h",
] ]
UNIFIED_SOURCES += [ UNIFIED_SOURCES += [

View File

@@ -127,14 +127,14 @@ bool WidevineVideoFrame::InitToBlack(int32_t aWidth, int32_t aHeight,
SetFormat(cdm::VideoFormat::kI420); SetFormat(cdm::VideoFormat::kI420);
SetSize(cdm::Size{aWidth, aHeight}); SetSize(cdm::Size{aWidth, aHeight});
SetFrameBuffer(buffer); SetFrameBuffer(buffer);
SetPlaneOffset(cdm::VideoPlane::kYPlane, 0); SetPlaneOffset(cdm::kYPlane, 0);
SetStride(cdm::VideoPlane::kYPlane, aWidth); SetStride(cdm::kYPlane, aWidth);
// Note: U and V planes are stored at the same place in order to // Note: U and V planes are stored at the same place in order to
// save memory since their contents are the same. // save memory since their contents are the same.
SetPlaneOffset(cdm::VideoPlane::kUPlane, ySize); SetPlaneOffset(cdm::kUPlane, ySize);
SetStride(cdm::VideoPlane::kUPlane, halfWidth); SetStride(cdm::kUPlane, halfWidth);
SetPlaneOffset(cdm::VideoPlane::kVPlane, ySize); SetPlaneOffset(cdm::kVPlane, ySize);
SetStride(cdm::VideoPlane::kVPlane, halfWidth); SetStride(cdm::kVPlane, halfWidth);
SetTimestamp(aTimeStamp); SetTimestamp(aTimeStamp);
return true; return true;
} }

View File

@@ -44,8 +44,8 @@ class WidevineVideoFrame : public cdm::VideoFrame {
cdm::VideoFormat mFormat; cdm::VideoFormat mFormat;
cdm::Size mSize; cdm::Size mSize;
cdm::Buffer* mBuffer; cdm::Buffer* mBuffer;
uint32_t mPlaneOffsets[cdm::VideoPlane::kMaxPlanes]; uint32_t mPlaneOffsets[cdm::kMaxPlanes];
uint32_t mPlaneStrides[cdm::VideoPlane::kMaxPlanes]; uint32_t mPlaneStrides[cdm::kMaxPlanes];
int64_t mTimestamp; int64_t mTimestamp;
}; };

View File

@@ -8,7 +8,6 @@
#include <type_traits> #include <type_traits>
#include "content_decryption_module_export.h" #include "content_decryption_module_export.h"
#include "content_decryption_module_proxy.h"
#if defined(_MSC_VER) #if defined(_MSC_VER)
typedef unsigned char uint8_t; typedef unsigned char uint8_t;
@@ -16,7 +15,7 @@ typedef unsigned int uint32_t;
typedef int int32_t; typedef int int32_t;
typedef __int64 int64_t; typedef __int64 int64_t;
#else #else
# include <stdint.h> #include <stdint.h>
#endif #endif
#include "mozilla/DefineEnum.h" #include "mozilla/DefineEnum.h"
@@ -413,6 +412,7 @@ CHECK_TYPE(InitDataType, 4, 4);
enum SessionType : uint32_t { enum SessionType : uint32_t {
kTemporary = 0, kTemporary = 0,
kPersistentLicense = 1, kPersistentLicense = 1,
kPersistentUsageRecord = 2
}; };
CHECK_TYPE(SessionType, 4, 4); CHECK_TYPE(SessionType, 4, 4);
@@ -481,12 +481,13 @@ class CDM_CLASS_API DecryptedBlock {
virtual ~DecryptedBlock() {} virtual ~DecryptedBlock() {}
}; };
enum VideoPlane : uint32_t { // This intentionally avoids using an enum, since it will be used to do math
kYPlane = 0, // with other enums, which is deprecated in C++20.
kUPlane = 1, using VideoPlane = uint32_t;
kVPlane = 2, constexpr VideoPlane kYPlane = 0;
kMaxPlanes = 3, constexpr VideoPlane kUPlane = 1;
}; constexpr VideoPlane kVPlane = 2;
constexpr VideoPlane kMaxPlanes = 3;
CHECK_TYPE(VideoPlane, 4, 4); CHECK_TYPE(VideoPlane, 4, 4);
class CDM_CLASS_API VideoFrame { class CDM_CLASS_API VideoFrame {
@@ -624,7 +625,8 @@ class CDM_CLASS_API FileIOClient {
// - kInUse indicates that there are other read/write operations pending. // - kInUse indicates that there are other read/write operations pending.
// - kError indicates read failure, e.g. the storage is not open or cannot be // - kError indicates read failure, e.g. the storage is not open or cannot be
// fully read. // fully read.
virtual void OnReadComplete(Status status, const uint8_t* data, virtual void OnReadComplete(Status status,
const uint8_t* data,
uint32_t data_size) = 0; uint32_t data_size) = 0;
// Response to a FileIO::Write() call. // Response to a FileIO::Write() call.
@@ -641,8 +643,21 @@ class CDM_CLASS_API FileIOClient {
virtual ~FileIOClient() {} virtual ~FileIOClient() {}
}; };
// Metrics that will be reported from the CDM through the ReportMetrics()
// function. To add a new metric, please add it to the end of this enum list
// without changing any existing enum values.
// Note: For forward compatibility, Host implementations must gracefully handle
// unexpected (new) enum values, e.g. no-op.
enum MetricName : uint32_t {
kSdkVersion,
kCertificateSerialNumber,
kDecoderBypassBlockCount,
};
CHECK_TYPE(MetricName, 4, 4);
class CDM_CLASS_API Host_10; class CDM_CLASS_API Host_10;
class CDM_CLASS_API Host_11; class CDM_CLASS_API Host_11;
class CDM_CLASS_API Host_12;
// ContentDecryptionModule interface that all CDMs need to implement. // ContentDecryptionModule interface that all CDMs need to implement.
// The interface is versioned for backward compatibility. // The interface is versioned for backward compatibility.
@@ -710,28 +725,33 @@ class CDM_CLASS_API ContentDecryptionModule_10 {
// The CDM must respond by calling either Host::OnResolveNewSessionPromise() // The CDM must respond by calling either Host::OnResolveNewSessionPromise()
// or Host::OnRejectPromise(). If the session is not found, call // or Host::OnRejectPromise(). If the session is not found, call
// Host::OnResolveNewSessionPromise() with session_id = NULL. // Host::OnResolveNewSessionPromise() with session_id = NULL.
virtual void LoadSession(uint32_t promise_id, SessionType session_type, virtual void LoadSession(uint32_t promise_id,
SessionType session_type,
const char* session_id, const char* session_id,
uint32_t session_id_size) = 0; uint32_t session_id_size) = 0;
// Updates the session with |response|. The CDM must respond by calling // Updates the session with |response|. The CDM must respond by calling
// either Host::OnResolvePromise() or Host::OnRejectPromise(). // either Host::OnResolvePromise() or Host::OnRejectPromise().
virtual void UpdateSession(uint32_t promise_id, const char* session_id, virtual void UpdateSession(uint32_t promise_id,
uint32_t session_id_size, const uint8_t* response, const char* session_id,
uint32_t session_id_size,
const uint8_t* response,
uint32_t response_size) = 0; uint32_t response_size) = 0;
// Requests that the CDM close the session. The CDM must respond by calling // Requests that the CDM close the session. The CDM must respond by calling
// either Host::OnResolvePromise() or Host::OnRejectPromise() when the request // either Host::OnResolvePromise() or Host::OnRejectPromise() when the request
// has been processed. This may be before the session is closed. Once the // has been processed. This may be before the session is closed. Once the
// session is closed, Host::OnSessionClosed() must also be called. // session is closed, Host::OnSessionClosed() must also be called.
virtual void CloseSession(uint32_t promise_id, const char* session_id, virtual void CloseSession(uint32_t promise_id,
const char* session_id,
uint32_t session_id_size) = 0; uint32_t session_id_size) = 0;
// Removes any stored session data associated with this session. Will only be // Removes any stored session data associated with this session. Will only be
// called for persistent sessions. The CDM must respond by calling either // called for persistent sessions. The CDM must respond by calling either
// Host::OnResolvePromise() or Host::OnRejectPromise() when the request has // Host::OnResolvePromise() or Host::OnRejectPromise() when the request has
// been processed. // been processed.
virtual void RemoveSession(uint32_t promise_id, const char* session_id, virtual void RemoveSession(uint32_t promise_id,
const char* session_id,
uint32_t session_id_size) = 0; uint32_t session_id_size) = 0;
// Performs scheduled operation with |context| when the timer fires. // Performs scheduled operation with |context| when the timer fires.
@@ -835,7 +855,8 @@ class CDM_CLASS_API ContentDecryptionModule_10 {
// then |link_mask| and |output_protection_mask| are undefined and should // then |link_mask| and |output_protection_mask| are undefined and should
// be ignored. // be ignored.
virtual void OnQueryOutputProtectionStatus( virtual void OnQueryOutputProtectionStatus(
QueryResult result, uint32_t link_mask, QueryResult result,
uint32_t link_mask,
uint32_t output_protection_mask) = 0; uint32_t output_protection_mask) = 0;
// Called by the host after a call to Host::RequestStorageId(). If the // Called by the host after a call to Host::RequestStorageId(). If the
@@ -846,7 +867,8 @@ class CDM_CLASS_API ContentDecryptionModule_10 {
// If the requested version is not available, null/zero will be provided as // If the requested version is not available, null/zero will be provided as
// |storage_id| and |storage_id_size|, respectively, and |version| should be // |storage_id| and |storage_id_size|, respectively, and |version| should be
// ignored. // ignored.
virtual void OnStorageId(uint32_t version, const uint8_t* storage_id, virtual void OnStorageId(uint32_t version,
const uint8_t* storage_id,
uint32_t storage_id_size) = 0; uint32_t storage_id_size) = 0;
// Destroys the object in the same context as it was created. // Destroys the object in the same context as it was created.
@@ -857,8 +879,6 @@ class CDM_CLASS_API ContentDecryptionModule_10 {
virtual ~ContentDecryptionModule_10() {} virtual ~ContentDecryptionModule_10() {}
}; };
// ----- Note: CDM interface(s) below still in development and not stable! -----
// ContentDecryptionModule interface that all CDMs need to implement. // ContentDecryptionModule interface that all CDMs need to implement.
// The interface is versioned for backward compatibility. // The interface is versioned for backward compatibility.
// Note: ContentDecryptionModule implementations must use the allocator // Note: ContentDecryptionModule implementations must use the allocator
@@ -868,7 +888,7 @@ class CDM_CLASS_API ContentDecryptionModule_10 {
class CDM_CLASS_API ContentDecryptionModule_11 { class CDM_CLASS_API ContentDecryptionModule_11 {
public: public:
static const int kVersion = 11; static const int kVersion = 11;
static const bool kIsStable = false; static const bool kIsStable = true;
typedef Host_11 Host; typedef Host_11 Host;
// Initializes the CDM instance, providing information about permitted // Initializes the CDM instance, providing information about permitted
@@ -925,21 +945,247 @@ class CDM_CLASS_API ContentDecryptionModule_11 {
// The CDM must respond by calling either Host::OnResolveNewSessionPromise() // The CDM must respond by calling either Host::OnResolveNewSessionPromise()
// or Host::OnRejectPromise(). If the session is not found, call // or Host::OnRejectPromise(). If the session is not found, call
// Host::OnResolveNewSessionPromise() with session_id = NULL. // Host::OnResolveNewSessionPromise() with session_id = NULL.
virtual void LoadSession(uint32_t promise_id, SessionType session_type, virtual void LoadSession(uint32_t promise_id,
SessionType session_type,
const char* session_id, const char* session_id,
uint32_t session_id_size) = 0; uint32_t session_id_size) = 0;
// Updates the session with |response|. The CDM must respond by calling // Updates the session with |response|. The CDM must respond by calling
// either Host::OnResolvePromise() or Host::OnRejectPromise(). // either Host::OnResolvePromise() or Host::OnRejectPromise().
virtual void UpdateSession(uint32_t promise_id, const char* session_id, virtual void UpdateSession(uint32_t promise_id,
uint32_t session_id_size, const uint8_t* response, const char* session_id,
uint32_t session_id_size,
const uint8_t* response,
uint32_t response_size) = 0; uint32_t response_size) = 0;
// Requests that the CDM close the session. The CDM must respond by calling // Requests that the CDM close the session. The CDM must respond by calling
// either Host::OnResolvePromise() or Host::OnRejectPromise() when the request // either Host::OnResolvePromise() or Host::OnRejectPromise() when the request
// has been processed. This may be before the session is closed. Once the // has been processed. This may be before the session is closed. Once the
// session is closed, Host::OnSessionClosed() must also be called. // session is closed, Host::OnSessionClosed() must also be called.
virtual void CloseSession(uint32_t promise_id, const char* session_id, virtual void CloseSession(uint32_t promise_id,
const char* session_id,
uint32_t session_id_size) = 0;
// Removes any stored session data associated with this session. Will only be
// called for persistent sessions. The CDM must respond by calling either
// Host::OnResolvePromise() or Host::OnRejectPromise() when the request has
// been processed.
virtual void RemoveSession(uint32_t promise_id,
const char* session_id,
uint32_t session_id_size) = 0;
// Performs scheduled operation with |context| when the timer fires.
virtual void TimerExpired(void* context) = 0;
// Decrypts the |encrypted_buffer|.
//
// Returns kSuccess if decryption succeeded, in which case the callee
// should have filled the |decrypted_buffer| and passed the ownership of
// |data| in |decrypted_buffer| to the caller.
// Returns kNoKey if the CDM did not have the necessary decryption key
// to decrypt.
// Returns kDecryptError if any other error happened.
// If the return value is not kSuccess, |decrypted_buffer| should be ignored
// by the caller.
virtual Status Decrypt(const InputBuffer_2& encrypted_buffer,
DecryptedBlock* decrypted_buffer) = 0;
// Initializes the CDM audio decoder with |audio_decoder_config|. This
// function must be called before DecryptAndDecodeSamples() is called.
//
// Returns kSuccess if the |audio_decoder_config| is supported and the CDM
// audio decoder is successfully initialized.
// Returns kInitializationError if |audio_decoder_config| is not supported.
// The CDM may still be able to do Decrypt().
// Returns kDeferredInitialization if the CDM is not ready to initialize the
// decoder at this time. Must call Host::OnDeferredInitializationDone() once
// initialization is complete.
virtual Status InitializeAudioDecoder(
const AudioDecoderConfig_2& audio_decoder_config) = 0;
// Initializes the CDM video decoder with |video_decoder_config|. This
// function must be called before DecryptAndDecodeFrame() is called.
//
// Returns kSuccess if the |video_decoder_config| is supported and the CDM
// video decoder is successfully initialized.
// Returns kInitializationError if |video_decoder_config| is not supported.
// The CDM may still be able to do Decrypt().
// Returns kDeferredInitialization if the CDM is not ready to initialize the
// decoder at this time. Must call Host::OnDeferredInitializationDone() once
// initialization is complete.
virtual Status InitializeVideoDecoder(
const VideoDecoderConfig_2& video_decoder_config) = 0;
// De-initializes the CDM decoder and sets it to an uninitialized state. The
// caller can initialize the decoder again after this call to re-initialize
// it. This can be used to reconfigure the decoder if the configuration
// changes.
virtual void DeinitializeDecoder(StreamType decoder_type) = 0;
// Resets the CDM decoder to an initialized clean state. All internal buffers
// MUST be flushed.
virtual void ResetDecoder(StreamType decoder_type) = 0;
// Decrypts the |encrypted_buffer| and decodes the decrypted buffer into a
// |video_frame|. Upon end-of-stream, the caller should call this function
// repeatedly with empty |encrypted_buffer| (|data| == NULL) until
// kNeedMoreData is returned.
//
// Returns kSuccess if decryption and decoding both succeeded, in which case
// the callee will have filled the |video_frame| and passed the ownership of
// |frame_buffer| in |video_frame| to the caller.
// Returns kNoKey if the CDM did not have the necessary decryption key
// to decrypt.
// Returns kNeedMoreData if more data was needed by the decoder to generate
// a decoded frame (e.g. during initialization and end-of-stream).
// Returns kDecryptError if any decryption error happened.
// Returns kDecodeError if any decoding error happened.
// If the return value is not kSuccess, |video_frame| should be ignored by
// the caller.
virtual Status DecryptAndDecodeFrame(const InputBuffer_2& encrypted_buffer,
VideoFrame* video_frame) = 0;
// Decrypts the |encrypted_buffer| and decodes the decrypted buffer into
// |audio_frames|. Upon end-of-stream, the caller should call this function
// repeatedly with empty |encrypted_buffer| (|data| == NULL) until only empty
// |audio_frames| is produced.
//
// Returns kSuccess if decryption and decoding both succeeded, in which case
// the callee will have filled |audio_frames| and passed the ownership of
// |data| in |audio_frames| to the caller.
// Returns kNoKey if the CDM did not have the necessary decryption key
// to decrypt.
// Returns kNeedMoreData if more data was needed by the decoder to generate
// audio samples (e.g. during initialization and end-of-stream).
// Returns kDecryptError if any decryption error happened.
// Returns kDecodeError if any decoding error happened.
// If the return value is not kSuccess, |audio_frames| should be ignored by
// the caller.
virtual Status DecryptAndDecodeSamples(const InputBuffer_2& encrypted_buffer,
AudioFrames* audio_frames) = 0;
// Called by the host after a platform challenge was initiated via
// Host::SendPlatformChallenge().
virtual void OnPlatformChallengeResponse(
const PlatformChallengeResponse& response) = 0;
// Called by the host after a call to Host::QueryOutputProtectionStatus(). The
// |link_mask| is a bit mask of OutputLinkTypes and |output_protection_mask|
// is a bit mask of OutputProtectionMethods. If |result| is kQueryFailed,
// then |link_mask| and |output_protection_mask| are undefined and should
// be ignored.
virtual void OnQueryOutputProtectionStatus(
QueryResult result,
uint32_t link_mask,
uint32_t output_protection_mask) = 0;
// Called by the host after a call to Host::RequestStorageId(). If the
// version of the storage ID requested is available, |storage_id| and
// |storage_id_size| are set appropriately. |version| will be the same as
// what was requested, unless 0 (latest) was requested, in which case
// |version| will be the actual version number for the |storage_id| returned.
// If the requested version is not available, null/zero will be provided as
// |storage_id| and |storage_id_size|, respectively, and |version| should be
// ignored.
virtual void OnStorageId(uint32_t version,
const uint8_t* storage_id,
uint32_t storage_id_size) = 0;
// Destroys the object in the same context as it was created.
virtual void Destroy() = 0;
protected:
ContentDecryptionModule_11() {}
virtual ~ContentDecryptionModule_11() {}
};
// ----- Note: CDM interface(s) below still in development and not stable! -----
// ContentDecryptionModule interface that all CDMs need to implement.
// The interface is versioned for backward compatibility.
// Note: ContentDecryptionModule implementations must use the allocator
// provided in CreateCdmInstance() to allocate any Buffer that needs to
// be passed back to the caller. Implementations must call Buffer::Destroy()
// when a Buffer is created that will never be returned to the caller.
class CDM_CLASS_API ContentDecryptionModule_12 {
public:
static const int kVersion = 12;
static const bool kIsStable = false;
typedef Host_12 Host;
// Initializes the CDM instance, providing information about permitted
// functionalities. The CDM must respond by calling Host::OnInitialized()
// with whether the initialization succeeded. No other calls will be made by
// the host before Host::OnInitialized() returns.
// If |allow_distinctive_identifier| is false, messages from the CDM,
// such as message events, must not contain a Distinctive Identifier,
// even in an encrypted form.
// If |allow_persistent_state| is false, the CDM must not attempt to
// persist state. Calls to CreateFileIO() will fail.
// If |use_hw_secure_codecs| is true, the CDM must ensure the decryption key
// and video buffers (compressed and uncompressed) are securely protected by
// hardware.
virtual void Initialize(bool allow_distinctive_identifier,
bool allow_persistent_state,
bool use_hw_secure_codecs) = 0;
// Gets the key status if the CDM has a hypothetical key with the |policy|.
// The CDM must respond by calling either Host::OnResolveKeyStatusPromise()
// with the result key status or Host::OnRejectPromise() if an unexpected
// error happened or this method is not supported.
virtual void GetStatusForPolicy(uint32_t promise_id,
const Policy& policy) = 0;
// SetServerCertificate(), CreateSessionAndGenerateRequest(), LoadSession(),
// UpdateSession(), CloseSession(), and RemoveSession() all accept a
// |promise_id|, which must be passed to the completion Host method
// (e.g. Host::OnResolveNewSessionPromise()).
// Provides a server certificate to be used to encrypt messages to the
// license server. The CDM must respond by calling either
// Host::OnResolvePromise() or Host::OnRejectPromise().
// If the CDM does not support server certificates, the promise should be
// rejected with kExceptionNotSupportedError. If |server_certificate_data|
// is empty, reject with kExceptionTypeError. Any other error should be
// rejected with kExceptionInvalidStateError or kExceptionQuotaExceededError.
// TODO(crbug.com/796417): Add support for the promise to return true or
// false, rather than using kExceptionNotSupportedError to mean false.
virtual void SetServerCertificate(uint32_t promise_id,
const uint8_t* server_certificate_data,
uint32_t server_certificate_data_size) = 0;
// Creates a session given |session_type|, |init_data_type|, and |init_data|.
// The CDM must respond by calling either Host::OnResolveNewSessionPromise()
// or Host::OnRejectPromise().
virtual void CreateSessionAndGenerateRequest(uint32_t promise_id,
SessionType session_type,
InitDataType init_data_type,
const uint8_t* init_data,
uint32_t init_data_size) = 0;
// Loads the session of type |session_type| specified by |session_id|.
// The CDM must respond by calling either Host::OnResolveNewSessionPromise()
// or Host::OnRejectPromise(). If the session is not found, call
// Host::OnResolveNewSessionPromise() with session_id = NULL.
virtual void LoadSession(uint32_t promise_id,
SessionType session_type,
const char* session_id,
uint32_t session_id_size) = 0;
// Updates the session with |response|. The CDM must respond by calling
// either Host::OnResolvePromise() or Host::OnRejectPromise().
virtual void UpdateSession(uint32_t promise_id,
const char* session_id,
uint32_t session_id_size,
const uint8_t* response,
uint32_t response_size) = 0;
// Requests that the CDM close the session. The CDM must respond by calling
// either Host::OnResolvePromise() or Host::OnRejectPromise() when the request
// has been processed. This may be before the session is closed. Once the
// session is closed, Host::OnSessionClosed() must also be called.
virtual void CloseSession(uint32_t promise_id,
const char* session_id,
uint32_t session_id_size) = 0; uint32_t session_id_size) = 0;
// Removes any stored session data associated with this session. Removes all // Removes any stored session data associated with this session. Removes all
@@ -950,7 +1196,8 @@ class CDM_CLASS_API ContentDecryptionModule_11 {
// processed by UpdateSession(). The CDM must respond by calling either // processed by UpdateSession(). The CDM must respond by calling either
// Host::OnResolvePromise() or Host::OnRejectPromise() when the request has // Host::OnResolvePromise() or Host::OnRejectPromise() when the request has
// been processed. // been processed.
virtual void RemoveSession(uint32_t promise_id, const char* session_id, virtual void RemoveSession(uint32_t promise_id,
const char* session_id,
uint32_t session_id_size) = 0; uint32_t session_id_size) = 0;
// Performs scheduled operation with |context| when the timer fires. // Performs scheduled operation with |context| when the timer fires.
@@ -1054,7 +1301,8 @@ class CDM_CLASS_API ContentDecryptionModule_11 {
// then |link_mask| and |output_protection_mask| are undefined and should // then |link_mask| and |output_protection_mask| are undefined and should
// be ignored. // be ignored.
virtual void OnQueryOutputProtectionStatus( virtual void OnQueryOutputProtectionStatus(
QueryResult result, uint32_t link_mask, QueryResult result,
uint32_t link_mask,
uint32_t output_protection_mask) = 0; uint32_t output_protection_mask) = 0;
// Called by the host after a call to Host::RequestStorageId(). If the // Called by the host after a call to Host::RequestStorageId(). If the
@@ -1065,15 +1313,16 @@ class CDM_CLASS_API ContentDecryptionModule_11 {
// If the requested version is not available, null/zero will be provided as // If the requested version is not available, null/zero will be provided as
// |storage_id| and |storage_id_size|, respectively, and |version| should be // |storage_id| and |storage_id_size|, respectively, and |version| should be
// ignored. // ignored.
virtual void OnStorageId(uint32_t version, const uint8_t* storage_id, virtual void OnStorageId(uint32_t version,
const uint8_t* storage_id,
uint32_t storage_id_size) = 0; uint32_t storage_id_size) = 0;
// Destroys the object in the same context as it was created. // Destroys the object in the same context as it was created.
virtual void Destroy() = 0; virtual void Destroy() = 0;
protected: protected:
ContentDecryptionModule_11() {} ContentDecryptionModule_12() {}
virtual ~ContentDecryptionModule_11() {} virtual ~ContentDecryptionModule_12() {}
}; };
class CDM_CLASS_API Host_10 { class CDM_CLASS_API Host_10 {
@@ -1120,15 +1369,18 @@ class CDM_CLASS_API Host_10 {
// ContentDecryptionModule calls that accept a |promise_id|. // ContentDecryptionModule calls that accept a |promise_id|.
// |exception| must be specified. |error_message| and |system_code| // |exception| must be specified. |error_message| and |system_code|
// are optional. |error_message_size| should not include null termination. // are optional. |error_message_size| should not include null termination.
virtual void OnRejectPromise(uint32_t promise_id, Exception exception, virtual void OnRejectPromise(uint32_t promise_id,
uint32_t system_code, const char* error_message, Exception exception,
uint32_t system_code,
const char* error_message,
uint32_t error_message_size) = 0; uint32_t error_message_size) = 0;
// Called by the CDM when it has a message for session |session_id|. // Called by the CDM when it has a message for session |session_id|.
// Size parameters should not include null termination. // Size parameters should not include null termination.
virtual void OnSessionMessage(const char* session_id, virtual void OnSessionMessage(const char* session_id,
uint32_t session_id_size, uint32_t session_id_size,
MessageType message_type, const char* message, MessageType message_type,
const char* message,
uint32_t message_size) = 0; uint32_t message_size) = 0;
// Called by the CDM when there has been a change in keys or their status for // Called by the CDM when there has been a change in keys or their status for
@@ -1253,15 +1505,18 @@ class CDM_CLASS_API Host_11 {
// ContentDecryptionModule calls that accept a |promise_id|. // ContentDecryptionModule calls that accept a |promise_id|.
// |exception| must be specified. |error_message| and |system_code| // |exception| must be specified. |error_message| and |system_code|
// are optional. |error_message_size| should not include null termination. // are optional. |error_message_size| should not include null termination.
virtual void OnRejectPromise(uint32_t promise_id, Exception exception, virtual void OnRejectPromise(uint32_t promise_id,
uint32_t system_code, const char* error_message, Exception exception,
uint32_t system_code,
const char* error_message,
uint32_t error_message_size) = 0; uint32_t error_message_size) = 0;
// Called by the CDM when it has a message for session |session_id|. // Called by the CDM when it has a message for session |session_id|.
// Size parameters should not include null termination. // Size parameters should not include null termination.
virtual void OnSessionMessage(const char* session_id, virtual void OnSessionMessage(const char* session_id,
uint32_t session_id_size, uint32_t session_id_size,
MessageType message_type, const char* message, MessageType message_type,
const char* message,
uint32_t message_size) = 0; uint32_t message_size) = 0;
// Called by the CDM when there has been a change in keys or their status for // Called by the CDM when there has been a change in keys or their status for
@@ -1328,18 +1583,146 @@ class CDM_CLASS_API Host_11 {
// CDM can call this method multiple times to operate on different files. // CDM can call this method multiple times to operate on different files.
virtual FileIO* CreateFileIO(FileIOClient* client) = 0; virtual FileIO* CreateFileIO(FileIOClient* client) = 0;
// Requests a CdmProxy that proxies part of CDM functionalities to a different // Requests a specific version of the storage ID. A storage ID is a stable,
// entity, e.g. a hardware CDM module. A CDM instance can have at most one // device specific ID used by the CDM to securely store persistent data. The
// CdmProxy throughout its lifetime, which must be requested and initialized // ID will be returned by the host via ContentDecryptionModule::OnStorageId().
// during CDM instance initialization time, i.e. in or after CDM::Initialize() // If |version| is 0, the latest version will be returned. All |version|s
// and before OnInitialized() is called, to ensure proper connection of the // that are greater than or equal to 0x80000000 are reserved for the CDM and
// CdmProxy and the media player (e.g. hardware decoder). The CdmProxy is // should not be supported or returned by the host. The CDM must not expose
// owned by the host and is guaranteed to be valid throughout the CDM // the ID outside the client device, even in encrypted form.
// instance's lifetime. The CDM must ensure that the |client| remain valid virtual void RequestStorageId(uint32_t version) = 0;
// before the CDM instance is destroyed. Returns null if CdmProxy is not
// supported, called before CDM::Initialize(), RequestCdmProxy() is called // Reports the metric |metric_name| with value |value| to the host. Can be
// more than once, or called after the CDM instance has been initialized. // called by the CDM at any time. May report the same metric multiple times
virtual CdmProxy* RequestCdmProxy(CdmProxyClient* client) = 0; // during the lifetime of the CDM.
virtual void ReportMetrics(MetricName metric_name, uint64_t value) = 0;
protected:
Host_11() {}
virtual ~Host_11() {}
};
class CDM_CLASS_API Host_12 {
public:
static const int kVersion = 12;
// Returns a Buffer* containing non-zero members upon success, or NULL on
// failure. The caller owns the Buffer* after this call. The buffer is not
// guaranteed to be zero initialized. The capacity of the allocated Buffer
// is guaranteed to be not less than |capacity|.
virtual Buffer* Allocate(uint32_t capacity) = 0;
// Requests the host to call ContentDecryptionModule::TimerFired() |delay_ms|
// from now with |context|.
virtual void SetTimer(int64_t delay_ms, void* context) = 0;
// Returns the current wall time.
virtual Time GetCurrentWallTime() = 0;
// Called by the CDM with the result after the CDM instance was initialized.
virtual void OnInitialized(bool success) = 0;
// Called by the CDM when a key status is available in response to
// GetStatusForPolicy().
virtual void OnResolveKeyStatusPromise(uint32_t promise_id,
KeyStatus key_status) = 0;
// Called by the CDM when a session is created or loaded and the value for the
// MediaKeySession's sessionId attribute is available (|session_id|).
// This must be called before OnSessionMessage() or
// OnSessionKeysChange() is called for the same session. |session_id_size|
// should not include null termination.
// When called in response to LoadSession(), the |session_id| must be the
// same as the |session_id| passed in LoadSession(), or NULL if the
// session could not be loaded.
virtual void OnResolveNewSessionPromise(uint32_t promise_id,
const char* session_id,
uint32_t session_id_size) = 0;
// Called by the CDM when a session is updated or released.
virtual void OnResolvePromise(uint32_t promise_id) = 0;
// Called by the CDM when an error occurs as a result of one of the
// ContentDecryptionModule calls that accept a |promise_id|.
// |exception| must be specified. |error_message| and |system_code|
// are optional. |error_message_size| should not include null termination.
virtual void OnRejectPromise(uint32_t promise_id,
Exception exception,
uint32_t system_code,
const char* error_message,
uint32_t error_message_size) = 0;
// Called by the CDM when it has a message for session |session_id|.
// Size parameters should not include null termination.
virtual void OnSessionMessage(const char* session_id,
uint32_t session_id_size,
MessageType message_type,
const char* message,
uint32_t message_size) = 0;
// Called by the CDM when there has been a change in keys or their status for
// session |session_id|. |has_additional_usable_key| should be set if a
// key is newly usable (e.g. new key available, previously expired key has
// been renewed, etc.) and the browser should attempt to resume playback.
// |keys_info| is the list of key IDs for this session along with their
// current status. |keys_info_count| is the number of entries in |keys_info|.
// Size parameter for |session_id| should not include null termination.
virtual void OnSessionKeysChange(const char* session_id,
uint32_t session_id_size,
bool has_additional_usable_key,
const KeyInformation* keys_info,
uint32_t keys_info_count) = 0;
// Called by the CDM when there has been a change in the expiration time for
// session |session_id|. This can happen as the result of an Update() call
// or some other event. If this happens as a result of a call to Update(),
// it must be called before resolving the Update() promise. |new_expiry_time|
// represents the time after which the key(s) in the session will no longer
// be usable for decryption. It can be 0 if no such time exists or if the
// license explicitly never expires. Size parameter should not include null
// termination.
virtual void OnExpirationChange(const char* session_id,
uint32_t session_id_size,
Time new_expiry_time) = 0;
// Called by the CDM when session |session_id| is closed. Size
// parameter should not include null termination.
virtual void OnSessionClosed(const char* session_id,
uint32_t session_id_size) = 0;
// The following are optional methods that may not be implemented on all
// platforms.
// Sends a platform challenge for the given |service_id|. |challenge| is at
// most 256 bits of data to be signed. Once the challenge has been completed,
// the host will call ContentDecryptionModule::OnPlatformChallengeResponse()
// with the signed challenge response and platform certificate. Size
// parameters should not include null termination.
virtual void SendPlatformChallenge(const char* service_id,
uint32_t service_id_size,
const char* challenge,
uint32_t challenge_size) = 0;
// Attempts to enable output protection (e.g. HDCP) on the display link. The
// |desired_protection_mask| is a bit mask of OutputProtectionMethods. No
// status callback is issued, the CDM must call QueryOutputProtectionStatus()
// periodically to ensure the desired protections are applied.
virtual void EnableOutputProtection(uint32_t desired_protection_mask) = 0;
// Requests the current output protection status. Once the host has the status
// it will call ContentDecryptionModule::OnQueryOutputProtectionStatus().
virtual void QueryOutputProtectionStatus() = 0;
// Must be called by the CDM if it returned kDeferredInitialization during
// InitializeAudioDecoder() or InitializeVideoDecoder().
virtual void OnDeferredInitializationDone(StreamType stream_type,
Status decoder_status) = 0;
// Creates a FileIO object from the host to do file IO operation. Returns NULL
// if a FileIO object cannot be obtained. Once a valid FileIO object is
// returned, |client| must be valid until FileIO::Close() is called. The
// CDM can call this method multiple times to operate on different files.
virtual FileIO* CreateFileIO(FileIOClient* client) = 0;
// Requests a specific version of the storage ID. A storage ID is a stable, // Requests a specific version of the storage ID. A storage ID is a stable,
// device specific ID used by the CDM to securely store persistent data. The // device specific ID used by the CDM to securely store persistent data. The
@@ -1350,9 +1733,14 @@ class CDM_CLASS_API Host_11 {
// the ID outside the client device, even in encrypted form. // the ID outside the client device, even in encrypted form.
virtual void RequestStorageId(uint32_t version) = 0; virtual void RequestStorageId(uint32_t version) = 0;
// Reports the metric |metric_name| with value |value| to the host. Can be
// called by the CDM at any time. May report the same metric multiple times
// during the lifetime of the CDM.
virtual void ReportMetrics(MetricName metric_name, uint64_t value) = 0;
protected: protected:
Host_11() {} Host_12() {}
virtual ~Host_11() {} virtual ~Host_12() {}
}; };
} // namespace cdm } // namespace cdm

View File

@@ -1,121 +0,0 @@
// Copyright 2017 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 CDM_CONTENT_DECRYPTION_MODULE_PROXY_H_
#define CDM_CONTENT_DECRYPTION_MODULE_PROXY_H_
#include "content_decryption_module_export.h"
#if defined(_MSC_VER)
typedef unsigned char uint8_t;
typedef unsigned int uint32_t;
typedef unsigned __int64 uint64_t;
#else
# include <stdint.h>
#endif
namespace cdm {
class CDM_CLASS_API CdmProxyClient;
// A proxy class for the CDM.
// In general, the interpretation of the CdmProxy and CdmProxyClient method
// parameters are protocol dependent. For enum parameters, values outside the
// enum range may not work.
class CDM_CLASS_API CdmProxy {
public:
enum Function : uint32_t {
// For Intel Negotiate Crypto SessionKey Exchange (CSME) path to call
// ID3D11VideoContext::NegotiateCryptoSessionKeyExchange.
kIntelNegotiateCryptoSessionKeyExchange = 1,
// There will be more values in the future e.g. for D3D11 RSA method.
};
enum KeyType : uint32_t {
kDecryptOnly = 0,
kDecryptAndDecode = 1,
};
// Initializes the proxy. The results will be returned in
// CdmProxyClient::OnInitialized().
virtual void Initialize() = 0;
// Processes and updates the state of the proxy.
// |output_data_size| is required by some protocol to set up the output data.
// The operation may fail if the |output_data_size| is wrong. The results will
// be returned in CdmProxyClient::OnProcessed().
virtual void Process(Function function, uint32_t crypto_session_id,
const uint8_t* input_data, uint32_t input_data_size,
uint32_t output_data_size) = 0;
// Creates a crypto session for handling media.
// If extra data has to be passed to further setup the media crypto session,
// pass the data as |input_data|. The results will be returned in
// CdmProxyClient::OnMediaCryptoSessionCreated().
virtual void CreateMediaCryptoSession(const uint8_t* input_data,
uint32_t input_data_size) = 0;
// Sets a key for the session identified by |crypto_session_id|.
virtual void SetKey(uint32_t crypto_session_id, const uint8_t* key_id,
uint32_t key_id_size, KeyType key_type,
const uint8_t* key_blob, uint32_t key_blob_size) = 0;
// Removes a key for the session identified by |crypto_session_id|.
virtual void RemoveKey(uint32_t crypto_session_id, const uint8_t* key_id,
uint32_t key_id_size) = 0;
protected:
CdmProxy() {}
virtual ~CdmProxy() {}
};
// Responses to CdmProxy calls. All responses will be called asynchronously.
class CDM_CLASS_API CdmProxyClient {
public:
enum Status : uint32_t {
kOk,
kFail,
};
enum Protocol : uint32_t {
kNone = 0, // No protocol supported. Can be used in failure cases.
kIntel, // Method using Intel CSME.
// There will be more values in the future e.g. kD3D11RsaHardware,
// kD3D11RsaSoftware to use the D3D11 RSA method.
};
// Callback for Initialize(). If the proxy created a crypto session, then the
// ID for the crypto session is |crypto_session_id|.
virtual void OnInitialized(Status status, Protocol protocol,
uint32_t crypto_session_id) = 0;
// Callback for Process(). |output_data| is the output of processing.
virtual void OnProcessed(Status status, const uint8_t* output_data,
uint32_t output_data_size) = 0;
// Callback for CreateMediaCryptoSession(). On success:
// - |crypto_session_id| is the ID for the created crypto session.
// - |output_data| is extra value, if any.
// Otherwise, |crypto_session_id| and |output_data| should be ignored.
virtual void OnMediaCryptoSessionCreated(Status status,
uint32_t crypto_session_id,
uint64_t output_data) = 0;
// Callback for SetKey().
virtual void OnKeySet(Status status) = 0;
// Callback for RemoveKey().
virtual void OnKeyRemoved(Status status) = 0;
// Called when there is a hardware reset and all the hardware context is lost.
virtual void NotifyHardwareReset() = 0;
protected:
CdmProxyClient() {}
virtual ~CdmProxyClient() {}
};
} // namespace cdm
#endif // CDM_CONTENT_DECRYPTION_MODULE_PROXY_H_

View File

@@ -10,7 +10,14 @@ SOURCES += [
"WidevineVideoFrame.cpp", "WidevineVideoFrame.cpp",
] ]
EXPORTS += ["WidevineFileIO.h", "WidevineUtils.h", "WidevineVideoFrame.h"] EXPORTS += [
"content_decryption_module.h",
"content_decryption_module_export.h",
"content_decryption_module_ext.h",
"WidevineFileIO.h",
"WidevineUtils.h",
"WidevineVideoFrame.h",
]
FINAL_LIBRARY = "xul" FINAL_LIBRARY = "xul"

View File

@@ -219,9 +219,9 @@ VideoDecoder::SampleToVideoFrame(IMFSample* aSample, int32_t aPictureWidth,
uint32_t srcUVSize = stride * (aFrameHeight + padding) / 4; uint32_t srcUVSize = stride * (aFrameHeight + padding) / 4;
uint32_t halfStride = (stride + 1) / 2; uint32_t halfStride = (stride + 1) / 2;
aVideoFrame->SetStride(cdm::VideoPlane::kYPlane, stride); aVideoFrame->SetStride(cdm::kYPlane, stride);
aVideoFrame->SetStride(cdm::VideoPlane::kUPlane, halfStride); aVideoFrame->SetStride(cdm::kUPlane, halfStride);
aVideoFrame->SetStride(cdm::VideoPlane::kVPlane, halfStride); aVideoFrame->SetStride(cdm::kVPlane, halfStride);
aVideoFrame->SetSize(cdm::Size{aPictureWidth, aPictureHeight}); aVideoFrame->SetSize(cdm::Size{aPictureWidth, aPictureHeight});
@@ -252,17 +252,17 @@ VideoDecoder::SampleToVideoFrame(IMFSample* aSample, int32_t aPictureWidth,
uint8_t* outBuffer = buffer->Data(); uint8_t* outBuffer = buffer->Data();
aVideoFrame->SetPlaneOffset(cdm::VideoPlane::kYPlane, 0); aVideoFrame->SetPlaneOffset(cdm::kYPlane, 0);
// Offset of U plane is the size of the Y plane, excluding the padding that // Offset of U plane is the size of the Y plane, excluding the padding that
// WMF adds. // WMF adds.
uint32_t dstUOffset = stride * aPictureHeight; uint32_t dstUOffset = stride * aPictureHeight;
aVideoFrame->SetPlaneOffset(cdm::VideoPlane::kUPlane, dstUOffset); aVideoFrame->SetPlaneOffset(cdm::kUPlane, dstUOffset);
// Offset of the V plane is the size of the Y plane + the size of the U plane, // Offset of the V plane is the size of the Y plane + the size of the U plane,
// excluding any padding WMF adds. // excluding any padding WMF adds.
uint32_t dstVOffset = stride * aPictureHeight + (stride * aPictureHeight) / 4; uint32_t dstVOffset = stride * aPictureHeight + (stride * aPictureHeight) / 4;
aVideoFrame->SetPlaneOffset(cdm::VideoPlane::kVPlane, dstVOffset); aVideoFrame->SetPlaneOffset(cdm::kVPlane, dstVOffset);
// Copy the pixel data, excluding WMF's padding. // Copy the pixel data, excluding WMF's padding.
memcpy(outBuffer, data, stride * aPictureHeight); memcpy(outBuffer, data, stride * aPictureHeight);

View File

@@ -30,7 +30,6 @@ dom/media/gmp/rlz/
dom/media/gmp/widevine-adapter/content_decryption_module_export.h dom/media/gmp/widevine-adapter/content_decryption_module_export.h
dom/media/gmp/widevine-adapter/content_decryption_module_ext.h dom/media/gmp/widevine-adapter/content_decryption_module_ext.h
dom/media/gmp/widevine-adapter/content_decryption_module.h dom/media/gmp/widevine-adapter/content_decryption_module.h
dom/media/gmp/widevine-adapter/content_decryption_module_proxy.h
dom/media/platforms/ffmpeg/ffmpeg57/ dom/media/platforms/ffmpeg/ffmpeg57/
dom/media/platforms/ffmpeg/ffmpeg58/ dom/media/platforms/ffmpeg/ffmpeg58/
dom/media/platforms/ffmpeg/ffmpeg59/ dom/media/platforms/ffmpeg/ffmpeg59/