Bug 1041384 - Update GMP APIs for decrypt without decoding and reporting capabilities. r=jesup

This commit is contained in:
Chris Pearce 2014-07-24 09:35:02 +12:00
Родитель 7b82110ed9
Коммит 499998ccd9
7 изменённых файлов: 136 добавлений и 76 удалений

Просмотреть файл

@ -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_