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 "content/renderer/pepper/content_decryptor_delegate.h" | 5 #include "content/renderer/pepper/content_decryptor_delegate.h" |
6 | 6 |
7 #include "base/callback_helpers.h" | 7 #include "base/callback_helpers.h" |
8 #include "base/message_loop/message_loop_proxy.h" | 8 #include "base/message_loop/message_loop_proxy.h" |
9 #include "base/metrics/sparse_histogram.h" | 9 #include "base/metrics/sparse_histogram.h" |
10 #include "base/numerics/safe_conversions.h" | 10 #include "base/numerics/safe_conversions.h" |
| 11 #include "base/stl_util.h" |
11 #include "base/trace_event/trace_event.h" | 12 #include "base/trace_event/trace_event.h" |
12 #include "content/renderer/pepper/ppb_buffer_impl.h" | 13 #include "content/renderer/pepper/ppb_buffer_impl.h" |
13 #include "media/base/audio_buffer.h" | 14 #include "media/base/audio_buffer.h" |
14 #include "media/base/audio_decoder_config.h" | 15 #include "media/base/audio_decoder_config.h" |
15 #include "media/base/bind_to_current_loop.h" | 16 #include "media/base/bind_to_current_loop.h" |
16 #include "media/base/cdm_key_information.h" | 17 #include "media/base/cdm_key_information.h" |
17 #include "media/base/channel_layout.h" | 18 #include "media/base/channel_layout.h" |
18 #include "media/base/data_buffer.h" | 19 #include "media/base/data_buffer.h" |
19 #include "media/base/decoder_buffer.h" | 20 #include "media/base/decoder_buffer.h" |
20 #include "media/base/decrypt_config.h" | 21 #include "media/base/decrypt_config.h" |
(...skipping 25 matching lines...) Expand all Loading... |
46 | 47 |
47 namespace content { | 48 namespace content { |
48 | 49 |
49 namespace { | 50 namespace { |
50 | 51 |
51 // Fills |resource| with a PPB_Buffer_Impl and copies |data| into the buffer | 52 // Fills |resource| with a PPB_Buffer_Impl and copies |data| into the buffer |
52 // resource. The |*resource|, if valid, will be in the ResourceTracker with a | 53 // resource. The |*resource|, if valid, will be in the ResourceTracker with a |
53 // reference-count of 0. If |data| is NULL, sets |*resource| to NULL. Returns | 54 // reference-count of 0. If |data| is NULL, sets |*resource| to NULL. Returns |
54 // true upon success and false if any error happened. | 55 // true upon success and false if any error happened. |
55 bool MakeBufferResource(PP_Instance instance, | 56 bool MakeBufferResource(PP_Instance instance, |
56 const uint8* data, | 57 const uint8_t* data, |
57 uint32_t size, | 58 uint32_t size, |
58 scoped_refptr<PPB_Buffer_Impl>* resource) { | 59 scoped_refptr<PPB_Buffer_Impl>* resource) { |
59 TRACE_EVENT0("media", "ContentDecryptorDelegate - MakeBufferResource"); | 60 TRACE_EVENT0("media", "ContentDecryptorDelegate - MakeBufferResource"); |
60 DCHECK(resource); | 61 DCHECK(resource); |
61 | 62 |
62 if (!data || !size) { | 63 if (!data || !size) { |
63 DCHECK(!data && !size); | 64 DCHECK(!data && !size); |
64 resource = NULL; | 65 resource = NULL; |
65 return true; | 66 return true; |
66 } | 67 } |
67 | 68 |
68 scoped_refptr<PPB_Buffer_Impl> buffer( | 69 scoped_refptr<PPB_Buffer_Impl> buffer( |
69 PPB_Buffer_Impl::CreateResource(instance, size)); | 70 PPB_Buffer_Impl::CreateResource(instance, size)); |
70 if (!buffer.get()) | 71 if (!buffer.get()) |
71 return false; | 72 return false; |
72 | 73 |
73 BufferAutoMapper mapper(buffer.get()); | 74 BufferAutoMapper mapper(buffer.get()); |
74 if (!mapper.data() || mapper.size() < size) | 75 if (!mapper.data() || mapper.size() < size) |
75 return false; | 76 return false; |
76 memcpy(mapper.data(), data, size); | 77 memcpy(mapper.data(), data, size); |
77 | 78 |
78 *resource = buffer; | 79 *resource = buffer; |
79 return true; | 80 return true; |
80 } | 81 } |
81 | 82 |
82 // Copies the content of |str| into |array|. | 83 // Copies the content of |str| into |array|. |
83 // Returns true if copy succeeded. Returns false if copy failed, e.g. if the | 84 // Returns true if copy succeeded. Returns false if copy failed, e.g. if the |
84 // |array_size| is smaller than the |str| length. | 85 // |array_size| is smaller than the |str| length. |
85 template <uint32_t array_size> | 86 template <uint32_t array_size> |
86 bool CopyStringToArray(const std::string& str, uint8 (&array)[array_size]) { | 87 bool CopyStringToArray(const std::string& str, uint8_t(&array)[array_size]) { |
87 if (array_size < str.size()) | 88 if (array_size < str.size()) |
88 return false; | 89 return false; |
89 | 90 |
90 memcpy(array, str.data(), str.size()); | 91 memcpy(array, str.data(), str.size()); |
91 return true; | 92 return true; |
92 } | 93 } |
93 | 94 |
94 // Fills the |block_info| with information from |encrypted_buffer|. | 95 // Fills the |block_info| with information from |encrypted_buffer|. |
95 // | 96 // |
96 // Returns true if |block_info| is successfully filled. Returns false | 97 // Returns true if |block_info| is successfully filled. Returns false |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
338 case PP_CDMMESSAGETYPE_LICENSE_RELEASE: | 339 case PP_CDMMESSAGETYPE_LICENSE_RELEASE: |
339 return MediaKeys::LICENSE_RELEASE; | 340 return MediaKeys::LICENSE_RELEASE; |
340 default: | 341 default: |
341 NOTREACHED(); | 342 NOTREACHED(); |
342 return MediaKeys::LICENSE_REQUEST; | 343 return MediaKeys::LICENSE_REQUEST; |
343 } | 344 } |
344 } | 345 } |
345 | 346 |
346 // TODO(xhwang): Unify EME UMA reporting code when prefixed EME is deprecated. | 347 // TODO(xhwang): Unify EME UMA reporting code when prefixed EME is deprecated. |
347 // See http://crbug.com/412987 for details. | 348 // See http://crbug.com/412987 for details. |
348 void ReportSystemCodeUMA(const std::string& key_system, uint32 system_code) { | 349 void ReportSystemCodeUMA(const std::string& key_system, uint32_t system_code) { |
349 // Sparse histogram macro does not cache the histogram, so it's safe to use | 350 // Sparse histogram macro does not cache the histogram, so it's safe to use |
350 // macro with non-static histogram name here. | 351 // macro with non-static histogram name here. |
351 UMA_HISTOGRAM_SPARSE_SLOWLY( | 352 UMA_HISTOGRAM_SPARSE_SLOWLY( |
352 "Media.EME." + media::GetKeySystemNameForUMA(key_system) + ".SystemCode", | 353 "Media.EME." + media::GetKeySystemNameForUMA(key_system) + ".SystemCode", |
353 system_code); | 354 system_code); |
354 } | 355 } |
355 | 356 |
356 } // namespace | 357 } // namespace |
357 | 358 |
358 ContentDecryptorDelegate::ContentDecryptorDelegate( | 359 ContentDecryptorDelegate::ContentDecryptorDelegate( |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
398 PP_FromBool(allow_distinctive_identifier), | 399 PP_FromBool(allow_distinctive_identifier), |
399 PP_FromBool(allow_persistent_state)); | 400 PP_FromBool(allow_persistent_state)); |
400 } | 401 } |
401 | 402 |
402 void ContentDecryptorDelegate::InstanceCrashed() { | 403 void ContentDecryptorDelegate::InstanceCrashed() { |
403 fatal_plugin_error_cb_.Run(); | 404 fatal_plugin_error_cb_.Run(); |
404 SatisfyAllPendingCallbacksOnError(); | 405 SatisfyAllPendingCallbacksOnError(); |
405 } | 406 } |
406 | 407 |
407 void ContentDecryptorDelegate::SetServerCertificate( | 408 void ContentDecryptorDelegate::SetServerCertificate( |
408 const uint8_t* certificate, | 409 const std::vector<uint8_t>& certificate, |
409 uint32_t certificate_length, | |
410 scoped_ptr<media::SimpleCdmPromise> promise) { | 410 scoped_ptr<media::SimpleCdmPromise> promise) { |
411 if (!certificate || | 411 if (certificate.size() < media::limits::kMinCertificateLength || |
412 certificate_length < media::limits::kMinCertificateLength || | 412 certificate.size() > media::limits::kMaxCertificateLength) { |
413 certificate_length > media::limits::kMaxCertificateLength) { | |
414 promise->reject( | 413 promise->reject( |
415 media::MediaKeys::INVALID_ACCESS_ERROR, 0, "Incorrect certificate."); | 414 media::MediaKeys::INVALID_ACCESS_ERROR, 0, "Incorrect certificate."); |
416 return; | 415 return; |
417 } | 416 } |
418 | 417 |
419 uint32_t promise_id = cdm_promise_adapter_.SavePromise(promise.Pass()); | 418 uint32_t promise_id = cdm_promise_adapter_.SavePromise(promise.Pass()); |
420 PP_Var certificate_array = | 419 PP_Var certificate_array = |
421 PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar( | 420 PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar( |
422 certificate_length, certificate); | 421 base::checked_cast<uint32>(certificate.size()), |
| 422 vector_as_array(&certificate)); |
423 plugin_decryption_interface_->SetServerCertificate( | 423 plugin_decryption_interface_->SetServerCertificate( |
424 pp_instance_, promise_id, certificate_array); | 424 pp_instance_, promise_id, certificate_array); |
425 } | 425 } |
426 | 426 |
427 void ContentDecryptorDelegate::CreateSessionAndGenerateRequest( | 427 void ContentDecryptorDelegate::CreateSessionAndGenerateRequest( |
428 MediaKeys::SessionType session_type, | 428 MediaKeys::SessionType session_type, |
429 media::EmeInitDataType init_data_type, | 429 media::EmeInitDataType init_data_type, |
430 const uint8* init_data, | 430 const std::vector<uint8_t>& init_data, |
431 int init_data_length, | |
432 scoped_ptr<NewSessionCdmPromise> promise) { | 431 scoped_ptr<NewSessionCdmPromise> promise) { |
433 uint32_t promise_id = cdm_promise_adapter_.SavePromise(promise.Pass()); | 432 uint32_t promise_id = cdm_promise_adapter_.SavePromise(promise.Pass()); |
434 PP_Var init_data_array = | 433 PP_Var init_data_array = |
435 PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar( | 434 PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar( |
436 init_data_length, init_data); | 435 base::checked_cast<uint32>(init_data.size()), |
| 436 vector_as_array(&init_data)); |
437 plugin_decryption_interface_->CreateSessionAndGenerateRequest( | 437 plugin_decryption_interface_->CreateSessionAndGenerateRequest( |
438 pp_instance_, promise_id, MediaSessionTypeToPpSessionType(session_type), | 438 pp_instance_, promise_id, MediaSessionTypeToPpSessionType(session_type), |
439 MediaInitDataTypeToPpInitDataType(init_data_type), init_data_array); | 439 MediaInitDataTypeToPpInitDataType(init_data_type), init_data_array); |
440 } | 440 } |
441 | 441 |
442 void ContentDecryptorDelegate::LoadSession( | 442 void ContentDecryptorDelegate::LoadSession( |
443 media::MediaKeys::SessionType session_type, | 443 media::MediaKeys::SessionType session_type, |
444 const std::string& session_id, | 444 const std::string& session_id, |
445 scoped_ptr<NewSessionCdmPromise> promise) { | 445 scoped_ptr<NewSessionCdmPromise> promise) { |
446 uint32_t promise_id = cdm_promise_adapter_.SavePromise(promise.Pass()); | 446 uint32_t promise_id = cdm_promise_adapter_.SavePromise(promise.Pass()); |
447 plugin_decryption_interface_->LoadSession( | 447 plugin_decryption_interface_->LoadSession( |
448 pp_instance_, promise_id, MediaSessionTypeToPpSessionType(session_type), | 448 pp_instance_, promise_id, MediaSessionTypeToPpSessionType(session_type), |
449 StringVar::StringToPPVar(session_id)); | 449 StringVar::StringToPPVar(session_id)); |
450 } | 450 } |
451 | 451 |
452 void ContentDecryptorDelegate::UpdateSession( | 452 void ContentDecryptorDelegate::UpdateSession( |
453 const std::string& session_id, | 453 const std::string& session_id, |
454 const uint8* response, | 454 const std::vector<uint8_t>& response, |
455 int response_length, | |
456 scoped_ptr<SimpleCdmPromise> promise) { | 455 scoped_ptr<SimpleCdmPromise> promise) { |
457 uint32_t promise_id = cdm_promise_adapter_.SavePromise(promise.Pass()); | 456 uint32_t promise_id = cdm_promise_adapter_.SavePromise(promise.Pass()); |
458 PP_Var response_array = | 457 PP_Var response_array = |
459 PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar( | 458 PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar( |
460 response_length, response); | 459 base::checked_cast<uint32>(response.size()), |
| 460 vector_as_array(&response)); |
461 plugin_decryption_interface_->UpdateSession( | 461 plugin_decryption_interface_->UpdateSession( |
462 pp_instance_, promise_id, StringVar::StringToPPVar(session_id), | 462 pp_instance_, promise_id, StringVar::StringToPPVar(session_id), |
463 response_array); | 463 response_array); |
464 } | 464 } |
465 | 465 |
466 void ContentDecryptorDelegate::CloseSession( | 466 void ContentDecryptorDelegate::CloseSession( |
467 const std::string& session_id, | 467 const std::string& session_id, |
468 scoped_ptr<SimpleCdmPromise> promise) { | 468 scoped_ptr<SimpleCdmPromise> promise) { |
469 if (session_id.length() > media::limits::kMaxSessionIdLength) { | 469 if (session_id.length() > media::limits::kMaxSessionIdLength) { |
470 promise->reject( | 470 promise->reject( |
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
727 // buffer. | 727 // buffer. |
728 video_decode_cb_.Set(request_id, video_decode_cb); | 728 video_decode_cb_.Set(request_id, video_decode_cb); |
729 | 729 |
730 // TODO(tomfinegan): Need to get stream type from media stack. | 730 // TODO(tomfinegan): Need to get stream type from media stack. |
731 ScopedPPResource pp_resource(encrypted_resource.get()); | 731 ScopedPPResource pp_resource(encrypted_resource.get()); |
732 plugin_decryption_interface_->DecryptAndDecode( | 732 plugin_decryption_interface_->DecryptAndDecode( |
733 pp_instance_, PP_DECRYPTORSTREAMTYPE_VIDEO, pp_resource, &block_info); | 733 pp_instance_, PP_DECRYPTORSTREAMTYPE_VIDEO, pp_resource, &block_info); |
734 return true; | 734 return true; |
735 } | 735 } |
736 | 736 |
737 void ContentDecryptorDelegate::OnPromiseResolved(uint32 promise_id) { | 737 void ContentDecryptorDelegate::OnPromiseResolved(uint32_t promise_id) { |
738 cdm_promise_adapter_.ResolvePromise(promise_id); | 738 cdm_promise_adapter_.ResolvePromise(promise_id); |
739 } | 739 } |
740 | 740 |
741 void ContentDecryptorDelegate::OnPromiseResolvedWithSession(uint32 promise_id, | 741 void ContentDecryptorDelegate::OnPromiseResolvedWithSession(uint32_t promise_id, |
742 PP_Var session_id) { | 742 PP_Var session_id) { |
743 StringVar* session_id_string = StringVar::FromPPVar(session_id); | 743 StringVar* session_id_string = StringVar::FromPPVar(session_id); |
744 DCHECK(session_id_string); | 744 DCHECK(session_id_string); |
745 cdm_promise_adapter_.ResolvePromise(promise_id, session_id_string->value()); | 745 cdm_promise_adapter_.ResolvePromise(promise_id, session_id_string->value()); |
746 } | 746 } |
747 | 747 |
748 void ContentDecryptorDelegate::OnPromiseRejected( | 748 void ContentDecryptorDelegate::OnPromiseRejected( |
749 uint32 promise_id, | 749 uint32_t promise_id, |
750 PP_CdmExceptionCode exception_code, | 750 PP_CdmExceptionCode exception_code, |
751 uint32 system_code, | 751 uint32_t system_code, |
752 PP_Var error_description) { | 752 PP_Var error_description) { |
753 ReportSystemCodeUMA(key_system_, system_code); | 753 ReportSystemCodeUMA(key_system_, system_code); |
754 | 754 |
755 StringVar* error_description_string = StringVar::FromPPVar(error_description); | 755 StringVar* error_description_string = StringVar::FromPPVar(error_description); |
756 DCHECK(error_description_string); | 756 DCHECK(error_description_string); |
757 cdm_promise_adapter_.RejectPromise( | 757 cdm_promise_adapter_.RejectPromise( |
758 promise_id, PpExceptionTypeToMediaException(exception_code), system_code, | 758 promise_id, PpExceptionTypeToMediaException(exception_code), system_code, |
759 error_description_string->value()); | 759 error_description_string->value()); |
760 } | 760 } |
761 | 761 |
762 void ContentDecryptorDelegate::OnSessionMessage(PP_Var session_id, | 762 void ContentDecryptorDelegate::OnSessionMessage(PP_Var session_id, |
763 PP_CdmMessageType message_type, | 763 PP_CdmMessageType message_type, |
764 PP_Var message, | 764 PP_Var message, |
765 PP_Var legacy_destination_url) { | 765 PP_Var legacy_destination_url) { |
766 if (session_message_cb_.is_null()) | 766 if (session_message_cb_.is_null()) |
767 return; | 767 return; |
768 | 768 |
769 StringVar* session_id_string = StringVar::FromPPVar(session_id); | 769 StringVar* session_id_string = StringVar::FromPPVar(session_id); |
770 DCHECK(session_id_string); | 770 DCHECK(session_id_string); |
771 | 771 |
772 ArrayBufferVar* message_array_buffer = ArrayBufferVar::FromPPVar(message); | 772 ArrayBufferVar* message_array_buffer = ArrayBufferVar::FromPPVar(message); |
773 std::vector<uint8> message_vector; | 773 std::vector<uint8_t> message_vector; |
774 if (message_array_buffer) { | 774 if (message_array_buffer) { |
775 const uint8* data = static_cast<const uint8*>(message_array_buffer->Map()); | 775 const uint8_t* data = |
| 776 static_cast<const uint8_t*>(message_array_buffer->Map()); |
776 message_vector.assign(data, data + message_array_buffer->ByteLength()); | 777 message_vector.assign(data, data + message_array_buffer->ByteLength()); |
777 } | 778 } |
778 | 779 |
779 StringVar* destination_url_string = | 780 StringVar* destination_url_string = |
780 StringVar::FromPPVar(legacy_destination_url); | 781 StringVar::FromPPVar(legacy_destination_url); |
781 if (!destination_url_string) { | 782 if (!destination_url_string) { |
782 NOTREACHED(); | 783 NOTREACHED(); |
783 return; | 784 return; |
784 } | 785 } |
785 | 786 |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
842 | 843 |
843 StringVar* session_id_string = StringVar::FromPPVar(session_id); | 844 StringVar* session_id_string = StringVar::FromPPVar(session_id); |
844 DCHECK(session_id_string); | 845 DCHECK(session_id_string); |
845 | 846 |
846 session_closed_cb_.Run(session_id_string->value()); | 847 session_closed_cb_.Run(session_id_string->value()); |
847 } | 848 } |
848 | 849 |
849 void ContentDecryptorDelegate::OnLegacySessionError( | 850 void ContentDecryptorDelegate::OnLegacySessionError( |
850 PP_Var session_id, | 851 PP_Var session_id, |
851 PP_CdmExceptionCode exception_code, | 852 PP_CdmExceptionCode exception_code, |
852 uint32 system_code, | 853 uint32_t system_code, |
853 PP_Var error_description) { | 854 PP_Var error_description) { |
854 ReportSystemCodeUMA(key_system_, system_code); | 855 ReportSystemCodeUMA(key_system_, system_code); |
855 | 856 |
856 if (legacy_session_error_cb_.is_null()) | 857 if (legacy_session_error_cb_.is_null()) |
857 return; | 858 return; |
858 | 859 |
859 StringVar* session_id_string = StringVar::FromPPVar(session_id); | 860 StringVar* session_id_string = StringVar::FromPPVar(session_id); |
860 DCHECK(session_id_string); | 861 DCHECK(session_id_string); |
861 | 862 |
862 StringVar* error_description_string = StringVar::FromPPVar(error_description); | 863 StringVar* error_description_string = StringVar::FromPPVar(error_description); |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
942 BufferAutoMapper mapper(enter.object()); | 943 BufferAutoMapper mapper(enter.object()); |
943 if (!mapper.data() || !mapper.size() || | 944 if (!mapper.data() || !mapper.size() || |
944 mapper.size() < block_info->data_size) { | 945 mapper.size() < block_info->data_size) { |
945 decrypt_cb.Run(Decryptor::kError, NULL); | 946 decrypt_cb.Run(Decryptor::kError, NULL); |
946 return; | 947 return; |
947 } | 948 } |
948 | 949 |
949 // TODO(tomfinegan): Find a way to take ownership of the shared memory | 950 // TODO(tomfinegan): Find a way to take ownership of the shared memory |
950 // managed by the PPB_Buffer_Dev, and avoid the extra copy. | 951 // managed by the PPB_Buffer_Dev, and avoid the extra copy. |
951 scoped_refptr<media::DecoderBuffer> decrypted_buffer( | 952 scoped_refptr<media::DecoderBuffer> decrypted_buffer( |
952 media::DecoderBuffer::CopyFrom(static_cast<uint8*>(mapper.data()), | 953 media::DecoderBuffer::CopyFrom(static_cast<uint8_t*>(mapper.data()), |
953 block_info->data_size)); | 954 block_info->data_size)); |
954 decrypted_buffer->set_timestamp( | 955 decrypted_buffer->set_timestamp( |
955 base::TimeDelta::FromMicroseconds(block_info->tracking_info.timestamp)); | 956 base::TimeDelta::FromMicroseconds(block_info->tracking_info.timestamp)); |
956 decrypt_cb.Run(Decryptor::kSuccess, decrypted_buffer); | 957 decrypt_cb.Run(Decryptor::kSuccess, decrypted_buffer); |
957 } | 958 } |
958 | 959 |
959 // Use a non-class-member function here so that if for some reason | 960 // Use a non-class-member function here so that if for some reason |
960 // ContentDecryptorDelegate is destroyed before VideoFrame calls this callback, | 961 // ContentDecryptorDelegate is destroyed before VideoFrame calls this callback, |
961 // we can still get the shared memory unmapped. | 962 // we can still get the shared memory unmapped. |
962 static void BufferNoLongerNeeded( | 963 static void BufferNoLongerNeeded( |
963 const scoped_refptr<PPB_Buffer_Impl>& ppb_buffer, | 964 const scoped_refptr<PPB_Buffer_Impl>& ppb_buffer, |
964 base::Closure buffer_no_longer_needed_cb) { | 965 base::Closure buffer_no_longer_needed_cb) { |
965 ppb_buffer->Unmap(); | 966 ppb_buffer->Unmap(); |
966 buffer_no_longer_needed_cb.Run(); | 967 buffer_no_longer_needed_cb.Run(); |
967 } | 968 } |
968 | 969 |
969 // Enters |resource|, maps shared memory and returns pointer of mapped data. | 970 // Enters |resource|, maps shared memory and returns pointer of mapped data. |
970 // Returns NULL if any error occurs. | 971 // Returns NULL if any error occurs. |
971 static uint8* GetMappedBuffer(PP_Resource resource, | 972 static uint8_t* GetMappedBuffer(PP_Resource resource, |
972 scoped_refptr<PPB_Buffer_Impl>* ppb_buffer) { | 973 scoped_refptr<PPB_Buffer_Impl>* ppb_buffer) { |
973 EnterResourceNoLock<PPB_Buffer_API> enter(resource, true); | 974 EnterResourceNoLock<PPB_Buffer_API> enter(resource, true); |
974 if (!enter.succeeded()) | 975 if (!enter.succeeded()) |
975 return NULL; | 976 return NULL; |
976 | 977 |
977 uint8* mapped_data = static_cast<uint8*>(enter.object()->Map()); | 978 uint8_t* mapped_data = static_cast<uint8_t*>(enter.object()->Map()); |
978 if (!enter.object()->IsMapped() || !mapped_data) | 979 if (!enter.object()->IsMapped() || !mapped_data) |
979 return NULL; | 980 return NULL; |
980 | 981 |
981 uint32_t mapped_size = 0; | 982 uint32_t mapped_size = 0; |
982 if (!enter.object()->Describe(&mapped_size) || !mapped_size) { | 983 if (!enter.object()->Describe(&mapped_size) || !mapped_size) { |
983 enter.object()->Unmap(); | 984 enter.object()->Unmap(); |
984 return NULL; | 985 return NULL; |
985 } | 986 } |
986 | 987 |
987 *ppb_buffer = static_cast<PPB_Buffer_Impl*>(enter.object()); | 988 *ppb_buffer = static_cast<PPB_Buffer_Impl*>(enter.object()); |
(...skipping 23 matching lines...) Expand all Loading... |
1011 | 1012 |
1012 Decryptor::Status status = | 1013 Decryptor::Status status = |
1013 PpDecryptResultToMediaDecryptorStatus(frame_info->result); | 1014 PpDecryptResultToMediaDecryptorStatus(frame_info->result); |
1014 if (status != Decryptor::kSuccess) { | 1015 if (status != Decryptor::kSuccess) { |
1015 DCHECK(!frame_info->tracking_info.buffer_id); | 1016 DCHECK(!frame_info->tracking_info.buffer_id); |
1016 video_decode_cb.Run(status, NULL); | 1017 video_decode_cb.Run(status, NULL); |
1017 return; | 1018 return; |
1018 } | 1019 } |
1019 | 1020 |
1020 scoped_refptr<PPB_Buffer_Impl> ppb_buffer; | 1021 scoped_refptr<PPB_Buffer_Impl> ppb_buffer; |
1021 uint8* frame_data = GetMappedBuffer(decrypted_frame, &ppb_buffer); | 1022 uint8_t* frame_data = GetMappedBuffer(decrypted_frame, &ppb_buffer); |
1022 if (!frame_data) { | 1023 if (!frame_data) { |
1023 FreeBuffer(frame_info->tracking_info.buffer_id); | 1024 FreeBuffer(frame_info->tracking_info.buffer_id); |
1024 video_decode_cb.Run(Decryptor::kError, NULL); | 1025 video_decode_cb.Run(Decryptor::kError, NULL); |
1025 return; | 1026 return; |
1026 } | 1027 } |
1027 | 1028 |
1028 gfx::Size frame_size(frame_info->width, frame_info->height); | 1029 gfx::Size frame_size(frame_info->width, frame_info->height); |
1029 DCHECK_EQ(frame_info->format, PP_DECRYPTEDFRAMEFORMAT_YV12); | 1030 DCHECK_EQ(frame_info->format, PP_DECRYPTEDFRAMEFORMAT_YV12); |
1030 | 1031 |
1031 scoped_refptr<media::VideoFrame> decoded_frame = | 1032 scoped_refptr<media::VideoFrame> decoded_frame = |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1201 return false; | 1202 return false; |
1202 | 1203 |
1203 BufferAutoMapper mapper(enter.object()); | 1204 BufferAutoMapper mapper(enter.object()); |
1204 if (!mapper.data() || !mapper.size() || | 1205 if (!mapper.data() || !mapper.size() || |
1205 mapper.size() < static_cast<uint32_t>(data_size)) | 1206 mapper.size() < static_cast<uint32_t>(data_size)) |
1206 return false; | 1207 return false; |
1207 | 1208 |
1208 // TODO(jrummell): Pass ownership of data() directly to AudioBuffer to avoid | 1209 // TODO(jrummell): Pass ownership of data() directly to AudioBuffer to avoid |
1209 // the copy. Since it is possible to get multiple buffers, it would need to be | 1210 // the copy. Since it is possible to get multiple buffers, it would need to be |
1210 // sliced and ref counted appropriately. http://crbug.com/255576. | 1211 // sliced and ref counted appropriately. http://crbug.com/255576. |
1211 const uint8* cur = static_cast<uint8*>(mapper.data()); | 1212 const uint8_t* cur = static_cast<uint8_t*>(mapper.data()); |
1212 size_t bytes_left = data_size; | 1213 size_t bytes_left = data_size; |
1213 | 1214 |
1214 const int audio_bytes_per_frame = | 1215 const int audio_bytes_per_frame = |
1215 media::SampleFormatToBytesPerChannel(sample_format) * | 1216 media::SampleFormatToBytesPerChannel(sample_format) * |
1216 audio_channel_count_; | 1217 audio_channel_count_; |
1217 if (audio_bytes_per_frame <= 0) | 1218 if (audio_bytes_per_frame <= 0) |
1218 return false; | 1219 return false; |
1219 | 1220 |
1220 // Allocate space for the channel pointers given to AudioBuffer. | 1221 // Allocate space for the channel pointers given to AudioBuffer. |
1221 std::vector<const uint8*> channel_ptrs(audio_channel_count_, | 1222 std::vector<const uint8_t*> channel_ptrs(audio_channel_count_, nullptr); |
1222 static_cast<const uint8*>(NULL)); | |
1223 do { | 1223 do { |
1224 int64 timestamp = 0; | 1224 int64 timestamp = 0; |
1225 int64 frame_size = -1; | 1225 int64 frame_size = -1; |
1226 const size_t kHeaderSize = sizeof(timestamp) + sizeof(frame_size); | 1226 const size_t kHeaderSize = sizeof(timestamp) + sizeof(frame_size); |
1227 | 1227 |
1228 if (bytes_left < kHeaderSize) | 1228 if (bytes_left < kHeaderSize) |
1229 return false; | 1229 return false; |
1230 | 1230 |
1231 memcpy(×tamp, cur, sizeof(timestamp)); | 1231 memcpy(×tamp, cur, sizeof(timestamp)); |
1232 cur += sizeof(timestamp); | 1232 cur += sizeof(timestamp); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1288 empty_frames); | 1288 empty_frames); |
1289 } | 1289 } |
1290 | 1290 |
1291 if (!video_decode_cb_.is_null()) | 1291 if (!video_decode_cb_.is_null()) |
1292 video_decode_cb_.ResetAndReturn().Run(media::Decryptor::kError, NULL); | 1292 video_decode_cb_.ResetAndReturn().Run(media::Decryptor::kError, NULL); |
1293 | 1293 |
1294 cdm_promise_adapter_.Clear(); | 1294 cdm_promise_adapter_.Clear(); |
1295 } | 1295 } |
1296 | 1296 |
1297 } // namespace content | 1297 } // namespace content |
OLD | NEW |