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

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

Issue 11091005: Update PluginInstance for decrypt-and-decode video. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "webkit/plugins/ppapi/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
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) {
ddorwin 2012/10/08 19:05:57 Why not avoid 0 like we do above?
xhwang 2012/10/08 20:50:51 I'd like it to be initialized to an invalid reques
ddorwin 2012/10/09 02:10:48 We should try to initialize these in a consistent
xhwang 2012/10/09 22:29:32 As discussed offline, we need the pending_video_de
458 pp_instance_ = HostGlobals::Get()->AddInstance(this); 461 pp_instance_ = HostGlobals::Get()->AddInstance(this);
459 462
460 memset(&current_print_settings_, 0, sizeof(current_print_settings_)); 463 memset(&current_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
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)
ddorwin 2012/10/08 19:05:57 What is the purpose of this? Fixing wrapping?
xhwang 2012/10/08 20:50:51 So that the request_id can never be invalid. Pleas
ddorwin 2012/10/09 02:10:48 DeliverFrame only deals with pending_video_decode_
xhwang 2012/10/09 22:29:32 Removed this as it's not possible to hit.
1534 next_decryption_request_id_++;
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;
ddorwin 2012/10/08 19:05:57 What purpose do these IDs serve? For decrypt, it w
xhwang 2012/10/08 20:50:51 As discussed offline and replied here (http://code
ddorwin 2012/10/09 02:10:48 As discussed offline (and in fischman's comment),
xhwang 2012/10/09 22:29:32 Comments added in header file.
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
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);
xhwang 2012/10/08 17:50:36 +tomf: can we control what the output format is? O
Tom Finegan 2012/10/09 06:25:34 Since we support only VP8, and it outputs only I42
xhwang 2012/10/09 22:29:32 I am asking because VideoFrame::CreateFrame only s
2376 gfx::Size frame_size(frame_info->width, frame_info->height);
2377 scoped_refptr<media::VideoFrame> decoded_frame(
ddorwin 2012/10/08 19:05:57 I hate to add all this media code to ppapi code. C
xhwang 2012/10/08 20:50:51 Agreed. For now the callback will get posted onto
ddorwin 2012/10/09 02:10:48 I think that's a separate issue, but we should avo
xhwang 2012/10/09 22:29:32 TODO added before #include "media/base/video_util.
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
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
OLDNEW
« webkit/plugins/ppapi/ppapi_plugin_instance.h ('K') | « webkit/plugins/ppapi/ppapi_plugin_instance.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698