diff options
Diffstat (limited to 'dom/media/gmp/gmp-api')
-rw-r--r-- | dom/media/gmp/gmp-api/gmp-async-shutdown.h | 54 | ||||
-rw-r--r-- | dom/media/gmp/gmp-api/gmp-audio-codec.h | 43 | ||||
-rw-r--r-- | dom/media/gmp/gmp-api/gmp-audio-decode.h | 84 | ||||
-rw-r--r-- | dom/media/gmp/gmp-api/gmp-audio-host.h | 32 | ||||
-rw-r--r-- | dom/media/gmp/gmp-api/gmp-audio-samples.h | 74 | ||||
-rw-r--r-- | dom/media/gmp/gmp-api/gmp-decryption.h | 459 | ||||
-rw-r--r-- | dom/media/gmp/gmp-api/gmp-entrypoints.h | 75 | ||||
-rw-r--r-- | dom/media/gmp/gmp-api/gmp-errors.h | 58 | ||||
-rw-r--r-- | dom/media/gmp/gmp-api/gmp-platform.h | 118 | ||||
-rw-r--r-- | dom/media/gmp/gmp-api/gmp-storage.h | 141 | ||||
-rw-r--r-- | dom/media/gmp/gmp-api/gmp-video-codec.h | 226 | ||||
-rw-r--r-- | dom/media/gmp/gmp-api/gmp-video-decode.h | 127 | ||||
-rw-r--r-- | dom/media/gmp/gmp-api/gmp-video-encode.h | 135 | ||||
-rw-r--r-- | dom/media/gmp/gmp-api/gmp-video-frame-encoded.h | 99 | ||||
-rw-r--r-- | dom/media/gmp/gmp-api/gmp-video-frame-i420.h | 132 | ||||
-rw-r--r-- | dom/media/gmp/gmp-api/gmp-video-frame.h | 51 | ||||
-rw-r--r-- | dom/media/gmp/gmp-api/gmp-video-host.h | 53 | ||||
-rw-r--r-- | dom/media/gmp/gmp-api/gmp-video-plane.h | 94 |
18 files changed, 2055 insertions, 0 deletions
diff --git a/dom/media/gmp/gmp-api/gmp-async-shutdown.h b/dom/media/gmp/gmp-api/gmp-async-shutdown.h new file mode 100644 index 0000000000..42268668f1 --- /dev/null +++ b/dom/media/gmp/gmp-api/gmp-async-shutdown.h @@ -0,0 +1,54 @@ +/* +* Copyright 2013, Mozilla Foundation and contributors +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef GMP_ASYNC_SHUTDOWN_H_ +#define GMP_ASYNC_SHUTDOWN_H_ + +#define GMP_API_ASYNC_SHUTDOWN "async-shutdown" + +// API exposed by the plugin library to manage asynchronous shutdown. +// Some plugins require special cleanup which may need to make calls +// to host services and wait for async responses. +// +// To enable a plugins to block shutdown until its async shutdown is +// complete, implement the GMPAsyncShutdown interface and return it when +// your plugin's GMPGetAPI function is called with "async-shutdown". +// When your GMPAsyncShutdown's BeginShutdown() implementation is called +// by the GMP host, you should initate your async shutdown process. +// Once you have completed shutdown, call the ShutdownComplete() function +// of the GMPAsyncShutdownHost that is passed as the host argument to the +// GMPGetAPI() call. +// +// Note: Your GMP's GMPShutdown function will still be called after your +// call to ShutdownComplete(). +// +// API name macro: GMP_API_ASYNC_SHUTDOWN +// Host API: GMPAsyncShutdownHost +class GMPAsyncShutdown { +public: + virtual ~GMPAsyncShutdown() {} + + virtual void BeginShutdown() = 0; +}; + +class GMPAsyncShutdownHost { +public: + virtual ~GMPAsyncShutdownHost() {} + + virtual void ShutdownComplete() = 0; +}; + +#endif // GMP_ASYNC_SHUTDOWN_H_ diff --git a/dom/media/gmp/gmp-api/gmp-audio-codec.h b/dom/media/gmp/gmp-api/gmp-audio-codec.h new file mode 100644 index 0000000000..5a5c17bb90 --- /dev/null +++ b/dom/media/gmp/gmp-api/gmp-audio-codec.h @@ -0,0 +1,43 @@ +/* +* Copyright 2013, Mozilla Foundation and contributors +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef GMP_AUDIO_CODEC_h_ +#define GMP_AUDIO_CODEC_h_ + +#include <stdint.h> + +enum GMPAudioCodecType +{ + kGMPAudioCodecAAC, + kGMPAudioCodecVorbis, + kGMPAudioCodecInvalid // Should always be last. +}; + +struct GMPAudioCodec +{ + GMPAudioCodecType mCodecType; + uint32_t mChannelCount; + uint32_t mBitsPerChannel; + uint32_t mSamplesPerSecond; + + // Codec extra data, such as vorbis setup header, or + // AAC AudioSpecificConfig. + // These are null/0 if not externally negotiated + const uint8_t* mExtraData; + uint32_t mExtraDataLen; +}; + +#endif // GMP_AUDIO_CODEC_h_ diff --git a/dom/media/gmp/gmp-api/gmp-audio-decode.h b/dom/media/gmp/gmp-api/gmp-audio-decode.h new file mode 100644 index 0000000000..8b017c0afc --- /dev/null +++ b/dom/media/gmp/gmp-api/gmp-audio-decode.h @@ -0,0 +1,84 @@ +/* +* Copyright 2013, Mozilla Foundation and contributors +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef GMP_AUDIO_DECODE_h_ +#define GMP_AUDIO_DECODE_h_ + +#include "gmp-errors.h" +#include "gmp-audio-samples.h" +#include "gmp-audio-codec.h" +#include <stdint.h> + +// ALL METHODS MUST BE CALLED ON THE MAIN THREAD +class GMPAudioDecoderCallback +{ +public: + virtual ~GMPAudioDecoderCallback() {} + + virtual void Decoded(GMPAudioSamples* aDecodedSamples) = 0; + + virtual void InputDataExhausted() = 0; + + virtual void DrainComplete() = 0; + + virtual void ResetComplete() = 0; + + // Called when the decoder encounters a catestrophic error and cannot + // continue. Gecko will not send any more input for decoding. + virtual void Error(GMPErr aError) = 0; +}; + +#define GMP_API_AUDIO_DECODER "decode-audio" + +// Audio decoding for a single stream. A GMP may be asked to create multiple +// decoders concurrently. +// +// API name macro: GMP_API_AUDIO_DECODER +// Host API: GMPAudioHost +// +// ALL METHODS MUST BE CALLED ON THE MAIN THREAD +class GMPAudioDecoder +{ +public: + virtual ~GMPAudioDecoder() {} + + // aCallback: Subclass should retain reference to it until DecodingComplete + // is called. Do not attempt to delete it, host retains ownership. + // TODO: Pass AudioHost so decoder can create GMPAudioEncodedFrame objects? + virtual void InitDecode(const GMPAudioCodec& aCodecSettings, + GMPAudioDecoderCallback* aCallback) = 0; + + // Decode encoded audio frames (as a part of an audio stream). The decoded + // frames must be returned to the user through the decode complete callback. + virtual void Decode(GMPAudioSamples* aEncodedSamples) = 0; + + // Reset decoder state and prepare for a new call to Decode(...). + // Flushes the decoder pipeline. + // The decoder should enqueue a task to run ResetComplete() on the main + // thread once the reset has finished. + virtual void Reset() = 0; + + // Output decoded frames for any data in the pipeline, regardless of ordering. + // All remaining decoded frames should be immediately returned via callback. + // The decoder should enqueue a task to run DrainComplete() on the main + // thread once the reset has finished. + virtual void Drain() = 0; + + // May free decoder memory. + virtual void DecodingComplete() = 0; +}; + +#endif // GMP_VIDEO_DECODE_h_ diff --git a/dom/media/gmp/gmp-api/gmp-audio-host.h b/dom/media/gmp/gmp-api/gmp-audio-host.h new file mode 100644 index 0000000000..fe36419387 --- /dev/null +++ b/dom/media/gmp/gmp-api/gmp-audio-host.h @@ -0,0 +1,32 @@ +/* +* Copyright 2013, Mozilla Foundation and contributors +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef GMP_AUDIO_HOST_h_ +#define GMP_AUDIO_HOST_h_ + +#include "gmp-errors.h" +#include "gmp-audio-samples.h" + +class GMPAudioHost +{ +public: + // Construct various Audio API objects. Host does not retain reference, + // caller is owner and responsible for deleting. + virtual GMPErr CreateSamples(GMPAudioFormat aFormat, + GMPAudioSamples** aSamples) = 0; +}; + +#endif // GMP_AUDIO_HOST_h_ diff --git a/dom/media/gmp/gmp-api/gmp-audio-samples.h b/dom/media/gmp/gmp-api/gmp-audio-samples.h new file mode 100644 index 0000000000..a47fc74b99 --- /dev/null +++ b/dom/media/gmp/gmp-api/gmp-audio-samples.h @@ -0,0 +1,74 @@ +/* +* Copyright 2013, Mozilla Foundation and contributors +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef GMP_AUDIO_FRAME_h_ +#define GMP_AUDIO_FRAME_h_ + +#include <stdint.h> +#include "gmp-errors.h" +#include "gmp-decryption.h" + +enum GMPAudioFormat +{ + kGMPAudioEncodedSamples, // Raw compressed data, i.e. an AAC/Vorbis packet. + kGMPAudioIS16Samples, // Interleaved int16_t PCM samples. + kGMPAudioSamplesFormatInvalid // Should always be last. +}; + +class GMPAudioSamples { +public: + // The format of the buffer. + virtual GMPAudioFormat GetFormat() = 0; + virtual void Destroy() = 0; + + // MAIN THREAD ONLY + // Buffer size must be exactly what's required to contain all samples in + // the buffer; every byte is assumed to be part of a sample. + virtual GMPErr SetBufferSize(uint32_t aSize) = 0; + + // Size of the buffer in bytes. + virtual uint32_t Size() = 0; + + // Timestamps are in microseconds, and are the playback start time of the + // first sample in the buffer. + virtual void SetTimeStamp(uint64_t aTimeStamp) = 0; + virtual uint64_t TimeStamp() = 0; + virtual const uint8_t* Buffer() const = 0; + virtual uint8_t* Buffer() = 0; + + // Get metadata describing how this frame is encrypted, or nullptr if the + // buffer is not encrypted. + virtual const GMPEncryptedBufferMetadata* GetDecryptionData() const = 0; + + virtual uint32_t Channels() const = 0; + virtual void SetChannels(uint32_t aChannels) = 0; + + // Rate; the number of frames per second, where a "frame" is one sample for + // each channel. + // + // For IS16 samples, the number of samples should be: + // Size() / (Channels() * sizeof(int16_t)). + // + // Note: Channels() and Rate() may not be constant across a decoding + // session. For example the rate for decoded samples may be different + // than the rate advertised by the MP4 container for encoded samples + // for HE-AAC streams with SBR/PS, and an EME-GMP may need to downsample + // to satisfy DRM requirements. + virtual uint32_t Rate() const = 0; + virtual void SetRate(uint32_t aRate) = 0; +}; + +#endif // GMP_AUDIO_FRAME_h_ diff --git a/dom/media/gmp/gmp-api/gmp-decryption.h b/dom/media/gmp/gmp-api/gmp-decryption.h new file mode 100644 index 0000000000..046a05759e --- /dev/null +++ b/dom/media/gmp/gmp-api/gmp-decryption.h @@ -0,0 +1,459 @@ +/* +* Copyright 2013, Mozilla Foundation and contributors +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef GMP_DECRYPTION_h_ +#define GMP_DECRYPTION_h_ + +#include "gmp-platform.h" + +class GMPStringList { +public: + virtual uint32_t Size() const = 0; + + virtual void StringAt(uint32_t aIndex, + const char** aOutString, uint32_t* aOutLength) const = 0; + + virtual ~GMPStringList() { } +}; + +class GMPEncryptedBufferMetadata { +public: + // Key ID to identify the decryption key. + virtual const uint8_t* KeyId() const = 0; + + // Size (in bytes) of |KeyId()|. + virtual uint32_t KeyIdSize() const = 0; + + // Initialization vector. + virtual const uint8_t* IV() const = 0; + + // Size (in bytes) of |IV|. + virtual uint32_t IVSize() const = 0; + + // Number of entries returned by ClearBytes() and CipherBytes(). + virtual uint32_t NumSubsamples() const = 0; + + virtual const uint16_t* ClearBytes() const = 0; + + virtual const uint32_t* CipherBytes() const = 0; + + virtual ~GMPEncryptedBufferMetadata() {} + + // The set of MediaKeySession IDs associated with this decryption key in + // the current stream. + virtual const GMPStringList* SessionIds() 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 { + kGMPNoModificationAllowedError = 7, + kGMPNotFoundError = 8, + kGMPNotSupportedError = 9, + kGMPInvalidStateError = 11, + kGMPSyntaxError = 12, + kGMPInvalidModificationError = 13, + kGMPInvalidAccessError = 15, + kGMPSecurityError = 18, + kGMPAbortError = 20, + kGMPQuotaExceededError = 22, + kGMPTimeoutError = 23, + kGMPTypeError = 52 +}; + +enum GMPSessionMessageType { + kGMPLicenseRequest = 0, + kGMPLicenseRenewal = 1, + kGMPLicenseRelease = 2, + kGMPIndividualizationRequest = 3, + kGMPMessageInvalid = 4 // Must always be last. +}; + +enum GMPMediaKeyStatus { + kGMPUsable = 0, + kGMPExpired = 1, + kGMPOutputDownscaled = 2, + kGMPOutputRestricted = 3, + kGMPInternalError = 4, + kGMPUnknown = 5, // Removes key from MediaKeyStatusMap + kGMPReleased = 6, + kGMPStatusPending = 7, + kGMPMediaKeyStatusInvalid = 8 // Must always be last. +}; + +struct GMPMediaKeyInfo { + GMPMediaKeyInfo() {} + GMPMediaKeyInfo(const uint8_t* aKeyId, + uint32_t aKeyIdSize, + GMPMediaKeyStatus aStatus) + : keyid(aKeyId) + , keyid_size(aKeyIdSize) + , status(aStatus) + {} + const uint8_t* keyid; + uint32_t keyid_size; + GMPMediaKeyStatus status; +}; + +// Time in milliseconds, as offset from epoch, 1 Jan 1970. +typedef int64_t GMPTimestamp; + +// Callbacks to be called from the CDM. Threadsafe. +class GMPDecryptorCallback { +public: + + // The GMPDecryptor should call this in response to a call to + // GMPDecryptor::CreateSession(). The GMP host calls CreateSession() when + // MediaKeySession.generateRequest() is called by JavaScript. + // After CreateSession() is called, the GMPDecryptor should call + // GMPDecryptorCallback::SetSessionId() to set the sessionId exposed to + // JavaScript on the MediaKeySession on which the generateRequest() was + // called. SetSessionId() must be called before + // GMPDecryptorCallback::SessionMessage() will work. + // aSessionId must be null terminated. + // Note: pass the aCreateSessionToken from the CreateSession() call, + // and then once the session has sent any messages required for the + // license request to be sent, then resolve the aPromiseId that was passed + // to GMPDecryptor::CreateSession(). + // Note: GMPDecryptor::LoadSession() does *not* need to call SetSessionId() + // for GMPDecryptorCallback::SessionMessage() to work. + virtual void SetSessionId(uint32_t aCreateSessionToken, + const char* aSessionId, + uint32_t aSessionIdLength) = 0; + + // Resolves a promise for a session loaded. + // Resolves to false if we don't have any session data stored for the given + // session ID. + // Must be called before SessionMessage(). + virtual void ResolveLoadSessionPromise(uint32_t aPromiseId, + bool aSuccess) = 0; + + // Called to resolve a specified promise with "undefined". + 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 RejectPromise(uint32_t aPromiseId, + GMPDOMException aException, + const char* aMessage, + uint32_t aMessageLength) = 0; + + // Called by the CDM when it has a message for a session. + // Length parameters should not include null termination. + // aSessionId must be null terminated. + virtual void SessionMessage(const char* aSessionId, + uint32_t aSessionIdLength, + GMPSessionMessageType aMessageType, + const uint8_t* aMessage, + uint32_t aMessageLength) = 0; + + // aSessionId must be null terminated. + 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 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 SessionError(const char* aSessionId, + uint32_t aSessionIdLength, + GMPDOMException aException, + uint32_t aSystemCode, + const char* aMessage, + uint32_t aMessageLength) = 0; + + // Notifies the status of a key. 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 KeyStatusChanged(const char* aSessionId, + uint32_t aSessionIdLength, + const uint8_t* aKeyId, + uint32_t aKeyIdLength, + GMPMediaKeyStatus aStatus) = 0; + + // DEPRECATED; this function has no affect. + virtual void SetCapabilities(uint64_t aCaps) = 0; + + // Returns decrypted buffer to Gecko, or reports failure. + virtual void Decrypted(GMPBuffer* aBuffer, GMPErr aResult) = 0; + + // To aggregate KeyStatusChanged into single callback per session id. + virtual void BatchedKeyStatusChanged(const char* aSessionId, + uint32_t aSessionIdLength, + const GMPMediaKeyInfo* aKeyInfos, + uint32_t aKeyInfosLength) = 0; + + virtual ~GMPDecryptorCallback() {} +}; + +// Host interface, passed to GetAPIFunc(), with "decrypt". +class GMPDecryptorHost { +public: + virtual void GetSandboxVoucher(const uint8_t** aVoucher, + uint32_t* aVoucherLength) = 0; + + virtual void GetPluginVoucher(const uint8_t** aVoucher, + uint32_t* aVoucherLength) = 0; + + virtual ~GMPDecryptorHost() {} +}; + +enum GMPSessionType { + kGMPTemporySession = 0, + kGMPPersistentSession = 1, + kGMPSessionInvalid = 2 // Must always be last. +}; + +// Gecko supports the current GMPDecryptor version, and the obsolete +// version that the Adobe GMP still uses. +#define GMP_API_DECRYPTOR "eme-decrypt-v9" +#define GMP_API_DECRYPTOR_BACKWARDS_COMPAT "eme-decrypt-v7" + +// API exposed by plugin library to manage decryption sessions. +// When the Host requests this by calling GMPGetAPIFunc(). +// +// API name macro: GMP_API_DECRYPTOR +// Host API: GMPDecryptorHost +class GMPDecryptor { +public: + + // Sets the callback to use with the decryptor to return results + // to Gecko. + virtual void Init(GMPDecryptorCallback* aCallback, + bool aDistinctiveIdentifierRequired, + bool aPersistentStateRequired) = 0; + + // Initiates the creation of a session given |aType| and |aInitData|, and + // the generation of a license request message. + // + // This corresponds to a MediaKeySession.generateRequest() call in JS. + // + // The GMPDecryptor must do the following, in order, upon this method + // being called: + // + // 1. Generate a sessionId to expose to JS, and call + // GMPDecryptorCallback::SetSessionId(aCreateSessionToken, sessionId...) + // with the sessionId to be exposed to JS/EME on the MediaKeySession + // object on which generateRequest() was called, and then + // 2. send any messages to JS/EME required to generate a license request + // given the supplied initData, and then + // 3. generate a license request message, and send it to JS/EME, and then + // 4. call GMPDecryptorCallback::ResolvePromise(). + // + // Note: GMPDecryptorCallback::SetSessionId(aCreateSessionToken, sessionId, ...) + // *must* be called before GMPDecryptorCallback::SendMessage(sessionId, ...) + // will work. + // + // If generating the request fails, reject aPromiseId by calling + // GMPDecryptorCallback::RejectPromise(). + virtual void CreateSession(uint32_t aCreateSessionToken, + uint32_t aPromiseId, + const char* aInitDataType, + uint32_t aInitDataTypeSize, + const uint8_t* aInitData, + uint32_t aInitDataSize, + GMPSessionType aSessionType) = 0; + + // Loads a previously loaded persistent session. + // + // This corresponds to a MediaKeySession.load() call in JS. + // + // The GMPDecryptor must do the following, in order, upon this method + // being called: + // + // 1. Send any messages to JS/EME, or read from storage, whatever is + // required to load the session, and then + // 2. if there is no session with the given sessionId loadable, call + // ResolveLoadSessionPromise(aPromiseId, false), otherwise + // 2. mark the session's keys as usable, and then + // 3. update the session's expiration, and then + // 4. call GMPDecryptorCallback::ResolveLoadSessionPromise(aPromiseId, true). + // + // If loading the session fails due to error, reject aPromiseId by calling + // GMPDecryptorCallback::RejectPromise(). + virtual void LoadSession(uint32_t aPromiseId, + const char* aSessionId, + uint32_t aSessionIdLength) = 0; + + // Updates the session with |aResponse|. + // This corresponds to a MediaKeySession.update() call in JS. + virtual void UpdateSession(uint32_t aPromiseId, + const char* aSessionId, + uint32_t aSessionIdLength, + const uint8_t* aResponse, + uint32_t aResponseSize) = 0; + + // Releases the resources (keys) for the specified session. + // This corresponds to a MediaKeySession.close() call in JS. + virtual void CloseSession(uint32_t aPromiseId, + const char* aSessionId, + uint32_t aSessionIdLength) = 0; + + // Removes the resources (keys) for the specified session. + // This corresponds to a MediaKeySession.remove() call in JS. + virtual void RemoveSession(uint32_t aPromiseId, + const char* aSessionId, + uint32_t aSessionIdLength) = 0; + + // Resolve/reject promise on completion. + // This corresponds to a MediaKeySession.setServerCertificate() call in JS. + 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. + // Note: When Decrypted() is called and aBuffer is passed back, aBuffer + // is deleted. Don't forget to call Decrypted(), as otherwise aBuffer's + // memory will leak! + virtual void Decrypt(GMPBuffer* aBuffer, + GMPEncryptedBufferMetadata* aMetadata) = 0; + + // Called when the decryption operations are complete. + // Do not call the GMPDecryptorCallback's functions after this is called. + virtual void DecryptingComplete() = 0; + + virtual ~GMPDecryptor() {} +}; + +// v7 is the latest decryptor version supported by the Adobe GMP. +// +// API name macro: GMP_API_DECRYPTOR_BACKWARDS_COMPAT +// Host API: GMPDecryptorHost +class GMPDecryptor7 { +public: + + // Sets the callback to use with the decryptor to return results + // to Gecko. + virtual void Init(GMPDecryptorCallback* aCallback) = 0; + + // Initiates the creation of a session given |aType| and |aInitData|, and + // the generation of a license request message. + // + // This corresponds to a MediaKeySession.generateRequest() call in JS. + // + // The GMPDecryptor must do the following, in order, upon this method + // being called: + // + // 1. Generate a sessionId to expose to JS, and call + // GMPDecryptorCallback::SetSessionId(aCreateSessionToken, sessionId...) + // with the sessionId to be exposed to JS/EME on the MediaKeySession + // object on which generateRequest() was called, and then + // 2. send any messages to JS/EME required to generate a license request + // given the supplied initData, and then + // 3. generate a license request message, and send it to JS/EME, and then + // 4. call GMPDecryptorCallback::ResolvePromise(). + // + // Note: GMPDecryptorCallback::SetSessionId(aCreateSessionToken, sessionId, ...) + // *must* be called before GMPDecryptorCallback::SendMessage(sessionId, ...) + // will work. + // + // If generating the request fails, reject aPromiseId by calling + // GMPDecryptorCallback::RejectPromise(). + virtual void CreateSession(uint32_t aCreateSessionToken, + uint32_t aPromiseId, + const char* aInitDataType, + uint32_t aInitDataTypeSize, + const uint8_t* aInitData, + uint32_t aInitDataSize, + GMPSessionType aSessionType) = 0; + + // Loads a previously loaded persistent session. + // + // This corresponds to a MediaKeySession.load() call in JS. + // + // The GMPDecryptor must do the following, in order, upon this method + // being called: + // + // 1. Send any messages to JS/EME, or read from storage, whatever is + // required to load the session, and then + // 2. if there is no session with the given sessionId loadable, call + // ResolveLoadSessionPromise(aPromiseId, false), otherwise + // 2. mark the session's keys as usable, and then + // 3. update the session's expiration, and then + // 4. call GMPDecryptorCallback::ResolveLoadSessionPromise(aPromiseId, true). + // + // If loading the session fails due to error, reject aPromiseId by calling + // GMPDecryptorCallback::RejectPromise(). + virtual void LoadSession(uint32_t aPromiseId, + const char* aSessionId, + uint32_t aSessionIdLength) = 0; + + // Updates the session with |aResponse|. + // This corresponds to a MediaKeySession.update() call in JS. + virtual void UpdateSession(uint32_t aPromiseId, + const char* aSessionId, + uint32_t aSessionIdLength, + const uint8_t* aResponse, + uint32_t aResponseSize) = 0; + + // Releases the resources (keys) for the specified session. + // This corresponds to a MediaKeySession.close() call in JS. + virtual void CloseSession(uint32_t aPromiseId, + const char* aSessionId, + uint32_t aSessionIdLength) = 0; + + // Removes the resources (keys) for the specified session. + // This corresponds to a MediaKeySession.remove() call in JS. + virtual void RemoveSession(uint32_t aPromiseId, + const char* aSessionId, + uint32_t aSessionIdLength) = 0; + + // Resolve/reject promise on completion. + // This corresponds to a MediaKeySession.setServerCertificate() call in JS. + 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. + // Note: When Decrypted() is called and aBuffer is passed back, aBuffer + // is deleted. Don't forget to call Decrypted(), as otherwise aBuffer's + // memory will leak! + virtual void Decrypt(GMPBuffer* aBuffer, + GMPEncryptedBufferMetadata* aMetadata) = 0; + + // Called when the decryption operations are complete. + // Do not call the GMPDecryptorCallback's functions after this is called. + virtual void DecryptingComplete() = 0; + + virtual ~GMPDecryptor7() {} +}; + +#endif // GMP_DECRYPTION_h_ diff --git a/dom/media/gmp/gmp-api/gmp-entrypoints.h b/dom/media/gmp/gmp-api/gmp-entrypoints.h new file mode 100644 index 0000000000..214c9dbfc0 --- /dev/null +++ b/dom/media/gmp/gmp-api/gmp-entrypoints.h @@ -0,0 +1,75 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* Copyright (c) 2011, The WebRTC project authors. All rights reserved. + * Copyright (c) 2014, Mozilla + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + ** Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + ** Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + ** Neither the name of Google nor the names of its contributors may + * be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef GMP_ENTRYPOINTS_h_ +#define GMP_ENTRYPOINTS_h_ + +#include "gmp-errors.h" +#include "gmp-platform.h" + +/* C functions exposed by Gecko Media Plugin shared library. */ + +// GMPInit +// - Called once after plugin library is loaded, before GMPGetAPI or GMPShutdown are called. +// - Called on main thread. +// - 'aPlatformAPI' is a structure containing platform-provided APIs. It is valid until +// 'GMPShutdown' is called. Owned and must be deleted by plugin. +typedef GMPErr (*GMPInitFunc)(const GMPPlatformAPI* aPlatformAPI); + +// GMPGetAPI +// - Called when host wants to use an API. +// - Called on main thread. +// - 'aAPIName' is a string indicating the API being requested. This should +// match one of the GMP_API_* macros. Subsequent iterations of the GMP_APIs +// may change the value of the GMP_API_* macros when ABI changes occur. So +// make sure you compare aAPIName against the corresponding GMP_API_* macro! +// - 'aHostAPI' is the host API which is specific to the API being requested +// from the plugin. It is valid so long as the API object requested from the +// plugin is valid. It is owned by the host, plugin should not attempt to delete. +// May be null. +// - 'aPluginAPI' is for returning the requested API. Destruction of the requsted +// API object is defined by the API. +typedef GMPErr (*GMPGetAPIFunc)(const char* aAPIName, void* aHostAPI, void** aPluginAPI); + +// GMPShutdown +// - Called once before exiting process (unloading library). +// - Called on main thread. +typedef void (*GMPShutdownFunc)(void); + +// GMPSetNodeId +// - Optional, not required to be implemented. Only useful for EME plugins. +// - Called after GMPInit to set the device-bound origin-specific node id +// that this GMP instance is running under. +typedef void (*GMPSetNodeIdFunc)(const char* aNodeId, uint32_t aLength); + +#endif // GMP_ENTRYPOINTS_h_ diff --git a/dom/media/gmp/gmp-api/gmp-errors.h b/dom/media/gmp/gmp-api/gmp-errors.h new file mode 100644 index 0000000000..7f20e2a79b --- /dev/null +++ b/dom/media/gmp/gmp-api/gmp-errors.h @@ -0,0 +1,58 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* Copyright (c) 2014, Mozilla + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + ** Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + ** Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + ** Neither the name of Google nor the names of its contributors may + * be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef GMP_ERRORS_h_ +#define GMP_ERRORS_h_ + +typedef enum { + GMPNoErr = 0, + GMPGenericErr = 1, + GMPClosedErr = 2, + GMPAllocErr = 3, + GMPNotImplementedErr = 4, + GMPRecordInUse = 5, + GMPQuotaExceededErr = 6, + GMPDecodeErr = 7, + GMPEncodeErr = 8, + GMPNoKeyErr = 9, + GMPCryptoErr = 10, + GMPEndOfEnumeration = 11, + GMPInvalidArgErr = 12, + GMPAbortedErr = 13, + GMPRecordCorrupted = 14, + GMPLastErr // Placeholder, must be last. This enum's values must remain consecutive! +} GMPErr; + +#define GMP_SUCCEEDED(x) ((x) == GMPNoErr) +#define GMP_FAILED(x) ((x) != GMPNoErr) + +#endif // GMP_ERRORS_h_ diff --git a/dom/media/gmp/gmp-api/gmp-platform.h b/dom/media/gmp/gmp-api/gmp-platform.h new file mode 100644 index 0000000000..f915050b31 --- /dev/null +++ b/dom/media/gmp/gmp-api/gmp-platform.h @@ -0,0 +1,118 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* Copyright (c) 2014, Mozilla + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + ** Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + ** Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + ** Neither the name of Google nor the names of its contributors may + * be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef GMP_PLATFORM_h_ +#define GMP_PLATFORM_h_ + +#include "gmp-errors.h" +#include "gmp-storage.h" +#include <stdint.h> + +/* Platform helper API. */ + +class GMPTask { +public: + virtual void Destroy() = 0; // Deletes object. + virtual ~GMPTask() {} + virtual void Run() = 0; +}; + +class GMPThread { +public: + virtual ~GMPThread() {} + virtual void Post(GMPTask* aTask) = 0; + virtual void Join() = 0; // Deletes object after join completes. +}; + +// A re-entrant monitor; can be locked from the same thread multiple times. +// Must be unlocked the same number of times it's locked. +class GMPMutex { +public: + virtual ~GMPMutex() {} + virtual void Acquire() = 0; + virtual void Release() = 0; + virtual void Destroy() = 0; // Deletes object. +}; + +// Time is defined as the number of milliseconds since the +// Epoch (00:00:00 UTC, January 1, 1970). +typedef int64_t GMPTimestamp; + +typedef GMPErr (*GMPCreateThreadPtr)(GMPThread** aThread); +typedef GMPErr (*GMPRunOnMainThreadPtr)(GMPTask* aTask); +typedef GMPErr (*GMPSyncRunOnMainThreadPtr)(GMPTask* aTask); +typedef GMPErr (*GMPCreateMutexPtr)(GMPMutex** aMutex); + +// Call on main thread only. +typedef GMPErr (*GMPCreateRecordPtr)(const char* aRecordName, + uint32_t aRecordNameSize, + GMPRecord** aOutRecord, + GMPRecordClient* aClient); + +// Call on main thread only. +typedef GMPErr (*GMPSetTimerOnMainThreadPtr)(GMPTask* aTask, int64_t aTimeoutMS); +typedef GMPErr (*GMPGetCurrentTimePtr)(GMPTimestamp* aOutTime); + +typedef void (*RecvGMPRecordIteratorPtr)(GMPRecordIterator* aRecordIterator, + void* aUserArg, + GMPErr aStatus); + +// Creates a GMPCreateRecordIterator to enumerate the records in storage. +// When the iterator is ready, the function at aRecvIteratorFunc +// is called with the GMPRecordIterator as an argument. If the operation +// fails, RecvGMPRecordIteratorPtr is called with a failure aStatus code. +// The list that the iterator is covering is fixed when +// GMPCreateRecordIterator is called, it is *not* updated when changes are +// made to storage. +// Iterator begins pointing at first record. +// aUserArg is passed to the aRecvIteratorFunc upon completion. +typedef GMPErr (*GMPCreateRecordIteratorPtr)(RecvGMPRecordIteratorPtr aRecvIteratorFunc, + void* aUserArg); + +struct GMPPlatformAPI { + // Increment the version when things change. Can only add to the struct, + // do not change what already exists. Pointers to functions may be NULL + // when passed to plugins, but beware backwards compat implications of + // doing that. + uint16_t version; // Currently version 0 + + GMPCreateThreadPtr createthread; + GMPRunOnMainThreadPtr runonmainthread; + GMPSyncRunOnMainThreadPtr syncrunonmainthread; + GMPCreateMutexPtr createmutex; + GMPCreateRecordPtr createrecord; + GMPSetTimerOnMainThreadPtr settimer; + GMPGetCurrentTimePtr getcurrenttime; + GMPCreateRecordIteratorPtr getrecordenumerator; +}; + +#endif // GMP_PLATFORM_h_ diff --git a/dom/media/gmp/gmp-api/gmp-storage.h b/dom/media/gmp/gmp-api/gmp-storage.h new file mode 100644 index 0000000000..43ad12b01a --- /dev/null +++ b/dom/media/gmp/gmp-api/gmp-storage.h @@ -0,0 +1,141 @@ +/* +* Copyright 2013, Mozilla Foundation and contributors +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#ifndef GMP_STORAGE_h_ +#define GMP_STORAGE_h_ + +#include "gmp-errors.h" +#include <stdint.h> + +// Maximum size of a record, in bytes; 10 megabytes. +#define GMP_MAX_RECORD_SIZE (10 * 1024 * 1024) + +// Maximum length of a record name in bytes. +#define GMP_MAX_RECORD_NAME_SIZE 2000 + +// Provides basic per-origin storage for CDMs. GMPRecord instances can be +// 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. +// +// Lifecycle: Once opened, the GMPRecord object remains allocated until +// GMPRecord::Close() is called. If any GMPRecord function, either +// synchronously or asynchronously through a GMPRecordClient callback, +// returns an error, the GMP is responsible for calling Close() on the +// GMPRecord to delete the GMPRecord object's memory. If your GMP does not +// call Close(), the GMPRecord's memory will leak. +class GMPRecord { +public: + + // Opens the record. Calls OpenComplete() once the record is open. + // Note: Only work when GMP is loading content from a webserver. + // Does not work for web pages on loaded from disk. + // Note: OpenComplete() is only called if this returns GMPNoErr. + virtual GMPErr Open() = 0; + + // 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 record, overwriting the + // contents of the record, truncating it to aDataSize length. + // Overwriting with 0 bytes "deletes" the record. + // Note: WriteComplete is only called if this returns GMPNoErr. + virtual GMPErr Write(const uint8_t* aData, uint32_t aDataSize) = 0; + + // Closes a record, deletes the GMPRecord object. The 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() {} +}; + +// Callback object that receives the results of GMPRecord calls. Callbacks +// run asynchronously to the GMPRecord call, on the main thread. +class GMPRecordClient { + public: + + // Response to a GMPRecord::Open() call with the open |status|. + // aStatus values: + // - GMPNoErr - Record opened successfully. Record may be empty. + // - GMPRecordInUse - This record is in use by another client. + // - GMPGenericErr - Unspecified error. + // If aStatus is not GMPNoErr, the GMPRecord is unusable, and you must + // call Close() on the GMPRecord to dispose of it. + virtual void OpenComplete(GMPErr aStatus) = 0; + + // 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 ReadComplete. + // Copy it if you want to hang onto it! + // aStatus values: + // - GMPNoErr - Record contents read successfully, aDataSize 0 means record + // is empty. + // - GMPRecordInUse - There are other operations or clients in use on + // this record. + // - GMPGenericErr - Unspecified error. + // If aStatus is not GMPNoErr, the GMPRecord is unusable, and you must + // call Close() on the GMPRecord to dispose of it. + virtual void ReadComplete(GMPErr aStatus, + const uint8_t* aData, + uint32_t aDataSize) = 0; + + // Response to a GMPRecord::Write() call. + // - GMPNoErr - File contents written successfully. + // - GMPRecordInUse - There are other operations or clients in use on + // this record. + // - GMPGenericErr - Unspecified error. + // If aStatus is not GMPNoErr, the GMPRecord is unusable, and you must + // call Close() on the GMPRecord to dispose of it. + virtual void WriteComplete(GMPErr aStatus) = 0; + + virtual ~GMPRecordClient() {} +}; + +// Iterates over the records that are available. Note: this list maintains +// a snapshot of the records that were present when the iterator was created. +// Create by calling the GMPCreateRecordIteratorPtr function on the +// GMPPlatformAPI struct. +// Iteration is in alphabetical order. +class GMPRecordIterator { +public: + // Retrieve the name for the current record. + // aOutName is null terminated at character at index (*aOutNameLength). + // Returns GMPNoErr if successful, or GMPEndOfEnumeration if iteration has + // reached the end. + virtual GMPErr GetName(const char ** aOutName, uint32_t * aOutNameLength) = 0; + + // Advance iteration to the next record. + // Returns GMPNoErr if successful, or GMPEndOfEnumeration if iteration has + // reached the end. + virtual GMPErr NextRecord() = 0; + + // Signals to the GMP host that the GMP is finished with the + // GMPRecordIterator. GMPs must call this to release memory held by + // the GMPRecordIterator. Do not access the GMPRecordIterator pointer + // after calling this! + // Memory retrieved by GetName is *not* valid after calling Close()! + virtual void Close() = 0; + + virtual ~GMPRecordIterator() {} +}; + +#endif // GMP_STORAGE_h_ diff --git a/dom/media/gmp/gmp-api/gmp-video-codec.h b/dom/media/gmp/gmp-api/gmp-video-codec.h new file mode 100644 index 0000000000..e068ab43dd --- /dev/null +++ b/dom/media/gmp/gmp-api/gmp-video-codec.h @@ -0,0 +1,226 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* Copyright (c) 2011, The WebRTC project authors. All rights reserved. + * Copyright (c) 2014, Mozilla + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + ** Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + ** Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + ** Neither the name of Google nor the names of its contributors may + * be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef GMP_VIDEO_CODEC_h_ +#define GMP_VIDEO_CODEC_h_ + +#include <stdint.h> +#include <stddef.h> + +enum { kGMPPayloadNameSize = 32}; +enum { kGMPMaxSimulcastStreams = 4}; + +enum GMPVideoCodecComplexity +{ + kGMPComplexityNormal = 0, + kGMPComplexityHigh = 1, + kGMPComplexityHigher = 2, + kGMPComplexityMax = 3, + kGMPComplexityInvalid // Should always be last +}; + +enum GMPVP8ResilienceMode { + kResilienceOff, // The stream produced by the encoder requires a + // recovery frame (typically a key frame) to be + // decodable after a packet loss. + kResilientStream, // A stream produced by the encoder is resilient to + // packet losses, but packets within a frame subsequent + // to a loss can't be decoded. + kResilientFrames, // Same as kResilientStream but with added resilience + // within a frame. + kResilienceInvalid // Should always be last. +}; + +// VP8 specific +struct GMPVideoCodecVP8 +{ + bool mPictureLossIndicationOn; + bool mFeedbackModeOn; + GMPVideoCodecComplexity mComplexity; + GMPVP8ResilienceMode mResilience; + uint32_t mNumberOfTemporalLayers; + bool mDenoisingOn; + bool mErrorConcealmentOn; + bool mAutomaticResizeOn; +}; + +// H264 specific + +// Needs to match a binary spec for this structure. +// Note: the mSPS at the end of this structure is variable length. +struct GMPVideoCodecH264AVCC +{ + uint8_t mVersion; // == 0x01 + uint8_t mProfile; // these 3 are profile_level_id + uint8_t mConstraints; + uint8_t mLevel; + uint8_t mLengthSizeMinusOne; // lower 2 bits (== GMPBufferType-1). Top 6 reserved (1's) + + // SPS/PPS will not generally be present for interactive use unless SDP + // parameter-sets are used. + uint8_t mNumSPS; // lower 5 bits; top 5 reserved (1's) + + /*** uint8_t mSPS[]; (Not defined due to compiler warnings and warnings-as-errors ...) **/ + // Following mNumSPS is a variable number of bytes, which is the SPS and PPS. + // Each SPS == 16 bit size, ("N"), then "N" bytes, + // then uint8_t mNumPPS, then each PPS == 16 bit size ("N"), then "N" bytes. +}; + +// Codec specific data for H.264 decoding/encoding. +// Cast the "aCodecSpecific" parameter of GMPVideoDecoder::InitDecode() and +// GMPVideoEncoder::InitEncode() to this structure. +struct GMPVideoCodecH264 +{ + uint8_t mPacketizationMode; // 0 or 1 + struct GMPVideoCodecH264AVCC mAVCC; // holds a variable-sized struct GMPVideoCodecH264AVCC mAVCC; +}; + +enum GMPVideoCodecType +{ + kGMPVideoCodecVP8, + + // Encoded frames are in AVCC format; NAL length field of 4 bytes, followed + // by frame data. May be multiple NALUs per sample. Codec specific extra data + // is the AVCC extra data (in AVCC format). + kGMPVideoCodecH264, + kGMPVideoCodecVP9, + kGMPVideoCodecInvalid // Should always be last. +}; + +// Simulcast is when the same stream is encoded multiple times with different +// settings such as resolution. +struct GMPSimulcastStream +{ + uint32_t mWidth; + uint32_t mHeight; + uint32_t mNumberOfTemporalLayers; + uint32_t mMaxBitrate; // kilobits/sec. + uint32_t mTargetBitrate; // kilobits/sec. + uint32_t mMinBitrate; // kilobits/sec. + uint32_t mQPMax; // minimum quality +}; + +enum GMPVideoCodecMode { + kGMPRealtimeVideo, + kGMPScreensharing, + kGMPStreamingVideo, + kGMPCodecModeInvalid // Should always be last. +}; + +enum GMPApiVersion { + kGMPVersion32 = 1, // leveraging that V32 had mCodecType first, and only supported H264 + kGMPVersion33 = 33, +}; + +struct GMPVideoCodec +{ + uint32_t mGMPApiVersion; + + GMPVideoCodecType mCodecType; + char mPLName[kGMPPayloadNameSize]; // Must be NULL-terminated! + uint32_t mPLType; + + uint32_t mWidth; + uint32_t mHeight; + + uint32_t mStartBitrate; // kilobits/sec. + uint32_t mMaxBitrate; // kilobits/sec. + uint32_t mMinBitrate; // kilobits/sec. + uint32_t mMaxFramerate; + + bool mFrameDroppingOn; + int32_t mKeyFrameInterval; + + uint32_t mQPMax; + uint32_t mNumberOfSimulcastStreams; + GMPSimulcastStream mSimulcastStream[kGMPMaxSimulcastStreams]; + + GMPVideoCodecMode mMode; +}; + +// Either single encoded unit, or multiple units separated by 8/16/24/32 +// bit lengths, all with the same timestamp. Note there is no final 0-length +// entry; one should check the overall end-of-buffer against where the next +// length would be. +enum GMPBufferType { + GMP_BufferSingle = 0, + GMP_BufferLength8, + GMP_BufferLength16, + GMP_BufferLength24, + GMP_BufferLength32, + GMP_BufferInvalid, +}; + +struct GMPCodecSpecificInfoGeneric { + uint8_t mSimulcastIdx; +}; + +struct GMPCodecSpecificInfoH264 { + uint8_t mSimulcastIdx; +}; + +// Note: if any pointers are added to this struct, it must be fitted +// with a copy-constructor. See below. +struct GMPCodecSpecificInfoVP8 +{ + bool mHasReceivedSLI; + uint8_t mPictureIdSLI; + bool mHasReceivedRPSI; + uint64_t mPictureIdRPSI; + int16_t mPictureId; // negative value to skip pictureId + bool mNonReference; + uint8_t mSimulcastIdx; + uint8_t mTemporalIdx; + bool mLayerSync; + int32_t mTL0PicIdx; // negative value to skip tl0PicIdx + int8_t mKeyIdx; // negative value to skip keyIdx +}; + +union GMPCodecSpecificInfoUnion +{ + GMPCodecSpecificInfoGeneric mGeneric; + GMPCodecSpecificInfoVP8 mVP8; + GMPCodecSpecificInfoH264 mH264; +}; + +// Note: if any pointers are added to this struct or its sub-structs, it +// must be fitted with a copy-constructor. This is because it is copied +// in the copy-constructor of VCMEncodedFrame. +struct GMPCodecSpecificInfo +{ + GMPVideoCodecType mCodecType; + GMPBufferType mBufferType; + GMPCodecSpecificInfoUnion mCodecSpecific; +}; + +#endif // GMP_VIDEO_CODEC_h_ diff --git a/dom/media/gmp/gmp-api/gmp-video-decode.h b/dom/media/gmp/gmp-api/gmp-video-decode.h new file mode 100644 index 0000000000..e07a7525e9 --- /dev/null +++ b/dom/media/gmp/gmp-api/gmp-video-decode.h @@ -0,0 +1,127 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* Copyright (c) 2011, The WebRTC project authors. All rights reserved. + * Copyright (c) 2014, Mozilla + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + ** Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + ** Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + ** Neither the name of Google nor the names of its contributors may + * be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef GMP_VIDEO_DECODE_h_ +#define GMP_VIDEO_DECODE_h_ + +#include "gmp-errors.h" +#include "gmp-video-frame-i420.h" +#include "gmp-video-frame-encoded.h" +#include "gmp-video-codec.h" +#include <stdint.h> + +// ALL METHODS MUST BE CALLED ON THE MAIN THREAD +class GMPVideoDecoderCallback +{ +public: + virtual ~GMPVideoDecoderCallback() {} + + virtual void Decoded(GMPVideoi420Frame* aDecodedFrame) = 0; + + virtual void ReceivedDecodedReferenceFrame(const uint64_t aPictureId) = 0; + + virtual void ReceivedDecodedFrame(const uint64_t aPictureId) = 0; + + virtual void InputDataExhausted() = 0; + + virtual void DrainComplete() = 0; + + virtual void ResetComplete() = 0; + + // Called when the decoder encounters a catestrophic error and cannot + // continue. Gecko will not send any more input for decoding. + virtual void Error(GMPErr aError) = 0; +}; + +#define GMP_API_VIDEO_DECODER "decode-video" + +// Video decoding for a single stream. A GMP may be asked to create multiple +// decoders concurrently. +// +// API name macro: GMP_API_VIDEO_DECODER +// Host API: GMPVideoHost +// +// ALL METHODS MUST BE CALLED ON THE MAIN THREAD +class GMPVideoDecoder +{ +public: + virtual ~GMPVideoDecoder() {} + + // - aCodecSettings: Details of decoder to create. + // - aCodecSpecific: codec specific data, cast to a GMPVideoCodecXXX struct + // to get codec specific config data. + // - aCodecSpecificLength: number of bytes in aCodecSpecific. + // - aCallback: Subclass should retain reference to it until DecodingComplete + // is called. Do not attempt to delete it, host retains ownership. + // aCoreCount: number of CPU cores. + virtual void InitDecode(const GMPVideoCodec& aCodecSettings, + const uint8_t* aCodecSpecific, + uint32_t aCodecSpecificLength, + GMPVideoDecoderCallback* aCallback, + int32_t aCoreCount) = 0; + + // Decode encoded frame (as a part of a video stream). The decoded frame + // will be returned to the user through the decode complete callback. + // + // - aInputFrame: Frame to decode. Call Destroy() on frame when it's decoded. + // - aMissingFrames: True if one or more frames have been lost since the + // previous decode call. + // - aCodecSpecificInfo : codec specific data, pointer to a + // GMPCodecSpecificInfo structure appropriate for + // this codec type. + // - aCodecSpecificInfoLength : number of bytes in aCodecSpecificInfo + // - renderTimeMs : System time to render in milliseconds. Only used by + // decoders with internal rendering. + virtual void Decode(GMPVideoEncodedFrame* aInputFrame, + bool aMissingFrames, + const uint8_t* aCodecSpecificInfo, + uint32_t aCodecSpecificInfoLength, + int64_t aRenderTimeMs = -1) = 0; + + // Reset decoder state and prepare for a new call to Decode(...). + // Flushes the decoder pipeline. + // The decoder should enqueue a task to run ResetComplete() on the main + // thread once the reset has finished. + virtual void Reset() = 0; + + // Output decoded frames for any data in the pipeline, regardless of ordering. + // All remaining decoded frames should be immediately returned via callback. + // The decoder should enqueue a task to run DrainComplete() on the main + // thread once the reset has finished. + virtual void Drain() = 0; + + // May free decoder memory. + virtual void DecodingComplete() = 0; +}; + +#endif // GMP_VIDEO_DECODE_h_ diff --git a/dom/media/gmp/gmp-api/gmp-video-encode.h b/dom/media/gmp/gmp-api/gmp-video-encode.h new file mode 100644 index 0000000000..5c9cde39cd --- /dev/null +++ b/dom/media/gmp/gmp-api/gmp-video-encode.h @@ -0,0 +1,135 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* Copyright (c) 2011, The WebRTC project authors. All rights reserved. + * Copyright (c) 2014, Mozilla + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + ** Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + ** Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + ** Neither the name of Google nor the names of its contributors may + * be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef GMP_VIDEO_ENCODE_h_ +#define GMP_VIDEO_ENCODE_h_ + +#include <vector> +#include <stdint.h> + +#include "gmp-errors.h" +#include "gmp-video-frame-i420.h" +#include "gmp-video-frame-encoded.h" +#include "gmp-video-codec.h" + +// ALL METHODS MUST BE CALLED ON THE MAIN THREAD +class GMPVideoEncoderCallback +{ +public: + virtual ~GMPVideoEncoderCallback() {} + + virtual void Encoded(GMPVideoEncodedFrame* aEncodedFrame, + const uint8_t* aCodecSpecificInfo, + uint32_t aCodecSpecificInfoLength) = 0; + + // Called when the encoder encounters a catestrophic error and cannot + // continue. Gecko will not send any more input for encoding. + virtual void Error(GMPErr aError) = 0; +}; + +#define GMP_API_VIDEO_ENCODER "encode-video" + +// Video encoding for a single stream. A GMP may be asked to create multiple +// encoders concurrently. +// +// API name macro: GMP_API_VIDEO_ENCODER +// Host API: GMPVideoHost +// +// ALL METHODS MUST BE CALLED ON THE MAIN THREAD +class GMPVideoEncoder +{ +public: + virtual ~GMPVideoEncoder() {} + + // Initialize the encoder with the information from the VideoCodec. + // + // Input: + // - codecSettings : Codec settings + // - aCodecSpecific : codec specific data, pointer to a + // GMPCodecSpecific structure appropriate for + // this codec type. + // - aCodecSpecificLength : number of bytes in aCodecSpecific + // - aCallback: Subclass should retain reference to it until EncodingComplete + // is called. Do not attempt to delete it, host retains ownership. + // - aNnumberOfCores : Number of cores available for the encoder + // - aMaxPayloadSize : The maximum size each payload is allowed + // to have. Usually MTU - overhead. + virtual void InitEncode(const GMPVideoCodec& aCodecSettings, + const uint8_t* aCodecSpecific, + uint32_t aCodecSpecificLength, + GMPVideoEncoderCallback* aCallback, + int32_t aNumberOfCores, + uint32_t aMaxPayloadSize) = 0; + + // Encode an I420 frame (as a part of a video stream). The encoded frame + // will be returned to the user through the encode complete callback. + // + // Input: + // - aInputFrame : Frame to be encoded + // - aCodecSpecificInfo : codec specific data, pointer to a + // GMPCodecSpecificInfo structure appropriate for + // this codec type. + // - aCodecSpecificInfoLength : number of bytes in aCodecSpecific + // - aFrameTypes : The frame type to encode + // - aFrameTypesLength : The number of elements in aFrameTypes array. + virtual void Encode(GMPVideoi420Frame* aInputFrame, + const uint8_t* aCodecSpecificInfo, + uint32_t aCodecSpecificInfoLength, + const GMPVideoFrameType* aFrameTypes, + uint32_t aFrameTypesLength) = 0; + + // Inform the encoder about the packet loss and round trip time on the + // network used to decide the best pattern and signaling. + // + // - packetLoss : Fraction lost (loss rate in percent = + // 100 * packetLoss / 255) + // - rtt : Round-trip time in milliseconds + virtual void SetChannelParameters(uint32_t aPacketLoss, uint32_t aRTT) = 0; + + // Inform the encoder about the new target bit rate. + // + // - newBitRate : New target bit rate + // - frameRate : The target frame rate + virtual void SetRates(uint32_t aNewBitRate, uint32_t aFrameRate) = 0; + + // Use this function to enable or disable periodic key frames. Can be useful for codecs + // which have other ways of stopping error propagation. + // + // - enable : Enable or disable periodic key frames + virtual void SetPeriodicKeyFrames(bool aEnable) = 0; + + // May free Encoder memory. + virtual void EncodingComplete() = 0; +}; + +#endif // GMP_VIDEO_ENCODE_h_ diff --git a/dom/media/gmp/gmp-api/gmp-video-frame-encoded.h b/dom/media/gmp/gmp-api/gmp-video-frame-encoded.h new file mode 100644 index 0000000000..76af7349f9 --- /dev/null +++ b/dom/media/gmp/gmp-api/gmp-video-frame-encoded.h @@ -0,0 +1,99 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* Copyright (c) 2011, The WebRTC project authors. All rights reserved. + * Copyright (c) 2014, Mozilla + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + ** Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + ** Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + ** Neither the name of Google nor the names of its contributors may + * be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef GMP_VIDEO_FRAME_ENCODED_h_ +#define GMP_VIDEO_FRAME_ENCODED_h_ + +#include <stdint.h> +#include "gmp-decryption.h" +#include "gmp-video-frame.h" +#include "gmp-video-codec.h" + +enum GMPVideoFrameType +{ + kGMPKeyFrame = 0, + kGMPDeltaFrame = 1, + kGMPGoldenFrame = 2, + kGMPAltRefFrame = 3, + kGMPSkipFrame = 4, + kGMPVideoFrameInvalid = 5 // Must always be last. +}; + +// The implementation backing this interface uses shared memory for the +// buffer(s). This means it can only be used by the "owning" process. +// At first the process which created the object owns it. When the object +// is passed to an interface the creator loses ownership and must Destroy() +// the object. Further attempts to use it may fail due to not being able to +// access the underlying buffer(s). +// +// Methods that create or destroy shared memory must be called on the main +// thread. They are marked below. +class GMPVideoEncodedFrame : public GMPVideoFrame +{ +public: + // MAIN THREAD ONLY + virtual GMPErr CreateEmptyFrame(uint32_t aSize) = 0; + // MAIN THREAD ONLY + virtual GMPErr CopyFrame(const GMPVideoEncodedFrame& aVideoFrame) = 0; + virtual void SetEncodedWidth(uint32_t aEncodedWidth) = 0; + virtual uint32_t EncodedWidth() = 0; + virtual void SetEncodedHeight(uint32_t aEncodedHeight) = 0; + virtual uint32_t EncodedHeight() = 0; + // Microseconds + virtual void SetTimeStamp(uint64_t aTimeStamp) = 0; + virtual uint64_t TimeStamp() = 0; + // Set frame duration (microseconds) + // NOTE: next-frame's Timestamp() != this-frame's TimeStamp()+Duration() + // depending on rounding to avoid having to track roundoff errors + // and dropped/missing frames(!) (which may leave a large gap) + virtual void SetDuration(uint64_t aDuration) = 0; + virtual uint64_t Duration() const = 0; + virtual void SetFrameType(GMPVideoFrameType aFrameType) = 0; + virtual GMPVideoFrameType FrameType() = 0; + virtual void SetAllocatedSize(uint32_t aNewSize) = 0; + virtual uint32_t AllocatedSize() = 0; + virtual void SetSize(uint32_t aSize) = 0; + virtual uint32_t Size() = 0; + virtual void SetCompleteFrame(bool aCompleteFrame) = 0; + virtual bool CompleteFrame() = 0; + virtual const uint8_t* Buffer() const = 0; + virtual uint8_t* Buffer() = 0; + virtual GMPBufferType BufferType() const = 0; + virtual void SetBufferType(GMPBufferType aBufferType) = 0; + + // Get metadata describing how this frame is encrypted, or nullptr if the + // frame is not encrypted. + virtual const GMPEncryptedBufferMetadata* GetDecryptionData() const = 0; +}; + +#endif // GMP_VIDEO_FRAME_ENCODED_h_ diff --git a/dom/media/gmp/gmp-api/gmp-video-frame-i420.h b/dom/media/gmp/gmp-api/gmp-video-frame-i420.h new file mode 100644 index 0000000000..14c2c33cd5 --- /dev/null +++ b/dom/media/gmp/gmp-api/gmp-video-frame-i420.h @@ -0,0 +1,132 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* Copyright (c) 2011, The WebRTC project authors. All rights reserved. + * Copyright (c) 2014, Mozilla + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + ** Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + ** Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + ** Neither the name of Google nor the names of its contributors may + * be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef GMP_VIDEO_FRAME_I420_h_ +#define GMP_VIDEO_FRAME_I420_h_ + +#include "gmp-errors.h" +#include "gmp-video-frame.h" +#include "gmp-video-plane.h" + +#include <stdint.h> + +enum GMPPlaneType { + kGMPYPlane = 0, + kGMPUPlane = 1, + kGMPVPlane = 2, + kGMPNumOfPlanes = 3 +}; + +// The implementation backing this interface uses shared memory for the +// buffer(s). This means it can only be used by the "owning" process. +// At first the process which created the object owns it. When the object +// is passed to an interface the creator loses ownership and must Destroy() +// the object. Further attempts to use it may fail due to not being able to +// access the underlying buffer(s). +// +// Methods that create or destroy shared memory must be called on the main +// thread. They are marked below. +class GMPVideoi420Frame : public GMPVideoFrame { +public: + // MAIN THREAD ONLY + // CreateEmptyFrame: Sets frame dimensions and allocates buffers based + // on set dimensions - height and plane stride. + // If required size is bigger than the allocated one, new buffers of adequate + // size will be allocated. + virtual GMPErr CreateEmptyFrame(int32_t aWidth, int32_t aHeight, + int32_t aStride_y, int32_t aStride_u, int32_t aStride_v) = 0; + + // MAIN THREAD ONLY + // CreateFrame: Sets the frame's members and buffers. If required size is + // bigger than allocated one, new buffers of adequate size will be allocated. + virtual GMPErr CreateFrame(int32_t aSize_y, const uint8_t* aBuffer_y, + int32_t aSize_u, const uint8_t* aBuffer_u, + int32_t aSize_v, const uint8_t* aBuffer_v, + int32_t aWidth, int32_t aHeight, + int32_t aStride_y, int32_t aStride_u, int32_t aStride_v) = 0; + + // MAIN THREAD ONLY + // Copy frame: If required size is bigger than allocated one, new buffers of + // adequate size will be allocated. + virtual GMPErr CopyFrame(const GMPVideoi420Frame& aVideoFrame) = 0; + + // Swap Frame. + virtual void SwapFrame(GMPVideoi420Frame* aVideoFrame) = 0; + + // Get pointer to buffer per plane. + virtual uint8_t* Buffer(GMPPlaneType aType) = 0; + + // Overloading with const. + virtual const uint8_t* Buffer(GMPPlaneType aType) const = 0; + + // Get allocated size per plane. + virtual int32_t AllocatedSize(GMPPlaneType aType) const = 0; + + // Get allocated stride per plane. + virtual int32_t Stride(GMPPlaneType aType) const = 0; + + // Set frame width. + virtual GMPErr SetWidth(int32_t aWidth) = 0; + + // Set frame height. + virtual GMPErr SetHeight(int32_t aHeight) = 0; + + // Get frame width. + virtual int32_t Width() const = 0; + + // Get frame height. + virtual int32_t Height() const = 0; + + // Set frame timestamp (microseconds) + virtual void SetTimestamp(uint64_t aTimestamp) = 0; + + // Get frame timestamp (microseconds) + virtual uint64_t Timestamp() const = 0; + + // Set frame duration (microseconds) + // NOTE: next-frame's Timestamp() != this-frame's TimeStamp()+Duration() + // depending on rounding to avoid having to track roundoff errors + // and dropped/missing frames(!) (which may leave a large gap) + virtual void SetDuration(uint64_t aDuration) = 0; + + // Get frame duration (microseconds) + virtual uint64_t Duration() const = 0; + + // Return true if underlying plane buffers are of zero size, false if not. + virtual bool IsZeroSize() const = 0; + + // Reset underlying plane buffers sizes to 0. This function doesn't clear memory. + virtual void ResetSize() = 0; +}; + +#endif // GMP_VIDEO_FRAME_I420_h_ diff --git a/dom/media/gmp/gmp-api/gmp-video-frame.h b/dom/media/gmp/gmp-api/gmp-video-frame.h new file mode 100644 index 0000000000..b3c9f53ab1 --- /dev/null +++ b/dom/media/gmp/gmp-api/gmp-video-frame.h @@ -0,0 +1,51 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* Copyright (c) 2011, The WebRTC project authors. All rights reserved. + * Copyright (c) 2014, Mozilla + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + ** Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + ** Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + ** Neither the name of Google nor the names of its contributors may + * be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef GMP_VIDEO_FRAME_h_ +#define GMP_VIDEO_FRAME_h_ + +#include "gmp-video-plane.h" + +enum GMPVideoFrameFormat { + kGMPEncodedVideoFrame = 0, + kGMPI420VideoFrame = 1 +}; + +class GMPVideoFrame { +public: + virtual GMPVideoFrameFormat GetFrameFormat() = 0; + // MAIN THREAD ONLY IF OWNING PROCESS + virtual void Destroy() = 0; +}; + +#endif // GMP_VIDEO_FRAME_h_ diff --git a/dom/media/gmp/gmp-api/gmp-video-host.h b/dom/media/gmp/gmp-api/gmp-video-host.h new file mode 100644 index 0000000000..cf20e3f467 --- /dev/null +++ b/dom/media/gmp/gmp-api/gmp-video-host.h @@ -0,0 +1,53 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* Copyright (c) 2011, The WebRTC project authors. All rights reserved. + * Copyright (c) 2014, Mozilla + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + ** Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + ** Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + ** Neither the name of Google nor the names of its contributors may + * be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef GMP_VIDEO_HOST_h_ +#define GMP_VIDEO_HOST_h_ + +#include "gmp-errors.h" +#include "gmp-video-frame-i420.h" +#include "gmp-video-frame-encoded.h" +#include "gmp-video-codec.h" + +// This interface must be called on the main thread only. +class GMPVideoHost +{ +public: + // Construct various video API objects. Host does not retain reference, + // caller is owner and responsible for deleting. + // MAIN THREAD ONLY + virtual GMPErr CreateFrame(GMPVideoFrameFormat aFormat, GMPVideoFrame** aFrame) = 0; + virtual GMPErr CreatePlane(GMPPlane** aPlane) = 0; +}; + +#endif // GMP_VIDEO_HOST_h_ diff --git a/dom/media/gmp/gmp-api/gmp-video-plane.h b/dom/media/gmp/gmp-api/gmp-video-plane.h new file mode 100644 index 0000000000..777cc2495e --- /dev/null +++ b/dom/media/gmp/gmp-api/gmp-video-plane.h @@ -0,0 +1,94 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* Copyright (c) 2011, The WebRTC project authors. All rights reserved. + * Copyright (c) 2014, Mozilla + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + ** Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + ** Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + ** Neither the name of Google nor the names of its contributors may + * be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef GMP_VIDEO_PLANE_h_ +#define GMP_VIDEO_PLANE_h_ + +#include "gmp-errors.h" +#include <stdint.h> + +// The implementation backing this interface uses shared memory for the +// buffer(s). This means it can only be used by the "owning" process. +// At first the process which created the object owns it. When the object +// is passed to an interface the creator loses ownership and must Destroy() +// the object. Further attempts to use it may fail due to not being able to +// access the underlying buffer(s). +// +// Methods that create or destroy shared memory must be called on the main +// thread. They are marked below. +class GMPPlane { +public: + // MAIN THREAD ONLY + // CreateEmptyPlane - set allocated size, actual plane size and stride: + // If current size is smaller than current size, then a buffer of sufficient + // size will be allocated. + virtual GMPErr CreateEmptyPlane(int32_t aAllocatedSize, + int32_t aStride, + int32_t aPlaneSize) = 0; + + // MAIN THREAD ONLY + // Copy the entire plane data. + virtual GMPErr Copy(const GMPPlane& aPlane) = 0; + + // MAIN THREAD ONLY + // Copy buffer: If current size is smaller + // than current size, then a buffer of sufficient size will be allocated. + virtual GMPErr Copy(int32_t aSize, int32_t aStride, const uint8_t* aBuffer) = 0; + + // Swap plane data. + virtual void Swap(GMPPlane& aPlane) = 0; + + // Get allocated size. + virtual int32_t AllocatedSize() const = 0; + + // Set actual size. + virtual void ResetSize() = 0; + + // Return true is plane size is zero, false if not. + virtual bool IsZeroSize() const = 0; + + // Get stride value. + virtual int32_t Stride() const = 0; + + // Return data pointer. + virtual const uint8_t* Buffer() const = 0; + + // Overloading with non-const. + virtual uint8_t* Buffer() = 0; + + // MAIN THREAD ONLY IF OWNING PROCESS + // Call this when done with the object. This may delete it. + virtual void Destroy() = 0; +}; + +#endif // GMP_VIDEO_PLANE_h_ |