blob: fd51c96f7fb623ccaf72d46e2ef952ae496547ec [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef MEDIA_BASE_DECRYPTOR_H_
#define MEDIA_BASE_DECRYPTOR_H_
#include <list>
#include <string>
#include "base/basictypes.h"
#include "base/callback.h"
#include "base/memory/ref_counted.h"
#include "media/base/audio_decoder.h"
#include "media/base/media_export.h"
namespace media {
class AudioDecoderConfig;
class Buffer;
class DecoderBuffer;
class VideoDecoderConfig;
class VideoFrame;
// Performs key operations and decrypts (and decodes) encrypted buffer.
//
// Key operations (GenerateKeyRequest(), AddKey() and CancelKeyRequest())
// are called on the renderer thread. Therefore, these calls should be fast
// and nonblocking; key events should be fired asynchronously.
// All other methods are called on the (video/audio) decoder thread.
// Decryptor implementations must be thread safe when methods are called
// following the above model.
// Depending on the implementation callbacks may be fired synchronously or
// asynchronously.
class MEDIA_EXPORT Decryptor {
public:
// Reported to UMA, so never reuse a value!
// Must be kept in sync with WebKit::WebMediaPlayerClient::MediaKeyErrorCode
// (enforced in webmediaplayer_impl.cc).
enum KeyError {
kUnknownError = 1,
kClientError,
kServiceError,
kOutputError,
kHardwareChangeError,
kDomainError,
kMaxKeyError // Must be last and greater than any legit value.
};
// TODO(xhwang): Replace kError with kDecryptError and kDecodeError.
// TODO(xhwang): Replace kNeedMoreData with kNotEnoughData.
enum Status {
kSuccess, // Decryption successfully completed. Decrypted buffer ready.
kNoKey, // No key is available to decrypt.
kNeedMoreData, // Decoder needs more data to produce a frame.
kError // Key is available but an error occurred during decryption.
};
// TODO(xhwang): Unify this with DemuxerStream::Type.
enum StreamType {
kAudio,
kVideo
};
Decryptor();
virtual ~Decryptor();
// Generates a key request for the |key_system| with |type| and
// |init_data| provided.
// Returns true if generating key request succeeded, false otherwise.
// Note: AddKey() and CancelKeyRequest() should only be called after
// GenerateKeyRequest() returns true.
virtual bool GenerateKeyRequest(const std::string& key_system,
const std::string& type,
const uint8* init_data,
int init_data_length) = 0;
// Adds a |key| to the |key_system|. The |key| is not limited to a decryption
// key. It can be any data that the key system accepts, such as a license.
// If multiple calls of this function set different keys for the same
// key ID, the older key will be replaced by the newer key.
virtual void AddKey(const std::string& key_system,
const uint8* key,
int key_length,
const uint8* init_data,
int init_data_length,
const std::string& session_id) = 0;
// Cancels the key request specified by |session_id|.
virtual void CancelKeyRequest(const std::string& key_system,
const std::string& session_id) = 0;
// Indicates that a key has been added to the Decryptor.
typedef base::Callback<void()> KeyAddedCB;
// Registers a KeyAddedCB which should be called when a key is added to the
// decryptor. Only one KeyAddedCB can be registered for one |stream_type|.
// If this function is called multiple times for the same |stream_type|, the
// previously registered callback will be replaced. In other words,
// registering a null callback cancels the originally registered callback.
virtual void RegisterKeyAddedCB(StreamType stream_type,
const KeyAddedCB& key_added_cb) = 0;
// Indicates completion of a decryption operation.
//
// First parameter: The status of the decryption operation.
// - Set to kSuccess if the encrypted buffer is successfully decrypted and
// the decrypted buffer is ready to be read.
// - Set to kNoKey if no decryption key is available to decrypt the encrypted
// buffer. In this case the decrypted buffer must be NULL.
// - Set to kError if unexpected error has occurred. In this case the
// decrypted buffer must be NULL.
// - This parameter should not be set to kNeedMoreData.
// Second parameter: The decrypted buffer.
typedef base::Callback<void(Status,
const scoped_refptr<DecoderBuffer>&)> DecryptCB;
// Decrypts the |encrypted| buffer. The decrypt status and decrypted buffer
// are returned via the provided callback |decrypt_cb|. The |encrypted| buffer
// must not be NULL.
// Decrypt() should not be called until any previous DecryptCB of the same
// |stream_type| has completed. Thus, only one DecryptCB may be pending at
// a time for a given |stream_type|.
virtual void Decrypt(StreamType stream_type,
const scoped_refptr<DecoderBuffer>& encrypted,
const DecryptCB& decrypt_cb) = 0;
// Cancels the scheduled decryption operation for |stream_type| and fires the
// pending DecryptCB immediately with kSuccess and NULL.
// Decrypt() should not be called again before the pending DecryptCB for the
// same |stream_type| is fired.
virtual void CancelDecrypt(StreamType stream_type) = 0;
// Indicates completion of audio/video decoder initialization.
//
// First Parameter: Indicates initialization success.
// - Set to true if initialization was successful. False if an error occurred.
typedef base::Callback<void(bool)> DecoderInitCB;
// Initializes a decoder with the given |config|, executing the |init_cb|
// upon completion.
virtual void InitializeAudioDecoder(scoped_ptr<AudioDecoderConfig> config,
const DecoderInitCB& init_cb) = 0;
virtual void InitializeVideoDecoder(scoped_ptr<VideoDecoderConfig> config,
const DecoderInitCB& init_cb) = 0;
// Helper structure for managing multiple decoded audio buffers per input.
// TODO(xhwang): Rename this to AudioFrames.
typedef std::list<scoped_refptr<Buffer> > AudioBuffers;
// Indicates completion of audio/video decrypt-and-decode operation.
//
// First parameter: The status of the decrypt-and-decode operation.
// - Set to kSuccess if the encrypted buffer is successfully decrypted and
// decoded. In this case, the decoded frame/buffers can be/contain:
// 1) NULL, which means the operation has been aborted.
// 2) End-of-stream (EOS) frame, which means that the decoder has hit EOS,
// flushed all internal buffers and cannot produce more video frames.
// 3) Decrypted and decoded video frame or audio buffer.
// - Set to kNoKey if no decryption key is available to decrypt the encrypted
// buffer. In this case the returned frame(s) must be NULL/empty.
// - Set to kNeedMoreData if more data is needed to produce a video frame. In
// this case the returned frame(s) must be NULL/empty.
// - Set to kError if unexpected error has occurred. In this case the
// returned frame(s) must be NULL/empty.
// Second parameter: The decoded video frame or audio buffers.
typedef base::Callback<void(Status, const AudioBuffers&)> AudioDecodeCB;
typedef base::Callback<void(Status,
const scoped_refptr<VideoFrame>&)> VideoDecodeCB;
// Decrypts and decodes the |encrypted| buffer. The status and the decrypted
// buffer are returned via the provided callback.
// The |encrypted| buffer must not be NULL.
// At end-of-stream, this method should be called repeatedly with
// end-of-stream DecoderBuffer until no frame/buffer can be produced.
// These methods can only be called after the corresponding decoder has
// been successfully initialized.
virtual void DecryptAndDecodeAudio(
const scoped_refptr<DecoderBuffer>& encrypted,
const AudioDecodeCB& audio_decode_cb) = 0;
virtual void DecryptAndDecodeVideo(
const scoped_refptr<DecoderBuffer>& encrypted,
const VideoDecodeCB& video_decode_cb) = 0;
// Resets the decoder to an initialized clean state, cancels any scheduled
// decrypt-and-decode operations, and fires any pending
// AudioDecodeCB/VideoDecodeCB immediately with kError and NULL.
// This method can only be called after the corresponding decoder has been
// successfully initialized.
virtual void ResetDecoder(StreamType stream_type) = 0;
// Releases decoder resources, deinitializes the decoder, cancels any
// scheduled initialization or decrypt-and-decode operations, and fires
// any pending DecoderInitCB/AudioDecodeCB/VideoDecodeCB immediately.
// DecoderInitCB should be fired with false. AudioDecodeCB/VideoDecodeCB
// should be fired with kError.
// This method can be called any time after Initialize{Audio|Video}Decoder()
// has been called (with the correct stream type).
// After this operation, the decoder is set to an uninitialized state.
// The decoder can be reinitialized after it is uninitialized.
virtual void DeinitializeDecoder(StreamType stream_type) = 0;
private:
DISALLOW_COPY_AND_ASSIGN(Decryptor);
};
// Callback to notify that a decryptor is ready.
typedef base::Callback<void(Decryptor*)> DecryptorReadyCB;
// Callback to set/cancel a DecryptorReadyCB.
// Calling this callback with a non-null callback registers decryptor ready
// notification. When the decryptor is ready, notification will be sent
// through the provided callback.
// Calling this callback with a null callback cancels previously registered
// decryptor ready notification. Any previously provided callback will be
// fired immediately with NULL.
typedef base::Callback<void(const DecryptorReadyCB&)> SetDecryptorReadyCB;
} // namespace media
#endif // MEDIA_BASE_DECRYPTOR_H_