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 "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/debug/trace_event.h" | 8 #include "base/debug/trace_event.h" |
| 9 #include "base/message_loop/message_loop_proxy.h" | 9 #include "base/message_loop/message_loop_proxy.h" |
| 10 #include "base/safe_numerics.h" | 10 #include "base/safe_numerics.h" |
| 11 #include "content/renderer/pepper/ppb_buffer_impl.h" | 11 #include "content/renderer/pepper/ppb_buffer_impl.h" |
| 12 #include "media/base/audio_buffer.h" | 12 #include "media/base/audio_buffer.h" |
| 13 #include "media/base/audio_decoder_config.h" | 13 #include "media/base/audio_decoder_config.h" |
| 14 #include "media/base/bind_to_loop.h" | 14 #include "media/base/bind_to_loop.h" |
| 15 #include "media/base/channel_layout.h" | 15 #include "media/base/channel_layout.h" |
| 16 #include "media/base/data_buffer.h" | 16 #include "media/base/data_buffer.h" |
| 17 #include "media/base/decoder_buffer.h" | 17 #include "media/base/decoder_buffer.h" |
| 18 #include "media/base/decrypt_config.h" | 18 #include "media/base/decrypt_config.h" |
| 19 #include "media/base/video_decoder_config.h" | 19 #include "media/base/video_decoder_config.h" |
| 20 #include "media/base/video_frame.h" | 20 #include "media/base/video_frame.h" |
| 21 #include "media/base/video_util.h" | 21 #include "media/base/video_util.h" |
| 22 #include "ppapi/shared_impl/scoped_pp_resource.h" | 22 #include "ppapi/shared_impl/scoped_pp_resource.h" |
| 23 #include "ppapi/shared_impl/var.h" | 23 #include "ppapi/shared_impl/var.h" |
| 24 #include "ppapi/shared_impl/var_tracker.h" | 24 #include "ppapi/shared_impl/var_tracker.h" |
| 25 #include "ppapi/thunk/enter.h" | 25 #include "ppapi/thunk/enter.h" |
| 26 #include "ppapi/thunk/ppb_buffer_api.h" | 26 #include "ppapi/thunk/ppb_buffer_api.h" |
| 27 #include "ui/gfx/rect.h" | 27 #include "ui/gfx/rect.h" |
| 28 | 28 |
| 29 using media::Decryptor; | |
| 29 using ppapi::ArrayBufferVar; | 30 using ppapi::ArrayBufferVar; |
| 30 using ppapi::PpapiGlobals; | 31 using ppapi::PpapiGlobals; |
| 31 using ppapi::ScopedPPResource; | 32 using ppapi::ScopedPPResource; |
| 32 using ppapi::StringVar; | 33 using ppapi::StringVar; |
| 33 using ppapi::thunk::EnterResourceNoLock; | 34 using ppapi::thunk::EnterResourceNoLock; |
| 34 using ppapi::thunk::PPB_Buffer_API; | 35 using ppapi::thunk::PPB_Buffer_API; |
| 35 | 36 |
| 36 namespace content { | 37 namespace content { |
| 37 | 38 |
| 38 namespace { | 39 namespace { |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 179 switch (format) { | 180 switch (format) { |
| 180 case media::VideoFrame::YV12: | 181 case media::VideoFrame::YV12: |
| 181 return PP_DECRYPTEDFRAMEFORMAT_YV12; | 182 return PP_DECRYPTEDFRAMEFORMAT_YV12; |
| 182 case media::VideoFrame::I420: | 183 case media::VideoFrame::I420: |
| 183 return PP_DECRYPTEDFRAMEFORMAT_I420; | 184 return PP_DECRYPTEDFRAMEFORMAT_I420; |
| 184 default: | 185 default: |
| 185 return PP_DECRYPTEDFRAMEFORMAT_UNKNOWN; | 186 return PP_DECRYPTEDFRAMEFORMAT_UNKNOWN; |
| 186 } | 187 } |
| 187 } | 188 } |
| 188 | 189 |
| 189 media::Decryptor::Status PpDecryptResultToMediaDecryptorStatus( | 190 Decryptor::Status PpDecryptResultToMediaDecryptorStatus( |
| 190 PP_DecryptResult result) { | 191 PP_DecryptResult result) { |
| 191 switch (result) { | 192 switch (result) { |
| 192 case PP_DECRYPTRESULT_SUCCESS: | 193 case PP_DECRYPTRESULT_SUCCESS: |
| 193 return media::Decryptor::kSuccess; | 194 return Decryptor::kSuccess; |
| 194 case PP_DECRYPTRESULT_DECRYPT_NOKEY: | 195 case PP_DECRYPTRESULT_DECRYPT_NOKEY: |
| 195 return media::Decryptor::kNoKey; | 196 return Decryptor::kNoKey; |
| 196 case PP_DECRYPTRESULT_NEEDMOREDATA: | 197 case PP_DECRYPTRESULT_NEEDMOREDATA: |
| 197 return media::Decryptor::kNeedMoreData; | 198 return Decryptor::kNeedMoreData; |
| 198 case PP_DECRYPTRESULT_DECRYPT_ERROR: | 199 case PP_DECRYPTRESULT_DECRYPT_ERROR: |
| 199 return media::Decryptor::kError; | 200 return Decryptor::kError; |
| 200 case PP_DECRYPTRESULT_DECODE_ERROR: | 201 case PP_DECRYPTRESULT_DECODE_ERROR: |
| 201 return media::Decryptor::kError; | 202 return Decryptor::kError; |
| 202 default: | 203 default: |
| 203 NOTREACHED(); | 204 NOTREACHED(); |
| 204 return media::Decryptor::kError; | 205 return Decryptor::kError; |
| 205 } | 206 } |
| 206 } | 207 } |
| 207 | 208 |
| 208 PP_DecryptorStreamType MediaDecryptorStreamTypeToPpStreamType( | 209 PP_DecryptorStreamType MediaDecryptorStreamTypeToPpStreamType( |
| 209 media::Decryptor::StreamType stream_type) { | 210 Decryptor::StreamType stream_type) { |
| 210 switch (stream_type) { | 211 switch (stream_type) { |
| 211 case media::Decryptor::kAudio: | 212 case Decryptor::kAudio: |
| 212 return PP_DECRYPTORSTREAMTYPE_AUDIO; | 213 return PP_DECRYPTORSTREAMTYPE_AUDIO; |
| 213 case media::Decryptor::kVideo: | 214 case Decryptor::kVideo: |
| 214 return PP_DECRYPTORSTREAMTYPE_VIDEO; | 215 return PP_DECRYPTORSTREAMTYPE_VIDEO; |
| 215 default: | 216 default: |
| 216 NOTREACHED(); | 217 NOTREACHED(); |
| 217 return PP_DECRYPTORSTREAMTYPE_VIDEO; | 218 return PP_DECRYPTORSTREAMTYPE_VIDEO; |
| 218 } | 219 } |
| 219 } | 220 } |
| 220 | 221 |
| 221 media::SampleFormat PpDecryptedSampleFormatToMediaSampleFormat( | 222 media::SampleFormat PpDecryptedSampleFormatToMediaSampleFormat( |
| 222 PP_DecryptedSampleFormat result) { | 223 PP_DecryptedSampleFormat result) { |
| 223 switch (result) { | 224 switch (result) { |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 240 } | 241 } |
| 241 | 242 |
| 242 } // namespace | 243 } // namespace |
| 243 | 244 |
| 244 ContentDecryptorDelegate::ContentDecryptorDelegate( | 245 ContentDecryptorDelegate::ContentDecryptorDelegate( |
| 245 PP_Instance pp_instance, | 246 PP_Instance pp_instance, |
| 246 const PPP_ContentDecryptor_Private* plugin_decryption_interface) | 247 const PPP_ContentDecryptor_Private* plugin_decryption_interface) |
| 247 : pp_instance_(pp_instance), | 248 : pp_instance_(pp_instance), |
| 248 plugin_decryption_interface_(plugin_decryption_interface), | 249 plugin_decryption_interface_(plugin_decryption_interface), |
| 249 next_decryption_request_id_(1), | 250 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), | 251 audio_samples_per_second_(0), |
| 257 audio_channel_count_(0), | 252 audio_channel_count_(0), |
| 258 weak_ptr_factory_(this) { | 253 weak_ptr_factory_(this) { |
| 259 weak_this_ = weak_ptr_factory_.GetWeakPtr(); | 254 weak_this_ = weak_ptr_factory_.GetWeakPtr(); |
| 260 } | 255 } |
| 261 | 256 |
| 262 ContentDecryptorDelegate::~ContentDecryptorDelegate() { | 257 ContentDecryptorDelegate::~ContentDecryptorDelegate() { |
| 263 } | 258 } |
| 264 | 259 |
| 265 void ContentDecryptorDelegate::Initialize(const std::string& key_system) { | 260 void ContentDecryptorDelegate::Initialize(const std::string& key_system) { |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 312 } | 307 } |
| 313 | 308 |
| 314 bool ContentDecryptorDelegate::ReleaseSession(uint32 session_id) { | 309 bool ContentDecryptorDelegate::ReleaseSession(uint32 session_id) { |
| 315 plugin_decryption_interface_->ReleaseSession(pp_instance_, session_id); | 310 plugin_decryption_interface_->ReleaseSession(pp_instance_, session_id); |
| 316 return true; | 311 return true; |
| 317 } | 312 } |
| 318 | 313 |
| 319 // TODO(xhwang): Remove duplication of code in Decrypt(), | 314 // TODO(xhwang): Remove duplication of code in Decrypt(), |
| 320 // DecryptAndDecodeAudio() and DecryptAndDecodeVideo(). | 315 // DecryptAndDecodeAudio() and DecryptAndDecodeVideo(). |
| 321 bool ContentDecryptorDelegate::Decrypt( | 316 bool ContentDecryptorDelegate::Decrypt( |
| 322 media::Decryptor::StreamType stream_type, | 317 Decryptor::StreamType stream_type, |
| 323 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, | 318 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, |
| 324 const media::Decryptor::DecryptCB& decrypt_cb) { | 319 const Decryptor::DecryptCB& decrypt_cb) { |
| 325 DVLOG(3) << "Decrypt() - stream_type: " << stream_type; | 320 DVLOG(3) << "Decrypt() - stream_type: " << stream_type; |
| 326 // |{audio|video}_input_resource_| is not being used by the plugin | 321 // |{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 | 322 // now because there is only one pending audio/video decrypt request at any |
| 328 // time. This is enforced by the media pipeline. | 323 // time. This is enforced by the media pipeline. |
| 329 scoped_refptr<PPB_Buffer_Impl> encrypted_resource; | 324 scoped_refptr<PPB_Buffer_Impl> encrypted_resource; |
| 330 if (!MakeMediaBufferResource( | 325 if (!MakeMediaBufferResource( |
| 331 stream_type, encrypted_buffer, &encrypted_resource) || | 326 stream_type, encrypted_buffer, &encrypted_resource) || |
| 332 !encrypted_resource.get()) { | 327 !encrypted_resource.get()) { |
| 333 return false; | 328 return false; |
| 334 } | 329 } |
| 335 ScopedPPResource pp_resource(encrypted_resource.get()); | 330 ScopedPPResource pp_resource(encrypted_resource.get()); |
| 336 | 331 |
| 337 const uint32_t request_id = next_decryption_request_id_++; | 332 const uint32_t request_id = next_decryption_request_id_++; |
| 338 DVLOG(2) << "Decrypt() - request_id " << request_id; | 333 DVLOG(2) << "Decrypt() - request_id " << request_id; |
| 339 | 334 |
| 340 PP_EncryptedBlockInfo block_info = {}; | 335 PP_EncryptedBlockInfo block_info = {}; |
| 341 DCHECK(encrypted_buffer->decrypt_config()); | 336 DCHECK(encrypted_buffer->decrypt_config()); |
| 342 if (!MakeEncryptedBlockInfo(encrypted_buffer, request_id, &block_info)) { | 337 if (!MakeEncryptedBlockInfo(encrypted_buffer, request_id, &block_info)) { |
| 343 return false; | 338 return false; |
| 344 } | 339 } |
| 345 | 340 |
| 346 // There is only one pending decrypt request at any time per stream. This is | 341 // There is only one pending decrypt request at any time per stream. This is |
| 347 // enforced by the media pipeline. | 342 // enforced by the media pipeline. |
| 348 switch (stream_type) { | 343 switch (stream_type) { |
| 349 case media::Decryptor::kAudio: | 344 case Decryptor::kAudio: |
| 350 DCHECK_EQ(pending_audio_decrypt_request_id_, 0u); | 345 audio_decrypt_cb_.Set(request_id, decrypt_cb); |
| 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; | 346 break; |
| 355 case media::Decryptor::kVideo: | 347 case Decryptor::kVideo: |
| 356 DCHECK_EQ(pending_video_decrypt_request_id_, 0u); | 348 video_decrypt_cb_.Set(request_id, decrypt_cb); |
| 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; | 349 break; |
| 361 default: | 350 default: |
| 362 NOTREACHED(); | 351 NOTREACHED(); |
| 363 return false; | 352 return false; |
| 364 } | 353 } |
| 365 | 354 |
| 366 SetBufferToFreeInTrackingInfo(&block_info.tracking_info); | 355 SetBufferToFreeInTrackingInfo(&block_info.tracking_info); |
| 367 | 356 |
| 368 plugin_decryption_interface_->Decrypt(pp_instance_, | 357 plugin_decryption_interface_->Decrypt(pp_instance_, |
| 369 pp_resource, | 358 pp_resource, |
| 370 &block_info); | 359 &block_info); |
| 371 return true; | 360 return true; |
| 372 } | 361 } |
| 373 | 362 |
| 374 bool ContentDecryptorDelegate::CancelDecrypt( | 363 bool ContentDecryptorDelegate::CancelDecrypt( |
| 375 media::Decryptor::StreamType stream_type) { | 364 Decryptor::StreamType stream_type) { |
| 376 DVLOG(3) << "CancelDecrypt() - stream_type: " << stream_type; | 365 DVLOG(3) << "CancelDecrypt() - stream_type: " << stream_type; |
| 377 | 366 |
| 378 media::Decryptor::DecryptCB decrypt_cb; | 367 Decryptor::DecryptCB decrypt_cb; |
| 379 switch (stream_type) { | 368 switch (stream_type) { |
| 380 case media::Decryptor::kAudio: | 369 case Decryptor::kAudio: |
| 381 // Release the shared memory as it can still be in use by the plugin. | 370 // 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 | 371 // The next Decrypt() call will need to allocate a new shared memory |
| 383 // buffer. | 372 // buffer. |
| 384 audio_input_resource_ = NULL; | 373 audio_input_resource_ = NULL; |
| 385 pending_audio_decrypt_request_id_ = 0; | 374 decrypt_cb = audio_decrypt_cb_.ResetAndReturn(); |
| 386 decrypt_cb = base::ResetAndReturn(&pending_audio_decrypt_cb_); | |
| 387 break; | 375 break; |
| 388 case media::Decryptor::kVideo: | 376 case Decryptor::kVideo: |
| 389 // Release the shared memory as it can still be in use by the plugin. | 377 // 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 | 378 // The next Decrypt() call will need to allocate a new shared memory |
| 391 // buffer. | 379 // buffer. |
| 392 video_input_resource_ = NULL; | 380 video_input_resource_ = NULL; |
| 393 pending_video_decrypt_request_id_ = 0; | 381 decrypt_cb = video_decrypt_cb_.ResetAndReturn(); |
| 394 decrypt_cb = base::ResetAndReturn(&pending_video_decrypt_cb_); | |
| 395 break; | 382 break; |
| 396 default: | 383 default: |
| 397 NOTREACHED(); | 384 NOTREACHED(); |
| 398 return false; | 385 return false; |
| 399 } | 386 } |
| 400 | 387 |
| 401 if (!decrypt_cb.is_null()) | 388 if (!decrypt_cb.is_null()) |
| 402 decrypt_cb.Run(media::Decryptor::kSuccess, NULL); | 389 decrypt_cb.Run(Decryptor::kSuccess, NULL); |
| 403 | 390 |
| 404 return true; | 391 return true; |
| 405 } | 392 } |
| 406 | 393 |
| 407 bool ContentDecryptorDelegate::InitializeAudioDecoder( | 394 bool ContentDecryptorDelegate::InitializeAudioDecoder( |
| 408 const media::AudioDecoderConfig& decoder_config, | 395 const media::AudioDecoderConfig& decoder_config, |
| 409 const media::Decryptor::DecoderInitCB& init_cb) { | 396 const Decryptor::DecoderInitCB& init_cb) { |
| 410 PP_AudioDecoderConfig pp_decoder_config; | 397 PP_AudioDecoderConfig pp_decoder_config; |
| 411 pp_decoder_config.codec = | 398 pp_decoder_config.codec = |
| 412 MediaAudioCodecToPpAudioCodec(decoder_config.codec()); | 399 MediaAudioCodecToPpAudioCodec(decoder_config.codec()); |
| 413 pp_decoder_config.channel_count = | 400 pp_decoder_config.channel_count = |
| 414 media::ChannelLayoutToChannelCount(decoder_config.channel_layout()); | 401 media::ChannelLayoutToChannelCount(decoder_config.channel_layout()); |
| 415 pp_decoder_config.bits_per_channel = decoder_config.bits_per_channel(); | 402 pp_decoder_config.bits_per_channel = decoder_config.bits_per_channel(); |
| 416 pp_decoder_config.samples_per_second = decoder_config.samples_per_second(); | 403 pp_decoder_config.samples_per_second = decoder_config.samples_per_second(); |
| 417 pp_decoder_config.request_id = next_decryption_request_id_++; | 404 pp_decoder_config.request_id = next_decryption_request_id_++; |
| 418 | 405 |
| 419 audio_samples_per_second_ = pp_decoder_config.samples_per_second; | 406 audio_samples_per_second_ = pp_decoder_config.samples_per_second; |
| 420 audio_channel_count_ = pp_decoder_config.channel_count; | 407 audio_channel_count_ = pp_decoder_config.channel_count; |
| 421 | 408 |
| 422 scoped_refptr<PPB_Buffer_Impl> extra_data_resource; | 409 scoped_refptr<PPB_Buffer_Impl> extra_data_resource; |
| 423 if (!MakeBufferResource(pp_instance_, | 410 if (!MakeBufferResource(pp_instance_, |
| 424 decoder_config.extra_data(), | 411 decoder_config.extra_data(), |
| 425 decoder_config.extra_data_size(), | 412 decoder_config.extra_data_size(), |
| 426 &extra_data_resource)) { | 413 &extra_data_resource)) { |
| 427 return false; | 414 return false; |
| 428 } | 415 } |
| 429 ScopedPPResource pp_resource(extra_data_resource.get()); | 416 ScopedPPResource pp_resource(extra_data_resource.get()); |
| 430 | 417 |
| 431 DCHECK_EQ(pending_audio_decoder_init_request_id_, 0u); | 418 audio_decoder_init_cb_.Set(pp_decoder_config.request_id, init_cb); |
| 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_, | 419 plugin_decryption_interface_->InitializeAudioDecoder(pp_instance_, |
| 437 &pp_decoder_config, | 420 &pp_decoder_config, |
| 438 pp_resource); | 421 pp_resource); |
| 439 return true; | 422 return true; |
| 440 } | 423 } |
| 441 | 424 |
| 442 bool ContentDecryptorDelegate::InitializeVideoDecoder( | 425 bool ContentDecryptorDelegate::InitializeVideoDecoder( |
| 443 const media::VideoDecoderConfig& decoder_config, | 426 const media::VideoDecoderConfig& decoder_config, |
| 444 const media::Decryptor::DecoderInitCB& init_cb) { | 427 const Decryptor::DecoderInitCB& init_cb) { |
| 445 PP_VideoDecoderConfig pp_decoder_config; | 428 PP_VideoDecoderConfig pp_decoder_config; |
| 446 pp_decoder_config.codec = | 429 pp_decoder_config.codec = |
| 447 MediaVideoCodecToPpVideoCodec(decoder_config.codec()); | 430 MediaVideoCodecToPpVideoCodec(decoder_config.codec()); |
| 448 pp_decoder_config.profile = | 431 pp_decoder_config.profile = |
| 449 MediaVideoCodecProfileToPpVideoCodecProfile(decoder_config.profile()); | 432 MediaVideoCodecProfileToPpVideoCodecProfile(decoder_config.profile()); |
| 450 pp_decoder_config.format = | 433 pp_decoder_config.format = |
| 451 MediaVideoFormatToPpDecryptedFrameFormat(decoder_config.format()); | 434 MediaVideoFormatToPpDecryptedFrameFormat(decoder_config.format()); |
| 452 pp_decoder_config.width = decoder_config.coded_size().width(); | 435 pp_decoder_config.width = decoder_config.coded_size().width(); |
| 453 pp_decoder_config.height = decoder_config.coded_size().height(); | 436 pp_decoder_config.height = decoder_config.coded_size().height(); |
| 454 pp_decoder_config.request_id = next_decryption_request_id_++; | 437 pp_decoder_config.request_id = next_decryption_request_id_++; |
| 455 | 438 |
| 456 scoped_refptr<PPB_Buffer_Impl> extra_data_resource; | 439 scoped_refptr<PPB_Buffer_Impl> extra_data_resource; |
| 457 if (!MakeBufferResource(pp_instance_, | 440 if (!MakeBufferResource(pp_instance_, |
| 458 decoder_config.extra_data(), | 441 decoder_config.extra_data(), |
| 459 decoder_config.extra_data_size(), | 442 decoder_config.extra_data_size(), |
| 460 &extra_data_resource)) { | 443 &extra_data_resource)) { |
| 461 return false; | 444 return false; |
| 462 } | 445 } |
| 463 ScopedPPResource pp_resource(extra_data_resource.get()); | 446 ScopedPPResource pp_resource(extra_data_resource.get()); |
| 464 | 447 |
| 465 DCHECK_EQ(pending_video_decoder_init_request_id_, 0u); | 448 video_decoder_init_cb_.Set(pp_decoder_config.request_id, init_cb); |
| 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(); | 449 natural_size_ = decoder_config.natural_size(); |
| 471 | 450 |
| 472 plugin_decryption_interface_->InitializeVideoDecoder(pp_instance_, | 451 plugin_decryption_interface_->InitializeVideoDecoder(pp_instance_, |
| 473 &pp_decoder_config, | 452 &pp_decoder_config, |
| 474 pp_resource); | 453 pp_resource); |
| 475 return true; | 454 return true; |
| 476 } | 455 } |
| 477 | 456 |
| 478 bool ContentDecryptorDelegate::DeinitializeDecoder( | 457 bool ContentDecryptorDelegate::DeinitializeDecoder( |
| 479 media::Decryptor::StreamType stream_type) { | 458 Decryptor::StreamType stream_type) { |
| 480 CancelDecode(stream_type); | 459 CancelDecode(stream_type); |
| 481 | 460 |
| 482 natural_size_ = gfx::Size(); | 461 natural_size_ = gfx::Size(); |
| 483 | 462 |
| 484 // TODO(tomfinegan): Add decoder deinitialize request tracking, and get | 463 // TODO(tomfinegan): Add decoder deinitialize request tracking, and get |
| 485 // stream type from media stack. | 464 // stream type from media stack. |
| 486 plugin_decryption_interface_->DeinitializeDecoder( | 465 plugin_decryption_interface_->DeinitializeDecoder( |
| 487 pp_instance_, MediaDecryptorStreamTypeToPpStreamType(stream_type), 0); | 466 pp_instance_, MediaDecryptorStreamTypeToPpStreamType(stream_type), 0); |
| 488 return true; | 467 return true; |
| 489 } | 468 } |
| 490 | 469 |
| 491 bool ContentDecryptorDelegate::ResetDecoder( | 470 bool ContentDecryptorDelegate::ResetDecoder(Decryptor::StreamType stream_type) { |
| 492 media::Decryptor::StreamType stream_type) { | |
| 493 CancelDecode(stream_type); | 471 CancelDecode(stream_type); |
| 494 | 472 |
| 495 // TODO(tomfinegan): Add decoder reset request tracking. | 473 // TODO(tomfinegan): Add decoder reset request tracking. |
| 496 plugin_decryption_interface_->ResetDecoder( | 474 plugin_decryption_interface_->ResetDecoder( |
| 497 pp_instance_, MediaDecryptorStreamTypeToPpStreamType(stream_type), 0); | 475 pp_instance_, MediaDecryptorStreamTypeToPpStreamType(stream_type), 0); |
| 498 return true; | 476 return true; |
| 499 } | 477 } |
| 500 | 478 |
| 501 bool ContentDecryptorDelegate::DecryptAndDecodeAudio( | 479 bool ContentDecryptorDelegate::DecryptAndDecodeAudio( |
| 502 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, | 480 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, |
| 503 const media::Decryptor::AudioDecodeCB& audio_decode_cb) { | 481 const Decryptor::AudioDecodeCB& audio_decode_cb) { |
| 504 // |audio_input_resource_| is not being used by the plugin now | 482 // |audio_input_resource_| is not being used by the plugin now |
| 505 // because there is only one pending audio decode request at any time. | 483 // because there is only one pending audio decode request at any time. |
| 506 // This is enforced by the media pipeline. | 484 // This is enforced by the media pipeline. |
| 507 scoped_refptr<PPB_Buffer_Impl> encrypted_resource; | 485 scoped_refptr<PPB_Buffer_Impl> encrypted_resource; |
| 508 if (!MakeMediaBufferResource(media::Decryptor::kAudio, | 486 if (!MakeMediaBufferResource( |
| 509 encrypted_buffer, | 487 Decryptor::kAudio, encrypted_buffer, &encrypted_resource)) { |
| 510 &encrypted_resource)) { | |
| 511 return false; | 488 return false; |
| 512 } | 489 } |
| 513 | 490 |
| 514 // The resource should not be NULL for non-EOS buffer. | 491 // The resource should not be NULL for non-EOS buffer. |
| 515 if (!encrypted_buffer->end_of_stream() && !encrypted_resource.get()) | 492 if (!encrypted_buffer->end_of_stream() && !encrypted_resource.get()) |
| 516 return false; | 493 return false; |
| 517 | 494 |
| 518 const uint32_t request_id = next_decryption_request_id_++; | 495 const uint32_t request_id = next_decryption_request_id_++; |
| 519 DVLOG(2) << "DecryptAndDecodeAudio() - request_id " << request_id; | 496 DVLOG(2) << "DecryptAndDecodeAudio() - request_id " << request_id; |
| 520 | 497 |
| 521 PP_EncryptedBlockInfo block_info = {}; | 498 PP_EncryptedBlockInfo block_info = {}; |
| 522 if (!MakeEncryptedBlockInfo(encrypted_buffer, request_id, &block_info)) { | 499 if (!MakeEncryptedBlockInfo(encrypted_buffer, request_id, &block_info)) { |
| 523 return false; | 500 return false; |
| 524 } | 501 } |
| 525 | 502 |
| 526 SetBufferToFreeInTrackingInfo(&block_info.tracking_info); | 503 SetBufferToFreeInTrackingInfo(&block_info.tracking_info); |
| 527 | 504 |
| 528 // There is only one pending audio decode request at any time. This is | 505 // 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 | 506 // 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 | 507 // reuse policy is not valid, and we may have race problems for the shared |
| 531 // buffer. | 508 // buffer. |
| 532 DCHECK_EQ(pending_audio_decode_request_id_, 0u); | 509 audio_decode_cb_.Set(request_id, audio_decode_cb); |
| 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 | 510 |
| 537 ScopedPPResource pp_resource(encrypted_resource.get()); | 511 ScopedPPResource pp_resource(encrypted_resource.get()); |
| 538 plugin_decryption_interface_->DecryptAndDecode(pp_instance_, | 512 plugin_decryption_interface_->DecryptAndDecode(pp_instance_, |
| 539 PP_DECRYPTORSTREAMTYPE_AUDIO, | 513 PP_DECRYPTORSTREAMTYPE_AUDIO, |
| 540 pp_resource, | 514 pp_resource, |
| 541 &block_info); | 515 &block_info); |
| 542 return true; | 516 return true; |
| 543 } | 517 } |
| 544 | 518 |
| 545 bool ContentDecryptorDelegate::DecryptAndDecodeVideo( | 519 bool ContentDecryptorDelegate::DecryptAndDecodeVideo( |
| 546 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, | 520 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, |
| 547 const media::Decryptor::VideoDecodeCB& video_decode_cb) { | 521 const Decryptor::VideoDecodeCB& video_decode_cb) { |
| 548 // |video_input_resource_| is not being used by the plugin now | 522 // |video_input_resource_| is not being used by the plugin now |
| 549 // because there is only one pending video decode request at any time. | 523 // because there is only one pending video decode request at any time. |
| 550 // This is enforced by the media pipeline. | 524 // This is enforced by the media pipeline. |
| 551 scoped_refptr<PPB_Buffer_Impl> encrypted_resource; | 525 scoped_refptr<PPB_Buffer_Impl> encrypted_resource; |
| 552 if (!MakeMediaBufferResource(media::Decryptor::kVideo, | 526 if (!MakeMediaBufferResource( |
| 553 encrypted_buffer, | 527 Decryptor::kVideo, encrypted_buffer, &encrypted_resource)) { |
|
dmichael (off chromium)
2014/01/03 18:44:43
style nit: I would probably put the first two para
xhwang
2014/01/07 22:40:21
Yeah, this is done by clang-format. Personally I w
| |
| 554 &encrypted_resource)) { | |
| 555 return false; | 528 return false; |
| 556 } | 529 } |
| 557 | 530 |
| 558 // The resource should not be 0 for non-EOS buffer. | 531 // The resource should not be 0 for non-EOS buffer. |
| 559 if (!encrypted_buffer->end_of_stream() && !encrypted_resource.get()) | 532 if (!encrypted_buffer->end_of_stream() && !encrypted_resource.get()) |
| 560 return false; | 533 return false; |
| 561 | 534 |
| 562 const uint32_t request_id = next_decryption_request_id_++; | 535 const uint32_t request_id = next_decryption_request_id_++; |
| 563 DVLOG(2) << "DecryptAndDecodeVideo() - request_id " << request_id; | 536 DVLOG(2) << "DecryptAndDecodeVideo() - request_id " << request_id; |
| 564 TRACE_EVENT_ASYNC_BEGIN0( | 537 TRACE_EVENT_ASYNC_BEGIN0( |
| 565 "media", "ContentDecryptorDelegate::DecryptAndDecodeVideo", request_id); | 538 "media", "ContentDecryptorDelegate::DecryptAndDecodeVideo", request_id); |
| 566 | 539 |
| 567 PP_EncryptedBlockInfo block_info = {}; | 540 PP_EncryptedBlockInfo block_info = {}; |
| 568 if (!MakeEncryptedBlockInfo(encrypted_buffer, request_id, &block_info)) { | 541 if (!MakeEncryptedBlockInfo(encrypted_buffer, request_id, &block_info)) { |
| 569 return false; | 542 return false; |
| 570 } | 543 } |
| 571 | 544 |
| 572 SetBufferToFreeInTrackingInfo(&block_info.tracking_info); | 545 SetBufferToFreeInTrackingInfo(&block_info.tracking_info); |
| 573 | 546 |
| 574 // Only one pending video decode request at any time. This is enforced by the | 547 // Only one pending video decode request at any time. This is enforced by the |
| 575 // media pipeline. If this DCHECK is violated, our buffer | 548 // media pipeline. If this DCHECK is violated, our buffer |
| 576 // reuse policy is not valid, and we may have race problems for the shared | 549 // reuse policy is not valid, and we may have race problems for the shared |
| 577 // buffer. | 550 // buffer. |
| 578 DCHECK_EQ(pending_video_decode_request_id_, 0u); | 551 video_decode_cb_.Set(request_id, video_decode_cb); |
| 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 | 552 |
| 583 // TODO(tomfinegan): Need to get stream type from media stack. | 553 // TODO(tomfinegan): Need to get stream type from media stack. |
| 584 ScopedPPResource pp_resource(encrypted_resource.get()); | 554 ScopedPPResource pp_resource(encrypted_resource.get()); |
| 585 plugin_decryption_interface_->DecryptAndDecode(pp_instance_, | 555 plugin_decryption_interface_->DecryptAndDecode(pp_instance_, |
| 586 PP_DECRYPTORSTREAMTYPE_VIDEO, | 556 PP_DECRYPTORSTREAMTYPE_VIDEO, |
| 587 pp_resource, | 557 pp_resource, |
| 588 &block_info); | 558 &block_info); |
| 589 return true; | 559 return true; |
| 590 } | 560 } |
| 591 | 561 |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 653 system_code); | 623 system_code); |
| 654 } | 624 } |
| 655 | 625 |
| 656 void ContentDecryptorDelegate::DecoderInitializeDone( | 626 void ContentDecryptorDelegate::DecoderInitializeDone( |
| 657 PP_DecryptorStreamType decoder_type, | 627 PP_DecryptorStreamType decoder_type, |
| 658 uint32_t request_id, | 628 uint32_t request_id, |
| 659 PP_Bool success) { | 629 PP_Bool success) { |
| 660 if (decoder_type == PP_DECRYPTORSTREAMTYPE_AUDIO) { | 630 if (decoder_type == PP_DECRYPTORSTREAMTYPE_AUDIO) { |
| 661 // If the request ID is not valid or does not match what's saved, do | 631 // If the request ID is not valid or does not match what's saved, do |
| 662 // nothing. | 632 // nothing. |
| 663 if (request_id == 0 || | 633 if (request_id == 0 || !audio_decoder_init_cb_.Matches(request_id)) |
| 664 request_id != pending_audio_decoder_init_request_id_) | |
| 665 return; | 634 return; |
| 666 | 635 |
| 667 DCHECK(!pending_audio_decoder_init_cb_.is_null()); | 636 audio_decoder_init_cb_.ResetAndReturn().Run(PP_ToBool(success)); |
| 668 pending_audio_decoder_init_request_id_ = 0; | |
| 669 base::ResetAndReturn( | |
| 670 &pending_audio_decoder_init_cb_).Run(PP_ToBool(success)); | |
| 671 } else { | 637 } else { |
| 672 if (request_id == 0 || | 638 if (request_id == 0 || !video_decoder_init_cb_.Matches(request_id)) |
| 673 request_id != pending_video_decoder_init_request_id_) | |
| 674 return; | 639 return; |
| 675 | 640 |
| 676 if (!success) | 641 if (!success) |
| 677 natural_size_ = gfx::Size(); | 642 natural_size_ = gfx::Size(); |
| 678 | 643 |
| 679 DCHECK(!pending_video_decoder_init_cb_.is_null()); | 644 video_decoder_init_cb_.ResetAndReturn().Run(PP_ToBool(success)); |
| 680 pending_video_decoder_init_request_id_ = 0; | |
| 681 base::ResetAndReturn( | |
| 682 &pending_video_decoder_init_cb_).Run(PP_ToBool(success)); | |
| 683 } | 645 } |
| 684 } | 646 } |
| 685 | 647 |
| 686 void ContentDecryptorDelegate::DecoderDeinitializeDone( | 648 void ContentDecryptorDelegate::DecoderDeinitializeDone( |
| 687 PP_DecryptorStreamType decoder_type, | 649 PP_DecryptorStreamType decoder_type, |
| 688 uint32_t request_id) { | 650 uint32_t request_id) { |
| 689 // TODO(tomfinegan): Add decoder stop completion handling. | 651 // TODO(tomfinegan): Add decoder stop completion handling. |
| 690 } | 652 } |
| 691 | 653 |
| 692 void ContentDecryptorDelegate::DecoderResetDone( | 654 void ContentDecryptorDelegate::DecoderResetDone( |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 704 | 666 |
| 705 const uint32_t request_id = block_info->tracking_info.request_id; | 667 const uint32_t request_id = block_info->tracking_info.request_id; |
| 706 DVLOG(2) << "DeliverBlock() - request_id: " << request_id; | 668 DVLOG(2) << "DeliverBlock() - request_id: " << request_id; |
| 707 | 669 |
| 708 // If the request ID is not valid or does not match what's saved, do nothing. | 670 // If the request ID is not valid or does not match what's saved, do nothing. |
| 709 if (request_id == 0) { | 671 if (request_id == 0) { |
| 710 DVLOG(1) << "DeliverBlock() - invalid request_id " << request_id; | 672 DVLOG(1) << "DeliverBlock() - invalid request_id " << request_id; |
| 711 return; | 673 return; |
| 712 } | 674 } |
| 713 | 675 |
| 714 media::Decryptor::DecryptCB decrypt_cb; | 676 Decryptor::DecryptCB decrypt_cb; |
| 715 if (request_id == pending_audio_decrypt_request_id_) { | 677 if (audio_decrypt_cb_.Matches(request_id)) { |
| 716 DCHECK(!pending_audio_decrypt_cb_.is_null()); | 678 decrypt_cb = audio_decrypt_cb_.ResetAndReturn(); |
| 717 pending_audio_decrypt_request_id_ = 0; | 679 } else if (video_decrypt_cb_.Matches(request_id)) { |
| 718 decrypt_cb = base::ResetAndReturn(&pending_audio_decrypt_cb_); | 680 decrypt_cb = video_decrypt_cb_.ResetAndReturn(); |
| 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 { | 681 } else { |
| 724 DVLOG(1) << "DeliverBlock() - request_id " << request_id << " not found"; | 682 DVLOG(1) << "DeliverBlock() - request_id " << request_id << " not found"; |
| 725 return; | 683 return; |
| 726 } | 684 } |
| 727 | 685 |
| 728 media::Decryptor::Status status = | 686 Decryptor::Status status = |
| 729 PpDecryptResultToMediaDecryptorStatus(block_info->result); | 687 PpDecryptResultToMediaDecryptorStatus(block_info->result); |
| 730 if (status != media::Decryptor::kSuccess) { | 688 if (status != Decryptor::kSuccess) { |
| 731 decrypt_cb.Run(status, NULL); | 689 decrypt_cb.Run(status, NULL); |
| 732 return; | 690 return; |
| 733 } | 691 } |
| 734 | 692 |
| 735 EnterResourceNoLock<PPB_Buffer_API> enter(decrypted_block, true); | 693 EnterResourceNoLock<PPB_Buffer_API> enter(decrypted_block, true); |
| 736 if (!enter.succeeded()) { | 694 if (!enter.succeeded()) { |
| 737 decrypt_cb.Run(media::Decryptor::kError, NULL); | 695 decrypt_cb.Run(Decryptor::kError, NULL); |
| 738 return; | 696 return; |
| 739 } | 697 } |
| 740 BufferAutoMapper mapper(enter.object()); | 698 BufferAutoMapper mapper(enter.object()); |
| 741 if (!mapper.data() || !mapper.size() || | 699 if (!mapper.data() || !mapper.size() || |
| 742 mapper.size() < block_info->data_size) { | 700 mapper.size() < block_info->data_size) { |
| 743 decrypt_cb.Run(media::Decryptor::kError, NULL); | 701 decrypt_cb.Run(Decryptor::kError, NULL); |
| 744 return; | 702 return; |
| 745 } | 703 } |
| 746 | 704 |
| 747 // TODO(tomfinegan): Find a way to take ownership of the shared memory | 705 // TODO(tomfinegan): Find a way to take ownership of the shared memory |
| 748 // managed by the PPB_Buffer_Dev, and avoid the extra copy. | 706 // managed by the PPB_Buffer_Dev, and avoid the extra copy. |
| 749 scoped_refptr<media::DecoderBuffer> decrypted_buffer( | 707 scoped_refptr<media::DecoderBuffer> decrypted_buffer( |
| 750 media::DecoderBuffer::CopyFrom( | 708 media::DecoderBuffer::CopyFrom( |
| 751 static_cast<uint8*>(mapper.data()), block_info->data_size)); | 709 static_cast<uint8*>(mapper.data()), block_info->data_size)); |
| 752 decrypted_buffer->set_timestamp(base::TimeDelta::FromMicroseconds( | 710 decrypted_buffer->set_timestamp(base::TimeDelta::FromMicroseconds( |
| 753 block_info->tracking_info.timestamp)); | 711 block_info->tracking_info.timestamp)); |
| 754 decrypt_cb.Run(media::Decryptor::kSuccess, decrypted_buffer); | 712 decrypt_cb.Run(Decryptor::kSuccess, decrypted_buffer); |
| 755 } | 713 } |
| 756 | 714 |
| 757 // Use a non-class-member function here so that if for some reason | 715 // Use a non-class-member function here so that if for some reason |
| 758 // ContentDecryptorDelegate is destroyed before VideoFrame calls this callback, | 716 // ContentDecryptorDelegate is destroyed before VideoFrame calls this callback, |
| 759 // we can still get the shared memory unmapped. | 717 // we can still get the shared memory unmapped. |
| 760 static void BufferNoLongerNeeded( | 718 static void BufferNoLongerNeeded( |
| 761 const scoped_refptr<PPB_Buffer_Impl>& ppb_buffer, | 719 const scoped_refptr<PPB_Buffer_Impl>& ppb_buffer, |
| 762 base::Closure buffer_no_longer_needed_cb) { | 720 base::Closure buffer_no_longer_needed_cb) { |
| 763 ppb_buffer->Unmap(); | 721 ppb_buffer->Unmap(); |
| 764 buffer_no_longer_needed_cb.Run(); | 722 buffer_no_longer_needed_cb.Run(); |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 789 | 747 |
| 790 void ContentDecryptorDelegate::DeliverFrame( | 748 void ContentDecryptorDelegate::DeliverFrame( |
| 791 PP_Resource decrypted_frame, | 749 PP_Resource decrypted_frame, |
| 792 const PP_DecryptedFrameInfo* frame_info) { | 750 const PP_DecryptedFrameInfo* frame_info) { |
| 793 DCHECK(frame_info); | 751 DCHECK(frame_info); |
| 794 | 752 |
| 795 const uint32_t request_id = frame_info->tracking_info.request_id; | 753 const uint32_t request_id = frame_info->tracking_info.request_id; |
| 796 DVLOG(2) << "DeliverFrame() - request_id: " << request_id; | 754 DVLOG(2) << "DeliverFrame() - request_id: " << request_id; |
| 797 | 755 |
| 798 // If the request ID is not valid or does not match what's saved, do nothing. | 756 // 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_) { | 757 if (request_id == 0 || !video_decode_cb_.Matches(request_id)) { |
| 800 DVLOG(1) << "DeliverFrame() - request_id " << request_id << " not found"; | 758 DVLOG(1) << "DeliverFrame() - request_id " << request_id << " not found"; |
| 801 FreeBuffer(frame_info->tracking_info.buffer_id); | 759 FreeBuffer(frame_info->tracking_info.buffer_id); |
| 802 return; | 760 return; |
| 803 } | 761 } |
| 804 | 762 |
| 805 TRACE_EVENT_ASYNC_END0( | 763 TRACE_EVENT_ASYNC_END0( |
| 806 "media", "ContentDecryptorDelegate::DecryptAndDecodeVideo", request_id); | 764 "media", "ContentDecryptorDelegate::DecryptAndDecodeVideo", request_id); |
| 807 | 765 |
| 808 DCHECK(!pending_video_decode_cb_.is_null()); | 766 Decryptor::VideoDecodeCB video_decode_cb = video_decode_cb_.ResetAndReturn(); |
| 809 pending_video_decode_request_id_ = 0; | |
| 810 media::Decryptor::VideoDecodeCB video_decode_cb = | |
| 811 base::ResetAndReturn(&pending_video_decode_cb_); | |
| 812 | 767 |
| 813 media::Decryptor::Status status = | 768 Decryptor::Status status = |
| 814 PpDecryptResultToMediaDecryptorStatus(frame_info->result); | 769 PpDecryptResultToMediaDecryptorStatus(frame_info->result); |
| 815 if (status != media::Decryptor::kSuccess) { | 770 if (status != Decryptor::kSuccess) { |
| 816 DCHECK(!frame_info->tracking_info.buffer_id); | 771 DCHECK(!frame_info->tracking_info.buffer_id); |
| 817 video_decode_cb.Run(status, NULL); | 772 video_decode_cb.Run(status, NULL); |
| 818 return; | 773 return; |
| 819 } | 774 } |
| 820 | 775 |
| 821 scoped_refptr<PPB_Buffer_Impl> ppb_buffer; | 776 scoped_refptr<PPB_Buffer_Impl> ppb_buffer; |
| 822 uint8* frame_data = GetMappedBuffer(decrypted_frame, &ppb_buffer); | 777 uint8* frame_data = GetMappedBuffer(decrypted_frame, &ppb_buffer); |
| 823 if (!frame_data) { | 778 if (!frame_data) { |
| 824 FreeBuffer(frame_info->tracking_info.buffer_id); | 779 FreeBuffer(frame_info->tracking_info.buffer_id); |
| 825 video_decode_cb.Run(media::Decryptor::kError, NULL); | 780 video_decode_cb.Run(Decryptor::kError, NULL); |
| 826 return; | 781 return; |
| 827 } | 782 } |
| 828 | 783 |
| 829 gfx::Size frame_size(frame_info->width, frame_info->height); | 784 gfx::Size frame_size(frame_info->width, frame_info->height); |
| 830 DCHECK_EQ(frame_info->format, PP_DECRYPTEDFRAMEFORMAT_YV12); | 785 DCHECK_EQ(frame_info->format, PP_DECRYPTEDFRAMEFORMAT_YV12); |
| 831 | 786 |
| 832 scoped_refptr<media::VideoFrame> decoded_frame = | 787 scoped_refptr<media::VideoFrame> decoded_frame = |
| 833 media::VideoFrame::WrapExternalYuvData( | 788 media::VideoFrame::WrapExternalYuvData( |
| 834 media::VideoFrame::YV12, | 789 media::VideoFrame::YV12, |
| 835 frame_size, | 790 frame_size, |
| 836 gfx::Rect(frame_size), | 791 gfx::Rect(frame_size), |
| 837 natural_size_, | 792 natural_size_, |
| 838 frame_info->strides[PP_DECRYPTEDFRAMEPLANES_Y], | 793 frame_info->strides[PP_DECRYPTEDFRAMEPLANES_Y], |
| 839 frame_info->strides[PP_DECRYPTEDFRAMEPLANES_U], | 794 frame_info->strides[PP_DECRYPTEDFRAMEPLANES_U], |
| 840 frame_info->strides[PP_DECRYPTEDFRAMEPLANES_V], | 795 frame_info->strides[PP_DECRYPTEDFRAMEPLANES_V], |
| 841 frame_data + frame_info->plane_offsets[PP_DECRYPTEDFRAMEPLANES_Y], | 796 frame_data + frame_info->plane_offsets[PP_DECRYPTEDFRAMEPLANES_Y], |
| 842 frame_data + frame_info->plane_offsets[PP_DECRYPTEDFRAMEPLANES_U], | 797 frame_data + frame_info->plane_offsets[PP_DECRYPTEDFRAMEPLANES_U], |
| 843 frame_data + frame_info->plane_offsets[PP_DECRYPTEDFRAMEPLANES_V], | 798 frame_data + frame_info->plane_offsets[PP_DECRYPTEDFRAMEPLANES_V], |
| 844 base::TimeDelta::FromMicroseconds( | 799 base::TimeDelta::FromMicroseconds( |
| 845 frame_info->tracking_info.timestamp), | 800 frame_info->tracking_info.timestamp), |
| 846 media::BindToLoop( | 801 media::BindToLoop( |
| 847 base::MessageLoopProxy::current(), | 802 base::MessageLoopProxy::current(), |
| 848 base::Bind(&BufferNoLongerNeeded, | 803 base::Bind(&BufferNoLongerNeeded, |
| 849 ppb_buffer, | 804 ppb_buffer, |
| 850 base::Bind(&ContentDecryptorDelegate::FreeBuffer, | 805 base::Bind(&ContentDecryptorDelegate::FreeBuffer, |
| 851 weak_this_, | 806 weak_this_, |
| 852 frame_info->tracking_info.buffer_id)))); | 807 frame_info->tracking_info.buffer_id)))); |
| 853 | 808 |
| 854 video_decode_cb.Run(media::Decryptor::kSuccess, decoded_frame); | 809 video_decode_cb.Run(Decryptor::kSuccess, decoded_frame); |
| 855 } | 810 } |
| 856 | 811 |
| 857 void ContentDecryptorDelegate::DeliverSamples( | 812 void ContentDecryptorDelegate::DeliverSamples( |
| 858 PP_Resource audio_frames, | 813 PP_Resource audio_frames, |
| 859 const PP_DecryptedSampleInfo* sample_info) { | 814 const PP_DecryptedSampleInfo* sample_info) { |
| 860 DCHECK(sample_info); | 815 DCHECK(sample_info); |
| 861 | 816 |
| 862 FreeBuffer(sample_info->tracking_info.buffer_id); | 817 FreeBuffer(sample_info->tracking_info.buffer_id); |
| 863 | 818 |
| 864 const uint32_t request_id = sample_info->tracking_info.request_id; | 819 const uint32_t request_id = sample_info->tracking_info.request_id; |
| 865 DVLOG(2) << "DeliverSamples() - request_id: " << request_id; | 820 DVLOG(2) << "DeliverSamples() - request_id: " << request_id; |
| 866 | 821 |
| 867 // If the request ID is not valid or does not match what's saved, do nothing. | 822 // 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_) { | 823 if (request_id == 0 || !audio_decode_cb_.Matches(request_id)) { |
| 869 DVLOG(1) << "DeliverSamples() - request_id " << request_id << " not found"; | 824 DVLOG(1) << "DeliverSamples() - request_id " << request_id << " not found"; |
| 870 return; | 825 return; |
| 871 } | 826 } |
| 872 | 827 |
| 873 DCHECK(!pending_audio_decode_cb_.is_null()); | 828 Decryptor::AudioDecodeCB audio_decode_cb = audio_decode_cb_.ResetAndReturn(); |
| 874 pending_audio_decode_request_id_ = 0; | |
| 875 media::Decryptor::AudioDecodeCB audio_decode_cb = | |
| 876 base::ResetAndReturn(&pending_audio_decode_cb_); | |
| 877 | 829 |
| 878 const media::Decryptor::AudioBuffers empty_frames; | 830 const Decryptor::AudioBuffers empty_frames; |
| 879 | 831 |
| 880 media::Decryptor::Status status = | 832 Decryptor::Status status = |
| 881 PpDecryptResultToMediaDecryptorStatus(sample_info->result); | 833 PpDecryptResultToMediaDecryptorStatus(sample_info->result); |
| 882 if (status != media::Decryptor::kSuccess) { | 834 if (status != Decryptor::kSuccess) { |
| 883 audio_decode_cb.Run(status, empty_frames); | 835 audio_decode_cb.Run(status, empty_frames); |
| 884 return; | 836 return; |
| 885 } | 837 } |
| 886 | 838 |
| 887 media::SampleFormat sample_format = | 839 media::SampleFormat sample_format = |
| 888 PpDecryptedSampleFormatToMediaSampleFormat(sample_info->format); | 840 PpDecryptedSampleFormatToMediaSampleFormat(sample_info->format); |
| 889 | 841 |
| 890 media::Decryptor::AudioBuffers audio_frame_list; | 842 Decryptor::AudioBuffers audio_frame_list; |
| 891 if (!DeserializeAudioFrames(audio_frames, | 843 if (!DeserializeAudioFrames(audio_frames, |
| 892 sample_info->data_size, | 844 sample_info->data_size, |
| 893 sample_format, | 845 sample_format, |
| 894 &audio_frame_list)) { | 846 &audio_frame_list)) { |
| 895 NOTREACHED() << "CDM did not serialize the buffer correctly."; | 847 NOTREACHED() << "CDM did not serialize the buffer correctly."; |
| 896 audio_decode_cb.Run(media::Decryptor::kError, empty_frames); | 848 audio_decode_cb.Run(Decryptor::kError, empty_frames); |
| 897 return; | 849 return; |
| 898 } | 850 } |
| 899 | 851 |
| 900 audio_decode_cb.Run(media::Decryptor::kSuccess, audio_frame_list); | 852 audio_decode_cb.Run(Decryptor::kSuccess, audio_frame_list); |
| 901 } | 853 } |
| 902 | 854 |
| 903 // TODO(xhwang): Try to remove duplicate logic here and in CancelDecrypt(). | 855 // TODO(xhwang): Try to remove duplicate logic here and in CancelDecrypt(). |
| 904 void ContentDecryptorDelegate::CancelDecode( | 856 void ContentDecryptorDelegate::CancelDecode(Decryptor::StreamType stream_type) { |
| 905 media::Decryptor::StreamType stream_type) { | |
| 906 switch (stream_type) { | 857 switch (stream_type) { |
| 907 case media::Decryptor::kAudio: | 858 case Decryptor::kAudio: |
| 908 // Release the shared memory as it can still be in use by the plugin. | 859 // 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 | 860 // The next DecryptAndDecode() call will need to allocate a new shared |
| 910 // memory buffer. | 861 // memory buffer. |
| 911 audio_input_resource_ = NULL; | 862 audio_input_resource_ = NULL; |
| 912 pending_audio_decode_request_id_ = 0; | 863 if (!audio_decode_cb_.is_null()) |
| 913 if (!pending_audio_decode_cb_.is_null()) | 864 audio_decode_cb_.ResetAndReturn().Run(Decryptor::kSuccess, |
| 914 base::ResetAndReturn(&pending_audio_decode_cb_).Run( | 865 Decryptor::AudioBuffers()); |
| 915 media::Decryptor::kSuccess, media::Decryptor::AudioBuffers()); | |
| 916 break; | 866 break; |
| 917 case media::Decryptor::kVideo: | 867 case Decryptor::kVideo: |
| 918 // Release the shared memory as it can still be in use by the plugin. | 868 // 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 | 869 // The next DecryptAndDecode() call will need to allocate a new shared |
| 920 // memory buffer. | 870 // memory buffer. |
| 921 video_input_resource_ = NULL; | 871 video_input_resource_ = NULL; |
| 922 pending_video_decode_request_id_ = 0; | 872 if (!video_decode_cb_.is_null()) |
| 923 if (!pending_video_decode_cb_.is_null()) | 873 video_decode_cb_.ResetAndReturn().Run(Decryptor::kSuccess, NULL); |
| 924 base::ResetAndReturn(&pending_video_decode_cb_).Run( | |
| 925 media::Decryptor::kSuccess, NULL); | |
| 926 break; | 874 break; |
| 927 default: | 875 default: |
| 928 NOTREACHED(); | 876 NOTREACHED(); |
| 929 } | 877 } |
| 930 } | 878 } |
| 931 | 879 |
| 932 bool ContentDecryptorDelegate::MakeMediaBufferResource( | 880 bool ContentDecryptorDelegate::MakeMediaBufferResource( |
| 933 media::Decryptor::StreamType stream_type, | 881 Decryptor::StreamType stream_type, |
| 934 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, | 882 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, |
| 935 scoped_refptr<PPB_Buffer_Impl>* resource) { | 883 scoped_refptr<PPB_Buffer_Impl>* resource) { |
| 936 TRACE_EVENT0("media", "ContentDecryptorDelegate::MakeMediaBufferResource"); | 884 TRACE_EVENT0("media", "ContentDecryptorDelegate::MakeMediaBufferResource"); |
| 937 | 885 |
| 938 // End of stream buffers are represented as null resources. | 886 // End of stream buffers are represented as null resources. |
| 939 if (encrypted_buffer->end_of_stream()) { | 887 if (encrypted_buffer->end_of_stream()) { |
| 940 *resource = NULL; | 888 *resource = NULL; |
| 941 return true; | 889 return true; |
| 942 } | 890 } |
| 943 | 891 |
| 944 DCHECK(stream_type == media::Decryptor::kAudio || | 892 DCHECK(stream_type == Decryptor::kAudio || stream_type == Decryptor::kVideo); |
| 945 stream_type == media::Decryptor::kVideo); | |
| 946 scoped_refptr<PPB_Buffer_Impl>& media_resource = | 893 scoped_refptr<PPB_Buffer_Impl>& media_resource = |
| 947 (stream_type == media::Decryptor::kAudio) ? audio_input_resource_ : | 894 (stream_type == Decryptor::kAudio) ? audio_input_resource_ |
| 948 video_input_resource_; | 895 : video_input_resource_; |
| 949 | 896 |
| 950 const size_t data_size = static_cast<size_t>(encrypted_buffer->data_size()); | 897 const size_t data_size = static_cast<size_t>(encrypted_buffer->data_size()); |
| 951 if (!media_resource.get() || media_resource->size() < data_size) { | 898 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 | 899 // Either the buffer hasn't been created yet, or we have one that isn't big |
| 953 // enough to fit |size| bytes. | 900 // enough to fit |size| bytes. |
| 954 | 901 |
| 955 // Media resource size starts from |kMinimumMediaBufferSize| and grows | 902 // Media resource size starts from |kMinimumMediaBufferSize| and grows |
| 956 // exponentially to avoid frequent re-allocation of PPB_Buffer_Impl, | 903 // exponentially to avoid frequent re-allocation of PPB_Buffer_Impl, |
| 957 // which is usually expensive. Since input media buffers are compressed, | 904 // which is usually expensive. Since input media buffers are compressed, |
| 958 // they are usually small (compared to outputs). The over-allocated memory | 905 // they are usually small (compared to outputs). The over-allocated memory |
| 959 // should be negligible. | 906 // should be negligible. |
| 960 const uint32_t kMinimumMediaBufferSize = 1024; | 907 const uint32_t kMinimumMediaBufferSize = 1024; |
| 961 uint32_t media_resource_size = | 908 uint32_t media_resource_size = |
| 962 media_resource.get() ? media_resource->size() : kMinimumMediaBufferSize; | 909 media_resource.get() ? media_resource->size() : kMinimumMediaBufferSize; |
| 963 while (media_resource_size < data_size) | 910 while (media_resource_size < data_size) |
| 964 media_resource_size *= 2; | 911 media_resource_size *= 2; |
| 965 | 912 |
| 966 DVLOG(2) << "Size of media buffer for " | 913 DVLOG(2) << "Size of media buffer for " |
| 967 << ((stream_type == media::Decryptor::kAudio) ? "audio" : "video") | 914 << ((stream_type == Decryptor::kAudio) ? "audio" : "video") |
| 968 << " stream bumped to " << media_resource_size | 915 << " stream bumped to " << media_resource_size |
| 969 << " bytes to fit input."; | 916 << " bytes to fit input."; |
| 970 media_resource = PPB_Buffer_Impl::CreateResource(pp_instance_, | 917 media_resource = PPB_Buffer_Impl::CreateResource(pp_instance_, |
| 971 media_resource_size); | 918 media_resource_size); |
| 972 if (!media_resource.get()) | 919 if (!media_resource.get()) |
| 973 return false; | 920 return false; |
| 974 } | 921 } |
| 975 | 922 |
| 976 BufferAutoMapper mapper(media_resource.get()); | 923 BufferAutoMapper mapper(media_resource.get()); |
| 977 if (!mapper.data() || mapper.size() < data_size) { | 924 if (!mapper.data() || mapper.size() < data_size) { |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 997 return; | 944 return; |
| 998 | 945 |
| 999 tracking_info->buffer_id = free_buffers_.front(); | 946 tracking_info->buffer_id = free_buffers_.front(); |
| 1000 free_buffers_.pop(); | 947 free_buffers_.pop(); |
| 1001 } | 948 } |
| 1002 | 949 |
| 1003 bool ContentDecryptorDelegate::DeserializeAudioFrames( | 950 bool ContentDecryptorDelegate::DeserializeAudioFrames( |
| 1004 PP_Resource audio_frames, | 951 PP_Resource audio_frames, |
| 1005 size_t data_size, | 952 size_t data_size, |
| 1006 media::SampleFormat sample_format, | 953 media::SampleFormat sample_format, |
| 1007 media::Decryptor::AudioBuffers* frames) { | 954 Decryptor::AudioBuffers* frames) { |
| 1008 DCHECK(frames); | 955 DCHECK(frames); |
| 1009 EnterResourceNoLock<PPB_Buffer_API> enter(audio_frames, true); | 956 EnterResourceNoLock<PPB_Buffer_API> enter(audio_frames, true); |
| 1010 if (!enter.succeeded()) | 957 if (!enter.succeeded()) |
| 1011 return false; | 958 return false; |
| 1012 | 959 |
| 1013 BufferAutoMapper mapper(enter.object()); | 960 BufferAutoMapper mapper(enter.object()); |
| 1014 if (!mapper.data() || !mapper.size() || | 961 if (!mapper.data() || !mapper.size() || |
| 1015 mapper.size() < static_cast<uint32_t>(data_size)) | 962 mapper.size() < static_cast<uint32_t>(data_size)) |
| 1016 return false; | 963 return false; |
| 1017 | 964 |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1068 frames->push_back(frame); | 1015 frames->push_back(frame); |
| 1069 | 1016 |
| 1070 cur += frame_size; | 1017 cur += frame_size; |
| 1071 bytes_left -= frame_size; | 1018 bytes_left -= frame_size; |
| 1072 } while (bytes_left > 0); | 1019 } while (bytes_left > 0); |
| 1073 | 1020 |
| 1074 return true; | 1021 return true; |
| 1075 } | 1022 } |
| 1076 | 1023 |
| 1077 } // namespace content | 1024 } // namespace content |
| OLD | NEW |