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 "media/base/audio_decoder_config.h" | 9 #include "media/base/audio_decoder_config.h" |
10 #include "media/base/channel_layout.h" | 10 #include "media/base/channel_layout.h" |
11 #include "media/base/data_buffer.h" | 11 #include "media/base/data_buffer.h" |
12 #include "media/base/decoder_buffer.h" | 12 #include "media/base/decoder_buffer.h" |
13 #include "media/base/decryptor_client.h" | 13 #include "media/base/decryptor_client.h" |
14 #include "media/base/video_decoder_config.h" | 14 #include "media/base/video_decoder_config.h" |
15 #include "media/base/video_frame.h" | 15 #include "media/base/video_frame.h" |
16 #include "media/base/video_util.h" | 16 #include "media/base/video_util.h" |
17 #include "ppapi/shared_impl/scoped_pp_resource.h" | |
18 #include "ppapi/shared_impl/var.h" | 17 #include "ppapi/shared_impl/var.h" |
19 #include "ppapi/shared_impl/var_tracker.h" | 18 #include "ppapi/shared_impl/var_tracker.h" |
20 #include "ppapi/thunk/enter.h" | 19 #include "ppapi/thunk/enter.h" |
21 #include "ppapi/thunk/ppb_buffer_api.h" | 20 #include "ppapi/thunk/ppb_buffer_api.h" |
22 #include "webkit/plugins/ppapi/ppb_buffer_impl.h" | 21 #include "webkit/plugins/ppapi/ppb_buffer_impl.h" |
23 | 22 |
24 using ppapi::PpapiGlobals; | 23 using ppapi::PpapiGlobals; |
25 using ppapi::ScopedPPResource; | 24 using ppapi::ScopedPPResource; |
26 using ppapi::StringVar; | 25 using ppapi::StringVar; |
27 using ppapi::thunk::EnterResourceNoLock; | 26 using ppapi::thunk::EnterResourceNoLock; |
28 using ppapi::thunk::PPB_Buffer_API; | 27 using ppapi::thunk::PPB_Buffer_API; |
29 | 28 |
30 namespace webkit { | 29 namespace webkit { |
31 namespace ppapi { | 30 namespace ppapi { |
32 | 31 |
33 namespace { | 32 namespace { |
34 | 33 |
34 const int kInitialMediaBufferSize = 1024; | |
35 | |
35 // Fills |resource| with a PP_Resource containing a PPB_Buffer_Impl and copies | 36 // Fills |resource| with a PP_Resource containing a PPB_Buffer_Impl and copies |
36 // |data| into the buffer resource. The |resource| has a reference count of 1. | 37 // |data| into the buffer resource. The |resource| has a reference count of 1. |
37 // If |data| is NULL, fills |resource| with a PP_Resource with ID of 0. | 38 // If |data| is NULL, fills |resource| with a PP_Resource with ID of 0. |
38 // Returns true upon success and false if any error happened. | 39 // Returns true upon success and false if any error happened. |
39 bool MakeBufferResource(PP_Instance instance, | 40 bool MakeBufferResource(PP_Instance instance, |
40 const uint8* data, int size, | 41 const uint8* data, int size, |
41 ScopedPPResource* resource) { | 42 ScopedPPResource* resource) { |
43 TRACE_EVENT0("eme", "ContentDecryptorDelegate - MakeBufferResource"); | |
42 DCHECK(resource); | 44 DCHECK(resource); |
43 | 45 |
44 if (!data || !size) { | 46 if (!data || !size) { |
45 DCHECK(!data && !size); | 47 DCHECK(!data && !size); |
46 resource->Release(); | 48 resource->Release(); |
47 return true; | 49 return true; |
48 } | 50 } |
49 | 51 |
50 ScopedPPResource scoped_resource(ScopedPPResource::PassRef(), | 52 ScopedPPResource scoped_resource(ScopedPPResource::PassRef(), |
51 PPB_Buffer_Impl::Create(instance, size)); | 53 PPB_Buffer_Impl::Create(instance, size)); |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
267 const PPP_ContentDecryptor_Private* plugin_decryption_interface) | 269 const PPP_ContentDecryptor_Private* plugin_decryption_interface) |
268 : pp_instance_(pp_instance), | 270 : pp_instance_(pp_instance), |
269 plugin_decryption_interface_(plugin_decryption_interface), | 271 plugin_decryption_interface_(plugin_decryption_interface), |
270 decryptor_client_(NULL), | 272 decryptor_client_(NULL), |
271 next_decryption_request_id_(1), | 273 next_decryption_request_id_(1), |
272 pending_audio_decrypt_request_id_(0), | 274 pending_audio_decrypt_request_id_(0), |
273 pending_video_decrypt_request_id_(0), | 275 pending_video_decrypt_request_id_(0), |
274 pending_audio_decoder_init_request_id_(0), | 276 pending_audio_decoder_init_request_id_(0), |
275 pending_video_decoder_init_request_id_(0), | 277 pending_video_decoder_init_request_id_(0), |
276 pending_audio_decode_request_id_(0), | 278 pending_audio_decode_request_id_(0), |
277 pending_video_decode_request_id_(0) { | 279 pending_video_decode_request_id_(0), |
280 audio_input_resource_size_(0), | |
281 video_input_resource_size_(0) { | |
278 } | 282 } |
279 | 283 |
280 void ContentDecryptorDelegate::set_decrypt_client( | 284 void ContentDecryptorDelegate::set_decrypt_client( |
281 media::DecryptorClient* decryptor_client) { | 285 media::DecryptorClient* decryptor_client) { |
282 decryptor_client_ = decryptor_client; | 286 decryptor_client_ = decryptor_client; |
283 } | 287 } |
284 | 288 |
285 bool ContentDecryptorDelegate::GenerateKeyRequest(const std::string& key_system, | 289 bool ContentDecryptorDelegate::GenerateKeyRequest(const std::string& key_system, |
286 const std::string& type, | 290 const std::string& type, |
287 const uint8* init_data, | 291 const uint8* init_data, |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
328 return true; | 332 return true; |
329 } | 333 } |
330 | 334 |
331 // TODO(xhwang): Remove duplication of code in Decrypt(), | 335 // TODO(xhwang): Remove duplication of code in Decrypt(), |
332 // DecryptAndDecodeAudio() and DecryptAndDecodeVideo(). | 336 // DecryptAndDecodeAudio() and DecryptAndDecodeVideo(). |
333 bool ContentDecryptorDelegate::Decrypt( | 337 bool ContentDecryptorDelegate::Decrypt( |
334 media::Decryptor::StreamType stream_type, | 338 media::Decryptor::StreamType stream_type, |
335 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, | 339 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, |
336 const media::Decryptor::DecryptCB& decrypt_cb) { | 340 const media::Decryptor::DecryptCB& decrypt_cb) { |
337 DVLOG(3) << "Decrypt() - stream_type: " << stream_type; | 341 DVLOG(3) << "Decrypt() - stream_type: " << stream_type; |
342 // |{audio|video}_input_resource_size_| must be available here because there | |
ddorwin
2012/11/17 02:07:38
What do you mean by "available"?
xhwang
2012/11/18 00:10:33
Done here and elsewhere.
| |
343 // is only one pending audio/video decrypt request at any time. This is | |
344 // enforced by the media pipeline. | |
338 ScopedPPResource encrypted_resource; | 345 ScopedPPResource encrypted_resource; |
339 if (!MakeBufferResource(pp_instance_, | 346 if (!MakeMediaBufferResource(stream_type, |
340 encrypted_buffer->GetData(), | 347 encrypted_buffer->GetData(), |
341 encrypted_buffer->GetDataSize(), | 348 encrypted_buffer->GetDataSize(), |
342 &encrypted_resource) || | 349 &encrypted_resource) || |
343 !encrypted_resource.get()) { | 350 !encrypted_resource.get()) { |
344 return false; | 351 return false; |
345 } | 352 } |
346 | 353 |
347 const uint32_t request_id = next_decryption_request_id_++; | 354 const uint32_t request_id = next_decryption_request_id_++; |
348 DVLOG(2) << "Decrypt() - request_id " << request_id; | 355 DVLOG(2) << "Decrypt() - request_id " << request_id; |
349 | 356 |
350 PP_EncryptedBlockInfo block_info; | 357 PP_EncryptedBlockInfo block_info; |
351 DCHECK(encrypted_buffer->GetDecryptConfig()); | 358 DCHECK(encrypted_buffer->GetDecryptConfig()); |
352 if (!MakeEncryptedBlockInfo(encrypted_buffer->GetDecryptConfig(), | 359 if (!MakeEncryptedBlockInfo(encrypted_buffer->GetDecryptConfig(), |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
492 pp_instance_, MediaDecryptorStreamTypeToPpStreamType(stream_type), 0); | 499 pp_instance_, MediaDecryptorStreamTypeToPpStreamType(stream_type), 0); |
493 return true; | 500 return true; |
494 } | 501 } |
495 | 502 |
496 bool ContentDecryptorDelegate::DecryptAndDecodeAudio( | 503 bool ContentDecryptorDelegate::DecryptAndDecodeAudio( |
497 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, | 504 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, |
498 const media::Decryptor::AudioDecodeCB& audio_decode_cb) { | 505 const media::Decryptor::AudioDecodeCB& audio_decode_cb) { |
499 // If |encrypted_buffer| is end-of-stream buffer, GetData() and GetDataSize() | 506 // If |encrypted_buffer| is end-of-stream buffer, GetData() and GetDataSize() |
500 // return NULL and 0 respectively. In that case, we'll just create a 0 | 507 // return NULL and 0 respectively. In that case, we'll just create a 0 |
501 // resource. | 508 // resource. |
509 // |audio_input_resource_size_| must be available here because there is only | |
510 // one pending audio decode request at any time. This is enforced by the media | |
511 // pipeline. | |
502 ScopedPPResource encrypted_resource; | 512 ScopedPPResource encrypted_resource; |
503 if (!MakeBufferResource(pp_instance_, | 513 if (!MakeMediaBufferResource(media::Decryptor::kAudio, |
504 encrypted_buffer->GetData(), | 514 encrypted_buffer->GetData(), |
505 encrypted_buffer->GetDataSize(), | 515 encrypted_buffer->GetDataSize(), |
506 &encrypted_resource)) { | 516 &encrypted_resource)) { |
507 return false; | 517 return false; |
508 } | 518 } |
509 | 519 |
510 // The resource should not be 0 for non-EOS buffer. | 520 // The resource should not be 0 for non-EOS buffer. |
511 if (!encrypted_buffer->IsEndOfStream() && !encrypted_resource.get()) | 521 if (!encrypted_buffer->IsEndOfStream() && !encrypted_resource.get()) |
512 return false; | 522 return false; |
513 | 523 |
514 const uint32_t request_id = next_decryption_request_id_++; | 524 const uint32_t request_id = next_decryption_request_id_++; |
515 DVLOG(2) << "DecryptAndDecodeAudio() - request_id " << request_id; | 525 DVLOG(2) << "DecryptAndDecodeAudio() - request_id " << request_id; |
516 | 526 |
(...skipping 19 matching lines...) Expand all Loading... | |
536 &block_info); | 546 &block_info); |
537 return true; | 547 return true; |
538 } | 548 } |
539 | 549 |
540 bool ContentDecryptorDelegate::DecryptAndDecodeVideo( | 550 bool ContentDecryptorDelegate::DecryptAndDecodeVideo( |
541 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, | 551 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, |
542 const media::Decryptor::VideoDecodeCB& video_decode_cb) { | 552 const media::Decryptor::VideoDecodeCB& video_decode_cb) { |
543 // If |encrypted_buffer| is end-of-stream buffer, GetData() and GetDataSize() | 553 // If |encrypted_buffer| is end-of-stream buffer, GetData() and GetDataSize() |
544 // return NULL and 0 respectively. In that case, we'll just create a 0 | 554 // return NULL and 0 respectively. In that case, we'll just create a 0 |
545 // resource. | 555 // resource. |
556 // |video_input_resource_size_| must be available here because there is only | |
557 // one pending video decode request at any time. This is enforced by the media | |
558 // pipeline. | |
546 ScopedPPResource encrypted_resource; | 559 ScopedPPResource encrypted_resource; |
547 if (!MakeBufferResource(pp_instance_, | 560 if (!MakeBufferResource(pp_instance_,//media::Decryptor::kVideo, |
ddorwin
2012/11/17 02:07:38
Huh? Why not MakeMediaBufferResource?
xhwang
2012/11/18 00:10:33
Oops, I used this to test how much gain I have and
| |
548 encrypted_buffer->GetData(), | 561 encrypted_buffer->GetData(), |
549 encrypted_buffer->GetDataSize(), | 562 encrypted_buffer->GetDataSize(), |
550 &encrypted_resource)) { | 563 &encrypted_resource)) { |
551 return false; | 564 return false; |
552 } | 565 } |
553 | 566 |
554 // The resource should not be 0 for non-EOS buffer. | 567 // The resource should not be 0 for non-EOS buffer. |
555 if (!encrypted_buffer->IsEndOfStream() && !encrypted_resource.get()) | 568 if (!encrypted_buffer->IsEndOfStream() && !encrypted_resource.get()) |
556 return false; | 569 return false; |
557 | 570 |
558 const uint32_t request_id = next_decryption_request_id_++; | 571 const uint32_t request_id = next_decryption_request_id_++; |
559 DVLOG(2) << "DecryptAndDecodeVideo() - request_id " << request_id; | 572 DVLOG(2) << "DecryptAndDecodeVideo() - request_id " << request_id; |
560 TRACE_EVENT_ASYNC_BEGIN0( | 573 TRACE_EVENT_ASYNC_BEGIN0( |
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
883 pending_video_decode_request_id_ = 0; | 896 pending_video_decode_request_id_ = 0; |
884 if (!pending_video_decode_cb_.is_null()) | 897 if (!pending_video_decode_cb_.is_null()) |
885 base::ResetAndReturn(&pending_video_decode_cb_).Run( | 898 base::ResetAndReturn(&pending_video_decode_cb_).Run( |
886 media::Decryptor::kSuccess, NULL); | 899 media::Decryptor::kSuccess, NULL); |
887 break; | 900 break; |
888 default: | 901 default: |
889 NOTREACHED(); | 902 NOTREACHED(); |
890 } | 903 } |
891 } | 904 } |
892 | 905 |
906 bool ContentDecryptorDelegate::MakeMediaBufferResource( | |
907 media::Decryptor::StreamType stream_type, | |
908 const uint8* data, int size, | |
909 ScopedPPResource* resource) { | |
910 TRACE_EVENT0("eme", "ContentDecryptorDelegate::MakeMediaBufferResource"); | |
911 | |
912 DCHECK(resource); | |
913 | |
914 if (!data || !size) { | |
915 DCHECK(!data && !size); | |
916 resource->Release(); | |
917 return true; | |
918 } | |
919 | |
920 DCHECK(stream_type == media::Decryptor::kAudio || | |
921 stream_type == media::Decryptor::kVideo); | |
922 ScopedPPResource& media_resource = (stream_type == media::Decryptor::kAudio) ? | |
923 audio_input_resource_ : video_input_resource_; | |
924 int& media_resource_size = (stream_type == media::Decryptor::kAudio) ? | |
925 audio_input_resource_size_ : video_input_resource_size_; | |
926 | |
927 if (media_resource_size < size) { | |
928 if (media_resource_size == 0) | |
929 media_resource_size = kInitialMediaBufferSize; | |
ddorwin
2012/11/17 02:07:38
Are you just trying to make it a power of 2? If so
xhwang
2012/11/18 00:10:33
It can really just be any size. Use power of 2 her
| |
930 | |
931 while (media_resource_size < size) { | |
932 media_resource_size *= 2; | |
ddorwin
2012/11/17 02:07:38
Should we just do pow(ceiling(log(size)))?
xhwang
2012/11/18 00:10:33
Using a while loop and double the size (shift one
| |
933 } | |
934 | |
935 DVLOG(2) << "Size of media buffer for " | |
936 << ((stream_type == media::Decryptor::kAudio) ? "audio" : "video") | |
937 << " stream bumped to " << media_resource_size | |
938 << " bytes to fit input."; | |
939 media_resource = ScopedPPResource( | |
940 ScopedPPResource::PassRef(), | |
941 PPB_Buffer_Impl::Create(pp_instance_, media_resource_size)); | |
942 } | |
ddorwin
2012/11/17 02:07:38
If any of the above fails, we need to reset the ap
xhwang
2012/11/18 00:10:33
Added reset of media_resource and media_resource_s
ddorwin
2012/11/18 00:37:19
It's better to have a unit of code function correc
xhwang
2012/11/19 21:16:34
okay
| |
943 | |
944 if (!media_resource.get()) | |
ddorwin
2012/11/17 02:07:38
This can never fail outside the bracket at 942 unl
xhwang
2012/11/18 00:10:33
This can happen for new created buffer. Move this
| |
945 return false; | |
946 | |
947 EnterResourceNoLock<PPB_Buffer_API> enter(media_resource, true); | |
948 if (enter.failed()) | |
949 return false; | |
950 | |
951 BufferAutoMapper mapper(enter.object()); | |
952 if (!mapper.data() || mapper.size() < static_cast<size_t>(size)) | |
953 return false; | |
954 memcpy(mapper.data(), data, size); | |
955 | |
956 *resource = media_resource; | |
957 return true; | |
958 } | |
959 | |
893 } // namespace ppapi | 960 } // namespace ppapi |
894 } // namespace webkit | 961 } // namespace webkit |
OLD | NEW |