| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #ifndef WEBKIT_MEDIA_CRYPTO_PPAPI_CONTENT_DECRYPTION_MODULE_H_ | |
| 6 #define WEBKIT_MEDIA_CRYPTO_PPAPI_CONTENT_DECRYPTION_MODULE_H_ | |
| 7 | |
| 8 #if defined(_MSC_VER) | |
| 9 typedef unsigned char uint8_t; | |
| 10 typedef unsigned int uint32_t; | |
| 11 typedef int int32_t; | |
| 12 typedef __int64 int64_t; | |
| 13 #else | |
| 14 #include <stdint.h> | |
| 15 #endif | |
| 16 | |
| 17 #include "webkit/media/crypto/ppapi/cdm_export.h" | |
| 18 | |
| 19 // The version number must be rolled when this file is updated! | |
| 20 // If the CDM and the plugin use different versions of this file, the plugin | |
| 21 // will fail to load or crash! | |
| 22 #define INITIALIZE_CDM_MODULE InitializeCdmModule_3 | |
| 23 | |
| 24 namespace cdm { | |
| 25 class Allocator; | |
| 26 class ContentDecryptionModule; | |
| 27 class Host; | |
| 28 } | |
| 29 | |
| 30 extern "C" { | |
| 31 CDM_EXPORT void INITIALIZE_CDM_MODULE(); | |
| 32 CDM_EXPORT void DeinitializeCdmModule(); | |
| 33 // Caller retains ownership of arguments, which must outlive the call to | |
| 34 // DestroyCdmInstance below. | |
| 35 CDM_EXPORT cdm::ContentDecryptionModule* CreateCdmInstance( | |
| 36 const char* key_system, | |
| 37 int key_system_size, | |
| 38 cdm::Allocator* allocator, | |
| 39 cdm::Host* host); | |
| 40 CDM_EXPORT void DestroyCdmInstance(cdm::ContentDecryptionModule* instance); | |
| 41 CDM_EXPORT const char* GetCdmVersion(); | |
| 42 } | |
| 43 | |
| 44 namespace cdm { | |
| 45 | |
| 46 class AudioFrames; | |
| 47 class Buffer; | |
| 48 class DecryptedBlock; | |
| 49 class VideoFrame; | |
| 50 | |
| 51 enum Status { | |
| 52 kSuccess = 0, | |
| 53 kNeedMoreData, // Decoder needs more data to produce a decoded frame/sample. | |
| 54 kNoKey, // The required decryption key is not available. | |
| 55 kSessionError, // Session management error. | |
| 56 kDecryptError, // Decryption failed. | |
| 57 kDecodeError // Error decoding audio or video. | |
| 58 }; | |
| 59 | |
| 60 // This must be consistent with MediaKeyError defined in the spec: | |
| 61 // http://goo.gl/rbdnR | |
| 62 enum MediaKeyError { | |
| 63 kUnknownError = 1, | |
| 64 kClientError, | |
| 65 kServiceError, | |
| 66 kOutputError, | |
| 67 kHardwareChangeError, | |
| 68 kDomainError | |
| 69 }; | |
| 70 | |
| 71 // An input buffer can be split into several continuous subsamples. | |
| 72 // A SubsampleEntry specifies the number of clear and cipher bytes in each | |
| 73 // subsample. For example, the following buffer has three subsamples: | |
| 74 // | |
| 75 // |<----- subsample1 ----->|<----- subsample2 ----->|<----- subsample3 ----->| | |
| 76 // | clear1 | cipher1 | clear2 | cipher2 | clear3 | cipher3 | | |
| 77 // | |
| 78 // For decryption, all of the cipher bytes in a buffer should be concatenated | |
| 79 // (in the subsample order) into a single logical stream. The clear bytes should | |
| 80 // not be considered as part of decryption. | |
| 81 // | |
| 82 // Stream to decrypt: | cipher1 | cipher2 | cipher3 | | |
| 83 // Decrypted stream: | decrypted1| decrypted2 | decrypted3 | | |
| 84 // | |
| 85 // After decryption, the decrypted bytes should be copied over the position | |
| 86 // of the corresponding cipher bytes in the original buffer to form the output | |
| 87 // buffer. Following the above example, the decrypted buffer should be: | |
| 88 // | |
| 89 // |<----- subsample1 ----->|<----- subsample2 ----->|<----- subsample3 ----->| | |
| 90 // | clear1 | decrypted1| clear2 | decrypted2 | clear3 | decrypted3 | | |
| 91 // | |
| 92 // TODO(xhwang): Add checks to make sure these structs have fixed layout. | |
| 93 struct SubsampleEntry { | |
| 94 SubsampleEntry(int32_t clear_bytes, int32_t cipher_bytes) | |
| 95 : clear_bytes(clear_bytes), cipher_bytes(cipher_bytes) {} | |
| 96 | |
| 97 int32_t clear_bytes; | |
| 98 int32_t cipher_bytes; | |
| 99 }; | |
| 100 | |
| 101 // Represents an input buffer to be decrypted (and possibly decoded). It does | |
| 102 // own any pointers in this struct. | |
| 103 struct InputBuffer { | |
| 104 InputBuffer() | |
| 105 : data(NULL), | |
| 106 data_size(0), | |
| 107 data_offset(0), | |
| 108 key_id(NULL), | |
| 109 key_id_size(0), | |
| 110 iv(NULL), | |
| 111 iv_size(0), | |
| 112 subsamples(NULL), | |
| 113 num_subsamples(0), | |
| 114 timestamp(0) {} | |
| 115 | |
| 116 const uint8_t* data; // Pointer to the beginning of the input data. | |
| 117 int32_t data_size; // Size (in bytes) of |data|. | |
| 118 | |
| 119 int32_t data_offset; // Number of bytes to be discarded before decryption. | |
| 120 | |
| 121 const uint8_t* key_id; // Key ID to identify the decryption key. | |
| 122 int32_t key_id_size; // Size (in bytes) of |key_id|. | |
| 123 | |
| 124 const uint8_t* iv; // Initialization vector. | |
| 125 int32_t iv_size; // Size (in bytes) of |iv|. | |
| 126 | |
| 127 const struct SubsampleEntry* subsamples; | |
| 128 int32_t num_subsamples; // Number of subsamples in |subsamples|. | |
| 129 | |
| 130 int64_t timestamp; // Presentation timestamp in microseconds. | |
| 131 }; | |
| 132 | |
| 133 struct AudioDecoderConfig { | |
| 134 enum AudioCodec { | |
| 135 kUnknownAudioCodec = 0, | |
| 136 kCodecVorbis, | |
| 137 kCodecAac | |
| 138 }; | |
| 139 | |
| 140 AudioDecoderConfig() | |
| 141 : codec(kUnknownAudioCodec), | |
| 142 channel_count(0), | |
| 143 bits_per_channel(0), | |
| 144 samples_per_second(0), | |
| 145 extra_data(NULL), | |
| 146 extra_data_size(0) {} | |
| 147 | |
| 148 AudioCodec codec; | |
| 149 int32_t channel_count; | |
| 150 int32_t bits_per_channel; | |
| 151 int32_t samples_per_second; | |
| 152 | |
| 153 // Optional byte data required to initialize audio decoders, such as the | |
| 154 // vorbis setup header. | |
| 155 uint8_t* extra_data; | |
| 156 int32_t extra_data_size; | |
| 157 }; | |
| 158 | |
| 159 // Surface formats based on FOURCC labels, see: http://www.fourcc.org/yuv.php | |
| 160 enum VideoFormat { | |
| 161 kUnknownVideoFormat = 0, // Unknown format value. Used for error reporting. | |
| 162 kYv12, // 12bpp YVU planar 1x1 Y, 2x2 VU samples. | |
| 163 kI420 // 12bpp YVU planar 1x1 Y, 2x2 UV samples. | |
| 164 }; | |
| 165 | |
| 166 struct Size { | |
| 167 Size() : width(0), height(0) {} | |
| 168 Size(int32_t width, int32_t height) : width(width), height(height) {} | |
| 169 | |
| 170 int32_t width; | |
| 171 int32_t height; | |
| 172 }; | |
| 173 | |
| 174 struct VideoDecoderConfig { | |
| 175 enum VideoCodec { | |
| 176 kUnknownVideoCodec = 0, | |
| 177 kCodecVp8, | |
| 178 kCodecH264 | |
| 179 }; | |
| 180 | |
| 181 enum VideoCodecProfile { | |
| 182 kUnknownVideoCodecProfile = 0, | |
| 183 kVp8ProfileMain, | |
| 184 kH264ProfileBaseline, | |
| 185 kH264ProfileMain, | |
| 186 kH264ProfileExtended, | |
| 187 kH264ProfileHigh, | |
| 188 kH264ProfileHigh10, | |
| 189 kH264ProfileHigh422, | |
| 190 kH264ProfileHigh444Predictive | |
| 191 }; | |
| 192 | |
| 193 VideoDecoderConfig() | |
| 194 : codec(kUnknownVideoCodec), | |
| 195 profile(kUnknownVideoCodecProfile), | |
| 196 format(kUnknownVideoFormat), | |
| 197 extra_data(NULL), | |
| 198 extra_data_size(0) {} | |
| 199 | |
| 200 VideoCodec codec; | |
| 201 VideoCodecProfile profile; | |
| 202 VideoFormat format; | |
| 203 | |
| 204 // Width and height of video frame immediately post-decode. Not all pixels | |
| 205 // in this region are valid. | |
| 206 Size coded_size; | |
| 207 | |
| 208 // Optional byte data required to initialize video decoders, such as H.264 | |
| 209 // AAVC data. | |
| 210 uint8_t* extra_data; | |
| 211 int32_t extra_data_size; | |
| 212 }; | |
| 213 | |
| 214 enum StreamType { | |
| 215 kStreamTypeAudio = 0, | |
| 216 kStreamTypeVideo = 1 | |
| 217 }; | |
| 218 | |
| 219 // ContentDecryptionModule interface that all CDMs need to implement. | |
| 220 // Note: ContentDecryptionModule implementations must use the allocator | |
| 221 // provided in CreateCdmInstance() to allocate any Buffer that needs to | |
| 222 // be passed back to the caller. Implementations must call Buffer::Destroy() | |
| 223 // when a Buffer is created that will never be returned to the caller. | |
| 224 class ContentDecryptionModule { | |
| 225 public: | |
| 226 // Generates a |key_request| given |type| and |init_data|. | |
| 227 // | |
| 228 // Returns kSuccess if the key request was successfully generated, in which | |
| 229 // case the CDM must send the key message by calling Host::SendKeyMessage(). | |
| 230 // Returns kSessionError if any error happened, in which case the CDM must | |
| 231 // send a key error by calling Host::SendKeyError(). | |
| 232 // TODO(xhwang): A CDM may support multiple key systems. Pass in key system | |
| 233 // in this and other calls to support that. | |
| 234 virtual Status GenerateKeyRequest( | |
| 235 const char* type, int type_size, | |
| 236 const uint8_t* init_data, int init_data_size) = 0; | |
| 237 | |
| 238 // Adds the |key| to the CDM to be associated with |key_id|. | |
| 239 // | |
| 240 // Returns kSuccess if the key was successfully added, kSessionError | |
| 241 // otherwise. | |
| 242 virtual Status AddKey(const char* session_id, int session_id_size, | |
| 243 const uint8_t* key, int key_size, | |
| 244 const uint8_t* key_id, int key_id_size) = 0; | |
| 245 | |
| 246 // Cancels any pending key request made to the CDM for |session_id|. | |
| 247 // | |
| 248 // Returns kSuccess if all pending key requests for |session_id| were | |
| 249 // successfully canceled or there was no key request to be canceled, | |
| 250 // kSessionError otherwise. | |
| 251 virtual Status CancelKeyRequest( | |
| 252 const char* session_id, int session_id_size) = 0; | |
| 253 | |
| 254 // Performs scheduled operation with |context| when the timer fires. | |
| 255 virtual void TimerExpired(void* context) = 0; | |
| 256 | |
| 257 // Decrypts the |encrypted_buffer|. | |
| 258 // | |
| 259 // Returns kSuccess if decryption succeeded, in which case the callee | |
| 260 // should have filled the |decrypted_buffer| and passed the ownership of | |
| 261 // |data| in |decrypted_buffer| to the caller. | |
| 262 // Returns kNoKey if the CDM did not have the necessary decryption key | |
| 263 // to decrypt. | |
| 264 // Returns kDecryptError if any other error happened. | |
| 265 // If the return value is not kSuccess, |decrypted_buffer| should be ignored | |
| 266 // by the caller. | |
| 267 virtual Status Decrypt(const InputBuffer& encrypted_buffer, | |
| 268 DecryptedBlock* decrypted_buffer) = 0; | |
| 269 | |
| 270 // Initializes the CDM audio decoder with |audio_decoder_config|. This | |
| 271 // function must be called before DecryptAndDecodeSamples() is called. | |
| 272 // | |
| 273 // Returns kSuccess if the |audio_decoder_config| is supported and the CDM | |
| 274 // audio decoder is successfully initialized. | |
| 275 // Returns kSessionError if |audio_decoder_config| is not supported. The CDM | |
| 276 // may still be able to do Decrypt(). | |
| 277 // | |
| 278 // TODO(xhwang): Add stream ID here and in the following audio decoder | |
| 279 // functions when we need to support multiple audio streams in one CDM. | |
| 280 virtual Status InitializeAudioDecoder( | |
| 281 const AudioDecoderConfig& audio_decoder_config) = 0; | |
| 282 | |
| 283 // Initializes the CDM video decoder with |video_decoder_config|. This | |
| 284 // function must be called before DecryptAndDecodeFrame() is called. | |
| 285 // | |
| 286 // Returns kSuccess if the |video_decoder_config| is supported and the CDM | |
| 287 // video decoder is successfully initialized. | |
| 288 // Returns kSessionError if |video_decoder_config| is not supported. The CDM | |
| 289 // may still be able to do Decrypt(). | |
| 290 // | |
| 291 // TODO(xhwang): Add stream ID here and in the following video decoder | |
| 292 // functions when we need to support multiple video streams in one CDM. | |
| 293 virtual Status InitializeVideoDecoder( | |
| 294 const VideoDecoderConfig& video_decoder_config) = 0; | |
| 295 | |
| 296 // De-initializes the CDM decoder and sets it to an uninitialized state. The | |
| 297 // caller can initialize the decoder again after this call to re-initialize | |
| 298 // it. This can be used to reconfigure the decoder if the configuration | |
| 299 // changes. | |
| 300 virtual void DeinitializeDecoder(StreamType decoder_type) = 0; | |
| 301 | |
| 302 // Resets the CDM decoder to an initialized clean state. All internal buffers | |
| 303 // MUST be flushed. | |
| 304 virtual void ResetDecoder(StreamType decoder_type) = 0; | |
| 305 | |
| 306 // Decrypts the |encrypted_buffer| and decodes the decrypted buffer into a | |
| 307 // |video_frame|. Upon end-of-stream, the caller should call this function | |
| 308 // repeatedly with empty |encrypted_buffer| (|data| == NULL) until only empty | |
| 309 // |video_frame| (|format| == kEmptyVideoFrame) is produced. | |
| 310 // | |
| 311 // Returns kSuccess if decryption and decoding both succeeded, in which case | |
| 312 // the callee will have filled the |video_frame| and passed the ownership of | |
| 313 // |frame_buffer| in |video_frame| to the caller. | |
| 314 // Returns kNoKey if the CDM did not have the necessary decryption key | |
| 315 // to decrypt. | |
| 316 // Returns kNeedMoreData if more data was needed by the decoder to generate | |
| 317 // a decoded frame (e.g. during initialization and end-of-stream). | |
| 318 // Returns kDecryptError if any decryption error happened. | |
| 319 // Returns kDecodeError if any decoding error happened. | |
| 320 // If the return value is not kSuccess, |video_frame| should be ignored by | |
| 321 // the caller. | |
| 322 virtual Status DecryptAndDecodeFrame(const InputBuffer& encrypted_buffer, | |
| 323 VideoFrame* video_frame) = 0; | |
| 324 | |
| 325 // Decrypts the |encrypted_buffer| and decodes the decrypted buffer into | |
| 326 // |audio_frames|. Upon end-of-stream, the caller should call this function | |
| 327 // repeatedly with empty |encrypted_buffer| (|data| == NULL) until only empty | |
| 328 // |audio_frames| is produced. | |
| 329 // | |
| 330 // Returns kSuccess if decryption and decoding both succeeded, in which case | |
| 331 // the callee will have filled |audio_frames| and passed the ownership of | |
| 332 // |data| in |audio_frames| to the caller. | |
| 333 // Returns kNoKey if the CDM did not have the necessary decryption key | |
| 334 // to decrypt. | |
| 335 // Returns kNeedMoreData if more data was needed by the decoder to generate | |
| 336 // audio samples (e.g. during initialization and end-of-stream). | |
| 337 // Returns kDecryptError if any decryption error happened. | |
| 338 // Returns kDecodeError if any decoding error happened. | |
| 339 // If the return value is not kSuccess, |audio_frames| should be ignored by | |
| 340 // the caller. | |
| 341 virtual Status DecryptAndDecodeSamples(const InputBuffer& encrypted_buffer, | |
| 342 AudioFrames* audio_frames) = 0; | |
| 343 | |
| 344 virtual ~ContentDecryptionModule() {} | |
| 345 }; | |
| 346 | |
| 347 // Represents a buffer created by Allocator implementations. | |
| 348 class Buffer { | |
| 349 public: | |
| 350 // Destroys the buffer in the same context as it was created. | |
| 351 virtual void Destroy() = 0; | |
| 352 | |
| 353 virtual int32_t Capacity() const = 0; | |
| 354 virtual uint8_t* Data() = 0; | |
| 355 virtual void SetSize(int32_t size) = 0; | |
| 356 virtual int32_t Size() const = 0; | |
| 357 | |
| 358 protected: | |
| 359 Buffer() {} | |
| 360 virtual ~Buffer() {} | |
| 361 | |
| 362 private: | |
| 363 Buffer(const Buffer&); | |
| 364 void operator=(const Buffer&); | |
| 365 }; | |
| 366 | |
| 367 // Interface class that hides cross object memory allocation details from CDMs. | |
| 368 class Allocator { | |
| 369 public: | |
| 370 // Returns a Buffer* containing non-zero members upon success, or NULL on | |
| 371 // failure. The caller owns the Buffer* after this call. The buffer is not | |
| 372 // guaranteed to be zero initialized. The capacity of the allocated Buffer | |
| 373 // is guaranteed to be not less than |capacity|. | |
| 374 virtual Buffer* Allocate(int32_t capacity) = 0; | |
| 375 | |
| 376 protected: | |
| 377 Allocator() {} | |
| 378 virtual ~Allocator() {} | |
| 379 }; | |
| 380 | |
| 381 class Host { | |
| 382 public: | |
| 383 Host() {} | |
| 384 virtual ~Host() {} | |
| 385 | |
| 386 // Requests the host to call ContentDecryptionModule::TimerFired() |delay_ms| | |
| 387 // from now with |context|. | |
| 388 virtual void SetTimer(int64_t delay_ms, void* context) = 0; | |
| 389 | |
| 390 // Returns the current epoch wall time in seconds. | |
| 391 virtual double GetCurrentWallTimeInSeconds() = 0; | |
| 392 | |
| 393 virtual void SendKeyMessage( | |
| 394 const char* session_id, int32_t session_id_length, | |
| 395 const char* message, int32_t message_length, | |
| 396 const char* default_url, int32_t default_url_length) = 0; | |
| 397 | |
| 398 virtual void SendKeyError(const char* session_id, | |
| 399 int32_t session_id_length, | |
| 400 MediaKeyError error_code, | |
| 401 uint32_t system_code) = 0; | |
| 402 }; | |
| 403 | |
| 404 // Represents a decrypted block that has not been decoded. | |
| 405 class DecryptedBlock { | |
| 406 public: | |
| 407 virtual void SetDecryptedBuffer(Buffer* buffer) = 0; | |
| 408 virtual Buffer* DecryptedBuffer() = 0; | |
| 409 | |
| 410 // TODO(tomfinegan): Figure out if timestamp is really needed. If it is not, | |
| 411 // we can just pass Buffer pointers around. | |
| 412 virtual void SetTimestamp(int64_t timestamp) = 0; | |
| 413 virtual int64_t Timestamp() const = 0; | |
| 414 | |
| 415 protected: | |
| 416 DecryptedBlock() {} | |
| 417 virtual ~DecryptedBlock() {} | |
| 418 }; | |
| 419 | |
| 420 class VideoFrame { | |
| 421 public: | |
| 422 enum VideoPlane { | |
| 423 kYPlane = 0, | |
| 424 kUPlane = 1, | |
| 425 kVPlane = 2, | |
| 426 kMaxPlanes = 3, | |
| 427 }; | |
| 428 | |
| 429 virtual void SetFormat(VideoFormat format) = 0; | |
| 430 virtual VideoFormat Format() const = 0; | |
| 431 | |
| 432 virtual void SetSize(cdm::Size size) = 0; | |
| 433 virtual cdm::Size Size() const = 0; | |
| 434 | |
| 435 virtual void SetFrameBuffer(Buffer* frame_buffer) = 0; | |
| 436 virtual Buffer* FrameBuffer() = 0; | |
| 437 | |
| 438 virtual void SetPlaneOffset(VideoPlane plane, int32_t offset) = 0; | |
| 439 virtual int32_t PlaneOffset(VideoPlane plane) = 0; | |
| 440 | |
| 441 virtual void SetStride(VideoPlane plane, int32_t stride) = 0; | |
| 442 virtual int32_t Stride(VideoPlane plane) = 0; | |
| 443 | |
| 444 virtual void SetTimestamp(int64_t timestamp) = 0; | |
| 445 virtual int64_t Timestamp() const = 0; | |
| 446 | |
| 447 protected: | |
| 448 VideoFrame() {} | |
| 449 virtual ~VideoFrame() {} | |
| 450 }; | |
| 451 | |
| 452 // Represents decrypted and decoded audio frames. AudioFrames can contain | |
| 453 // multiple audio output buffers, which are serialized into this format: | |
| 454 // | |
| 455 // |<------------------- serialized audio buffer ------------------->| | |
| 456 // | int64_t timestamp | int64_t length | length bytes of audio data | | |
| 457 // | |
| 458 // For example, with three audio output buffers, the AudioFrames will look | |
| 459 // like this: | |
| 460 // | |
| 461 // |<----------------- AudioFrames ------------------>| | |
| 462 // | audio buffer 0 | audio buffer 1 | audio buffer 2 | | |
| 463 class AudioFrames { | |
| 464 public: | |
| 465 virtual void SetFrameBuffer(Buffer* buffer) = 0; | |
| 466 virtual Buffer* FrameBuffer() = 0; | |
| 467 | |
| 468 protected: | |
| 469 AudioFrames() {} | |
| 470 virtual ~AudioFrames() {} | |
| 471 }; | |
| 472 | |
| 473 } // namespace cdm | |
| 474 | |
| 475 #endif // WEBKIT_MEDIA_CRYPTO_PPAPI_CONTENT_DECRYPTION_MODULE_H_ | |
| OLD | NEW |