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 |