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 3 // found in the LICENSE file. 4 5 #include "content/renderer/pepper/content_decryptor_delegate.h" 6 7 #include "base/callback_helpers.h" 8 #include "base/debug/trace_event.h" 9 #include "base/message_loop/message_loop_proxy.h" 10 #include "base/safe_numerics.h" 11 #include "content/renderer/pepper/ppb_buffer_impl.h" 12 #include "media/base/audio_buffer.h" 13 #include "media/base/audio_decoder_config.h" 14 #include "media/base/bind_to_loop.h" 15 #include "media/base/channel_layout.h" 16 #include "media/base/data_buffer.h" 17 #include "media/base/decoder_buffer.h" 18 #include "media/base/decrypt_config.h" 19 #include "media/base/video_decoder_config.h" 20 #include "media/base/video_frame.h" 21 #include "media/base/video_util.h" 22 #include "ppapi/shared_impl/scoped_pp_resource.h" 23 #include "ppapi/shared_impl/var.h" 24 #include "ppapi/shared_impl/var_tracker.h" 25 #include "ppapi/thunk/enter.h" 26 #include "ppapi/thunk/ppb_buffer_api.h" 27 #include "ui/gfx/rect.h" 28 29 using ppapi::ArrayBufferVar; 30 using ppapi::PpapiGlobals; 31 using ppapi::ScopedPPResource; 32 using ppapi::StringVar; 33 using ppapi::thunk::EnterResourceNoLock; 34 using ppapi::thunk::PPB_Buffer_API; 35 36 namespace content { 37 38 namespace { 39 40 // Fills |resource| with a PPB_Buffer_Impl and copies |data| into the buffer 41 // resource. The |*resource|, if valid, will be in the ResourceTracker with a 42 // reference-count of 0. If |data| is NULL, sets |*resource| to NULL. Returns 43 // true upon success and false if any error happened. 44 bool MakeBufferResource(PP_Instance instance, 45 const uint8* data, uint32_t size, 46 scoped_refptr<PPB_Buffer_Impl>* resource) { 47 TRACE_EVENT0("media", "ContentDecryptorDelegate - MakeBufferResource"); 48 DCHECK(resource); 49 50 if (!data || !size) { 51 DCHECK(!data && !size); 52 resource = NULL; 53 return true; 54 } 55 56 scoped_refptr<PPB_Buffer_Impl> buffer( 57 PPB_Buffer_Impl::CreateResource(instance, size)); 58 if (!buffer.get()) 59 return false; 60 61 BufferAutoMapper mapper(buffer.get()); 62 if (!mapper.data() || mapper.size() < size) 63 return false; 64 memcpy(mapper.data(), data, size); 65 66 *resource = buffer; 67 return true; 68 } 69 70 // Copies the content of |str| into |array|. 71 // Returns true if copy succeeded. Returns false if copy failed, e.g. if the 72 // |array_size| is smaller than the |str| length. 73 template <uint32_t array_size> 74 bool CopyStringToArray(const std::string& str, uint8 (&array)[array_size]) { 75 if (array_size < str.size()) 76 return false; 77 78 memcpy(array, str.data(), str.size()); 79 return true; 80 } 81 82 // Fills the |block_info| with information from |encrypted_buffer|. 83 // 84 // Returns true if |block_info| is successfully filled. Returns false 85 // otherwise. 86 static bool MakeEncryptedBlockInfo( 87 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, 88 uint32_t request_id, 89 PP_EncryptedBlockInfo* block_info) { 90 // TODO(xhwang): Fix initialization of PP_EncryptedBlockInfo here and 91 // anywhere else. 92 memset(block_info, 0, sizeof(*block_info)); 93 block_info->tracking_info.request_id = request_id; 94 95 // EOS buffers need a request ID and nothing more. 96 if (encrypted_buffer->end_of_stream()) 97 return true; 98 99 DCHECK(encrypted_buffer->data_size()) 100 << "DecryptConfig is set on an empty buffer"; 101 102 block_info->tracking_info.timestamp = 103 encrypted_buffer->timestamp().InMicroseconds(); 104 block_info->data_size = encrypted_buffer->data_size(); 105 106 const media::DecryptConfig* decrypt_config = 107 encrypted_buffer->decrypt_config(); 108 block_info->data_offset = decrypt_config->data_offset(); 109 110 if (!CopyStringToArray(decrypt_config->key_id(), block_info->key_id) || 111 !CopyStringToArray(decrypt_config->iv(), block_info->iv)) 112 return false; 113 114 block_info->key_id_size = decrypt_config->key_id().size(); 115 block_info->iv_size = decrypt_config->iv().size(); 116 117 if (decrypt_config->subsamples().size() > arraysize(block_info->subsamples)) 118 return false; 119 120 block_info->num_subsamples = decrypt_config->subsamples().size(); 121 for (uint32_t i = 0; i < block_info->num_subsamples; ++i) { 122 block_info->subsamples[i].clear_bytes = 123 decrypt_config->subsamples()[i].clear_bytes; 124 block_info->subsamples[i].cipher_bytes = 125 decrypt_config->subsamples()[i].cypher_bytes; 126 } 127 128 return true; 129 } 130 131 PP_AudioCodec MediaAudioCodecToPpAudioCodec(media::AudioCodec codec) { 132 switch (codec) { 133 case media::kCodecVorbis: 134 return PP_AUDIOCODEC_VORBIS; 135 case media::kCodecAAC: 136 return PP_AUDIOCODEC_AAC; 137 default: 138 return PP_AUDIOCODEC_UNKNOWN; 139 } 140 } 141 142 PP_VideoCodec MediaVideoCodecToPpVideoCodec(media::VideoCodec codec) { 143 switch (codec) { 144 case media::kCodecVP8: 145 return PP_VIDEOCODEC_VP8; 146 case media::kCodecH264: 147 return PP_VIDEOCODEC_H264; 148 default: 149 return PP_VIDEOCODEC_UNKNOWN; 150 } 151 } 152 153 PP_VideoCodecProfile MediaVideoCodecProfileToPpVideoCodecProfile( 154 media::VideoCodecProfile profile) { 155 switch (profile) { 156 case media::VP8PROFILE_MAIN: 157 return PP_VIDEOCODECPROFILE_VP8_MAIN; 158 case media::H264PROFILE_BASELINE: 159 return PP_VIDEOCODECPROFILE_H264_BASELINE; 160 case media::H264PROFILE_MAIN: 161 return PP_VIDEOCODECPROFILE_H264_MAIN; 162 case media::H264PROFILE_EXTENDED: 163 return PP_VIDEOCODECPROFILE_H264_EXTENDED; 164 case media::H264PROFILE_HIGH: 165 return PP_VIDEOCODECPROFILE_H264_HIGH; 166 case media::H264PROFILE_HIGH10PROFILE: 167 return PP_VIDEOCODECPROFILE_H264_HIGH_10; 168 case media::H264PROFILE_HIGH422PROFILE: 169 return PP_VIDEOCODECPROFILE_H264_HIGH_422; 170 case media::H264PROFILE_HIGH444PREDICTIVEPROFILE: 171 return PP_VIDEOCODECPROFILE_H264_HIGH_444_PREDICTIVE; 172 default: 173 return PP_VIDEOCODECPROFILE_UNKNOWN; 174 } 175 } 176 177 PP_DecryptedFrameFormat MediaVideoFormatToPpDecryptedFrameFormat( 178 media::VideoFrame::Format format) { 179 switch (format) { 180 case media::VideoFrame::YV12: 181 return PP_DECRYPTEDFRAMEFORMAT_YV12; 182 case media::VideoFrame::I420: 183 return PP_DECRYPTEDFRAMEFORMAT_I420; 184 default: 185 return PP_DECRYPTEDFRAMEFORMAT_UNKNOWN; 186 } 187 } 188 189 media::Decryptor::Status PpDecryptResultToMediaDecryptorStatus( 190 PP_DecryptResult result) { 191 switch (result) { 192 case PP_DECRYPTRESULT_SUCCESS: 193 return media::Decryptor::kSuccess; 194 case PP_DECRYPTRESULT_DECRYPT_NOKEY: 195 return media::Decryptor::kNoKey; 196 case PP_DECRYPTRESULT_NEEDMOREDATA: 197 return media::Decryptor::kNeedMoreData; 198 case PP_DECRYPTRESULT_DECRYPT_ERROR: 199 return media::Decryptor::kError; 200 case PP_DECRYPTRESULT_DECODE_ERROR: 201 return media::Decryptor::kError; 202 default: 203 NOTREACHED(); 204 return media::Decryptor::kError; 205 } 206 } 207 208 PP_DecryptorStreamType MediaDecryptorStreamTypeToPpStreamType( 209 media::Decryptor::StreamType stream_type) { 210 switch (stream_type) { 211 case media::Decryptor::kAudio: 212 return PP_DECRYPTORSTREAMTYPE_AUDIO; 213 case media::Decryptor::kVideo: 214 return PP_DECRYPTORSTREAMTYPE_VIDEO; 215 default: 216 NOTREACHED(); 217 return PP_DECRYPTORSTREAMTYPE_VIDEO; 218 } 219 } 220 221 media::SampleFormat PpDecryptedSampleFormatToMediaSampleFormat( 222 PP_DecryptedSampleFormat result) { 223 switch (result) { 224 case PP_DECRYPTEDSAMPLEFORMAT_U8: 225 return media::kSampleFormatU8; 226 case PP_DECRYPTEDSAMPLEFORMAT_S16: 227 return media::kSampleFormatS16; 228 case PP_DECRYPTEDSAMPLEFORMAT_S32: 229 return media::kSampleFormatS32; 230 case PP_DECRYPTEDSAMPLEFORMAT_F32: 231 return media::kSampleFormatF32; 232 case PP_DECRYPTEDSAMPLEFORMAT_PLANAR_S16: 233 return media::kSampleFormatPlanarS16; 234 case PP_DECRYPTEDSAMPLEFORMAT_PLANAR_F32: 235 return media::kSampleFormatPlanarF32; 236 default: 237 NOTREACHED(); 238 return media::kUnknownSampleFormat; 239 } 240 } 241 242 } // namespace 243 244 ContentDecryptorDelegate::ContentDecryptorDelegate( 245 PP_Instance pp_instance, 246 const PPP_ContentDecryptor_Private* plugin_decryption_interface) 247 : pp_instance_(pp_instance), 248 plugin_decryption_interface_(plugin_decryption_interface), 249 next_decryption_request_id_(1), 250 pending_audio_decrypt_request_id_(0), 251 pending_video_decrypt_request_id_(0), 252 pending_audio_decoder_init_request_id_(0), 253 pending_video_decoder_init_request_id_(0), 254 pending_audio_decode_request_id_(0), 255 pending_video_decode_request_id_(0), 256 audio_samples_per_second_(0), 257 audio_channel_count_(0), 258 weak_ptr_factory_(this) { 259 weak_this_ = weak_ptr_factory_.GetWeakPtr(); 260 } 261 262 ContentDecryptorDelegate::~ContentDecryptorDelegate() { 263 } 264 265 void ContentDecryptorDelegate::Initialize(const std::string& key_system) { 266 DCHECK(!key_system.empty()); 267 DCHECK(key_system_.empty()); 268 key_system_ = key_system; 269 270 plugin_decryption_interface_->Initialize( 271 pp_instance_, 272 StringVar::StringToPPVar(key_system_)); 273 } 274 275 void ContentDecryptorDelegate::SetSessionEventCallbacks( 276 const media::SessionCreatedCB& session_created_cb, 277 const media::SessionMessageCB& session_message_cb, 278 const media::SessionReadyCB& session_ready_cb, 279 const media::SessionClosedCB& session_closed_cb, 280 const media::SessionErrorCB& session_error_cb) { 281 session_created_cb_ = session_created_cb; 282 session_message_cb_ = session_message_cb; 283 session_ready_cb_ = session_ready_cb; 284 session_closed_cb_ = session_closed_cb; 285 session_error_cb_ = session_error_cb; 286 } 287 288 bool ContentDecryptorDelegate::CreateSession(uint32 session_id, 289 const std::string& type, 290 const uint8* init_data, 291 int init_data_length) { 292 PP_Var init_data_array = 293 PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar( 294 init_data_length, init_data); 295 296 plugin_decryption_interface_->CreateSession(pp_instance_, 297 session_id, 298 StringVar::StringToPPVar(type), 299 init_data_array); 300 return true; 301 } 302 303 bool ContentDecryptorDelegate::UpdateSession(uint32 session_id, 304 const uint8* response, 305 int response_length) { 306 PP_Var response_array = 307 PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar( 308 response_length, response); 309 plugin_decryption_interface_->UpdateSession( 310 pp_instance_, session_id, response_array); 311 return true; 312 } 313 314 bool ContentDecryptorDelegate::ReleaseSession(uint32 session_id) { 315 plugin_decryption_interface_->ReleaseSession(pp_instance_, session_id); 316 return true; 317 } 318 319 // TODO(xhwang): Remove duplication of code in Decrypt(), 320 // DecryptAndDecodeAudio() and DecryptAndDecodeVideo(). 321 bool ContentDecryptorDelegate::Decrypt( 322 media::Decryptor::StreamType stream_type, 323 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, 324 const media::Decryptor::DecryptCB& decrypt_cb) { 325 DVLOG(3) << "Decrypt() - stream_type: " << stream_type; 326 // |{audio|video}_input_resource_| is not being used by the plugin 327 // now because there is only one pending audio/video decrypt request at any 328 // time. This is enforced by the media pipeline. 329 scoped_refptr<PPB_Buffer_Impl> encrypted_resource; 330 if (!MakeMediaBufferResource( 331 stream_type, encrypted_buffer, &encrypted_resource) || 332 !encrypted_resource.get()) { 333 return false; 334 } 335 ScopedPPResource pp_resource(encrypted_resource.get()); 336 337 const uint32_t request_id = next_decryption_request_id_++; 338 DVLOG(2) << "Decrypt() - request_id " << request_id; 339 340 PP_EncryptedBlockInfo block_info = {}; 341 DCHECK(encrypted_buffer->decrypt_config()); 342 if (!MakeEncryptedBlockInfo(encrypted_buffer, request_id, &block_info)) { 343 return false; 344 } 345 346 // There is only one pending decrypt request at any time per stream. This is 347 // enforced by the media pipeline. 348 switch (stream_type) { 349 case media::Decryptor::kAudio: 350 DCHECK_EQ(pending_audio_decrypt_request_id_, 0u); 351 DCHECK(pending_audio_decrypt_cb_.is_null()); 352 pending_audio_decrypt_request_id_ = request_id; 353 pending_audio_decrypt_cb_ = decrypt_cb; 354 break; 355 case media::Decryptor::kVideo: 356 DCHECK_EQ(pending_video_decrypt_request_id_, 0u); 357 DCHECK(pending_video_decrypt_cb_.is_null()); 358 pending_video_decrypt_request_id_ = request_id; 359 pending_video_decrypt_cb_ = decrypt_cb; 360 break; 361 default: 362 NOTREACHED(); 363 return false; 364 } 365 366 SetBufferToFreeInTrackingInfo(&block_info.tracking_info); 367 368 plugin_decryption_interface_->Decrypt(pp_instance_, 369 pp_resource, 370 &block_info); 371 return true; 372 } 373 374 bool ContentDecryptorDelegate::CancelDecrypt( 375 media::Decryptor::StreamType stream_type) { 376 DVLOG(3) << "CancelDecrypt() - stream_type: " << stream_type; 377 378 media::Decryptor::DecryptCB decrypt_cb; 379 switch (stream_type) { 380 case media::Decryptor::kAudio: 381 // Release the shared memory as it can still be in use by the plugin. 382 // The next Decrypt() call will need to allocate a new shared memory 383 // buffer. 384 audio_input_resource_ = NULL; 385 pending_audio_decrypt_request_id_ = 0; 386 decrypt_cb = base::ResetAndReturn(&pending_audio_decrypt_cb_); 387 break; 388 case media::Decryptor::kVideo: 389 // Release the shared memory as it can still be in use by the plugin. 390 // The next Decrypt() call will need to allocate a new shared memory 391 // buffer. 392 video_input_resource_ = NULL; 393 pending_video_decrypt_request_id_ = 0; 394 decrypt_cb = base::ResetAndReturn(&pending_video_decrypt_cb_); 395 break; 396 default: 397 NOTREACHED(); 398 return false; 399 } 400 401 if (!decrypt_cb.is_null()) 402 decrypt_cb.Run(media::Decryptor::kSuccess, NULL); 403 404 return true; 405 } 406 407 bool ContentDecryptorDelegate::InitializeAudioDecoder( 408 const media::AudioDecoderConfig& decoder_config, 409 const media::Decryptor::DecoderInitCB& init_cb) { 410 PP_AudioDecoderConfig pp_decoder_config; 411 pp_decoder_config.codec = 412 MediaAudioCodecToPpAudioCodec(decoder_config.codec()); 413 pp_decoder_config.channel_count = 414 media::ChannelLayoutToChannelCount(decoder_config.channel_layout()); 415 pp_decoder_config.bits_per_channel = decoder_config.bits_per_channel(); 416 pp_decoder_config.samples_per_second = decoder_config.samples_per_second(); 417 pp_decoder_config.request_id = next_decryption_request_id_++; 418 419 audio_samples_per_second_ = pp_decoder_config.samples_per_second; 420 audio_channel_count_ = pp_decoder_config.channel_count; 421 422 scoped_refptr<PPB_Buffer_Impl> extra_data_resource; 423 if (!MakeBufferResource(pp_instance_, 424 decoder_config.extra_data(), 425 decoder_config.extra_data_size(), 426 &extra_data_resource)) { 427 return false; 428 } 429 ScopedPPResource pp_resource(extra_data_resource.get()); 430 431 DCHECK_EQ(pending_audio_decoder_init_request_id_, 0u); 432 DCHECK(pending_audio_decoder_init_cb_.is_null()); 433 pending_audio_decoder_init_request_id_ = pp_decoder_config.request_id; 434 pending_audio_decoder_init_cb_ = init_cb; 435 436 plugin_decryption_interface_->InitializeAudioDecoder(pp_instance_, 437 &pp_decoder_config, 438 pp_resource); 439 return true; 440 } 441 442 bool ContentDecryptorDelegate::InitializeVideoDecoder( 443 const media::VideoDecoderConfig& decoder_config, 444 const media::Decryptor::DecoderInitCB& init_cb) { 445 PP_VideoDecoderConfig pp_decoder_config; 446 pp_decoder_config.codec = 447 MediaVideoCodecToPpVideoCodec(decoder_config.codec()); 448 pp_decoder_config.profile = 449 MediaVideoCodecProfileToPpVideoCodecProfile(decoder_config.profile()); 450 pp_decoder_config.format = 451 MediaVideoFormatToPpDecryptedFrameFormat(decoder_config.format()); 452 pp_decoder_config.width = decoder_config.coded_size().width(); 453 pp_decoder_config.height = decoder_config.coded_size().height(); 454 pp_decoder_config.request_id = next_decryption_request_id_++; 455 456 scoped_refptr<PPB_Buffer_Impl> extra_data_resource; 457 if (!MakeBufferResource(pp_instance_, 458 decoder_config.extra_data(), 459 decoder_config.extra_data_size(), 460 &extra_data_resource)) { 461 return false; 462 } 463 ScopedPPResource pp_resource(extra_data_resource.get()); 464 465 DCHECK_EQ(pending_video_decoder_init_request_id_, 0u); 466 DCHECK(pending_video_decoder_init_cb_.is_null()); 467 pending_video_decoder_init_request_id_ = pp_decoder_config.request_id; 468 pending_video_decoder_init_cb_ = init_cb; 469 470 natural_size_ = decoder_config.natural_size(); 471 472 plugin_decryption_interface_->InitializeVideoDecoder(pp_instance_, 473 &pp_decoder_config, 474 pp_resource); 475 return true; 476 } 477 478 bool ContentDecryptorDelegate::DeinitializeDecoder( 479 media::Decryptor::StreamType stream_type) { 480 CancelDecode(stream_type); 481 482 natural_size_ = gfx::Size(); 483 484 // TODO(tomfinegan): Add decoder deinitialize request tracking, and get 485 // stream type from media stack. 486 plugin_decryption_interface_->DeinitializeDecoder( 487 pp_instance_, MediaDecryptorStreamTypeToPpStreamType(stream_type), 0); 488 return true; 489 } 490 491 bool ContentDecryptorDelegate::ResetDecoder( 492 media::Decryptor::StreamType stream_type) { 493 CancelDecode(stream_type); 494 495 // TODO(tomfinegan): Add decoder reset request tracking. 496 plugin_decryption_interface_->ResetDecoder( 497 pp_instance_, MediaDecryptorStreamTypeToPpStreamType(stream_type), 0); 498 return true; 499 } 500 501 bool ContentDecryptorDelegate::DecryptAndDecodeAudio( 502 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, 503 const media::Decryptor::AudioDecodeCB& audio_decode_cb) { 504 // |audio_input_resource_| is not being used by the plugin now 505 // because there is only one pending audio decode request at any time. 506 // This is enforced by the media pipeline. 507 scoped_refptr<PPB_Buffer_Impl> encrypted_resource; 508 if (!MakeMediaBufferResource(media::Decryptor::kAudio, 509 encrypted_buffer, 510 &encrypted_resource)) { 511 return false; 512 } 513 514 // The resource should not be NULL for non-EOS buffer. 515 if (!encrypted_buffer->end_of_stream() && !encrypted_resource.get()) 516 return false; 517 518 const uint32_t request_id = next_decryption_request_id_++; 519 DVLOG(2) << "DecryptAndDecodeAudio() - request_id " << request_id; 520 521 PP_EncryptedBlockInfo block_info = {}; 522 if (!MakeEncryptedBlockInfo(encrypted_buffer, request_id, &block_info)) { 523 return false; 524 } 525 526 SetBufferToFreeInTrackingInfo(&block_info.tracking_info); 527 528 // There is only one pending audio decode request at any time. This is 529 // enforced by the media pipeline. If this DCHECK is violated, our buffer 530 // reuse policy is not valid, and we may have race problems for the shared 531 // buffer. 532 DCHECK_EQ(pending_audio_decode_request_id_, 0u); 533 DCHECK(pending_audio_decode_cb_.is_null()); 534 pending_audio_decode_request_id_ = request_id; 535 pending_audio_decode_cb_ = audio_decode_cb; 536 537 ScopedPPResource pp_resource(encrypted_resource.get()); 538 plugin_decryption_interface_->DecryptAndDecode(pp_instance_, 539 PP_DECRYPTORSTREAMTYPE_AUDIO, 540 pp_resource, 541 &block_info); 542 return true; 543 } 544 545 bool ContentDecryptorDelegate::DecryptAndDecodeVideo( 546 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, 547 const media::Decryptor::VideoDecodeCB& video_decode_cb) { 548 // |video_input_resource_| is not being used by the plugin now 549 // because there is only one pending video decode request at any time. 550 // This is enforced by the media pipeline. 551 scoped_refptr<PPB_Buffer_Impl> encrypted_resource; 552 if (!MakeMediaBufferResource(media::Decryptor::kVideo, 553 encrypted_buffer, 554 &encrypted_resource)) { 555 return false; 556 } 557 558 // The resource should not be 0 for non-EOS buffer. 559 if (!encrypted_buffer->end_of_stream() && !encrypted_resource.get()) 560 return false; 561 562 const uint32_t request_id = next_decryption_request_id_++; 563 DVLOG(2) << "DecryptAndDecodeVideo() - request_id " << request_id; 564 TRACE_EVENT_ASYNC_BEGIN0( 565 "media", "ContentDecryptorDelegate::DecryptAndDecodeVideo", request_id); 566 567 PP_EncryptedBlockInfo block_info = {}; 568 if (!MakeEncryptedBlockInfo(encrypted_buffer, request_id, &block_info)) { 569 return false; 570 } 571 572 SetBufferToFreeInTrackingInfo(&block_info.tracking_info); 573 574 // Only one pending video decode request at any time. This is enforced by the 575 // media pipeline. If this DCHECK is violated, our buffer 576 // reuse policy is not valid, and we may have race problems for the shared 577 // buffer. 578 DCHECK_EQ(pending_video_decode_request_id_, 0u); 579 DCHECK(pending_video_decode_cb_.is_null()); 580 pending_video_decode_request_id_ = request_id; 581 pending_video_decode_cb_ = video_decode_cb; 582 583 // TODO(tomfinegan): Need to get stream type from media stack. 584 ScopedPPResource pp_resource(encrypted_resource.get()); 585 plugin_decryption_interface_->DecryptAndDecode(pp_instance_, 586 PP_DECRYPTORSTREAMTYPE_VIDEO, 587 pp_resource, 588 &block_info); 589 return true; 590 } 591 592 void ContentDecryptorDelegate::OnSessionCreated(uint32 session_id, 593 PP_Var web_session_id_var) { 594 if (session_created_cb_.is_null()) 595 return; 596 597 StringVar* session_id_string = StringVar::FromPPVar(web_session_id_var); 598 599 if (!session_id_string) { 600 OnSessionError(session_id, media::MediaKeys::kUnknownError, 0); 601 return; 602 } 603 604 session_created_cb_.Run(session_id, session_id_string->value()); 605 } 606 607 void ContentDecryptorDelegate::OnSessionMessage(uint32 session_id, 608 PP_Var message_var, 609 PP_Var default_url_var) { 610 if (session_message_cb_.is_null()) 611 return; 612 613 ArrayBufferVar* message_array_buffer = ArrayBufferVar::FromPPVar(message_var); 614 615 std::vector<uint8> message; 616 if (message_array_buffer) { 617 const uint8* data = static_cast<const uint8*>(message_array_buffer->Map()); 618 message.assign(data, data + message_array_buffer->ByteLength()); 619 } 620 621 StringVar* default_url_string = StringVar::FromPPVar(default_url_var); 622 623 if (!default_url_string) { 624 OnSessionError(session_id, media::MediaKeys::kUnknownError, 0); 625 return; 626 } 627 628 session_message_cb_.Run(session_id, message, default_url_string->value()); 629 } 630 631 void ContentDecryptorDelegate::OnSessionReady(uint32 session_id) { 632 if (session_ready_cb_.is_null()) 633 return; 634 635 session_ready_cb_.Run(session_id); 636 } 637 638 void ContentDecryptorDelegate::OnSessionClosed(uint32 session_id) { 639 if (session_closed_cb_.is_null()) 640 return; 641 642 session_closed_cb_.Run(session_id); 643 } 644 645 void ContentDecryptorDelegate::OnSessionError(uint32 session_id, 646 int32_t media_error, 647 int32_t system_code) { 648 if (session_error_cb_.is_null()) 649 return; 650 651 session_error_cb_.Run(session_id, 652 static_cast<media::MediaKeys::KeyError>(media_error), 653 system_code); 654 } 655 656 void ContentDecryptorDelegate::DecoderInitializeDone( 657 PP_DecryptorStreamType decoder_type, 658 uint32_t request_id, 659 PP_Bool success) { 660 if (decoder_type == PP_DECRYPTORSTREAMTYPE_AUDIO) { 661 // If the request ID is not valid or does not match what's saved, do 662 // nothing. 663 if (request_id == 0 || 664 request_id != pending_audio_decoder_init_request_id_) 665 return; 666 667 DCHECK(!pending_audio_decoder_init_cb_.is_null()); 668 pending_audio_decoder_init_request_id_ = 0; 669 base::ResetAndReturn( 670 &pending_audio_decoder_init_cb_).Run(PP_ToBool(success)); 671 } else { 672 if (request_id == 0 || 673 request_id != pending_video_decoder_init_request_id_) 674 return; 675 676 if (!success) 677 natural_size_ = gfx::Size(); 678 679 DCHECK(!pending_video_decoder_init_cb_.is_null()); 680 pending_video_decoder_init_request_id_ = 0; 681 base::ResetAndReturn( 682 &pending_video_decoder_init_cb_).Run(PP_ToBool(success)); 683 } 684 } 685 686 void ContentDecryptorDelegate::DecoderDeinitializeDone( 687 PP_DecryptorStreamType decoder_type, 688 uint32_t request_id) { 689 // TODO(tomfinegan): Add decoder stop completion handling. 690 } 691 692 void ContentDecryptorDelegate::DecoderResetDone( 693 PP_DecryptorStreamType decoder_type, 694 uint32_t request_id) { 695 // TODO(tomfinegan): Add decoder reset completion handling. 696 } 697 698 void ContentDecryptorDelegate::DeliverBlock( 699 PP_Resource decrypted_block, 700 const PP_DecryptedBlockInfo* block_info) { 701 DCHECK(block_info); 702 703 FreeBuffer(block_info->tracking_info.buffer_id); 704 705 const uint32_t request_id = block_info->tracking_info.request_id; 706 DVLOG(2) << "DeliverBlock() - request_id: " << request_id; 707 708 // If the request ID is not valid or does not match what's saved, do nothing. 709 if (request_id == 0) { 710 DVLOG(1) << "DeliverBlock() - invalid request_id " << request_id; 711 return; 712 } 713 714 media::Decryptor::DecryptCB decrypt_cb; 715 if (request_id == pending_audio_decrypt_request_id_) { 716 DCHECK(!pending_audio_decrypt_cb_.is_null()); 717 pending_audio_decrypt_request_id_ = 0; 718 decrypt_cb = base::ResetAndReturn(&pending_audio_decrypt_cb_); 719 } else if (request_id == pending_video_decrypt_request_id_) { 720 DCHECK(!pending_video_decrypt_cb_.is_null()); 721 pending_video_decrypt_request_id_ = 0; 722 decrypt_cb = base::ResetAndReturn(&pending_video_decrypt_cb_); 723 } else { 724 DVLOG(1) << "DeliverBlock() - request_id " << request_id << " not found"; 725 return; 726 } 727 728 media::Decryptor::Status status = 729 PpDecryptResultToMediaDecryptorStatus(block_info->result); 730 if (status != media::Decryptor::kSuccess) { 731 decrypt_cb.Run(status, NULL); 732 return; 733 } 734 735 EnterResourceNoLock<PPB_Buffer_API> enter(decrypted_block, true); 736 if (!enter.succeeded()) { 737 decrypt_cb.Run(media::Decryptor::kError, NULL); 738 return; 739 } 740 BufferAutoMapper mapper(enter.object()); 741 if (!mapper.data() || !mapper.size() || 742 mapper.size() < block_info->data_size) { 743 decrypt_cb.Run(media::Decryptor::kError, NULL); 744 return; 745 } 746 747 // TODO(tomfinegan): Find a way to take ownership of the shared memory 748 // managed by the PPB_Buffer_Dev, and avoid the extra copy. 749 scoped_refptr<media::DecoderBuffer> decrypted_buffer( 750 media::DecoderBuffer::CopyFrom( 751 static_cast<uint8*>(mapper.data()), block_info->data_size)); 752 decrypted_buffer->set_timestamp(base::TimeDelta::FromMicroseconds( 753 block_info->tracking_info.timestamp)); 754 decrypt_cb.Run(media::Decryptor::kSuccess, decrypted_buffer); 755 } 756 757 // Use a non-class-member function here so that if for some reason 758 // ContentDecryptorDelegate is destroyed before VideoFrame calls this callback, 759 // we can still get the shared memory unmapped. 760 static void BufferNoLongerNeeded( 761 const scoped_refptr<PPB_Buffer_Impl>& ppb_buffer, 762 base::Closure buffer_no_longer_needed_cb) { 763 ppb_buffer->Unmap(); 764 buffer_no_longer_needed_cb.Run(); 765 } 766 767 // Enters |resource|, maps shared memory and returns pointer of mapped data. 768 // Returns NULL if any error occurs. 769 static uint8* GetMappedBuffer(PP_Resource resource, 770 scoped_refptr<PPB_Buffer_Impl>* ppb_buffer) { 771 EnterResourceNoLock<PPB_Buffer_API> enter(resource, true); 772 if (!enter.succeeded()) 773 return NULL; 774 775 uint8* mapped_data = static_cast<uint8*>(enter.object()->Map()); 776 if (!enter.object()->IsMapped() || !mapped_data) 777 return NULL; 778 779 uint32_t mapped_size = 0; 780 if (!enter.object()->Describe(&mapped_size) || !mapped_size) { 781 enter.object()->Unmap(); 782 return NULL; 783 } 784 785 *ppb_buffer = static_cast<PPB_Buffer_Impl*>(enter.object()); 786 787 return mapped_data; 788 } 789 790 void ContentDecryptorDelegate::DeliverFrame( 791 PP_Resource decrypted_frame, 792 const PP_DecryptedFrameInfo* frame_info) { 793 DCHECK(frame_info); 794 795 const uint32_t request_id = frame_info->tracking_info.request_id; 796 DVLOG(2) << "DeliverFrame() - request_id: " << request_id; 797 798 // If the request ID is not valid or does not match what's saved, do nothing. 799 if (request_id == 0 || request_id != pending_video_decode_request_id_) { 800 DVLOG(1) << "DeliverFrame() - request_id " << request_id << " not found"; 801 FreeBuffer(frame_info->tracking_info.buffer_id); 802 return; 803 } 804 805 TRACE_EVENT_ASYNC_END0( 806 "media", "ContentDecryptorDelegate::DecryptAndDecodeVideo", request_id); 807 808 DCHECK(!pending_video_decode_cb_.is_null()); 809 pending_video_decode_request_id_ = 0; 810 media::Decryptor::VideoDecodeCB video_decode_cb = 811 base::ResetAndReturn(&pending_video_decode_cb_); 812 813 media::Decryptor::Status status = 814 PpDecryptResultToMediaDecryptorStatus(frame_info->result); 815 if (status != media::Decryptor::kSuccess) { 816 DCHECK(!frame_info->tracking_info.buffer_id); 817 video_decode_cb.Run(status, NULL); 818 return; 819 } 820 821 scoped_refptr<PPB_Buffer_Impl> ppb_buffer; 822 uint8* frame_data = GetMappedBuffer(decrypted_frame, &ppb_buffer); 823 if (!frame_data) { 824 FreeBuffer(frame_info->tracking_info.buffer_id); 825 video_decode_cb.Run(media::Decryptor::kError, NULL); 826 return; 827 } 828 829 gfx::Size frame_size(frame_info->width, frame_info->height); 830 DCHECK_EQ(frame_info->format, PP_DECRYPTEDFRAMEFORMAT_YV12); 831 832 scoped_refptr<media::VideoFrame> decoded_frame = 833 media::VideoFrame::WrapExternalYuvData( 834 media::VideoFrame::YV12, 835 frame_size, 836 gfx::Rect(frame_size), 837 natural_size_, 838 frame_info->strides[PP_DECRYPTEDFRAMEPLANES_Y], 839 frame_info->strides[PP_DECRYPTEDFRAMEPLANES_U], 840 frame_info->strides[PP_DECRYPTEDFRAMEPLANES_V], 841 frame_data + frame_info->plane_offsets[PP_DECRYPTEDFRAMEPLANES_Y], 842 frame_data + frame_info->plane_offsets[PP_DECRYPTEDFRAMEPLANES_U], 843 frame_data + frame_info->plane_offsets[PP_DECRYPTEDFRAMEPLANES_V], 844 base::TimeDelta::FromMicroseconds( 845 frame_info->tracking_info.timestamp), 846 media::BindToLoop( 847 base::MessageLoopProxy::current(), 848 base::Bind(&BufferNoLongerNeeded, 849 ppb_buffer, 850 base::Bind(&ContentDecryptorDelegate::FreeBuffer, 851 weak_this_, 852 frame_info->tracking_info.buffer_id)))); 853 854 video_decode_cb.Run(media::Decryptor::kSuccess, decoded_frame); 855 } 856 857 void ContentDecryptorDelegate::DeliverSamples( 858 PP_Resource audio_frames, 859 const PP_DecryptedSampleInfo* sample_info) { 860 DCHECK(sample_info); 861 862 FreeBuffer(sample_info->tracking_info.buffer_id); 863 864 const uint32_t request_id = sample_info->tracking_info.request_id; 865 DVLOG(2) << "DeliverSamples() - request_id: " << request_id; 866 867 // If the request ID is not valid or does not match what's saved, do nothing. 868 if (request_id == 0 || request_id != pending_audio_decode_request_id_) { 869 DVLOG(1) << "DeliverSamples() - request_id " << request_id << " not found"; 870 return; 871 } 872 873 DCHECK(!pending_audio_decode_cb_.is_null()); 874 pending_audio_decode_request_id_ = 0; 875 media::Decryptor::AudioDecodeCB audio_decode_cb = 876 base::ResetAndReturn(&pending_audio_decode_cb_); 877 878 const media::Decryptor::AudioBuffers empty_frames; 879 880 media::Decryptor::Status status = 881 PpDecryptResultToMediaDecryptorStatus(sample_info->result); 882 if (status != media::Decryptor::kSuccess) { 883 audio_decode_cb.Run(status, empty_frames); 884 return; 885 } 886 887 media::SampleFormat sample_format = 888 PpDecryptedSampleFormatToMediaSampleFormat(sample_info->format); 889 890 media::Decryptor::AudioBuffers audio_frame_list; 891 if (!DeserializeAudioFrames(audio_frames, 892 sample_info->data_size, 893 sample_format, 894 &audio_frame_list)) { 895 NOTREACHED() << "CDM did not serialize the buffer correctly."; 896 audio_decode_cb.Run(media::Decryptor::kError, empty_frames); 897 return; 898 } 899 900 audio_decode_cb.Run(media::Decryptor::kSuccess, audio_frame_list); 901 } 902 903 // TODO(xhwang): Try to remove duplicate logic here and in CancelDecrypt(). 904 void ContentDecryptorDelegate::CancelDecode( 905 media::Decryptor::StreamType stream_type) { 906 switch (stream_type) { 907 case media::Decryptor::kAudio: 908 // Release the shared memory as it can still be in use by the plugin. 909 // The next DecryptAndDecode() call will need to allocate a new shared 910 // memory buffer. 911 audio_input_resource_ = NULL; 912 pending_audio_decode_request_id_ = 0; 913 if (!pending_audio_decode_cb_.is_null()) 914 base::ResetAndReturn(&pending_audio_decode_cb_).Run( 915 media::Decryptor::kSuccess, media::Decryptor::AudioBuffers()); 916 break; 917 case media::Decryptor::kVideo: 918 // Release the shared memory as it can still be in use by the plugin. 919 // The next DecryptAndDecode() call will need to allocate a new shared 920 // memory buffer. 921 video_input_resource_ = NULL; 922 pending_video_decode_request_id_ = 0; 923 if (!pending_video_decode_cb_.is_null()) 924 base::ResetAndReturn(&pending_video_decode_cb_).Run( 925 media::Decryptor::kSuccess, NULL); 926 break; 927 default: 928 NOTREACHED(); 929 } 930 } 931 932 bool ContentDecryptorDelegate::MakeMediaBufferResource( 933 media::Decryptor::StreamType stream_type, 934 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, 935 scoped_refptr<PPB_Buffer_Impl>* resource) { 936 TRACE_EVENT0("media", "ContentDecryptorDelegate::MakeMediaBufferResource"); 937 938 // End of stream buffers are represented as null resources. 939 if (encrypted_buffer->end_of_stream()) { 940 *resource = NULL; 941 return true; 942 } 943 944 DCHECK(stream_type == media::Decryptor::kAudio || 945 stream_type == media::Decryptor::kVideo); 946 scoped_refptr<PPB_Buffer_Impl>& media_resource = 947 (stream_type == media::Decryptor::kAudio) ? audio_input_resource_ : 948 video_input_resource_; 949 950 const size_t data_size = static_cast<size_t>(encrypted_buffer->data_size()); 951 if (!media_resource.get() || media_resource->size() < data_size) { 952 // Either the buffer hasn't been created yet, or we have one that isn't big 953 // enough to fit |size| bytes. 954 955 // Media resource size starts from |kMinimumMediaBufferSize| and grows 956 // exponentially to avoid frequent re-allocation of PPB_Buffer_Impl, 957 // which is usually expensive. Since input media buffers are compressed, 958 // they are usually small (compared to outputs). The over-allocated memory 959 // should be negligible. 960 const uint32_t kMinimumMediaBufferSize = 1024; 961 uint32_t media_resource_size = 962 media_resource.get() ? media_resource->size() : kMinimumMediaBufferSize; 963 while (media_resource_size < data_size) 964 media_resource_size *= 2; 965 966 DVLOG(2) << "Size of media buffer for " 967 << ((stream_type == media::Decryptor::kAudio) ? "audio" : "video") 968 << " stream bumped to " << media_resource_size 969 << " bytes to fit input."; 970 media_resource = PPB_Buffer_Impl::CreateResource(pp_instance_, 971 media_resource_size); 972 if (!media_resource.get()) 973 return false; 974 } 975 976 BufferAutoMapper mapper(media_resource.get()); 977 if (!mapper.data() || mapper.size() < data_size) { 978 media_resource = NULL; 979 return false; 980 } 981 memcpy(mapper.data(), encrypted_buffer->data(), data_size); 982 983 *resource = media_resource; 984 return true; 985 } 986 987 void ContentDecryptorDelegate::FreeBuffer(uint32_t buffer_id) { 988 if (buffer_id) 989 free_buffers_.push(buffer_id); 990 } 991 992 void ContentDecryptorDelegate::SetBufferToFreeInTrackingInfo( 993 PP_DecryptTrackingInfo* tracking_info) { 994 DCHECK_EQ(tracking_info->buffer_id, 0u); 995 996 if (free_buffers_.empty()) 997 return; 998 999 tracking_info->buffer_id = free_buffers_.front(); 1000 free_buffers_.pop(); 1001 } 1002 1003 bool ContentDecryptorDelegate::DeserializeAudioFrames( 1004 PP_Resource audio_frames, 1005 size_t data_size, 1006 media::SampleFormat sample_format, 1007 media::Decryptor::AudioBuffers* frames) { 1008 DCHECK(frames); 1009 EnterResourceNoLock<PPB_Buffer_API> enter(audio_frames, true); 1010 if (!enter.succeeded()) 1011 return false; 1012 1013 BufferAutoMapper mapper(enter.object()); 1014 if (!mapper.data() || !mapper.size() || 1015 mapper.size() < static_cast<uint32_t>(data_size)) 1016 return false; 1017 1018 // TODO(jrummell): Pass ownership of data() directly to AudioBuffer to avoid 1019 // the copy. Since it is possible to get multiple buffers, it would need to be 1020 // sliced and ref counted appropriately. http://crbug.com/255576. 1021 const uint8* cur = static_cast<uint8*>(mapper.data()); 1022 size_t bytes_left = data_size; 1023 1024 const int audio_bytes_per_frame = 1025 media::SampleFormatToBytesPerChannel(sample_format) * 1026 audio_channel_count_; 1027 1028 // Allocate space for the channel pointers given to AudioBuffer. 1029 std::vector<const uint8*> channel_ptrs( 1030 audio_channel_count_, static_cast<const uint8*>(NULL)); 1031 do { 1032 int64 timestamp = 0; 1033 int64 frame_size = -1; 1034 const size_t kHeaderSize = sizeof(timestamp) + sizeof(frame_size); 1035 1036 if (bytes_left < kHeaderSize) 1037 return false; 1038 1039 memcpy(×tamp, cur, sizeof(timestamp)); 1040 cur += sizeof(timestamp); 1041 bytes_left -= sizeof(timestamp); 1042 1043 memcpy(&frame_size, cur, sizeof(frame_size)); 1044 cur += sizeof(frame_size); 1045 bytes_left -= sizeof(frame_size); 1046 1047 // We should *not* have empty frames in the list. 1048 if (frame_size <= 0 || 1049 bytes_left < base::checked_numeric_cast<size_t>(frame_size)) { 1050 return false; 1051 } 1052 1053 // Setup channel pointers. AudioBuffer::CopyFrom() will only use the first 1054 // one in the case of interleaved data. 1055 const int size_per_channel = frame_size / audio_channel_count_; 1056 for (int i = 0; i < audio_channel_count_; ++i) 1057 channel_ptrs[i] = cur + i * size_per_channel; 1058 1059 const int frame_count = frame_size / audio_bytes_per_frame; 1060 scoped_refptr<media::AudioBuffer> frame = media::AudioBuffer::CopyFrom( 1061 sample_format, 1062 audio_channel_count_, 1063 frame_count, 1064 &channel_ptrs[0], 1065 base::TimeDelta::FromMicroseconds(timestamp), 1066 base::TimeDelta::FromMicroseconds(audio_samples_per_second_ / 1067 frame_count)); 1068 frames->push_back(frame); 1069 1070 cur += frame_size; 1071 bytes_left -= frame_size; 1072 } while (bytes_left > 0); 1073 1074 return true; 1075 } 1076 1077 } // namespace content 1078