Chromium Code Reviews| 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 |