OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "webkit/plugins/ppapi/content_decryptor_delegate.h" | 5 #include "webkit/plugins/ppapi/content_decryptor_delegate.h" |
6 | 6 |
7 #include "base/callback_helpers.h" | 7 #include "base/callback_helpers.h" |
8 #include "base/debug/trace_event.h" | 8 #include "base/debug/trace_event.h" |
9 #include "base/message_loop/message_loop_proxy.h" | 9 #include "base/message_loop/message_loop_proxy.h" |
10 #include "media/base/audio_decoder_config.h" | 10 #include "media/base/audio_decoder_config.h" |
(...skipping 22 matching lines...) Expand all Loading... | |
33 | 33 |
34 namespace webkit { | 34 namespace webkit { |
35 namespace ppapi { | 35 namespace ppapi { |
36 | 36 |
37 namespace { | 37 namespace { |
38 | 38 |
39 // Fills |resource| with a PPB_Buffer_Impl and copies |data| into the buffer | 39 // Fills |resource| with a PPB_Buffer_Impl and copies |data| into the buffer |
40 // resource. The |*resource|, if valid, will be in the ResourceTracker with a | 40 // resource. The |*resource|, if valid, will be in the ResourceTracker with a |
41 // reference-count of 0. If |data| is NULL, sets |*resource| to NULL. Returns | 41 // reference-count of 0. If |data| is NULL, sets |*resource| to NULL. Returns |
42 // true upon success and false if any error happened. | 42 // true upon success and false if any error happened. |
43 bool MakeBufferResource(PP_Instance instance, | 43 bool MakeBufferResource(PP_Instance instance, const uint8* data, uint32_t size, |
44 const uint8* data, uint32_t size, | |
45 scoped_refptr<PPB_Buffer_Impl>* resource) { | 44 scoped_refptr<PPB_Buffer_Impl>* resource) { |
46 TRACE_EVENT0("eme", "ContentDecryptorDelegate - MakeBufferResource"); | 45 TRACE_EVENT0("eme", "ContentDecryptorDelegate - MakeBufferResource"); |
47 DCHECK(resource); | 46 DCHECK(resource); |
48 | 47 |
49 if (!data || !size) { | 48 if (!data || !size) { |
50 DCHECK(!data && !size); | 49 DCHECK(!data && !size); |
51 resource = NULL; | 50 resource = NULL; |
52 return true; | 51 return true; |
53 } | 52 } |
54 | 53 |
55 scoped_refptr<PPB_Buffer_Impl> buffer( | 54 scoped_refptr<PPB_Buffer_Impl> buffer( |
56 PPB_Buffer_Impl::CreateResource(instance, size)); | 55 PPB_Buffer_Impl::CreateResource(instance, size)); |
57 if (!buffer.get()) | 56 if (!buffer.get()) |
58 return false; | 57 return false; |
59 | 58 |
60 BufferAutoMapper mapper(buffer.get()); | 59 BufferAutoMapper mapper(buffer.get()); |
61 if (!mapper.data() || mapper.size() < size) | 60 if (!mapper.data() || mapper.size() < size) |
62 return false; | 61 return false; |
63 memcpy(mapper.data(), data, size); | 62 memcpy(mapper.data(), data, size); |
64 | 63 |
65 *resource = buffer; | 64 *resource = buffer; |
66 return true; | 65 return true; |
67 } | 66 } |
68 | 67 |
69 // Copies the content of |str| into |array|. | 68 // Copies the content of |str| into |array|. |
70 // Returns true if copy succeeded. Returns false if copy failed, e.g. if the | 69 // Returns true if copy succeeded. Returns false if copy failed, e.g. if the |
71 // |array_size| is smaller than the |str| length. | 70 // |array_size| is smaller than the |str| length. |
72 template <uint32_t array_size> | 71 template <uint32_t array_size> |
73 bool CopyStringToArray(const std::string& str, uint8 (&array)[array_size]) { | 72 bool CopyStringToArray(const std::string& str, uint8 (&array)[array_size]) { |
74 if (array_size < str.size()) | 73 if (array_size < str.size()) return false; |
scherkus (not reviewing)
2013/06/21 23:39:16
hey!
| |
75 return false; | |
76 | 74 |
77 memcpy(array, str.data(), str.size()); | 75 memcpy(array, str.data(), str.size()); |
78 return true; | 76 return true; |
79 } | 77 } |
80 | 78 |
81 // Fills the |block_info| with information from |encrypted_buffer|. | 79 // Fills the |block_info| with information from |encrypted_buffer|. |
82 // | 80 // |
83 // Returns true if |block_info| is successfully filled. Returns false | 81 // Returns true if |block_info| is successfully filled. Returns false |
84 // otherwise. | 82 // otherwise. |
85 static bool MakeEncryptedBlockInfo( | 83 static bool MakeEncryptedBlockInfo( |
86 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, | 84 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, |
87 uint32_t request_id, | 85 uint32_t request_id, PP_EncryptedBlockInfo* block_info) { |
88 PP_EncryptedBlockInfo* block_info) { | |
89 // TODO(xhwang): Fix initialization of PP_EncryptedBlockInfo here and | 86 // TODO(xhwang): Fix initialization of PP_EncryptedBlockInfo here and |
90 // anywhere else. | 87 // anywhere else. |
91 memset(block_info, 0, sizeof(*block_info)); | 88 memset(block_info, 0, sizeof(*block_info)); |
92 block_info->tracking_info.request_id = request_id; | 89 block_info->tracking_info.request_id = request_id; |
93 | 90 |
94 // EOS buffers need a request ID and nothing more. | 91 // EOS buffers need a request ID and nothing more. |
95 if (encrypted_buffer->IsEndOfStream()) | 92 if (encrypted_buffer->IsEndOfStream()) |
96 return true; | 93 return true; |
97 | 94 |
98 DCHECK(encrypted_buffer->GetDataSize()) | 95 DCHECK(encrypted_buffer->GetDataSize()) |
(...skipping 23 matching lines...) Expand all Loading... | |
122 decrypt_config->subsamples()[i].clear_bytes; | 119 decrypt_config->subsamples()[i].clear_bytes; |
123 block_info->subsamples[i].cipher_bytes = | 120 block_info->subsamples[i].cipher_bytes = |
124 decrypt_config->subsamples()[i].cypher_bytes; | 121 decrypt_config->subsamples()[i].cypher_bytes; |
125 } | 122 } |
126 | 123 |
127 return true; | 124 return true; |
128 } | 125 } |
129 | 126 |
130 // Deserializes audio data stored in |audio_frames| into individual audio | 127 // Deserializes audio data stored in |audio_frames| into individual audio |
131 // buffers in |frames|. Returns true upon success. | 128 // buffers in |frames|. Returns true upon success. |
132 bool DeserializeAudioFrames(PP_Resource audio_frames, | 129 bool DeserializeAudioFrames(PP_Resource audio_frames, int data_size, |
133 int data_size, | |
134 media::Decryptor::AudioBuffers* frames) { | 130 media::Decryptor::AudioBuffers* frames) { |
135 DCHECK(frames); | 131 DCHECK(frames); |
136 EnterResourceNoLock<PPB_Buffer_API> enter(audio_frames, true); | 132 EnterResourceNoLock<PPB_Buffer_API> enter(audio_frames, true); |
137 if (!enter.succeeded()) | 133 if (!enter.succeeded()) |
138 return false; | 134 return false; |
139 | 135 |
140 BufferAutoMapper mapper(enter.object()); | 136 BufferAutoMapper mapper(enter.object()); |
141 if (!mapper.data() || !mapper.size() || | 137 if (!mapper.data() || !mapper.size() || |
142 mapper.size() < static_cast<uint32_t>(data_size)) | 138 mapper.size() < static_cast<uint32_t>(data_size)) |
143 return false; | 139 return false; |
(...skipping 16 matching lines...) Expand all Loading... | |
160 memcpy(&frame_size, cur, sizeof(frame_size)); | 156 memcpy(&frame_size, cur, sizeof(frame_size)); |
161 cur += sizeof(frame_size); | 157 cur += sizeof(frame_size); |
162 bytes_left -= sizeof(frame_size); | 158 bytes_left -= sizeof(frame_size); |
163 | 159 |
164 // We should *not* have empty frame in the list. | 160 // We should *not* have empty frame in the list. |
165 if (frame_size <= 0 || bytes_left < frame_size) | 161 if (frame_size <= 0 || bytes_left < frame_size) |
166 return false; | 162 return false; |
167 | 163 |
168 scoped_refptr<media::DataBuffer> frame = | 164 scoped_refptr<media::DataBuffer> frame = |
169 media::DataBuffer::CopyFrom(cur, frame_size); | 165 media::DataBuffer::CopyFrom(cur, frame_size); |
170 frame->SetTimestamp(base::TimeDelta::FromMicroseconds(timestamp)); | 166 frame->set_timestamp(base::TimeDelta::FromMicroseconds(timestamp)); |
171 frames->push_back(frame); | 167 frames->push_back(frame); |
172 | 168 |
173 cur += frame_size; | 169 cur += frame_size; |
174 bytes_left -= frame_size; | 170 bytes_left -= frame_size; |
175 } while (bytes_left > 0); | 171 } while (bytes_left > 0); |
176 | 172 |
177 return true; | 173 return true; |
178 } | 174 } |
179 | 175 |
180 PP_AudioCodec MediaAudioCodecToPpAudioCodec(media::AudioCodec codec) { | 176 PP_AudioCodec MediaAudioCodecToPpAudioCodec(media::AudioCodec codec) { |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
275 : pp_instance_(pp_instance), | 271 : pp_instance_(pp_instance), |
276 plugin_decryption_interface_(plugin_decryption_interface), | 272 plugin_decryption_interface_(plugin_decryption_interface), |
277 next_decryption_request_id_(1), | 273 next_decryption_request_id_(1), |
278 pending_audio_decrypt_request_id_(0), | 274 pending_audio_decrypt_request_id_(0), |
279 pending_video_decrypt_request_id_(0), | 275 pending_video_decrypt_request_id_(0), |
280 pending_audio_decoder_init_request_id_(0), | 276 pending_audio_decoder_init_request_id_(0), |
281 pending_video_decoder_init_request_id_(0), | 277 pending_video_decoder_init_request_id_(0), |
282 pending_audio_decode_request_id_(0), | 278 pending_audio_decode_request_id_(0), |
283 pending_video_decode_request_id_(0), | 279 pending_video_decode_request_id_(0), |
284 weak_ptr_factory_(this), | 280 weak_ptr_factory_(this), |
285 weak_this_(weak_ptr_factory_.GetWeakPtr()) { | 281 weak_this_(weak_ptr_factory_.GetWeakPtr()) {} |
286 } | |
287 | 282 |
288 void ContentDecryptorDelegate::Initialize(const std::string& key_system) { | 283 void ContentDecryptorDelegate::Initialize(const std::string& key_system) { |
289 // TODO(ddorwin): Add an Initialize method to PPP_ContentDecryptor_Private. | 284 // TODO(ddorwin): Add an Initialize method to PPP_ContentDecryptor_Private. |
290 DCHECK(!key_system.empty()); | 285 DCHECK(!key_system.empty()); |
291 key_system_ = key_system; | 286 key_system_ = key_system; |
292 } | 287 } |
293 | 288 |
294 void ContentDecryptorDelegate::SetKeyEventCallbacks( | 289 void ContentDecryptorDelegate::SetKeyEventCallbacks( |
295 const media::KeyAddedCB& key_added_cb, | 290 const media::KeyAddedCB& key_added_cb, |
296 const media::KeyErrorCB& key_error_cb, | 291 const media::KeyErrorCB& key_error_cb, |
297 const media::KeyMessageCB& key_message_cb, | 292 const media::KeyMessageCB& key_message_cb, |
298 const media::NeedKeyCB& need_key_cb) { | 293 const media::NeedKeyCB& need_key_cb) { |
299 key_added_cb_ = key_added_cb; | 294 key_added_cb_ = key_added_cb; |
300 key_error_cb_ = key_error_cb; | 295 key_error_cb_ = key_error_cb; |
301 key_message_cb_ = key_message_cb; | 296 key_message_cb_ = key_message_cb; |
302 need_key_cb_ = need_key_cb; | 297 need_key_cb_ = need_key_cb; |
303 } | 298 } |
304 | 299 |
305 bool ContentDecryptorDelegate::GenerateKeyRequest(const std::string& type, | 300 bool ContentDecryptorDelegate::GenerateKeyRequest(const std::string& type, |
306 const uint8* init_data, | 301 const uint8* init_data, |
307 int init_data_length) { | 302 int init_data_length) { |
308 PP_Var init_data_array = | 303 PP_Var init_data_array = PpapiGlobals::Get()->GetVarTracker() |
309 PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar( | 304 ->MakeArrayBufferPPVar(init_data_length, init_data); |
310 init_data_length, init_data); | |
311 | 305 |
312 plugin_decryption_interface_->GenerateKeyRequest( | 306 plugin_decryption_interface_->GenerateKeyRequest( |
313 pp_instance_, | 307 pp_instance_, |
314 StringVar::StringToPPVar(key_system_), // TODO(ddorwin): Remove. | 308 StringVar::StringToPPVar(key_system_), // TODO(ddorwin): Remove. |
315 StringVar::StringToPPVar(type), | 309 StringVar::StringToPPVar(type), init_data_array); |
316 init_data_array); | |
317 return true; | 310 return true; |
318 } | 311 } |
319 | 312 |
320 bool ContentDecryptorDelegate::AddKey(const std::string& session_id, | 313 bool ContentDecryptorDelegate::AddKey(const std::string& session_id, |
321 const uint8* key, | 314 const uint8* key, int key_length, |
322 int key_length, | |
323 const uint8* init_data, | 315 const uint8* init_data, |
324 int init_data_length) { | 316 int init_data_length) { |
325 PP_Var key_array = | 317 PP_Var key_array = PpapiGlobals::Get()->GetVarTracker() |
326 PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar(key_length, | 318 ->MakeArrayBufferPPVar(key_length, key); |
327 key); | 319 PP_Var init_data_array = PpapiGlobals::Get()->GetVarTracker() |
328 PP_Var init_data_array = | 320 ->MakeArrayBufferPPVar(init_data_length, init_data); |
329 PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar( | |
330 init_data_length, init_data); | |
331 | 321 |
332 plugin_decryption_interface_->AddKey( | 322 plugin_decryption_interface_->AddKey( |
333 pp_instance_, | 323 pp_instance_, StringVar::StringToPPVar(session_id), key_array, |
334 StringVar::StringToPPVar(session_id), | |
335 key_array, | |
336 init_data_array); | 324 init_data_array); |
337 return true; | 325 return true; |
338 } | 326 } |
339 | 327 |
340 bool ContentDecryptorDelegate::CancelKeyRequest(const std::string& session_id) { | 328 bool ContentDecryptorDelegate::CancelKeyRequest(const std::string& session_id) { |
341 plugin_decryption_interface_->CancelKeyRequest( | 329 plugin_decryption_interface_->CancelKeyRequest( |
342 pp_instance_, | 330 pp_instance_, StringVar::StringToPPVar(session_id)); |
343 StringVar::StringToPPVar(session_id)); | |
344 return true; | 331 return true; |
345 } | 332 } |
346 | 333 |
347 // TODO(xhwang): Remove duplication of code in Decrypt(), | 334 // TODO(xhwang): Remove duplication of code in Decrypt(), |
348 // DecryptAndDecodeAudio() and DecryptAndDecodeVideo(). | 335 // DecryptAndDecodeAudio() and DecryptAndDecodeVideo(). |
349 bool ContentDecryptorDelegate::Decrypt( | 336 bool ContentDecryptorDelegate::Decrypt( |
350 media::Decryptor::StreamType stream_type, | 337 media::Decryptor::StreamType stream_type, |
351 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, | 338 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, |
352 const media::Decryptor::DecryptCB& decrypt_cb) { | 339 const media::Decryptor::DecryptCB& decrypt_cb) { |
353 DVLOG(3) << "Decrypt() - stream_type: " << stream_type; | 340 DVLOG(3) << "Decrypt() - stream_type: " << stream_type; |
354 // |{audio|video}_input_resource_| is not being used by the plugin | 341 // |{audio|video}_input_resource_| is not being used by the plugin |
355 // now because there is only one pending audio/video decrypt request at any | 342 // now because there is only one pending audio/video decrypt request at any |
356 // time. This is enforced by the media pipeline. | 343 // time. This is enforced by the media pipeline. |
357 scoped_refptr<PPB_Buffer_Impl> encrypted_resource; | 344 scoped_refptr<PPB_Buffer_Impl> encrypted_resource; |
358 if (!MakeMediaBufferResource( | 345 if (!MakeMediaBufferResource(stream_type, encrypted_buffer, |
359 stream_type, encrypted_buffer, &encrypted_resource) || | 346 &encrypted_resource) || |
360 !encrypted_resource.get()) { | 347 !encrypted_resource.get()) { |
361 return false; | 348 return false; |
362 } | 349 } |
363 ScopedPPResource pp_resource(encrypted_resource.get()); | 350 ScopedPPResource pp_resource(encrypted_resource.get()); |
364 | 351 |
365 const uint32_t request_id = next_decryption_request_id_++; | 352 const uint32_t request_id = next_decryption_request_id_++; |
366 DVLOG(2) << "Decrypt() - request_id " << request_id; | 353 DVLOG(2) << "Decrypt() - request_id " << request_id; |
367 | 354 |
368 PP_EncryptedBlockInfo block_info = {}; | 355 PP_EncryptedBlockInfo block_info = {}; |
369 DCHECK(encrypted_buffer->GetDecryptConfig()); | 356 DCHECK(encrypted_buffer->GetDecryptConfig()); |
(...skipping 16 matching lines...) Expand all Loading... | |
386 pending_video_decrypt_request_id_ = request_id; | 373 pending_video_decrypt_request_id_ = request_id; |
387 pending_video_decrypt_cb_ = decrypt_cb; | 374 pending_video_decrypt_cb_ = decrypt_cb; |
388 break; | 375 break; |
389 default: | 376 default: |
390 NOTREACHED(); | 377 NOTREACHED(); |
391 return false; | 378 return false; |
392 } | 379 } |
393 | 380 |
394 SetBufferToFreeInTrackingInfo(&block_info.tracking_info); | 381 SetBufferToFreeInTrackingInfo(&block_info.tracking_info); |
395 | 382 |
396 plugin_decryption_interface_->Decrypt(pp_instance_, | 383 plugin_decryption_interface_->Decrypt(pp_instance_, pp_resource, &block_info); |
397 pp_resource, | |
398 &block_info); | |
399 return true; | 384 return true; |
400 } | 385 } |
401 | 386 |
402 bool ContentDecryptorDelegate::CancelDecrypt( | 387 bool ContentDecryptorDelegate::CancelDecrypt( |
403 media::Decryptor::StreamType stream_type) { | 388 media::Decryptor::StreamType stream_type) { |
404 DVLOG(3) << "CancelDecrypt() - stream_type: " << stream_type; | 389 DVLOG(3) << "CancelDecrypt() - stream_type: " << stream_type; |
405 | 390 |
406 media::Decryptor::DecryptCB decrypt_cb; | 391 media::Decryptor::DecryptCB decrypt_cb; |
407 switch (stream_type) { | 392 switch (stream_type) { |
408 case media::Decryptor::kAudio: | 393 case media::Decryptor::kAudio: |
(...skipping 29 matching lines...) Expand all Loading... | |
438 PP_AudioDecoderConfig pp_decoder_config; | 423 PP_AudioDecoderConfig pp_decoder_config; |
439 pp_decoder_config.codec = | 424 pp_decoder_config.codec = |
440 MediaAudioCodecToPpAudioCodec(decoder_config.codec()); | 425 MediaAudioCodecToPpAudioCodec(decoder_config.codec()); |
441 pp_decoder_config.channel_count = | 426 pp_decoder_config.channel_count = |
442 media::ChannelLayoutToChannelCount(decoder_config.channel_layout()); | 427 media::ChannelLayoutToChannelCount(decoder_config.channel_layout()); |
443 pp_decoder_config.bits_per_channel = decoder_config.bits_per_channel(); | 428 pp_decoder_config.bits_per_channel = decoder_config.bits_per_channel(); |
444 pp_decoder_config.samples_per_second = decoder_config.samples_per_second(); | 429 pp_decoder_config.samples_per_second = decoder_config.samples_per_second(); |
445 pp_decoder_config.request_id = next_decryption_request_id_++; | 430 pp_decoder_config.request_id = next_decryption_request_id_++; |
446 | 431 |
447 scoped_refptr<PPB_Buffer_Impl> extra_data_resource; | 432 scoped_refptr<PPB_Buffer_Impl> extra_data_resource; |
448 if (!MakeBufferResource(pp_instance_, | 433 if (!MakeBufferResource(pp_instance_, decoder_config.extra_data(), |
449 decoder_config.extra_data(), | |
450 decoder_config.extra_data_size(), | 434 decoder_config.extra_data_size(), |
451 &extra_data_resource)) { | 435 &extra_data_resource)) { |
452 return false; | 436 return false; |
453 } | 437 } |
454 ScopedPPResource pp_resource(extra_data_resource.get()); | 438 ScopedPPResource pp_resource(extra_data_resource.get()); |
455 | 439 |
456 DCHECK_EQ(pending_audio_decoder_init_request_id_, 0u); | 440 DCHECK_EQ(pending_audio_decoder_init_request_id_, 0u); |
457 DCHECK(pending_audio_decoder_init_cb_.is_null()); | 441 DCHECK(pending_audio_decoder_init_cb_.is_null()); |
458 pending_audio_decoder_init_request_id_ = pp_decoder_config.request_id; | 442 pending_audio_decoder_init_request_id_ = pp_decoder_config.request_id; |
459 pending_audio_decoder_init_cb_ = init_cb; | 443 pending_audio_decoder_init_cb_ = init_cb; |
460 | 444 |
461 plugin_decryption_interface_->InitializeAudioDecoder(pp_instance_, | 445 plugin_decryption_interface_->InitializeAudioDecoder( |
462 &pp_decoder_config, | 446 pp_instance_, &pp_decoder_config, pp_resource); |
463 pp_resource); | |
464 return true; | 447 return true; |
465 } | 448 } |
466 | 449 |
467 bool ContentDecryptorDelegate::InitializeVideoDecoder( | 450 bool ContentDecryptorDelegate::InitializeVideoDecoder( |
468 const media::VideoDecoderConfig& decoder_config, | 451 const media::VideoDecoderConfig& decoder_config, |
469 const media::Decryptor::DecoderInitCB& init_cb) { | 452 const media::Decryptor::DecoderInitCB& init_cb) { |
470 PP_VideoDecoderConfig pp_decoder_config; | 453 PP_VideoDecoderConfig pp_decoder_config; |
471 pp_decoder_config.codec = | 454 pp_decoder_config.codec = |
472 MediaVideoCodecToPpVideoCodec(decoder_config.codec()); | 455 MediaVideoCodecToPpVideoCodec(decoder_config.codec()); |
473 pp_decoder_config.profile = | 456 pp_decoder_config.profile = |
474 MediaVideoCodecProfileToPpVideoCodecProfile(decoder_config.profile()); | 457 MediaVideoCodecProfileToPpVideoCodecProfile(decoder_config.profile()); |
475 pp_decoder_config.format = | 458 pp_decoder_config.format = |
476 MediaVideoFormatToPpDecryptedFrameFormat(decoder_config.format()); | 459 MediaVideoFormatToPpDecryptedFrameFormat(decoder_config.format()); |
477 pp_decoder_config.width = decoder_config.coded_size().width(); | 460 pp_decoder_config.width = decoder_config.coded_size().width(); |
478 pp_decoder_config.height = decoder_config.coded_size().height(); | 461 pp_decoder_config.height = decoder_config.coded_size().height(); |
479 pp_decoder_config.request_id = next_decryption_request_id_++; | 462 pp_decoder_config.request_id = next_decryption_request_id_++; |
480 | 463 |
481 scoped_refptr<PPB_Buffer_Impl> extra_data_resource; | 464 scoped_refptr<PPB_Buffer_Impl> extra_data_resource; |
482 if (!MakeBufferResource(pp_instance_, | 465 if (!MakeBufferResource(pp_instance_, decoder_config.extra_data(), |
483 decoder_config.extra_data(), | |
484 decoder_config.extra_data_size(), | 466 decoder_config.extra_data_size(), |
485 &extra_data_resource)) { | 467 &extra_data_resource)) { |
486 return false; | 468 return false; |
487 } | 469 } |
488 ScopedPPResource pp_resource(extra_data_resource.get()); | 470 ScopedPPResource pp_resource(extra_data_resource.get()); |
489 | 471 |
490 DCHECK_EQ(pending_video_decoder_init_request_id_, 0u); | 472 DCHECK_EQ(pending_video_decoder_init_request_id_, 0u); |
491 DCHECK(pending_video_decoder_init_cb_.is_null()); | 473 DCHECK(pending_video_decoder_init_cb_.is_null()); |
492 pending_video_decoder_init_request_id_ = pp_decoder_config.request_id; | 474 pending_video_decoder_init_request_id_ = pp_decoder_config.request_id; |
493 pending_video_decoder_init_cb_ = init_cb; | 475 pending_video_decoder_init_cb_ = init_cb; |
494 | 476 |
495 natural_size_ = decoder_config.natural_size(); | 477 natural_size_ = decoder_config.natural_size(); |
496 | 478 |
497 plugin_decryption_interface_->InitializeVideoDecoder(pp_instance_, | 479 plugin_decryption_interface_->InitializeVideoDecoder( |
498 &pp_decoder_config, | 480 pp_instance_, &pp_decoder_config, pp_resource); |
499 pp_resource); | |
500 return true; | 481 return true; |
501 } | 482 } |
502 | 483 |
503 bool ContentDecryptorDelegate::DeinitializeDecoder( | 484 bool ContentDecryptorDelegate::DeinitializeDecoder( |
504 media::Decryptor::StreamType stream_type) { | 485 media::Decryptor::StreamType stream_type) { |
505 CancelDecode(stream_type); | 486 CancelDecode(stream_type); |
506 | 487 |
507 natural_size_ = gfx::Size(); | 488 natural_size_ = gfx::Size(); |
508 | 489 |
509 // TODO(tomfinegan): Add decoder deinitialize request tracking, and get | 490 // TODO(tomfinegan): Add decoder deinitialize request tracking, and get |
(...skipping 13 matching lines...) Expand all Loading... | |
523 return true; | 504 return true; |
524 } | 505 } |
525 | 506 |
526 bool ContentDecryptorDelegate::DecryptAndDecodeAudio( | 507 bool ContentDecryptorDelegate::DecryptAndDecodeAudio( |
527 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, | 508 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, |
528 const media::Decryptor::AudioDecodeCB& audio_decode_cb) { | 509 const media::Decryptor::AudioDecodeCB& audio_decode_cb) { |
529 // |audio_input_resource_| is not being used by the plugin now | 510 // |audio_input_resource_| is not being used by the plugin now |
530 // because there is only one pending audio decode request at any time. | 511 // because there is only one pending audio decode request at any time. |
531 // This is enforced by the media pipeline. | 512 // This is enforced by the media pipeline. |
532 scoped_refptr<PPB_Buffer_Impl> encrypted_resource; | 513 scoped_refptr<PPB_Buffer_Impl> encrypted_resource; |
533 if (!MakeMediaBufferResource(media::Decryptor::kAudio, | 514 if (!MakeMediaBufferResource(media::Decryptor::kAudio, encrypted_buffer, |
534 encrypted_buffer, | |
535 &encrypted_resource)) { | 515 &encrypted_resource)) { |
536 return false; | 516 return false; |
537 } | 517 } |
538 | 518 |
539 // The resource should not be NULL for non-EOS buffer. | 519 // The resource should not be NULL for non-EOS buffer. |
540 if (!encrypted_buffer->IsEndOfStream() && !encrypted_resource.get()) | 520 if (!encrypted_buffer->IsEndOfStream() && !encrypted_resource.get()) |
541 return false; | 521 return false; |
542 | 522 |
543 const uint32_t request_id = next_decryption_request_id_++; | 523 const uint32_t request_id = next_decryption_request_id_++; |
544 DVLOG(2) << "DecryptAndDecodeAudio() - request_id " << request_id; | 524 DVLOG(2) << "DecryptAndDecodeAudio() - request_id " << request_id; |
545 | 525 |
546 PP_EncryptedBlockInfo block_info = {}; | 526 PP_EncryptedBlockInfo block_info = {}; |
547 if (!MakeEncryptedBlockInfo(encrypted_buffer, request_id, &block_info)) { | 527 if (!MakeEncryptedBlockInfo(encrypted_buffer, request_id, &block_info)) { |
548 return false; | 528 return false; |
549 } | 529 } |
550 | 530 |
551 SetBufferToFreeInTrackingInfo(&block_info.tracking_info); | 531 SetBufferToFreeInTrackingInfo(&block_info.tracking_info); |
552 | 532 |
553 // There is only one pending audio decode request at any time. This is | 533 // There is only one pending audio decode request at any time. This is |
554 // enforced by the media pipeline. If this DCHECK is violated, our buffer | 534 // enforced by the media pipeline. If this DCHECK is violated, our buffer |
555 // reuse policy is not valid, and we may have race problems for the shared | 535 // reuse policy is not valid, and we may have race problems for the shared |
556 // buffer. | 536 // buffer. |
557 DCHECK_EQ(pending_audio_decode_request_id_, 0u); | 537 DCHECK_EQ(pending_audio_decode_request_id_, 0u); |
558 DCHECK(pending_audio_decode_cb_.is_null()); | 538 DCHECK(pending_audio_decode_cb_.is_null()); |
559 pending_audio_decode_request_id_ = request_id; | 539 pending_audio_decode_request_id_ = request_id; |
560 pending_audio_decode_cb_ = audio_decode_cb; | 540 pending_audio_decode_cb_ = audio_decode_cb; |
561 | 541 |
562 ScopedPPResource pp_resource(encrypted_resource.get()); | 542 ScopedPPResource pp_resource(encrypted_resource.get()); |
563 plugin_decryption_interface_->DecryptAndDecode(pp_instance_, | 543 plugin_decryption_interface_->DecryptAndDecode( |
564 PP_DECRYPTORSTREAMTYPE_AUDIO, | 544 pp_instance_, PP_DECRYPTORSTREAMTYPE_AUDIO, pp_resource, &block_info); |
565 pp_resource, | |
566 &block_info); | |
567 return true; | 545 return true; |
568 } | 546 } |
569 | 547 |
570 bool ContentDecryptorDelegate::DecryptAndDecodeVideo( | 548 bool ContentDecryptorDelegate::DecryptAndDecodeVideo( |
571 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, | 549 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, |
572 const media::Decryptor::VideoDecodeCB& video_decode_cb) { | 550 const media::Decryptor::VideoDecodeCB& video_decode_cb) { |
573 // |video_input_resource_| is not being used by the plugin now | 551 // |video_input_resource_| is not being used by the plugin now |
574 // because there is only one pending video decode request at any time. | 552 // because there is only one pending video decode request at any time. |
575 // This is enforced by the media pipeline. | 553 // This is enforced by the media pipeline. |
576 scoped_refptr<PPB_Buffer_Impl> encrypted_resource; | 554 scoped_refptr<PPB_Buffer_Impl> encrypted_resource; |
577 if (!MakeMediaBufferResource(media::Decryptor::kVideo, | 555 if (!MakeMediaBufferResource(media::Decryptor::kVideo, encrypted_buffer, |
578 encrypted_buffer, | |
579 &encrypted_resource)) { | 556 &encrypted_resource)) { |
580 return false; | 557 return false; |
581 } | 558 } |
582 | 559 |
583 // The resource should not be 0 for non-EOS buffer. | 560 // The resource should not be 0 for non-EOS buffer. |
584 if (!encrypted_buffer->IsEndOfStream() && !encrypted_resource.get()) | 561 if (!encrypted_buffer->IsEndOfStream() && !encrypted_resource.get()) |
585 return false; | 562 return false; |
586 | 563 |
587 const uint32_t request_id = next_decryption_request_id_++; | 564 const uint32_t request_id = next_decryption_request_id_++; |
588 DVLOG(2) << "DecryptAndDecodeVideo() - request_id " << request_id; | 565 DVLOG(2) << "DecryptAndDecodeVideo() - request_id " << request_id; |
(...skipping 11 matching lines...) Expand all Loading... | |
600 // media pipeline. If this DCHECK is violated, our buffer | 577 // media pipeline. If this DCHECK is violated, our buffer |
601 // reuse policy is not valid, and we may have race problems for the shared | 578 // reuse policy is not valid, and we may have race problems for the shared |
602 // buffer. | 579 // buffer. |
603 DCHECK_EQ(pending_video_decode_request_id_, 0u); | 580 DCHECK_EQ(pending_video_decode_request_id_, 0u); |
604 DCHECK(pending_video_decode_cb_.is_null()); | 581 DCHECK(pending_video_decode_cb_.is_null()); |
605 pending_video_decode_request_id_ = request_id; | 582 pending_video_decode_request_id_ = request_id; |
606 pending_video_decode_cb_ = video_decode_cb; | 583 pending_video_decode_cb_ = video_decode_cb; |
607 | 584 |
608 // TODO(tomfinegan): Need to get stream type from media stack. | 585 // TODO(tomfinegan): Need to get stream type from media stack. |
609 ScopedPPResource pp_resource(encrypted_resource.get()); | 586 ScopedPPResource pp_resource(encrypted_resource.get()); |
610 plugin_decryption_interface_->DecryptAndDecode(pp_instance_, | 587 plugin_decryption_interface_->DecryptAndDecode( |
611 PP_DECRYPTORSTREAMTYPE_VIDEO, | 588 pp_instance_, PP_DECRYPTORSTREAMTYPE_VIDEO, pp_resource, &block_info); |
612 pp_resource, | |
613 &block_info); | |
614 return true; | 589 return true; |
615 } | 590 } |
616 | 591 |
617 void ContentDecryptorDelegate::NeedKey(PP_Var key_system_var, | 592 void ContentDecryptorDelegate::NeedKey(PP_Var key_system_var, |
618 PP_Var session_id_var, | 593 PP_Var session_id_var, |
619 PP_Var init_data_var) { | 594 PP_Var init_data_var) { |
620 // TODO(ddorwin): Remove from PPB_ContentDecryptor_Private. | 595 // TODO(ddorwin): Remove from PPB_ContentDecryptor_Private. |
621 NOTREACHED(); | 596 NOTREACHED(); |
622 } | 597 } |
623 | 598 |
(...skipping 13 matching lines...) Expand all Loading... | |
637 | 612 |
638 void ContentDecryptorDelegate::KeyMessage(PP_Var key_system_var, | 613 void ContentDecryptorDelegate::KeyMessage(PP_Var key_system_var, |
639 PP_Var session_id_var, | 614 PP_Var session_id_var, |
640 PP_Var message_var, | 615 PP_Var message_var, |
641 PP_Var default_url_var) { | 616 PP_Var default_url_var) { |
642 if (key_message_cb_.is_null()) | 617 if (key_message_cb_.is_null()) |
643 return; | 618 return; |
644 | 619 |
645 StringVar* session_id_string = StringVar::FromPPVar(session_id_var); | 620 StringVar* session_id_string = StringVar::FromPPVar(session_id_var); |
646 | 621 |
647 ArrayBufferVar* message_array_buffer = | 622 ArrayBufferVar* message_array_buffer = ArrayBufferVar::FromPPVar(message_var); |
648 ArrayBufferVar::FromPPVar(message_var); | |
649 | 623 |
650 std::string message; | 624 std::string message; |
651 if (message_array_buffer) { | 625 if (message_array_buffer) { |
652 const char* data = static_cast<const char*>(message_array_buffer->Map()); | 626 const char* data = static_cast<const char*>(message_array_buffer->Map()); |
653 message.assign(data, message_array_buffer->ByteLength()); | 627 message.assign(data, message_array_buffer->ByteLength()); |
654 } | 628 } |
655 | 629 |
656 StringVar* default_url_string = StringVar::FromPPVar(default_url_var); | 630 StringVar* default_url_string = StringVar::FromPPVar(default_url_var); |
657 | 631 |
658 if (!session_id_string || !default_url_string) { | 632 if (!session_id_string || !default_url_string) { |
659 key_error_cb_.Run(std::string(), media::MediaKeys::kUnknownError, 0); | 633 key_error_cb_.Run(std::string(), media::MediaKeys::kUnknownError, 0); |
660 return; | 634 return; |
661 } | 635 } |
662 | 636 |
663 key_message_cb_.Run(session_id_string->value(), | 637 key_message_cb_.Run(session_id_string->value(), message, |
664 message, | |
665 default_url_string->value()); | 638 default_url_string->value()); |
666 } | 639 } |
667 | 640 |
668 void ContentDecryptorDelegate::KeyError(PP_Var key_system_var, | 641 void ContentDecryptorDelegate::KeyError(PP_Var key_system_var, |
669 PP_Var session_id_var, | 642 PP_Var session_id_var, |
670 int32_t media_error, | 643 int32_t media_error, |
671 int32_t system_code) { | 644 int32_t system_code) { |
672 if (key_error_cb_.is_null()) | 645 if (key_error_cb_.is_null()) |
673 return; | 646 return; |
674 | 647 |
675 StringVar* session_id_string = StringVar::FromPPVar(session_id_var); | 648 StringVar* session_id_string = StringVar::FromPPVar(session_id_var); |
676 if (!session_id_string) { | 649 if (!session_id_string) { |
677 key_error_cb_.Run(std::string(), media::MediaKeys::kUnknownError, 0); | 650 key_error_cb_.Run(std::string(), media::MediaKeys::kUnknownError, 0); |
678 return; | 651 return; |
679 } | 652 } |
680 | 653 |
681 key_error_cb_.Run(session_id_string->value(), | 654 key_error_cb_.Run(session_id_string->value(), |
682 static_cast<media::MediaKeys::KeyError>(media_error), | 655 static_cast<media::MediaKeys::KeyError>(media_error), |
683 system_code); | 656 system_code); |
684 } | 657 } |
685 | 658 |
686 void ContentDecryptorDelegate::DecoderInitializeDone( | 659 void ContentDecryptorDelegate::DecoderInitializeDone( |
687 PP_DecryptorStreamType decoder_type, | 660 PP_DecryptorStreamType decoder_type, uint32_t request_id, PP_Bool success) { |
688 uint32_t request_id, | |
689 PP_Bool success) { | |
690 if (decoder_type == PP_DECRYPTORSTREAMTYPE_AUDIO) { | 661 if (decoder_type == PP_DECRYPTORSTREAMTYPE_AUDIO) { |
691 // If the request ID is not valid or does not match what's saved, do | 662 // If the request ID is not valid or does not match what's saved, do |
692 // nothing. | 663 // nothing. |
693 if (request_id == 0 || | 664 if (request_id == 0 || request_id != pending_audio_decoder_init_request_id_) |
694 request_id != pending_audio_decoder_init_request_id_) | |
695 return; | 665 return; |
696 | 666 |
697 DCHECK(!pending_audio_decoder_init_cb_.is_null()); | 667 DCHECK(!pending_audio_decoder_init_cb_.is_null()); |
698 pending_audio_decoder_init_request_id_ = 0; | 668 pending_audio_decoder_init_request_id_ = 0; |
699 base::ResetAndReturn( | 669 base::ResetAndReturn(&pending_audio_decoder_init_cb_) |
700 &pending_audio_decoder_init_cb_).Run(PP_ToBool(success)); | 670 .Run(PP_ToBool(success)); |
701 } else { | 671 } else { |
702 if (request_id == 0 || | 672 if (request_id == 0 || request_id != pending_video_decoder_init_request_id_) |
703 request_id != pending_video_decoder_init_request_id_) | |
704 return; | 673 return; |
705 | 674 |
706 if (!success) | 675 if (!success) natural_size_ = gfx::Size(); |
707 natural_size_ = gfx::Size(); | |
708 | 676 |
709 DCHECK(!pending_video_decoder_init_cb_.is_null()); | 677 DCHECK(!pending_video_decoder_init_cb_.is_null()); |
710 pending_video_decoder_init_request_id_ = 0; | 678 pending_video_decoder_init_request_id_ = 0; |
711 base::ResetAndReturn( | 679 base::ResetAndReturn(&pending_video_decoder_init_cb_) |
712 &pending_video_decoder_init_cb_).Run(PP_ToBool(success)); | 680 .Run(PP_ToBool(success)); |
713 } | 681 } |
714 } | 682 } |
715 | 683 |
716 void ContentDecryptorDelegate::DecoderDeinitializeDone( | 684 void ContentDecryptorDelegate::DecoderDeinitializeDone( |
717 PP_DecryptorStreamType decoder_type, | 685 PP_DecryptorStreamType decoder_type, uint32_t request_id) { |
718 uint32_t request_id) { | |
719 // TODO(tomfinegan): Add decoder stop completion handling. | 686 // TODO(tomfinegan): Add decoder stop completion handling. |
720 } | 687 } |
721 | 688 |
722 void ContentDecryptorDelegate::DecoderResetDone( | 689 void ContentDecryptorDelegate::DecoderResetDone( |
723 PP_DecryptorStreamType decoder_type, | 690 PP_DecryptorStreamType decoder_type, uint32_t request_id) { |
724 uint32_t request_id) { | |
725 // TODO(tomfinegan): Add decoder reset completion handling. | 691 // TODO(tomfinegan): Add decoder reset completion handling. |
726 } | 692 } |
727 | 693 |
728 void ContentDecryptorDelegate::DeliverBlock( | 694 void ContentDecryptorDelegate::DeliverBlock( |
729 PP_Resource decrypted_block, | 695 PP_Resource decrypted_block, const PP_DecryptedBlockInfo* block_info) { |
730 const PP_DecryptedBlockInfo* block_info) { | |
731 DCHECK(block_info); | 696 DCHECK(block_info); |
732 | 697 |
733 FreeBuffer(block_info->tracking_info.buffer_id); | 698 FreeBuffer(block_info->tracking_info.buffer_id); |
734 | 699 |
735 const uint32_t request_id = block_info->tracking_info.request_id; | 700 const uint32_t request_id = block_info->tracking_info.request_id; |
736 DVLOG(2) << "DeliverBlock() - request_id: " << request_id; | 701 DVLOG(2) << "DeliverBlock() - request_id: " << request_id; |
737 | 702 |
738 // If the request ID is not valid or does not match what's saved, do nothing. | 703 // If the request ID is not valid or does not match what's saved, do nothing. |
739 if (request_id == 0) { | 704 if (request_id == 0) { |
740 DVLOG(1) << "DeliverBlock() - invalid request_id " << request_id; | 705 DVLOG(1) << "DeliverBlock() - invalid request_id " << request_id; |
(...skipping 29 matching lines...) Expand all Loading... | |
770 BufferAutoMapper mapper(enter.object()); | 735 BufferAutoMapper mapper(enter.object()); |
771 if (!mapper.data() || !mapper.size() || | 736 if (!mapper.data() || !mapper.size() || |
772 mapper.size() < block_info->data_size) { | 737 mapper.size() < block_info->data_size) { |
773 decrypt_cb.Run(media::Decryptor::kError, NULL); | 738 decrypt_cb.Run(media::Decryptor::kError, NULL); |
774 return; | 739 return; |
775 } | 740 } |
776 | 741 |
777 // TODO(tomfinegan): Find a way to take ownership of the shared memory | 742 // TODO(tomfinegan): Find a way to take ownership of the shared memory |
778 // managed by the PPB_Buffer_Dev, and avoid the extra copy. | 743 // managed by the PPB_Buffer_Dev, and avoid the extra copy. |
779 scoped_refptr<media::DecoderBuffer> decrypted_buffer( | 744 scoped_refptr<media::DecoderBuffer> decrypted_buffer( |
780 media::DecoderBuffer::CopyFrom( | 745 media::DecoderBuffer::CopyFrom(static_cast<uint8*>(mapper.data()), |
781 static_cast<uint8*>(mapper.data()), block_info->data_size)); | 746 block_info->data_size)); |
782 decrypted_buffer->SetTimestamp(base::TimeDelta::FromMicroseconds( | 747 decrypted_buffer->SetTimestamp( |
783 block_info->tracking_info.timestamp)); | 748 base::TimeDelta::FromMicroseconds(block_info->tracking_info.timestamp)); |
784 decrypt_cb.Run(media::Decryptor::kSuccess, decrypted_buffer); | 749 decrypt_cb.Run(media::Decryptor::kSuccess, decrypted_buffer); |
785 } | 750 } |
786 | 751 |
787 // Use a non-class-member function here so that if for some reason | 752 // Use a non-class-member function here so that if for some reason |
788 // ContentDecryptorDelegate is destroyed before VideoFrame calls this callback, | 753 // ContentDecryptorDelegate is destroyed before VideoFrame calls this callback, |
789 // we can still get the shared memory unmapped. | 754 // we can still get the shared memory unmapped. |
790 static void BufferNoLongerNeeded( | 755 static void BufferNoLongerNeeded( |
791 const scoped_refptr<PPB_Buffer_Impl>& ppb_buffer, | 756 const scoped_refptr<PPB_Buffer_Impl>& ppb_buffer, |
792 base::Closure buffer_no_longer_needed_cb) { | 757 base::Closure buffer_no_longer_needed_cb) { |
793 ppb_buffer->Unmap(); | 758 ppb_buffer->Unmap(); |
(...skipping 17 matching lines...) Expand all Loading... | |
811 enter.object()->Unmap(); | 776 enter.object()->Unmap(); |
812 return NULL; | 777 return NULL; |
813 } | 778 } |
814 | 779 |
815 *ppb_buffer = static_cast<PPB_Buffer_Impl*>(enter.object()); | 780 *ppb_buffer = static_cast<PPB_Buffer_Impl*>(enter.object()); |
816 | 781 |
817 return mapped_data; | 782 return mapped_data; |
818 } | 783 } |
819 | 784 |
820 void ContentDecryptorDelegate::DeliverFrame( | 785 void ContentDecryptorDelegate::DeliverFrame( |
821 PP_Resource decrypted_frame, | 786 PP_Resource decrypted_frame, const PP_DecryptedFrameInfo* frame_info) { |
822 const PP_DecryptedFrameInfo* frame_info) { | |
823 DCHECK(frame_info); | 787 DCHECK(frame_info); |
824 | 788 |
825 const uint32_t request_id = frame_info->tracking_info.request_id; | 789 const uint32_t request_id = frame_info->tracking_info.request_id; |
826 DVLOG(2) << "DeliverFrame() - request_id: " << request_id; | 790 DVLOG(2) << "DeliverFrame() - request_id: " << request_id; |
827 | 791 |
828 // If the request ID is not valid or does not match what's saved, do nothing. | 792 // If the request ID is not valid or does not match what's saved, do nothing. |
829 if (request_id == 0 || request_id != pending_video_decode_request_id_) { | 793 if (request_id == 0 || request_id != pending_video_decode_request_id_) { |
830 DVLOG(1) << "DeliverFrame() - request_id " << request_id << " not found"; | 794 DVLOG(1) << "DeliverFrame() - request_id " << request_id << " not found"; |
831 FreeBuffer(frame_info->tracking_info.buffer_id); | 795 FreeBuffer(frame_info->tracking_info.buffer_id); |
832 return; | 796 return; |
(...skipping 21 matching lines...) Expand all Loading... | |
854 FreeBuffer(frame_info->tracking_info.buffer_id); | 818 FreeBuffer(frame_info->tracking_info.buffer_id); |
855 video_decode_cb.Run(media::Decryptor::kError, NULL); | 819 video_decode_cb.Run(media::Decryptor::kError, NULL); |
856 return; | 820 return; |
857 } | 821 } |
858 | 822 |
859 gfx::Size frame_size(frame_info->width, frame_info->height); | 823 gfx::Size frame_size(frame_info->width, frame_info->height); |
860 DCHECK_EQ(frame_info->format, PP_DECRYPTEDFRAMEFORMAT_YV12); | 824 DCHECK_EQ(frame_info->format, PP_DECRYPTEDFRAMEFORMAT_YV12); |
861 | 825 |
862 scoped_refptr<media::VideoFrame> decoded_frame = | 826 scoped_refptr<media::VideoFrame> decoded_frame = |
863 media::VideoFrame::WrapExternalYuvData( | 827 media::VideoFrame::WrapExternalYuvData( |
864 media::VideoFrame::YV12, | 828 media::VideoFrame::YV12, frame_size, gfx::Rect(frame_size), |
865 frame_size, gfx::Rect(frame_size), natural_size_, | 829 natural_size_, frame_info->strides[PP_DECRYPTEDFRAMEPLANES_Y], |
866 frame_info->strides[PP_DECRYPTEDFRAMEPLANES_Y], | |
867 frame_info->strides[PP_DECRYPTEDFRAMEPLANES_U], | 830 frame_info->strides[PP_DECRYPTEDFRAMEPLANES_U], |
868 frame_info->strides[PP_DECRYPTEDFRAMEPLANES_V], | 831 frame_info->strides[PP_DECRYPTEDFRAMEPLANES_V], |
869 frame_data + frame_info->plane_offsets[PP_DECRYPTEDFRAMEPLANES_Y], | 832 frame_data + frame_info->plane_offsets[PP_DECRYPTEDFRAMEPLANES_Y], |
870 frame_data + frame_info->plane_offsets[PP_DECRYPTEDFRAMEPLANES_U], | 833 frame_data + frame_info->plane_offsets[PP_DECRYPTEDFRAMEPLANES_U], |
871 frame_data + frame_info->plane_offsets[PP_DECRYPTEDFRAMEPLANES_V], | 834 frame_data + frame_info->plane_offsets[PP_DECRYPTEDFRAMEPLANES_V], |
872 base::TimeDelta::FromMicroseconds( | 835 base::TimeDelta::FromMicroseconds( |
873 frame_info->tracking_info.timestamp), | 836 frame_info->tracking_info.timestamp), |
874 media::BindToLoop( | 837 media::BindToLoop( |
875 base::MessageLoopProxy::current(), | 838 base::MessageLoopProxy::current(), |
876 base::Bind(&BufferNoLongerNeeded, ppb_buffer, | 839 base::Bind( |
877 base::Bind(&ContentDecryptorDelegate::FreeBuffer, | 840 &BufferNoLongerNeeded, ppb_buffer, |
878 weak_this_, | 841 base::Bind(&ContentDecryptorDelegate::FreeBuffer, weak_this_, |
879 frame_info->tracking_info.buffer_id)))); | 842 frame_info->tracking_info.buffer_id)))); |
880 | 843 |
881 video_decode_cb.Run(media::Decryptor::kSuccess, decoded_frame); | 844 video_decode_cb.Run(media::Decryptor::kSuccess, decoded_frame); |
882 } | 845 } |
883 | 846 |
884 void ContentDecryptorDelegate::DeliverSamples( | 847 void ContentDecryptorDelegate::DeliverSamples( |
885 PP_Resource audio_frames, | 848 PP_Resource audio_frames, const PP_DecryptedBlockInfo* block_info) { |
886 const PP_DecryptedBlockInfo* block_info) { | |
887 DCHECK(block_info); | 849 DCHECK(block_info); |
888 | 850 |
889 FreeBuffer(block_info->tracking_info.buffer_id); | 851 FreeBuffer(block_info->tracking_info.buffer_id); |
890 | 852 |
891 const uint32_t request_id = block_info->tracking_info.request_id; | 853 const uint32_t request_id = block_info->tracking_info.request_id; |
892 DVLOG(2) << "DeliverSamples() - request_id: " << request_id; | 854 DVLOG(2) << "DeliverSamples() - request_id: " << request_id; |
893 | 855 |
894 // If the request ID is not valid or does not match what's saved, do nothing. | 856 // If the request ID is not valid or does not match what's saved, do nothing. |
895 if (request_id == 0 || request_id != pending_audio_decode_request_id_) { | 857 if (request_id == 0 || request_id != pending_audio_decode_request_id_) { |
896 DVLOG(1) << "DeliverSamples() - request_id " << request_id << " not found"; | 858 DVLOG(1) << "DeliverSamples() - request_id " << request_id << " not found"; |
897 return; | 859 return; |
898 } | 860 } |
899 | 861 |
900 DCHECK(!pending_audio_decode_cb_.is_null()); | 862 DCHECK(!pending_audio_decode_cb_.is_null()); |
901 pending_audio_decode_request_id_ = 0; | 863 pending_audio_decode_request_id_ = 0; |
902 media::Decryptor::AudioDecodeCB audio_decode_cb = | 864 media::Decryptor::AudioDecodeCB audio_decode_cb = |
903 base::ResetAndReturn(&pending_audio_decode_cb_); | 865 base::ResetAndReturn(&pending_audio_decode_cb_); |
904 | 866 |
905 const media::Decryptor::AudioBuffers empty_frames; | 867 const media::Decryptor::AudioBuffers empty_frames; |
906 | 868 |
907 media::Decryptor::Status status = | 869 media::Decryptor::Status status = |
908 PpDecryptResultToMediaDecryptorStatus(block_info->result); | 870 PpDecryptResultToMediaDecryptorStatus(block_info->result); |
909 if (status != media::Decryptor::kSuccess) { | 871 if (status != media::Decryptor::kSuccess) { |
910 audio_decode_cb.Run(status, empty_frames); | 872 audio_decode_cb.Run(status, empty_frames); |
911 return; | 873 return; |
912 } | 874 } |
913 | 875 |
914 media::Decryptor::AudioBuffers audio_frame_list; | 876 media::Decryptor::AudioBuffers audio_frame_list; |
915 if (!DeserializeAudioFrames(audio_frames, | 877 if (!DeserializeAudioFrames(audio_frames, block_info->data_size, |
916 block_info->data_size, | |
917 &audio_frame_list)) { | 878 &audio_frame_list)) { |
918 NOTREACHED() << "CDM did not serialize the buffer correctly."; | 879 NOTREACHED() << "CDM did not serialize the buffer correctly."; |
919 audio_decode_cb.Run(media::Decryptor::kError, empty_frames); | 880 audio_decode_cb.Run(media::Decryptor::kError, empty_frames); |
920 return; | 881 return; |
921 } | 882 } |
922 | 883 |
923 audio_decode_cb.Run(media::Decryptor::kSuccess, audio_frame_list); | 884 audio_decode_cb.Run(media::Decryptor::kSuccess, audio_frame_list); |
924 } | 885 } |
925 | 886 |
926 // TODO(xhwang): Try to remove duplicate logic here and in CancelDecrypt(). | 887 // TODO(xhwang): Try to remove duplicate logic here and in CancelDecrypt(). |
927 void ContentDecryptorDelegate::CancelDecode( | 888 void ContentDecryptorDelegate::CancelDecode( |
928 media::Decryptor::StreamType stream_type) { | 889 media::Decryptor::StreamType stream_type) { |
929 switch (stream_type) { | 890 switch (stream_type) { |
930 case media::Decryptor::kAudio: | 891 case media::Decryptor::kAudio: |
931 // Release the shared memory as it can still be in use by the plugin. | 892 // Release the shared memory as it can still be in use by the plugin. |
932 // The next DecryptAndDecode() call will need to allocate a new shared | 893 // The next DecryptAndDecode() call will need to allocate a new shared |
933 // memory buffer. | 894 // memory buffer. |
934 audio_input_resource_ = NULL; | 895 audio_input_resource_ = NULL; |
935 pending_audio_decode_request_id_ = 0; | 896 pending_audio_decode_request_id_ = 0; |
936 if (!pending_audio_decode_cb_.is_null()) | 897 if (!pending_audio_decode_cb_.is_null()) |
937 base::ResetAndReturn(&pending_audio_decode_cb_).Run( | 898 base::ResetAndReturn(&pending_audio_decode_cb_) |
938 media::Decryptor::kSuccess, media::Decryptor::AudioBuffers()); | 899 .Run(media::Decryptor::kSuccess, media::Decryptor::AudioBuffers()); |
939 break; | 900 break; |
940 case media::Decryptor::kVideo: | 901 case media::Decryptor::kVideo: |
941 // Release the shared memory as it can still be in use by the plugin. | 902 // Release the shared memory as it can still be in use by the plugin. |
942 // The next DecryptAndDecode() call will need to allocate a new shared | 903 // The next DecryptAndDecode() call will need to allocate a new shared |
943 // memory buffer. | 904 // memory buffer. |
944 video_input_resource_ = NULL; | 905 video_input_resource_ = NULL; |
945 pending_video_decode_request_id_ = 0; | 906 pending_video_decode_request_id_ = 0; |
946 if (!pending_video_decode_cb_.is_null()) | 907 if (!pending_video_decode_cb_.is_null()) |
947 base::ResetAndReturn(&pending_video_decode_cb_).Run( | 908 base::ResetAndReturn(&pending_video_decode_cb_) |
948 media::Decryptor::kSuccess, NULL); | 909 .Run(media::Decryptor::kSuccess, NULL); |
949 break; | 910 break; |
950 default: | 911 default: |
951 NOTREACHED(); | 912 NOTREACHED(); |
952 } | 913 } |
953 } | 914 } |
954 | 915 |
955 bool ContentDecryptorDelegate::MakeMediaBufferResource( | 916 bool ContentDecryptorDelegate::MakeMediaBufferResource( |
956 media::Decryptor::StreamType stream_type, | 917 media::Decryptor::StreamType stream_type, |
957 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, | 918 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, |
958 scoped_refptr<PPB_Buffer_Impl>* resource) { | 919 scoped_refptr<PPB_Buffer_Impl>* resource) { |
959 TRACE_EVENT0("eme", "ContentDecryptorDelegate::MakeMediaBufferResource"); | 920 TRACE_EVENT0("eme", "ContentDecryptorDelegate::MakeMediaBufferResource"); |
960 | 921 |
961 // End of stream buffers are represented as null resources. | 922 // End of stream buffers are represented as null resources. |
962 if (encrypted_buffer->IsEndOfStream()) { | 923 if (encrypted_buffer->IsEndOfStream()) { |
963 *resource = NULL; | 924 *resource = NULL; |
964 return true; | 925 return true; |
965 } | 926 } |
966 | 927 |
967 DCHECK(stream_type == media::Decryptor::kAudio || | 928 DCHECK(stream_type == media::Decryptor::kAudio || |
968 stream_type == media::Decryptor::kVideo); | 929 stream_type == media::Decryptor::kVideo); |
969 scoped_refptr<PPB_Buffer_Impl>& media_resource = | 930 scoped_refptr<PPB_Buffer_Impl>& media_resource = |
970 (stream_type == media::Decryptor::kAudio) ? audio_input_resource_ : | 931 (stream_type == media::Decryptor::kAudio) ? audio_input_resource_ |
971 video_input_resource_; | 932 : video_input_resource_; |
972 | 933 |
973 const size_t data_size = static_cast<size_t>(encrypted_buffer->GetDataSize()); | 934 const size_t data_size = static_cast<size_t>(encrypted_buffer->GetDataSize()); |
974 if (!media_resource.get() || media_resource->size() < data_size) { | 935 if (!media_resource.get() || media_resource->size() < data_size) { |
975 // Either the buffer hasn't been created yet, or we have one that isn't big | 936 // Either the buffer hasn't been created yet, or we have one that isn't big |
976 // enough to fit |size| bytes. | 937 // enough to fit |size| bytes. |
977 | 938 |
978 // Media resource size starts from |kMinimumMediaBufferSize| and grows | 939 // Media resource size starts from |kMinimumMediaBufferSize| and grows |
979 // exponentially to avoid frequent re-allocation of PPB_Buffer_Impl, | 940 // exponentially to avoid frequent re-allocation of PPB_Buffer_Impl, |
980 // which is usually expensive. Since input media buffers are compressed, | 941 // which is usually expensive. Since input media buffers are compressed, |
981 // they are usually small (compared to outputs). The over-allocated memory | 942 // they are usually small (compared to outputs). The over-allocated memory |
982 // should be negligible. | 943 // should be negligible. |
983 const uint32_t kMinimumMediaBufferSize = 1024; | 944 const uint32_t kMinimumMediaBufferSize = 1024; |
984 uint32_t media_resource_size = | 945 uint32_t media_resource_size = |
985 media_resource.get() ? media_resource->size() : kMinimumMediaBufferSize; | 946 media_resource.get() ? media_resource->size() : kMinimumMediaBufferSize; |
986 while (media_resource_size < data_size) | 947 while (media_resource_size < data_size) media_resource_size *= 2; |
scherkus (not reviewing)
2013/06/21 23:39:16
hey!
| |
987 media_resource_size *= 2; | |
988 | 948 |
989 DVLOG(2) << "Size of media buffer for " | 949 DVLOG(2) << "Size of media buffer for " |
990 << ((stream_type == media::Decryptor::kAudio) ? "audio" : "video") | 950 << ((stream_type == media::Decryptor::kAudio) ? "audio" : "video") |
991 << " stream bumped to " << media_resource_size | 951 << " stream bumped to " << media_resource_size |
992 << " bytes to fit input."; | 952 << " bytes to fit input."; |
993 media_resource = PPB_Buffer_Impl::CreateResource(pp_instance_, | 953 media_resource = |
994 media_resource_size); | 954 PPB_Buffer_Impl::CreateResource(pp_instance_, media_resource_size); |
995 if (!media_resource.get()) | 955 if (!media_resource.get()) |
996 return false; | 956 return false; |
997 } | 957 } |
998 | 958 |
999 BufferAutoMapper mapper(media_resource.get()); | 959 BufferAutoMapper mapper(media_resource.get()); |
1000 if (!mapper.data() || mapper.size() < data_size) { | 960 if (!mapper.data() || mapper.size() < data_size) { |
1001 media_resource = NULL; | 961 media_resource = NULL; |
1002 return false; | 962 return false; |
1003 } | 963 } |
1004 memcpy(mapper.data(), encrypted_buffer->GetData(), data_size); | 964 memcpy(mapper.data(), encrypted_buffer->GetData(), data_size); |
(...skipping 13 matching lines...) Expand all Loading... | |
1018 | 978 |
1019 if (free_buffers_.empty()) | 979 if (free_buffers_.empty()) |
1020 return; | 980 return; |
1021 | 981 |
1022 tracking_info->buffer_id = free_buffers_.front(); | 982 tracking_info->buffer_id = free_buffers_.front(); |
1023 free_buffers_.pop(); | 983 free_buffers_.pop(); |
1024 } | 984 } |
1025 | 985 |
1026 } // namespace ppapi | 986 } // namespace ppapi |
1027 } // namespace webkit | 987 } // namespace webkit |
OLD | NEW |