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

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

Issue 11929015: Tighten up media::DecoderBuffer API contract for end of stream buffers (round 2). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 10 months 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
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 "base/message_loop_proxy.h" 9 #include "base/message_loop_proxy.h"
10 #include "media/base/audio_decoder_config.h" 10 #include "media/base/audio_decoder_config.h"
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
72 template <uint32_t array_size> 72 template <uint32_t array_size>
73 bool CopyStringToArray(const std::string& str, uint8 (&array)[array_size]) { 73 bool CopyStringToArray(const std::string& str, uint8 (&array)[array_size]) {
74 if (array_size < str.size()) 74 if (array_size < str.size())
75 return false; 75 return false;
76 76
77 memcpy(array, str.data(), str.size()); 77 memcpy(array, str.data(), str.size());
78 return true; 78 return true;
79 } 79 }
80 80
81 // Fills the |block_info| with information from |decrypt_config|, |timestamp| 81 // Fills the |block_info| with information from |decrypt_config|, |timestamp|
82 // and |request_id|. |decrypt_config| can be NULL if the block is not encrypted. 82 // and |request_id|.
83 // This is useful for end-of-stream blocks. 83 //
84 // Returns true if |block_info| is successfully filled. Returns false 84 // Returns true if |block_info| is successfully filled. Returns false
85 // otherwise. 85 // otherwise.
86 bool MakeEncryptedBlockInfo(int data_size, 86 static bool MakeEncryptedBlockInfo(
87 const media::DecryptConfig* decrypt_config, 87 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer,
88 int64_t timestamp, 88 uint32_t request_id,
89 uint32_t request_id, 89 PP_EncryptedBlockInfo* block_info) {
90 PP_EncryptedBlockInfo* block_info) {
91 DCHECK(block_info);
92
93 // TODO(xhwang): Fix initialization of PP_EncryptedBlockInfo here and 90 // TODO(xhwang): Fix initialization of PP_EncryptedBlockInfo here and
94 // anywhere else. 91 // anywhere else.
95 memset(block_info, 0, sizeof(*block_info)); 92 memset(block_info, 0, sizeof(*block_info));
93 block_info->tracking_info.request_id = request_id;
96 94
97 block_info->tracking_info.request_id = request_id; 95 // EOS buffers need a request ID and nothing more.
98 block_info->tracking_info.timestamp = timestamp; 96 if (encrypted_buffer->IsEndOfStream())
99
100 if (!decrypt_config)
101 return true; 97 return true;
102 98
103 DCHECK(data_size) << "DecryptConfig is set on an empty buffer"; 99 block_info->tracking_info.timestamp =
104 block_info->data_size = data_size; 100 encrypted_buffer->GetTimestamp().InMicroseconds();
101 block_info->data_size = encrypted_buffer->GetDataSize();
102
103 const media::DecryptConfig* decrypt_config =
104 encrypted_buffer->GetDecryptConfig();
105 block_info->data_offset = decrypt_config->data_offset(); 105 block_info->data_offset = decrypt_config->data_offset();
106 106
107 if (!CopyStringToArray(decrypt_config->key_id(), block_info->key_id) || 107 if (!CopyStringToArray(decrypt_config->key_id(), block_info->key_id) ||
108 !CopyStringToArray(decrypt_config->iv(), block_info->iv)) 108 !CopyStringToArray(decrypt_config->iv(), block_info->iv))
109 return false; 109 return false;
110 110
111 block_info->key_id_size = decrypt_config->key_id().size(); 111 block_info->key_id_size = decrypt_config->key_id().size();
112 block_info->iv_size = decrypt_config->iv().size(); 112 block_info->iv_size = decrypt_config->iv().size();
113 113
114 if (decrypt_config->subsamples().size() > arraysize(block_info->subsamples)) 114 if (decrypt_config->subsamples().size() > arraysize(block_info->subsamples))
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
358 !encrypted_resource) { 358 !encrypted_resource) {
359 return false; 359 return false;
360 } 360 }
361 ScopedPPResource pp_resource(encrypted_resource.get()); 361 ScopedPPResource pp_resource(encrypted_resource.get());
362 362
363 const uint32_t request_id = next_decryption_request_id_++; 363 const uint32_t request_id = next_decryption_request_id_++;
364 DVLOG(2) << "Decrypt() - request_id " << request_id; 364 DVLOG(2) << "Decrypt() - request_id " << request_id;
365 365
366 PP_EncryptedBlockInfo block_info = {}; 366 PP_EncryptedBlockInfo block_info = {};
367 DCHECK(encrypted_buffer->GetDecryptConfig()); 367 DCHECK(encrypted_buffer->GetDecryptConfig());
368 if (!MakeEncryptedBlockInfo(encrypted_buffer->GetDataSize(), 368 if (!MakeEncryptedBlockInfo(encrypted_buffer, request_id, &block_info)) {
369 encrypted_buffer->GetDecryptConfig(),
370 encrypted_buffer->GetTimestamp().InMicroseconds(),
371 request_id,
372 &block_info)) {
373 return false; 369 return false;
374 } 370 }
375 371
376 // There is only one pending decrypt request at any time per stream. This is 372 // There is only one pending decrypt request at any time per stream. This is
377 // enforced by the media pipeline. 373 // enforced by the media pipeline.
378 switch (stream_type) { 374 switch (stream_type) {
379 case media::Decryptor::kAudio: 375 case media::Decryptor::kAudio:
380 DCHECK_EQ(pending_audio_decrypt_request_id_, 0u); 376 DCHECK_EQ(pending_audio_decrypt_request_id_, 0u);
381 DCHECK(pending_audio_decrypt_cb_.is_null()); 377 DCHECK(pending_audio_decrypt_cb_.is_null());
382 pending_audio_decrypt_request_id_ = request_id; 378 pending_audio_decrypt_request_id_ = request_id;
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
528 bool ContentDecryptorDelegate::DecryptAndDecodeAudio( 524 bool ContentDecryptorDelegate::DecryptAndDecodeAudio(
529 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, 525 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer,
530 const media::Decryptor::AudioDecodeCB& audio_decode_cb) { 526 const media::Decryptor::AudioDecodeCB& audio_decode_cb) {
531 // If |encrypted_buffer| is end-of-stream buffer, GetData() and GetDataSize() 527 // If |encrypted_buffer| is end-of-stream buffer, GetData() and GetDataSize()
532 // return NULL and 0 respectively. In that case, we'll just create a NULL 528 // return NULL and 0 respectively. In that case, we'll just create a NULL
533 // resource. 529 // resource.
534 // |audio_input_resource_| is not being used by the plugin now 530 // |audio_input_resource_| is not being used by the plugin now
535 // because there is only one pending audio decode request at any time. 531 // because there is only one pending audio decode request at any time.
536 // This is enforced by the media pipeline. 532 // This is enforced by the media pipeline.
537 scoped_refptr<PPB_Buffer_Impl> encrypted_resource; 533 scoped_refptr<PPB_Buffer_Impl> encrypted_resource;
538 if (!MakeMediaBufferResource(media::Decryptor::kAudio, 534 if (!encrypted_buffer->IsEndOfStream() &&
535 !MakeMediaBufferResource(media::Decryptor::kAudio,
539 encrypted_buffer->GetData(), 536 encrypted_buffer->GetData(),
540 encrypted_buffer->GetDataSize(), 537 encrypted_buffer->GetDataSize(),
541 &encrypted_resource)) { 538 &encrypted_resource)) {
542 return false; 539 return false;
543 } 540 }
544 ScopedPPResource pp_resource(encrypted_resource.get());
545 541
546 // The resource should not be NULL for non-EOS buffer. 542 // The resource should not be NULL for non-EOS buffer.
547 if (!encrypted_buffer->IsEndOfStream() && !encrypted_resource) 543 if (!encrypted_buffer->IsEndOfStream() && !encrypted_resource)
548 return false; 544 return false;
549 545
550 const uint32_t request_id = next_decryption_request_id_++; 546 const uint32_t request_id = next_decryption_request_id_++;
551 DVLOG(2) << "DecryptAndDecodeAudio() - request_id " << request_id; 547 DVLOG(2) << "DecryptAndDecodeAudio() - request_id " << request_id;
552 548
553 PP_EncryptedBlockInfo block_info = {}; 549 PP_EncryptedBlockInfo block_info = {};
554 if (!MakeEncryptedBlockInfo( 550 if (!MakeEncryptedBlockInfo(encrypted_buffer, request_id, &block_info)) {
555 encrypted_buffer->GetDataSize(),
556 encrypted_buffer->GetDecryptConfig(),
557 encrypted_buffer->GetTimestamp().InMicroseconds(),
558 request_id,
559 &block_info)) {
560 return false; 551 return false;
561 } 552 }
562 553
563 SetBufferToFreeInTrackingInfo(&block_info.tracking_info); 554 SetBufferToFreeInTrackingInfo(&block_info.tracking_info);
564 555
565 // There is only one pending audio decode request at any time. This is 556 // There is only one pending audio decode request at any time. This is
566 // enforced by the media pipeline. If this DCHECK is violated, our buffer 557 // enforced by the media pipeline. If this DCHECK is violated, our buffer
567 // reuse policy is not valid, and we may have race problems for the shared 558 // reuse policy is not valid, and we may have race problems for the shared
568 // buffer. 559 // buffer.
569 DCHECK_EQ(pending_audio_decode_request_id_, 0u); 560 DCHECK_EQ(pending_audio_decode_request_id_, 0u);
570 DCHECK(pending_audio_decode_cb_.is_null()); 561 DCHECK(pending_audio_decode_cb_.is_null());
571 pending_audio_decode_request_id_ = request_id; 562 pending_audio_decode_request_id_ = request_id;
572 pending_audio_decode_cb_ = audio_decode_cb; 563 pending_audio_decode_cb_ = audio_decode_cb;
573 564
565 ScopedPPResource pp_resource(encrypted_resource.get());
574 plugin_decryption_interface_->DecryptAndDecode(pp_instance_, 566 plugin_decryption_interface_->DecryptAndDecode(pp_instance_,
575 PP_DECRYPTORSTREAMTYPE_AUDIO, 567 PP_DECRYPTORSTREAMTYPE_AUDIO,
576 pp_resource, 568 pp_resource,
577 &block_info); 569 &block_info);
578 return true; 570 return true;
579 } 571 }
580 572
581 bool ContentDecryptorDelegate::DecryptAndDecodeVideo( 573 bool ContentDecryptorDelegate::DecryptAndDecodeVideo(
582 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, 574 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer,
583 const media::Decryptor::VideoDecodeCB& video_decode_cb) { 575 const media::Decryptor::VideoDecodeCB& video_decode_cb) {
584 // If |encrypted_buffer| is end-of-stream buffer, GetData() and GetDataSize()
585 // return NULL and 0 respectively. In that case, we'll just get a NULL
586 // resource.
587 // |video_input_resource_| is not being used by the plugin now 576 // |video_input_resource_| is not being used by the plugin now
588 // because there is only one pending video decode request at any time. 577 // because there is only one pending video decode request at any time.
589 // This is enforced by the media pipeline. 578 // This is enforced by the media pipeline.
590 scoped_refptr<PPB_Buffer_Impl> encrypted_resource; 579 scoped_refptr<PPB_Buffer_Impl> encrypted_resource;
591 if (!MakeMediaBufferResource(media::Decryptor::kVideo, 580 if (!encrypted_buffer->IsEndOfStream() &&
581 !MakeMediaBufferResource(media::Decryptor::kVideo,
592 encrypted_buffer->GetData(), 582 encrypted_buffer->GetData(),
593 encrypted_buffer->GetDataSize(), 583 encrypted_buffer->GetDataSize(),
594 &encrypted_resource)) { 584 &encrypted_resource)) {
595 return false; 585 return false;
596 } 586 }
597 ScopedPPResource pp_resource(encrypted_resource.get());
598 587
599 // The resource should not be 0 for non-EOS buffer. 588 // The resource should not be 0 for non-EOS buffer.
600 if (!encrypted_buffer->IsEndOfStream() && !encrypted_resource) 589 if (!encrypted_buffer->IsEndOfStream() && !encrypted_resource)
601 return false; 590 return false;
602 591
603 const uint32_t request_id = next_decryption_request_id_++; 592 const uint32_t request_id = next_decryption_request_id_++;
604 DVLOG(2) << "DecryptAndDecodeVideo() - request_id " << request_id; 593 DVLOG(2) << "DecryptAndDecodeVideo() - request_id " << request_id;
605 TRACE_EVENT_ASYNC_BEGIN0( 594 TRACE_EVENT_ASYNC_BEGIN0(
606 "eme", "ContentDecryptorDelegate::DecryptAndDecodeVideo", request_id); 595 "eme", "ContentDecryptorDelegate::DecryptAndDecodeVideo", request_id);
607 596
608 PP_EncryptedBlockInfo block_info = {}; 597 PP_EncryptedBlockInfo block_info = {};
609 if (!MakeEncryptedBlockInfo( 598 if (!MakeEncryptedBlockInfo(encrypted_buffer, request_id, &block_info)) {
610 encrypted_buffer->GetDataSize(),
611 encrypted_buffer->GetDecryptConfig(),
612 encrypted_buffer->GetTimestamp().InMicroseconds(),
613 request_id,
614 &block_info)) {
615 return false; 599 return false;
616 } 600 }
617 601
618 SetBufferToFreeInTrackingInfo(&block_info.tracking_info); 602 SetBufferToFreeInTrackingInfo(&block_info.tracking_info);
619 603
620 // Only one pending video decode request at any time. This is enforced by the 604 // Only one pending video decode request at any time. This is enforced by the
621 // media pipeline. If this DCHECK is violated, our buffer 605 // media pipeline. If this DCHECK is violated, our buffer
622 // reuse policy is not valid, and we may have race problems for the shared 606 // reuse policy is not valid, and we may have race problems for the shared
623 // buffer. 607 // buffer.
624 DCHECK_EQ(pending_video_decode_request_id_, 0u); 608 DCHECK_EQ(pending_video_decode_request_id_, 0u);
625 DCHECK(pending_video_decode_cb_.is_null()); 609 DCHECK(pending_video_decode_cb_.is_null());
626 pending_video_decode_request_id_ = request_id; 610 pending_video_decode_request_id_ = request_id;
627 pending_video_decode_cb_ = video_decode_cb; 611 pending_video_decode_cb_ = video_decode_cb;
628 612
629 // TODO(tomfinegan): Need to get stream type from media stack. 613 // TODO(tomfinegan): Need to get stream type from media stack.
614 ScopedPPResource pp_resource(encrypted_resource.get());
630 plugin_decryption_interface_->DecryptAndDecode(pp_instance_, 615 plugin_decryption_interface_->DecryptAndDecode(pp_instance_,
631 PP_DECRYPTORSTREAMTYPE_VIDEO, 616 PP_DECRYPTORSTREAMTYPE_VIDEO,
632 pp_resource, 617 pp_resource,
633 &block_info); 618 &block_info);
634 return true; 619 return true;
635 } 620 }
636 621
637 void ContentDecryptorDelegate::NeedKey(PP_Var key_system_var, 622 void ContentDecryptorDelegate::NeedKey(PP_Var key_system_var,
638 PP_Var session_id_var, 623 PP_Var session_id_var,
639 PP_Var init_data_var) { 624 PP_Var init_data_var) {
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after
977 } 962 }
978 } 963 }
979 964
980 bool ContentDecryptorDelegate::MakeMediaBufferResource( 965 bool ContentDecryptorDelegate::MakeMediaBufferResource(
981 media::Decryptor::StreamType stream_type, 966 media::Decryptor::StreamType stream_type,
982 const uint8* data, uint32_t size, 967 const uint8* data, uint32_t size,
983 scoped_refptr<PPB_Buffer_Impl>* resource) { 968 scoped_refptr<PPB_Buffer_Impl>* resource) {
984 TRACE_EVENT0("eme", "ContentDecryptorDelegate::MakeMediaBufferResource"); 969 TRACE_EVENT0("eme", "ContentDecryptorDelegate::MakeMediaBufferResource");
985 970
986 DCHECK(resource); 971 DCHECK(resource);
987
988 if (!data || !size) {
989 DCHECK(!data && !size);
990 resource = NULL;
991 return true;
992 }
993
994 DCHECK(stream_type == media::Decryptor::kAudio || 972 DCHECK(stream_type == media::Decryptor::kAudio ||
995 stream_type == media::Decryptor::kVideo); 973 stream_type == media::Decryptor::kVideo);
996 scoped_refptr<PPB_Buffer_Impl>& media_resource = 974 scoped_refptr<PPB_Buffer_Impl>& media_resource =
997 (stream_type == media::Decryptor::kAudio) ? audio_input_resource_ : 975 (stream_type == media::Decryptor::kAudio) ? audio_input_resource_ :
998 video_input_resource_; 976 video_input_resource_;
999 if (!media_resource || (media_resource->size() < size)) { 977 if (!media_resource || (media_resource->size() < size)) {
1000 // Either the buffer hasn't been created yet, or we have one that isn't big 978 // Either the buffer hasn't been created yet, or we have one that isn't big
1001 // enough to fit |size| bytes. 979 // enough to fit |size| bytes.
1002 980
1003 // Media resource size starts from |kMinimumMediaBufferSize| and grows 981 // Media resource size starts from |kMinimumMediaBufferSize| and grows
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1043 1021
1044 if (free_buffers_.empty()) 1022 if (free_buffers_.empty())
1045 return; 1023 return;
1046 1024
1047 tracking_info->buffer_id = free_buffers_.front(); 1025 tracking_info->buffer_id = free_buffers_.front();
1048 free_buffers_.pop(); 1026 free_buffers_.pop();
1049 } 1027 }
1050 1028
1051 } // namespace ppapi 1029 } // namespace ppapi
1052 } // namespace webkit 1030 } // namespace webkit
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698