Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" | 5 #include "webkit/plugins/ppapi/ppapi_plugin_instance.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/callback_helpers.h" | |
| 8 #include "base/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" |
| 9 #include "base/logging.h" | 10 #include "base/logging.h" |
| 10 #include "base/memory/linked_ptr.h" | 11 #include "base/memory/linked_ptr.h" |
| 11 #include "base/message_loop.h" | 12 #include "base/message_loop.h" |
| 12 #include "base/stl_util.h" | 13 #include "base/stl_util.h" |
| 13 #include "base/stringprintf.h" | 14 #include "base/stringprintf.h" |
| 14 #include "base/time.h" | 15 #include "base/time.h" |
| 15 #include "base/utf_offset_string_conversions.h" | 16 #include "base/utf_offset_string_conversions.h" |
| 16 #include "base/utf_string_conversions.h" | 17 #include "base/utf_string_conversions.h" |
| 17 #include "media/base/decoder_buffer.h" | 18 #include "media/base/decoder_buffer.h" |
| 18 #include "media/base/decryptor_client.h" | 19 #include "media/base/decryptor_client.h" |
| 20 #include "media/base/video_util.h" | |
| 19 #include "ppapi/c/dev/ppb_find_dev.h" | 21 #include "ppapi/c/dev/ppb_find_dev.h" |
| 20 #include "ppapi/c/dev/ppb_zoom_dev.h" | 22 #include "ppapi/c/dev/ppb_zoom_dev.h" |
| 21 #include "ppapi/c/dev/ppp_find_dev.h" | 23 #include "ppapi/c/dev/ppp_find_dev.h" |
| 22 #include "ppapi/c/dev/ppp_selection_dev.h" | 24 #include "ppapi/c/dev/ppp_selection_dev.h" |
| 23 #include "ppapi/c/dev/ppp_text_input_dev.h" | 25 #include "ppapi/c/dev/ppp_text_input_dev.h" |
| 24 #include "ppapi/c/dev/ppp_zoom_dev.h" | 26 #include "ppapi/c/dev/ppp_zoom_dev.h" |
| 25 #include "ppapi/c/pp_rect.h" | 27 #include "ppapi/c/pp_rect.h" |
| 26 #include "ppapi/c/ppb_audio_config.h" | 28 #include "ppapi/c/ppb_audio_config.h" |
| 27 #include "ppapi/c/ppb_core.h" | 29 #include "ppapi/c/ppb_core.h" |
| 28 #include "ppapi/c/ppb_gamepad.h" | 30 #include "ppapi/c/ppb_gamepad.h" |
| (...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 447 filtered_input_event_mask_(0), | 449 filtered_input_event_mask_(0), |
| 448 text_input_type_(kPluginDefaultTextInputType), | 450 text_input_type_(kPluginDefaultTextInputType), |
| 449 text_input_caret_(0, 0, 0, 0), | 451 text_input_caret_(0, 0, 0, 0), |
| 450 text_input_caret_bounds_(0, 0, 0, 0), | 452 text_input_caret_bounds_(0, 0, 0, 0), |
| 451 text_input_caret_set_(false), | 453 text_input_caret_set_(false), |
| 452 selection_caret_(0), | 454 selection_caret_(0), |
| 453 selection_anchor_(0), | 455 selection_anchor_(0), |
| 454 pending_user_gesture_(0.0), | 456 pending_user_gesture_(0.0), |
| 455 flash_impl_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), | 457 flash_impl_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
| 456 decryptor_client_(NULL), | 458 decryptor_client_(NULL), |
| 457 next_decryption_request_id_(1) { | 459 next_decryption_request_id_(1), |
| 460 pending_video_decode_request_id_(0) { | |
| 458 pp_instance_ = HostGlobals::Get()->AddInstance(this); | 461 pp_instance_ = HostGlobals::Get()->AddInstance(this); |
| 459 | 462 |
| 460 memset(¤t_print_settings_, 0, sizeof(current_print_settings_)); | 463 memset(¤t_print_settings_, 0, sizeof(current_print_settings_)); |
| 461 DCHECK(delegate); | 464 DCHECK(delegate); |
| 462 module_->InstanceCreated(this); | 465 module_->InstanceCreated(this); |
| 463 delegate_->InstanceCreated(this); | 466 delegate_->InstanceCreated(this); |
| 464 message_channel_.reset(new MessageChannel(this)); | 467 message_channel_.reset(new MessageChannel(this)); |
| 465 | 468 |
| 466 view_data_.is_page_visible = delegate->IsPageVisible(); | 469 view_data_.is_page_visible = delegate->IsPageVisible(); |
| 467 | 470 |
| (...skipping 1052 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1520 | 1523 |
| 1521 ScopedPPResource encrypted_resource( | 1524 ScopedPPResource encrypted_resource( |
| 1522 ScopedPPResource::PassRef(), | 1525 ScopedPPResource::PassRef(), |
| 1523 MakeBufferResource(pp_instance(), | 1526 MakeBufferResource(pp_instance(), |
| 1524 encrypted_buffer->GetData(), | 1527 encrypted_buffer->GetData(), |
| 1525 encrypted_buffer->GetDataSize())); | 1528 encrypted_buffer->GetDataSize())); |
| 1526 if (!encrypted_resource.get()) | 1529 if (!encrypted_resource.get()) |
| 1527 return false; | 1530 return false; |
| 1528 | 1531 |
| 1529 uint32_t request_id = next_decryption_request_id_++; | 1532 uint32_t request_id = next_decryption_request_id_++; |
| 1533 if (next_decryption_request_id_ == 0) | |
| 1534 next_decryption_request_id_++; | |
|
xhwang
2012/10/09 22:29:32
Okay, it took a user to watch a 60fps movie for 2
| |
| 1530 | 1535 |
| 1531 PP_EncryptedBlockInfo block_info; | 1536 PP_EncryptedBlockInfo block_info; |
| 1532 DCHECK(encrypted_buffer->GetDecryptConfig()); | 1537 DCHECK(encrypted_buffer->GetDecryptConfig()); |
| 1533 if (!MakeEncryptedBlockInfo(*encrypted_buffer->GetDecryptConfig(), | 1538 if (!MakeEncryptedBlockInfo(*encrypted_buffer->GetDecryptConfig(), |
| 1534 encrypted_buffer->GetTimestamp().InMicroseconds(), | 1539 encrypted_buffer->GetTimestamp().InMicroseconds(), |
| 1535 request_id, | 1540 request_id, |
| 1536 &block_info)) { | 1541 &block_info)) { |
| 1537 return false; | 1542 return false; |
| 1538 } | 1543 } |
| 1539 | 1544 |
| 1540 DCHECK(!ContainsKey(pending_decryption_cbs_, request_id)); | 1545 DCHECK(!ContainsKey(pending_decryption_cbs_, request_id)); |
| 1541 pending_decryption_cbs_.insert(std::make_pair(request_id, decrypt_cb)); | 1546 pending_decryption_cbs_.insert(std::make_pair(request_id, decrypt_cb)); |
| 1542 | 1547 |
| 1543 plugin_decryption_interface_->Decrypt(pp_instance(), | 1548 plugin_decryption_interface_->Decrypt(pp_instance(), |
| 1544 encrypted_resource, | 1549 encrypted_resource, |
| 1545 &block_info); | 1550 &block_info); |
| 1546 return true; | 1551 return true; |
| 1547 } | 1552 } |
| 1548 | 1553 |
| 1549 // Note: this method can be used with an unencrypted frame. | 1554 // Note: this method can be used with an unencrypted frame. |
| 1550 bool PluginInstance::DecryptAndDecodeFrame( | 1555 bool PluginInstance::DecryptAndDecodeFrame( |
| 1551 const scoped_refptr<media::DecoderBuffer>& encrypted_frame, | 1556 const scoped_refptr<media::DecoderBuffer>& encrypted_frame, |
| 1552 const media::Decryptor::DecryptCB& decrypt_cb) { | 1557 const media::Decryptor::VideoDecodeCB& video_decode_cb) { |
| 1553 if (!LoadContentDecryptorInterface()) | 1558 if (!LoadContentDecryptorInterface()) |
| 1554 return false; | 1559 return false; |
| 1555 | 1560 |
| 1556 ScopedPPResource encrypted_resource(MakeBufferResource( | 1561 ScopedPPResource encrypted_resource(MakeBufferResource( |
| 1557 pp_instance(), | 1562 pp_instance(), |
| 1558 encrypted_frame->GetData(), | 1563 encrypted_frame->GetData(), |
| 1559 encrypted_frame->GetDataSize())); | 1564 encrypted_frame->GetDataSize())); |
| 1560 if (!encrypted_resource.get()) | 1565 if (!encrypted_resource.get()) |
| 1561 return false; | 1566 return false; |
| 1562 | 1567 |
| 1563 const uint32_t request_id = next_decryption_request_id_++; | 1568 uint32_t request_id = next_decryption_request_id_++; |
| 1569 if (next_decryption_request_id_ == 0) | |
| 1570 next_decryption_request_id_++; | |
| 1564 | 1571 |
| 1565 // TODO(tomfinegan): Need to get the video format information here somehow. | 1572 // TODO(tomfinegan): Need to get the video format information here somehow. |
| 1566 PP_EncryptedVideoFrameInfo frame_info; | 1573 PP_EncryptedVideoFrameInfo frame_info; |
| 1567 frame_info.width = 0; | 1574 frame_info.width = 0; |
| 1568 frame_info.height = 0; | 1575 frame_info.height = 0; |
| 1569 frame_info.format = PP_DECRYPTEDFRAMEFORMAT_UNKNOWN; | 1576 frame_info.format = PP_DECRYPTEDFRAMEFORMAT_UNKNOWN; |
| 1570 frame_info.codec = PP_VIDEOCODEC_UNKNOWN; | 1577 frame_info.codec = PP_VIDEOCODEC_UNKNOWN; |
| 1571 | 1578 |
| 1572 DCHECK(encrypted_frame->GetDecryptConfig()); | 1579 DCHECK(encrypted_frame->GetDecryptConfig()); |
| 1573 if (!MakeEncryptedBlockInfo(*encrypted_frame->GetDecryptConfig(), | 1580 if (!MakeEncryptedBlockInfo(*encrypted_frame->GetDecryptConfig(), |
| 1574 encrypted_frame->GetTimestamp().InMicroseconds(), | 1581 encrypted_frame->GetTimestamp().InMicroseconds(), |
| 1575 request_id, | 1582 request_id, |
| 1576 &frame_info.encryption_info)) { | 1583 &frame_info.encryption_info)) { |
| 1577 return false; | 1584 return false; |
| 1578 } | 1585 } |
| 1579 | 1586 |
| 1580 DCHECK(!ContainsKey(pending_decryption_cbs_, request_id)); | 1587 // Only one pending video decode request at any time. This is enforced by the |
| 1581 pending_decryption_cbs_.insert(std::make_pair(request_id, decrypt_cb)); | 1588 // media pipeline. |
| 1589 DCHECK_EQ(pending_video_decode_request_id_, 0u); | |
| 1590 DCHECK(pending_video_decode_cb_.is_null()); | |
| 1591 pending_video_decode_request_id_ = request_id; | |
| 1592 pending_video_decode_cb_ = video_decode_cb; | |
| 1582 | 1593 |
| 1583 plugin_decryption_interface_->DecryptAndDecodeFrame(pp_instance(), | 1594 plugin_decryption_interface_->DecryptAndDecodeFrame(pp_instance(), |
| 1584 encrypted_resource, | 1595 encrypted_resource, |
| 1585 &frame_info); | 1596 &frame_info); |
| 1586 return true; | 1597 return true; |
| 1587 } | 1598 } |
| 1588 | 1599 |
| 1589 bool PluginInstance::FlashIsFullscreenOrPending() { | 1600 bool PluginInstance::FlashIsFullscreenOrPending() { |
| 1590 return fullscreen_container_ != NULL; | 1601 return fullscreen_container_ != NULL; |
| 1591 } | 1602 } |
| (...skipping 695 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2287 block_info->tracking_info.request_id); | 2298 block_info->tracking_info.request_id); |
| 2288 if (found == pending_decryption_cbs_.end()) | 2299 if (found == pending_decryption_cbs_.end()) |
| 2289 return; | 2300 return; |
| 2290 media::Decryptor::DecryptCB decrypt_cb = found->second; | 2301 media::Decryptor::DecryptCB decrypt_cb = found->second; |
| 2291 pending_decryption_cbs_.erase(found); | 2302 pending_decryption_cbs_.erase(found); |
| 2292 | 2303 |
| 2293 if (block_info->result == PP_DECRYPTRESULT_DECRYPT_NOKEY) { | 2304 if (block_info->result == PP_DECRYPTRESULT_DECRYPT_NOKEY) { |
| 2294 decrypt_cb.Run(media::Decryptor::kNoKey, NULL); | 2305 decrypt_cb.Run(media::Decryptor::kNoKey, NULL); |
| 2295 return; | 2306 return; |
| 2296 } | 2307 } |
| 2308 | |
| 2297 if (block_info->result != PP_DECRYPTRESULT_SUCCESS) { | 2309 if (block_info->result != PP_DECRYPTRESULT_SUCCESS) { |
| 2298 decrypt_cb.Run(media::Decryptor::kError, NULL); | 2310 decrypt_cb.Run(media::Decryptor::kError, NULL); |
| 2299 return; | 2311 return; |
| 2300 } | 2312 } |
| 2301 | 2313 |
| 2302 EnterResourceNoLock<PPB_Buffer_API> enter(decrypted_block, true); | 2314 EnterResourceNoLock<PPB_Buffer_API> enter(decrypted_block, true); |
| 2303 if (!enter.succeeded()) { | 2315 if (!enter.succeeded()) { |
| 2304 decrypt_cb.Run(media::Decryptor::kError, NULL); | 2316 decrypt_cb.Run(media::Decryptor::kError, NULL); |
| 2305 return; | 2317 return; |
| 2306 } | 2318 } |
| 2307 BufferAutoMapper mapper(enter.object()); | 2319 BufferAutoMapper mapper(enter.object()); |
| 2308 if (!mapper.data() || !mapper.size()) { | 2320 if (!mapper.data() || !mapper.size()) { |
| 2309 decrypt_cb.Run(media::Decryptor::kError, NULL); | 2321 decrypt_cb.Run(media::Decryptor::kError, NULL); |
| 2310 return; | 2322 return; |
| 2311 } | 2323 } |
| 2312 | 2324 |
| 2313 // TODO(tomfinegan): Find a way to take ownership of the shared memory | 2325 // TODO(tomfinegan): Find a way to take ownership of the shared memory |
| 2314 // managed by the PPB_Buffer_Dev, and avoid the extra copy. | 2326 // managed by the PPB_Buffer_Dev, and avoid the extra copy. |
| 2315 scoped_refptr<media::DecoderBuffer> decrypted_buffer( | 2327 scoped_refptr<media::DecoderBuffer> decrypted_buffer( |
| 2316 media::DecoderBuffer::CopyFrom( | 2328 media::DecoderBuffer::CopyFrom( |
| 2317 reinterpret_cast<const uint8*>(mapper.data()), mapper.size())); | 2329 reinterpret_cast<const uint8*>(mapper.data()), mapper.size())); |
| 2318 decrypted_buffer->SetTimestamp(base::TimeDelta::FromMicroseconds( | 2330 decrypted_buffer->SetTimestamp(base::TimeDelta::FromMicroseconds( |
| 2319 block_info->tracking_info.timestamp)); | 2331 block_info->tracking_info.timestamp)); |
| 2320 decrypt_cb.Run(media::Decryptor::kSuccess, decrypted_buffer); | 2332 decrypt_cb.Run(media::Decryptor::kSuccess, decrypted_buffer); |
| 2321 } | 2333 } |
| 2322 | 2334 |
| 2323 void PluginInstance::DeliverFrame(PP_Instance instance, | 2335 void PluginInstance::DeliverFrame(PP_Instance instance, |
| 2324 PP_Resource decrypted_frame, | 2336 PP_Resource decrypted_frame, |
| 2325 const PP_DecryptedFrameInfo* frame_info) { | 2337 const PP_DecryptedFrameInfo* frame_info) { |
| 2326 // TODO(tomfinegan): To be implemented after completion of v0.1 of the | 2338 DCHECK(frame_info); |
| 2327 // EME/CDM work. | 2339 uint32_t request_id = frame_info->tracking_info.request_id; |
| 2340 | |
| 2341 // If the request ID is not valid or does not match what's saved, do nothing. | |
| 2342 if (request_id == 0 || request_id != pending_video_decode_request_id_) | |
| 2343 return; | |
| 2344 | |
| 2345 DCHECK(!pending_video_decode_cb_.is_null()); | |
| 2346 pending_video_decode_request_id_ = 0; | |
| 2347 media::Decryptor::VideoDecodeCB video_decode_cb = | |
| 2348 base::ResetAndReturn(&pending_video_decode_cb_); | |
| 2349 | |
| 2350 if (frame_info->result == PP_DECRYPTRESULT_DECRYPT_NOKEY) { | |
| 2351 video_decode_cb.Run(media::Decryptor::kNoKey, NULL); | |
| 2352 return; | |
| 2353 } | |
| 2354 | |
| 2355 if (frame_info->result != PP_DECRYPTRESULT_SUCCESS) { | |
| 2356 video_decode_cb.Run(media::Decryptor::kError, NULL); | |
| 2357 return; | |
| 2358 } | |
| 2359 | |
| 2360 EnterResourceNoLock<PPB_Buffer_API> enter(decrypted_frame, true); | |
| 2361 if (!enter.succeeded()) { | |
| 2362 video_decode_cb.Run(media::Decryptor::kError, NULL); | |
| 2363 return; | |
| 2364 } | |
| 2365 BufferAutoMapper mapper(enter.object()); | |
| 2366 if (!mapper.data() || !mapper.size()) { | |
| 2367 video_decode_cb.Run(media::Decryptor::kError, NULL); | |
| 2368 return; | |
| 2369 } | |
| 2370 | |
| 2371 const uint8* frame_data = reinterpret_cast<uint8*>(mapper.data()); | |
| 2372 | |
| 2373 // TODO(tomfinegan): Find a way to take ownership of the shared memory | |
| 2374 // managed by the PPB_Buffer_Dev, and avoid the extra copy. | |
| 2375 DCHECK(frame_info->format == PP_DECRYPTEDFRAMEFORMAT_YV12); | |
| 2376 gfx::Size frame_size(frame_info->width, frame_info->height); | |
| 2377 scoped_refptr<media::VideoFrame> decoded_frame( | |
| 2378 media::VideoFrame::CreateFrame( | |
| 2379 media::VideoFrame::YV12, frame_size, frame_size, | |
| 2380 base::TimeDelta::FromMicroseconds( | |
| 2381 frame_info->tracking_info.timestamp))); | |
| 2382 | |
| 2383 media::CopyYPlane( | |
| 2384 frame_data + frame_info->plane_offsets[PP_DECRYPTEDFRAMEPLANES_Y], | |
| 2385 frame_info->strides[PP_DECRYPTEDFRAMEPLANES_Y], | |
| 2386 frame_info->height, | |
| 2387 decoded_frame.get()); | |
| 2388 | |
| 2389 media::CopyUPlane( | |
| 2390 frame_data + frame_info->plane_offsets[PP_DECRYPTEDFRAMEPLANES_U], | |
| 2391 frame_info->strides[PP_DECRYPTEDFRAMEPLANES_U], | |
| 2392 frame_info->height, | |
| 2393 decoded_frame.get()); | |
| 2394 | |
| 2395 media::CopyVPlane( | |
| 2396 frame_data + frame_info->plane_offsets[PP_DECRYPTEDFRAMEPLANES_V], | |
| 2397 frame_info->strides[PP_DECRYPTEDFRAMEPLANES_V], | |
| 2398 frame_info->height, | |
| 2399 decoded_frame.get()); | |
| 2400 | |
| 2401 video_decode_cb.Run(media::Decryptor::kSuccess, decoded_frame); | |
| 2328 } | 2402 } |
| 2329 | 2403 |
| 2330 void PluginInstance::DeliverSamples(PP_Instance instance, | 2404 void PluginInstance::DeliverSamples(PP_Instance instance, |
| 2331 PP_Resource decrypted_samples, | 2405 PP_Resource decrypted_samples, |
| 2332 const PP_DecryptedBlockInfo* block_info) { | 2406 const PP_DecryptedBlockInfo* block_info) { |
| 2333 // TODO(tomfinegan): To be implemented after completion of v0.1 of the | 2407 // TODO(tomfinegan): To be implemented after completion of v0.1 of the |
| 2334 // EME/CDM work. | 2408 // EME/CDM work. |
| 2335 } | 2409 } |
| 2336 | 2410 |
| 2337 void PluginInstance::NumberOfFindResultsChanged(PP_Instance instance, | 2411 void PluginInstance::NumberOfFindResultsChanged(PP_Instance instance, |
| (...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2708 screen_size_for_fullscreen_ = gfx::Size(); | 2782 screen_size_for_fullscreen_ = gfx::Size(); |
| 2709 WebElement element = container_->element(); | 2783 WebElement element = container_->element(); |
| 2710 element.setAttribute(WebString::fromUTF8(kWidth), width_before_fullscreen_); | 2784 element.setAttribute(WebString::fromUTF8(kWidth), width_before_fullscreen_); |
| 2711 element.setAttribute(WebString::fromUTF8(kHeight), height_before_fullscreen_); | 2785 element.setAttribute(WebString::fromUTF8(kHeight), height_before_fullscreen_); |
| 2712 element.setAttribute(WebString::fromUTF8(kBorder), border_before_fullscreen_); | 2786 element.setAttribute(WebString::fromUTF8(kBorder), border_before_fullscreen_); |
| 2713 element.setAttribute(WebString::fromUTF8(kStyle), style_before_fullscreen_); | 2787 element.setAttribute(WebString::fromUTF8(kStyle), style_before_fullscreen_); |
| 2714 } | 2788 } |
| 2715 | 2789 |
| 2716 } // namespace ppapi | 2790 } // namespace ppapi |
| 2717 } // namespace webkit | 2791 } // namespace webkit |
| OLD | NEW |