Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(318)

Side by Side Diff: webkit/plugins/ppapi/content_decryptor_delegate.cc

Issue 11411053: Reuse PPB_Buffer_Impl in ContentDecryptorDelegate. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: nit Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « webkit/plugins/ppapi/content_decryptor_delegate.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
35 // Fills |resource| with a PP_Resource containing a PPB_Buffer_Impl and copies 34 // 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. 35 // |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. 36 // 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. 37 // Returns true upon success and false if any error happened.
39 bool MakeBufferResource(PP_Instance instance, 38 bool MakeBufferResource(PP_Instance instance,
40 const uint8* data, int size, 39 const uint8* data, int size,
41 ScopedPPResource* resource) { 40 ScopedPPResource* resource) {
41 TRACE_EVENT0("eme", "ContentDecryptorDelegate - MakeBufferResource");
42 DCHECK(resource); 42 DCHECK(resource);
43 43
44 if (!data || !size) { 44 if (!data || !size) {
45 DCHECK(!data && !size); 45 DCHECK(!data && !size);
46 resource->Release(); 46 resource->Release();
47 return true; 47 return true;
48 } 48 }
49 49
50 ScopedPPResource scoped_resource(ScopedPPResource::PassRef(), 50 ScopedPPResource scoped_resource(ScopedPPResource::PassRef(),
51 PPB_Buffer_Impl::Create(instance, size)); 51 PPB_Buffer_Impl::Create(instance, size));
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 const PPP_ContentDecryptor_Private* plugin_decryption_interface) 267 const PPP_ContentDecryptor_Private* plugin_decryption_interface)
268 : pp_instance_(pp_instance), 268 : pp_instance_(pp_instance),
269 plugin_decryption_interface_(plugin_decryption_interface), 269 plugin_decryption_interface_(plugin_decryption_interface),
270 decryptor_client_(NULL), 270 decryptor_client_(NULL),
271 next_decryption_request_id_(1), 271 next_decryption_request_id_(1),
272 pending_audio_decrypt_request_id_(0), 272 pending_audio_decrypt_request_id_(0),
273 pending_video_decrypt_request_id_(0), 273 pending_video_decrypt_request_id_(0),
274 pending_audio_decoder_init_request_id_(0), 274 pending_audio_decoder_init_request_id_(0),
275 pending_video_decoder_init_request_id_(0), 275 pending_video_decoder_init_request_id_(0),
276 pending_audio_decode_request_id_(0), 276 pending_audio_decode_request_id_(0),
277 pending_video_decode_request_id_(0) { 277 pending_video_decode_request_id_(0),
278 audio_input_resource_size_(0),
279 video_input_resource_size_(0) {
278 } 280 }
279 281
280 void ContentDecryptorDelegate::set_decrypt_client( 282 void ContentDecryptorDelegate::set_decrypt_client(
281 media::DecryptorClient* decryptor_client) { 283 media::DecryptorClient* decryptor_client) {
282 decryptor_client_ = decryptor_client; 284 decryptor_client_ = decryptor_client;
283 } 285 }
284 286
285 bool ContentDecryptorDelegate::GenerateKeyRequest(const std::string& key_system, 287 bool ContentDecryptorDelegate::GenerateKeyRequest(const std::string& key_system,
286 const std::string& type, 288 const std::string& type,
287 const uint8* init_data, 289 const uint8* init_data,
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 return true; 330 return true;
329 } 331 }
330 332
331 // TODO(xhwang): Remove duplication of code in Decrypt(), 333 // TODO(xhwang): Remove duplication of code in Decrypt(),
332 // DecryptAndDecodeAudio() and DecryptAndDecodeVideo(). 334 // DecryptAndDecodeAudio() and DecryptAndDecodeVideo().
333 bool ContentDecryptorDelegate::Decrypt( 335 bool ContentDecryptorDelegate::Decrypt(
334 media::Decryptor::StreamType stream_type, 336 media::Decryptor::StreamType stream_type,
335 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, 337 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer,
336 const media::Decryptor::DecryptCB& decrypt_cb) { 338 const media::Decryptor::DecryptCB& decrypt_cb) {
337 DVLOG(3) << "Decrypt() - stream_type: " << stream_type; 339 DVLOG(3) << "Decrypt() - stream_type: " << stream_type;
340 // |{audio|video}_input_resource_[size_]| is not being used by the plugin
341 // now because there is only one pending audio/video decrypt request at any
342 // time. This is enforced by the media pipeline.
338 ScopedPPResource encrypted_resource; 343 ScopedPPResource encrypted_resource;
339 if (!MakeBufferResource(pp_instance_, 344 if (!MakeMediaBufferResource(stream_type,
340 encrypted_buffer->GetData(), 345 encrypted_buffer->GetData(),
341 encrypted_buffer->GetDataSize(), 346 encrypted_buffer->GetDataSize(),
342 &encrypted_resource) || 347 &encrypted_resource) ||
343 !encrypted_resource.get()) { 348 !encrypted_resource.get()) {
344 return false; 349 return false;
345 } 350 }
346 351
347 const uint32_t request_id = next_decryption_request_id_++; 352 const uint32_t request_id = next_decryption_request_id_++;
348 DVLOG(2) << "Decrypt() - request_id " << request_id; 353 DVLOG(2) << "Decrypt() - request_id " << request_id;
349 354
350 PP_EncryptedBlockInfo block_info; 355 PP_EncryptedBlockInfo block_info;
351 DCHECK(encrypted_buffer->GetDecryptConfig()); 356 DCHECK(encrypted_buffer->GetDecryptConfig());
352 if (!MakeEncryptedBlockInfo(encrypted_buffer->GetDecryptConfig(), 357 if (!MakeEncryptedBlockInfo(encrypted_buffer->GetDecryptConfig(),
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
492 pp_instance_, MediaDecryptorStreamTypeToPpStreamType(stream_type), 0); 497 pp_instance_, MediaDecryptorStreamTypeToPpStreamType(stream_type), 0);
493 return true; 498 return true;
494 } 499 }
495 500
496 bool ContentDecryptorDelegate::DecryptAndDecodeAudio( 501 bool ContentDecryptorDelegate::DecryptAndDecodeAudio(
497 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, 502 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer,
498 const media::Decryptor::AudioDecodeCB& audio_decode_cb) { 503 const media::Decryptor::AudioDecodeCB& audio_decode_cb) {
499 // If |encrypted_buffer| is end-of-stream buffer, GetData() and GetDataSize() 504 // 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 505 // return NULL and 0 respectively. In that case, we'll just create a 0
501 // resource. 506 // resource.
507 // |audio_input_resource_size_| is not being used by the plugin now
508 // because there is only one pending audio decode request at any time.
509 // This is enforced by the media pipeline.
502 ScopedPPResource encrypted_resource; 510 ScopedPPResource encrypted_resource;
503 if (!MakeBufferResource(pp_instance_, 511 if (!MakeMediaBufferResource(media::Decryptor::kAudio,
504 encrypted_buffer->GetData(), 512 encrypted_buffer->GetData(),
505 encrypted_buffer->GetDataSize(), 513 encrypted_buffer->GetDataSize(),
506 &encrypted_resource)) { 514 &encrypted_resource)) {
507 return false; 515 return false;
508 } 516 }
509 517
510 // The resource should not be 0 for non-EOS buffer. 518 // The resource should not be 0 for non-EOS buffer.
511 if (!encrypted_buffer->IsEndOfStream() && !encrypted_resource.get()) 519 if (!encrypted_buffer->IsEndOfStream() && !encrypted_resource.get())
512 return false; 520 return false;
513 521
514 const uint32_t request_id = next_decryption_request_id_++; 522 const uint32_t request_id = next_decryption_request_id_++;
515 DVLOG(2) << "DecryptAndDecodeAudio() - request_id " << request_id; 523 DVLOG(2) << "DecryptAndDecodeAudio() - request_id " << request_id;
516 524
(...skipping 19 matching lines...) Expand all
536 &block_info); 544 &block_info);
537 return true; 545 return true;
538 } 546 }
539 547
540 bool ContentDecryptorDelegate::DecryptAndDecodeVideo( 548 bool ContentDecryptorDelegate::DecryptAndDecodeVideo(
541 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, 549 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer,
542 const media::Decryptor::VideoDecodeCB& video_decode_cb) { 550 const media::Decryptor::VideoDecodeCB& video_decode_cb) {
543 // If |encrypted_buffer| is end-of-stream buffer, GetData() and GetDataSize() 551 // 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 552 // return NULL and 0 respectively. In that case, we'll just create a 0
545 // resource. 553 // resource.
554 // |video_input_resource_size_| is not being used by the plugin now
555 // because there is only one pending video decode request at any time.
556 // This is enforced by the media pipeline.
546 ScopedPPResource encrypted_resource; 557 ScopedPPResource encrypted_resource;
547 if (!MakeBufferResource(pp_instance_, 558 if (!MakeMediaBufferResource(media::Decryptor::kVideo,
548 encrypted_buffer->GetData(), 559 encrypted_buffer->GetData(),
549 encrypted_buffer->GetDataSize(), 560 encrypted_buffer->GetDataSize(),
550 &encrypted_resource)) { 561 &encrypted_resource)) {
551 return false; 562 return false;
552 } 563 }
553 564
554 // The resource should not be 0 for non-EOS buffer. 565 // The resource should not be 0 for non-EOS buffer.
555 if (!encrypted_buffer->IsEndOfStream() && !encrypted_resource.get()) 566 if (!encrypted_buffer->IsEndOfStream() && !encrypted_resource.get())
556 return false; 567 return false;
557 568
558 const uint32_t request_id = next_decryption_request_id_++; 569 const uint32_t request_id = next_decryption_request_id_++;
559 DVLOG(2) << "DecryptAndDecodeVideo() - request_id " << request_id; 570 DVLOG(2) << "DecryptAndDecodeVideo() - request_id " << request_id;
560 TRACE_EVENT_ASYNC_BEGIN0( 571 TRACE_EVENT_ASYNC_BEGIN0(
561 "eme", "PluginInstance::DecryptAndDecodeVideo", request_id); 572 "eme", "ContentDecryptorDelegate::DecryptAndDecodeVideo", request_id);
562 573
563 PP_EncryptedBlockInfo block_info; 574 PP_EncryptedBlockInfo block_info;
564 if (!MakeEncryptedBlockInfo( 575 if (!MakeEncryptedBlockInfo(
565 encrypted_buffer->GetDecryptConfig(), 576 encrypted_buffer->GetDecryptConfig(),
566 encrypted_buffer->GetTimestamp().InMicroseconds(), 577 encrypted_buffer->GetTimestamp().InMicroseconds(),
567 request_id, 578 request_id,
568 &block_info)) { 579 &block_info)) {
569 return false; 580 return false;
570 } 581 }
571 582
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
765 const uint32_t request_id = frame_info->tracking_info.request_id; 776 const uint32_t request_id = frame_info->tracking_info.request_id;
766 DVLOG(2) << "DeliverFrame() - request_id: " << request_id; 777 DVLOG(2) << "DeliverFrame() - request_id: " << request_id;
767 778
768 // If the request ID is not valid or does not match what's saved, do nothing. 779 // If the request ID is not valid or does not match what's saved, do nothing.
769 if (request_id == 0 || request_id != pending_video_decode_request_id_) { 780 if (request_id == 0 || request_id != pending_video_decode_request_id_) {
770 DVLOG(1) << "DeliverFrame() - request_id " << request_id << " not found"; 781 DVLOG(1) << "DeliverFrame() - request_id " << request_id << " not found";
771 return; 782 return;
772 } 783 }
773 784
774 TRACE_EVENT_ASYNC_END0( 785 TRACE_EVENT_ASYNC_END0(
775 "eme", "PluginInstance::DecryptAndDecodeVideo", request_id); 786 "eme", "ContentDecryptorDelegate::DecryptAndDecodeVideo", request_id);
776 787
777 DCHECK(!pending_video_decode_cb_.is_null()); 788 DCHECK(!pending_video_decode_cb_.is_null());
778 pending_video_decode_request_id_ = 0; 789 pending_video_decode_request_id_ = 0;
779 media::Decryptor::VideoDecodeCB video_decode_cb = 790 media::Decryptor::VideoDecodeCB video_decode_cb =
780 base::ResetAndReturn(&pending_video_decode_cb_); 791 base::ResetAndReturn(&pending_video_decode_cb_);
781 792
782 media::Decryptor::Status status = 793 media::Decryptor::Status status =
783 PpDecryptResultToMediaDecryptorStatus(frame_info->result); 794 PpDecryptResultToMediaDecryptorStatus(frame_info->result);
784 if (status != media::Decryptor::kSuccess) { 795 if (status != media::Decryptor::kSuccess) {
785 video_decode_cb.Run(status, NULL); 796 video_decode_cb.Run(status, NULL);
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
883 pending_video_decode_request_id_ = 0; 894 pending_video_decode_request_id_ = 0;
884 if (!pending_video_decode_cb_.is_null()) 895 if (!pending_video_decode_cb_.is_null())
885 base::ResetAndReturn(&pending_video_decode_cb_).Run( 896 base::ResetAndReturn(&pending_video_decode_cb_).Run(
886 media::Decryptor::kSuccess, NULL); 897 media::Decryptor::kSuccess, NULL);
887 break; 898 break;
888 default: 899 default:
889 NOTREACHED(); 900 NOTREACHED();
890 } 901 }
891 } 902 }
892 903
904 bool ContentDecryptorDelegate::MakeMediaBufferResource(
905 media::Decryptor::StreamType stream_type,
906 const uint8* data, int size,
907 ScopedPPResource* resource) {
908 TRACE_EVENT0("eme", "ContentDecryptorDelegate::MakeMediaBufferResource");
909
910 DCHECK(resource);
911
912 if (!data || !size) {
913 DCHECK(!data && !size);
914 resource->Release();
915 return true;
916 }
917
918 DCHECK(stream_type == media::Decryptor::kAudio ||
919 stream_type == media::Decryptor::kVideo);
920 ScopedPPResource& media_resource = (stream_type == media::Decryptor::kAudio) ?
921 audio_input_resource_ : video_input_resource_;
922 int& media_resource_size = (stream_type == media::Decryptor::kAudio) ?
923 audio_input_resource_size_ : video_input_resource_size_;
924
925 if (media_resource_size < size) {
926 // Media resource size starts from |kMinimumMediaBufferSize| and grows
927 // exponentially to avoid frequent re-allocation of PPB_Buffer_Impl,
928 // which is usually expensive. Since input media buffers are compressed,
929 // they are usually small (compared to outputs). The over-allocated memory
930 // should be negligible.
931
932 if (media_resource_size == 0) {
933 const int kMinimumMediaBufferSize = 1024;
934 media_resource_size = kMinimumMediaBufferSize;
935 }
936
937 while (media_resource_size < size)
938 media_resource_size *= 2;
939
940 DVLOG(2) << "Size of media buffer for "
941 << ((stream_type == media::Decryptor::kAudio) ? "audio" : "video")
942 << " stream bumped to " << media_resource_size
943 << " bytes to fit input.";
944 media_resource = ScopedPPResource(
945 ScopedPPResource::PassRef(),
946 PPB_Buffer_Impl::Create(pp_instance_, media_resource_size));
947 if (!media_resource.get()) {
948 media_resource_size = 0;
949 return false;
950 }
951 }
952
953 EnterResourceNoLock<PPB_Buffer_API> enter(media_resource, true);
954 if (enter.failed()) {
955 media_resource.Release();
956 media_resource_size = 0;
957 return false;
958 }
959
960 BufferAutoMapper mapper(enter.object());
961 if (!mapper.data() || mapper.size() < static_cast<size_t>(size)) {
962 media_resource.Release();
963 media_resource_size = 0;
964 return false;
965 }
966 memcpy(mapper.data(), data, size);
967
968 *resource = media_resource;
969 return true;
970 }
971
893 } // namespace ppapi 972 } // namespace ppapi
894 } // namespace webkit 973 } // namespace webkit
OLDNEW
« no previous file with comments | « webkit/plugins/ppapi/content_decryptor_delegate.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698