зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1041384 - Update GMP APIs for decrypt without decoding and reporting capabilities. r=jesup
This commit is contained in:
Родитель
7b82110ed9
Коммит
499998ccd9
|
@ -51,7 +51,7 @@ GMPVideoEncodedFrameImpl::~GMPVideoEncodedFrameImpl()
|
|||
}
|
||||
}
|
||||
|
||||
const GMPEncryptedBufferData*
|
||||
const GMPEncryptedBufferMetadata*
|
||||
GMPVideoEncodedFrameImpl::GetDecryptionData() const
|
||||
{
|
||||
return nullptr;
|
||||
|
|
|
@ -91,7 +91,7 @@ public:
|
|||
virtual uint8_t* Buffer() MOZ_OVERRIDE;
|
||||
virtual GMPBufferType BufferType() const MOZ_OVERRIDE;
|
||||
virtual void SetBufferType(GMPBufferType aBufferType) MOZ_OVERRIDE;
|
||||
virtual const GMPEncryptedBufferData* GetDecryptionData() const MOZ_OVERRIDE;
|
||||
virtual const GMPEncryptedBufferMetadata* GetDecryptionData() const MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
void DestroyBuffer();
|
||||
|
|
|
@ -49,9 +49,9 @@ public:
|
|||
virtual const uint8_t* Buffer() const = 0;
|
||||
virtual uint8_t* Buffer() = 0;
|
||||
|
||||
// Get data describing how this frame is encrypted, or nullptr if the
|
||||
// Get metadata describing how this frame is encrypted, or nullptr if the
|
||||
// buffer is not encrypted.
|
||||
virtual const GMPEncryptedBufferData* GetDecryptionData() const = 0;
|
||||
virtual const GMPEncryptedBufferMetadata* GetDecryptionData() const = 0;
|
||||
};
|
||||
|
||||
#endif // GMP_AUDIO_FRAME_h_
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
#include "gmp-platform.h"
|
||||
|
||||
class GMPEncryptedBufferData {
|
||||
class GMPEncryptedBufferMetadata {
|
||||
public:
|
||||
// Key ID to identify the decryption key.
|
||||
virtual const uint8_t* KeyId() const = 0;
|
||||
|
@ -33,14 +33,23 @@ public:
|
|||
// Size (in bytes) of |IV|.
|
||||
virtual uint32_t IVSize() const = 0;
|
||||
|
||||
// Number of enties returned by ClearBytes and CipherBytes().
|
||||
// Number of entries returned by ClearBytes() and CipherBytes().
|
||||
virtual uint32_t NumSubsamples() const = 0;
|
||||
|
||||
virtual const uint32_t* ClearBytes() const = 0;
|
||||
virtual const uint16_t* ClearBytes() const = 0;
|
||||
|
||||
virtual const uint32_t* CipherBytes() const = 0;
|
||||
};
|
||||
|
||||
class GMPBuffer {
|
||||
public:
|
||||
virtual uint32_t Id() const = 0;
|
||||
virtual uint8_t* Data() = 0;
|
||||
virtual uint32_t Size() const = 0;
|
||||
virtual void Resize(uint32_t aSize) = 0;
|
||||
virtual ~GMPBuffer() {}
|
||||
};
|
||||
|
||||
// These match to the DOMException codes as per:
|
||||
// http://www.w3.org/TR/dom/#domexception
|
||||
enum GMPDOMException {
|
||||
|
@ -60,71 +69,106 @@ enum GMPDOMException {
|
|||
// Time in milliseconds, as offset from epoch, 1 Jan 1970.
|
||||
typedef int64_t GMPTimestamp;
|
||||
|
||||
// Capability definitions. The capabilities of the EME GMP are reported
|
||||
// to Gecko by calling the GMPDecryptorCallback::SetCapabilities()
|
||||
// callback and specifying the logical OR of the GMP_EME_CAP_* flags below.
|
||||
//
|
||||
// Note the DECRYPT and the DECRYPT_AND_DECODE are mutually exclusive;
|
||||
// only one mode should be reported for each stream type, but different
|
||||
// modes can be reported for different stream types.
|
||||
//
|
||||
// Note: Gecko does not currently support the caps changing at runtime.
|
||||
// Set them once per plugin initialization, during the startup of
|
||||
// the GMPdecryptor.
|
||||
|
||||
// Capability; CDM can decrypt encrypted buffers and return still
|
||||
// compressed buffers back to Gecko for decompression there.
|
||||
#define GMP_EME_CAP_DECRYPT_AUDIO (uint64_t(1) << 0)
|
||||
#define GMP_EME_CAP_DECRYPT_VIDEO (uint64_t(1) << 1)
|
||||
|
||||
// Capability; CDM can decrypt and then decode encrypted buffers,
|
||||
// and return decompressed samples to Gecko for playback.
|
||||
#define GMP_EME_CAP_DECRYPT_AND_DECODE_AUDIO (uint64_t(1) << 2)
|
||||
#define GMP_EME_CAP_DECRYPT_AND_DECODE_VIDEO (uint64_t(1) << 3)
|
||||
|
||||
class GMPDecryptorCallback {
|
||||
public:
|
||||
// Resolves a promise for a session created or loaded.
|
||||
// Passes the session id to be exposed to JavaScript.
|
||||
// Must be called before OnSessionMessage().
|
||||
// Must be called before SessionMessage().
|
||||
// aSessionId must be null terminated.
|
||||
virtual void OnResolveNewSessionPromise(uint32_t aPromiseId,
|
||||
const char* aSessionId,
|
||||
uint32_t aSessionIdLength) = 0;
|
||||
virtual void ResolveNewSessionPromise(uint32_t aPromiseId,
|
||||
const char* aSessionId,
|
||||
uint32_t aSessionIdLength) = 0;
|
||||
|
||||
// Called to resolve a specified promise with "undefined".
|
||||
virtual void OnResolvePromise(uint32_t aPromiseId) = 0;
|
||||
virtual void ResolvePromise(uint32_t aPromiseId) = 0;
|
||||
|
||||
// Called to reject a promise with a DOMException.
|
||||
// aMessage is logged to the WebConsole.
|
||||
// aMessage is optional, but if present must be null terminated.
|
||||
virtual void OnRejectPromise(uint32_t aPromiseId,
|
||||
GMPDOMException aException,
|
||||
const char* aMessage,
|
||||
uint32_t aMessageLength) = 0;
|
||||
virtual void RejectPromise(uint32_t aPromiseId,
|
||||
GMPDOMException aException,
|
||||
const char* aMessage,
|
||||
uint32_t aMessageLength) = 0;
|
||||
|
||||
// Called by the CDM when it has a message for session |session_id|.
|
||||
// Length parameters should not include null termination.
|
||||
// aSessionId must be null terminated.
|
||||
virtual void OnSessionMessage(const char* aSessionId,
|
||||
uint32_t aSessionIdLength,
|
||||
const uint8_t* aMessage,
|
||||
uint32_t aMessageLength,
|
||||
const char* aDestinationURL,
|
||||
uint32_t aDestinationURLLength) = 0;
|
||||
virtual void SessionMessage(const char* aSessionId,
|
||||
uint32_t aSessionIdLength,
|
||||
const uint8_t* aMessage,
|
||||
uint32_t aMessageLength,
|
||||
const char* aDestinationURL,
|
||||
uint32_t aDestinationURLLength) = 0;
|
||||
|
||||
// aSessionId must be null terminated.
|
||||
virtual void OnExpirationChange(const char* aSessionId,
|
||||
uint32_t aSessionIdLength,
|
||||
GMPTimestamp aExpiryTime) = 0;
|
||||
virtual void ExpirationChange(const char* aSessionId,
|
||||
uint32_t aSessionIdLength,
|
||||
GMPTimestamp aExpiryTime) = 0;
|
||||
|
||||
// Called by the GMP when a session is closed. All file IO
|
||||
// that a session requires should be complete before calling this.
|
||||
// aSessionId must be null terminated.
|
||||
virtual void OnSessionClosed(const char* aSessionId,
|
||||
uint32_t aSessionIdLength) = 0;
|
||||
virtual void SessionClosed(const char* aSessionId,
|
||||
uint32_t aSessionIdLength) = 0;
|
||||
|
||||
// Called by the GMP when an error occurs in a session.
|
||||
// aSessionId must be null terminated.
|
||||
// aMessage is logged to the WebConsole.
|
||||
// aMessage is optional, but if present must be null terminated.
|
||||
virtual void OnSessionError(const char* aSessionId,
|
||||
uint32_t aSessionIdLength,
|
||||
GMPDOMException aException,
|
||||
uint32_t aSystemCode,
|
||||
const char* aMessage,
|
||||
uint32_t aMessageLength) = 0;
|
||||
virtual void SessionError(const char* aSessionId,
|
||||
uint32_t aSessionIdLength,
|
||||
GMPDOMException aException,
|
||||
uint32_t aSystemCode,
|
||||
const char* aMessage,
|
||||
uint32_t aMessageLength) = 0;
|
||||
|
||||
virtual void OnKeyIdUsable(const char* aSessionId,
|
||||
uint32_t aSessionIdLength,
|
||||
const uint8_t* aKeyId,
|
||||
uint32_t aKeyIdLength) = 0;
|
||||
// Marks a key as usable. Gecko will not call into the CDM to decrypt
|
||||
// or decode content encrypted with a key unless the CDM has marked it
|
||||
// usable first. So a CDM *MUST* mark its usable keys as usable!
|
||||
virtual void KeyIdUsable(const char* aSessionId,
|
||||
uint32_t aSessionIdLength,
|
||||
const uint8_t* aKeyId,
|
||||
uint32_t aKeyIdLength) = 0;
|
||||
|
||||
// Marks a key as no longer usable.
|
||||
// Note: Keys are assumed to be not usable when a session is closed or removed.
|
||||
virtual void OnKeyIdNotUsable(const char* aSessionId,
|
||||
uint32_t aSessionIdLength,
|
||||
const uint8_t* aKeyId,
|
||||
uint32_t aKeyIdLength) = 0;
|
||||
virtual void KeyIdNotUsable(const char* aSessionId,
|
||||
uint32_t aSessionIdLength,
|
||||
const uint8_t* aKeyId,
|
||||
uint32_t aKeyIdLength) = 0;
|
||||
|
||||
// The CDM must report its capabilites of this CDM. aCaps should be a
|
||||
// logical OR of the GMP_EME_CAP_* flags. The CDM *MUST* call this
|
||||
// function and report whether it can decrypt and/or decode. Without
|
||||
// this, Gecko does not know how to use the CDM and will not send
|
||||
// samples to the CDM to decrypt or decrypt-and-decode mode. Note a
|
||||
// CDM cannot change modes once playback has begun.
|
||||
virtual void SetCapabilities(uint64_t aCaps) = 0;
|
||||
|
||||
// Returns decrypted buffer to Gecko, or reports failure.
|
||||
virtual void Decrypted(GMPBuffer* aBuffer, GMPErr aResult) = 0;
|
||||
};
|
||||
|
||||
// Host interface, passed to GetAPIFunc(), with "decrypt".
|
||||
|
@ -166,10 +210,14 @@ public:
|
|||
virtual void Init(GMPDecryptorCallback* aCallback) = 0;
|
||||
|
||||
// Requests the creation of a session given |aType| and |aInitData|.
|
||||
// Decryptor should callback GMPDecryptorCallback::OnSessionCreated()
|
||||
// with the web session ID on success, or OnSessionError() on failure,
|
||||
// and then call OnSessionReady() once all keys for that session are
|
||||
// available.
|
||||
// Decryptor should callback GMPDecryptorCallback::SessionCreated()
|
||||
// with the web session ID on success, or SessionError() on failure,
|
||||
// and then call KeyIdUsable() as keys for that session become
|
||||
// usable.
|
||||
//
|
||||
// The CDM must also call GMPDecryptorCallback::SetCapabilities()
|
||||
// exactly once during start up, to inform Gecko whether to use the CDM
|
||||
// in decrypt or decrypt-and-decode mode.
|
||||
virtual void CreateSession(uint32_t aPromiseId,
|
||||
const char* aInitDataType,
|
||||
uint32_t aInitDataTypeSize,
|
||||
|
@ -203,6 +251,15 @@ public:
|
|||
virtual void SetServerCertificate(uint32_t aPromiseId,
|
||||
const uint8_t* aServerCert,
|
||||
uint32_t aServerCertSize) = 0;
|
||||
|
||||
// Asynchronously decrypts aBuffer in place. When the decryption is
|
||||
// complete, GMPDecryptor should write the decrypted data back into the
|
||||
// same GMPBuffer object and return it to Gecko by calling Decrypted(),
|
||||
// with the GMPNoErr successcode. If decryption fails, call Decrypted()
|
||||
// with a failure code, and an error event will fire on the media element.
|
||||
virtual void Decrypt(GMPBuffer* aBuffer,
|
||||
GMPEncryptedBufferMetadata* aMetadata) = 0;
|
||||
|
||||
};
|
||||
|
||||
#endif // GMP_DECRYPTION_h_
|
||||
|
|
|
@ -39,7 +39,7 @@ typedef enum {
|
|||
GMPClosedErr = 2,
|
||||
GMPAllocErr = 3,
|
||||
GMPNotImplementedErr = 4,
|
||||
GMPNotClosedErr = 5,
|
||||
GMPRecordInUse = 5,
|
||||
GMPQuotaExceededErr = 6,
|
||||
GMPDecodeErr = 7,
|
||||
GMPEncodeErr = 8,
|
||||
|
|
|
@ -21,30 +21,31 @@
|
|||
#include <stdint.h>
|
||||
|
||||
// Provides basic per-origin storage for CDMs. GMPRecord instances can be
|
||||
// retrieved by calling GMPPlatformAPI->openstorage. Multiple GMPRecord
|
||||
// can be open at once. This interface is asynchronous, with results
|
||||
// being returned via callbacks to the GMPRecordClient pointer provided
|
||||
// to the GMPPlatformAPI->openstorage call, on the main thread.
|
||||
// retrieved by calling GMPPlatformAPI->openstorage. Multiple GMPRecords
|
||||
// with different names can be open at once, but a single record can only
|
||||
// be opened by one client at a time. This interface is asynchronous, with
|
||||
// results being returned via callbacks to the GMPRecordClient pointer
|
||||
// provided to the GMPPlatformAPI->openstorage call, on the main thread.
|
||||
class GMPRecord {
|
||||
public:
|
||||
|
||||
// Opens the record. Calls OnOpenComplete() once the record is open.
|
||||
// Note: OnReadComplete() is only called if this returns GMPNoErr.
|
||||
// Opens the record. Calls OpenComplete() once the record is open.
|
||||
// Note: OpenComplete() is only called if this returns GMPNoErr.
|
||||
virtual GMPErr Open() = 0;
|
||||
|
||||
// Reads the entire contents of the file, and calls
|
||||
// GMPRecordClient::OnReadComplete() once the operation is complete.
|
||||
// Note: OnReadComplete() is only called if this returns GMPNoErr.
|
||||
// Reads the entire contents of the record, and calls
|
||||
// GMPRecordClient::ReadComplete() once the operation is complete.
|
||||
// Note: ReadComplete() is only called if this returns GMPNoErr.
|
||||
virtual GMPErr Read() = 0;
|
||||
|
||||
// Writes aDataSize bytes of aData into the file, overwritting the contents
|
||||
// of the file. Overwriting with 0 bytes "deletes" the file.
|
||||
// Write 0 bytes to "delete" a file.
|
||||
// Note: OnWriteComplete is only called if this returns GMPNoErr.
|
||||
// Writes aDataSize bytes of aData into the record, overwriting the
|
||||
// contents of the record. Overwriting with 0 bytes "deletes" the file.
|
||||
// Note: WriteComplete is only called if this returns GMPNoErr.
|
||||
virtual GMPErr Write(const uint8_t* aData, uint32_t aDataSize) = 0;
|
||||
|
||||
// Closes a file. File must not be used after this is called. Cancels all
|
||||
// callbacks.
|
||||
// Closes a record. GMPRecord object must not be used after this is
|
||||
// called, request a new one with GMPPlatformAPI->openstorage to re-open
|
||||
// this record. Cancels all callbacks.
|
||||
virtual GMPErr Close() = 0;
|
||||
|
||||
virtual ~GMPRecord() {}
|
||||
|
@ -57,32 +58,34 @@ class GMPRecordClient {
|
|||
|
||||
// Response to a GMPRecord::Open() call with the open |status|.
|
||||
// aStatus values:
|
||||
// - GMPNoErr - File opened successfully. File may be empty.
|
||||
// - GMPFileInUse - There file is in use by another client.
|
||||
// - GMPNoErr - Record opened successfully. Record may be empty.
|
||||
// - GMPRecordInUse - This record is in use by another client.
|
||||
// - GMPGenericErr - Unspecified error.
|
||||
// Do not use the GMPRecord if aStatus is not GMPNoErr.
|
||||
virtual void OnOpenComplete(GMPErr aStatus) = 0;
|
||||
virtual void OpenComplete(GMPErr aStatus) = 0;
|
||||
|
||||
// Response to a GMPRecord::Read() call, where aData is the file contents,
|
||||
// Response to a GMPRecord::Read() call, where aData is the record contents,
|
||||
// of length aDataSize.
|
||||
// aData is only valid for the duration of the call to OnReadComplete.
|
||||
// aData is only valid for the duration of the call to ReadComplete.
|
||||
// Copy it if you want to hang onto it!
|
||||
// aStatus values:
|
||||
// - GMPNoErr - File contents read successfully, aDataSize 0 means file
|
||||
// - GMPNoErr - Record contents read successfully, aDataSize 0 means record
|
||||
// is empty.
|
||||
// - GMPFileInUse - There are other operations or clients in use on this file.
|
||||
// - GMPRecordInUse - There are other operations or clients in use on
|
||||
// this record.
|
||||
// - GMPGenericErr - Unspecified error.
|
||||
// Do not continue to use the GMPRecord if aStatus is not GMPNoErr.
|
||||
virtual void OnReadComplete(GMPErr aStatus,
|
||||
const uint8_t* aData,
|
||||
uint32_t aDataSize) = 0;
|
||||
virtual void ReadComplete(GMPErr aStatus,
|
||||
const uint8_t* aData,
|
||||
uint32_t aDataSize) = 0;
|
||||
|
||||
// Response to a GMPRecord::Write() call.
|
||||
// - GMPNoErr - File contents written successfully.
|
||||
// - GMPFileInUse - There are other operations or clients in use on this file.
|
||||
// - GMPGenericErr - Unspecified error. File should be regarded as corrupt.
|
||||
// - GMPRecordInUse - There are other operations or clients in use on
|
||||
// this record.
|
||||
// - GMPGenericErr - Unspecified error.
|
||||
// Do not continue to use the GMPRecord if aStatus is not GMPNoErr.
|
||||
virtual void OnWriteComplete(GMPErr aStatus) = 0;
|
||||
virtual void WriteComplete(GMPErr aStatus) = 0;
|
||||
|
||||
virtual ~GMPRecordClient() {}
|
||||
};
|
||||
|
|
|
@ -90,9 +90,9 @@ public:
|
|||
virtual GMPBufferType BufferType() const = 0;
|
||||
virtual void SetBufferType(GMPBufferType aBufferType) = 0;
|
||||
|
||||
// Get data describing how this frame is encrypted, or nullptr if the
|
||||
// Get metadata describing how this frame is encrypted, or nullptr if the
|
||||
// frame is not encrypted.
|
||||
virtual const GMPEncryptedBufferData* GetDecryptionData() const = 0;
|
||||
virtual const GMPEncryptedBufferMetadata* GetDecryptionData() const = 0;
|
||||
};
|
||||
|
||||
#endif // GMP_VIDEO_FRAME_ENCODED_h_
|
||||
|
|
Загрузка…
Ссылка в новой задаче