1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file. 4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/renderer/pepper/pepper_video_source_host.h" 6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/bind.h" 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/numerics/safe_conversions.h" 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/renderer/renderer_ppapi_host.h" 10bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch#include "content/renderer/pepper/ppb_image_data_impl.h" 11b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "content/renderer/render_thread_impl.h" 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ppapi/c/pp_errors.h" 13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ppapi/host/dispatch_host_message.h" 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ppapi/host/ppapi_host.h" 155b892326406927b709cdaf6c384d4ababf456332Ben Murdoch#include "ppapi/proxy/host_dispatcher.h" 16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ppapi/proxy/ppapi_messages.h" 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ppapi/proxy/ppb_image_data_proxy.h" 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ppapi/shared_impl/scoped_pp_resource.h" 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ppapi/thunk/enter.h" 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ppapi/thunk/ppb_image_data_api.h" 21c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "third_party/libyuv/include/libyuv/convert.h" 22b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "third_party/skia/include/core/SkBitmap.h" 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using ppapi::host::HostMessageContext; 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using ppapi::host::ReplyMessageContext; 26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace content { 28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 29a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)PepperVideoSourceHost::FrameReceiver::FrameReceiver( 30a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) const base::WeakPtr<PepperVideoSourceHost>& host) 31a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) : host_(host), 32a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch main_message_loop_proxy_(base::MessageLoopProxy::current()) {} 33a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 34a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochPepperVideoSourceHost::FrameReceiver::~FrameReceiver() {} 35a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 36a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)bool PepperVideoSourceHost::FrameReceiver::GotFrame( 37c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const scoped_refptr<media::VideoFrame>& frame) { 38a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // It's not safe to access the host from this thread, so post a task to our 39a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // main thread to transfer the new frame. 40a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) main_message_loop_proxy_->PostTask( 41a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch FROM_HERE, base::Bind(&FrameReceiver::OnGotFrame, this, frame)); 42a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 43a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return true; 44a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 45a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 46a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void PepperVideoSourceHost::FrameReceiver::OnGotFrame( 47c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const scoped_refptr<media::VideoFrame>& frame) { 48868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (host_.get()) { 49c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Hold a reference to the new frame and release the previous. 50c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch host_->last_frame_ = frame; 51a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 52a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (host_->get_frame_pending_) 53a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) host_->SendGetFrameReply(); 54a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) } 55a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)} 56a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 57a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochPepperVideoSourceHost::PepperVideoSourceHost(RendererPpapiHost* host, 58a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch PP_Instance instance, 59a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch PP_Resource resource) 60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : ResourceHost(host->GetPpapiHost(), instance, resource), 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) renderer_ppapi_host_(host), 6258e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch source_handler_(new VideoSourceHandler(NULL)), 633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) get_frame_pending_(false), 643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) weak_factory_(this) { 653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) frame_receiver_ = new FrameReceiver(weak_factory_.GetWeakPtr()); 665b892326406927b709cdaf6c384d4ababf456332Ben Murdoch memset(&shared_image_desc_, 0, sizeof(shared_image_desc_)); 67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 69a02191e04bc25c4935f804f2c080ae28663d096dBen MurdochPepperVideoSourceHost::~PepperVideoSourceHost() { Close(); } 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)int32_t PepperVideoSourceHost::OnResourceMessageReceived( 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const IPC::Message& msg, 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) HostMessageContext* context) { 74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PPAPI_BEGIN_MESSAGE_MAP(PepperVideoSourceHost, msg) 75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_VideoSource_Open, 76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) OnHostMsgOpen) 77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_VideoSource_GetFrame, 78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) OnHostMsgGetFrame) 79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_VideoSource_Close, 80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) OnHostMsgClose) 81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) PPAPI_END_MESSAGE_MAP() 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return PP_ERROR_FAILED; 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)int32_t PepperVideoSourceHost::OnHostMsgOpen(HostMessageContext* context, 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& stream_url) { 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GURL gurl(stream_url); 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!gurl.is_valid()) 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return PP_ERROR_BADARGUMENT; 90b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 91a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (!source_handler_->Open(gurl.spec(), frame_receiver_.get())) 92b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return PP_ERROR_BADARGUMENT; 93b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 94b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) stream_url_ = gurl.spec(); 95b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ReplyMessageContext reply_context = context->MakeReplyMessageContext(); 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) reply_context.params.set_result(PP_OK); 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) host()->SendReply(reply_context, PpapiPluginMsg_VideoSource_OpenReply()); 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return PP_OK_COMPLETIONPENDING; 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 102eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochint32_t PepperVideoSourceHost::OnHostMsgGetFrame(HostMessageContext* context) { 103b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!source_handler_.get()) 104b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return PP_ERROR_FAILED; 105b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (get_frame_pending_) 106b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return PP_ERROR_INPROGRESS; 107b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 108b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) reply_context_ = context->MakeReplyMessageContext(); 109b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) get_frame_pending_ = true; 110b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 111a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) // If a frame is ready, try to convert it and send the reply. 112a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (last_frame_.get()) 113a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) SendGetFrameReply(); 114b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 115b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return PP_OK_COMPLETIONPENDING; 116b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 117b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 118b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)int32_t PepperVideoSourceHost::OnHostMsgClose(HostMessageContext* context) { 119b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) Close(); 120b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) return PP_OK; 121b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 122b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 123a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void PepperVideoSourceHost::SendGetFrameReply() { 124a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) DCHECK(get_frame_pending_); 125a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) get_frame_pending_ = false; 126a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 127b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) DCHECK(last_frame_.get()); 128c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch scoped_refptr<media::VideoFrame> frame(last_frame_); 129c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch last_frame_ = NULL; 130c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 131c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const int dst_width = frame->visible_rect().width(); 132c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const int dst_height = frame->visible_rect().height(); 133b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 1345b892326406927b709cdaf6c384d4ababf456332Ben Murdoch // Note: We try to reuse the shared memory for the previous frame here. This 1355b892326406927b709cdaf6c384d4ababf456332Ben Murdoch // means that the previous frame may be overwritten and is no longer valid 1365b892326406927b709cdaf6c384d4ababf456332Ben Murdoch // after calling this function again. 137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) IPC::PlatformFileForTransit image_handle; 138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) uint32_t byte_count; 1395b892326406927b709cdaf6c384d4ababf456332Ben Murdoch if (shared_image_.get() && dst_width == shared_image_->width() && 1405b892326406927b709cdaf6c384d4ababf456332Ben Murdoch dst_height == shared_image_->height()) { 1415b892326406927b709cdaf6c384d4ababf456332Ben Murdoch // We have already allocated the correct size in shared memory. We need to 1425b892326406927b709cdaf6c384d4ababf456332Ben Murdoch // duplicate the handle for IPC however, which will close down the 1435b892326406927b709cdaf6c384d4ababf456332Ben Murdoch // duplicated handle when it's done. 1445b892326406927b709cdaf6c384d4ababf456332Ben Murdoch int local_fd = 0; 1455b892326406927b709cdaf6c384d4ababf456332Ben Murdoch if (shared_image_->GetSharedMemory(&local_fd, &byte_count) != PP_OK) { 1465b892326406927b709cdaf6c384d4ababf456332Ben Murdoch SendGetFrameErrorReply(PP_ERROR_FAILED); 1475b892326406927b709cdaf6c384d4ababf456332Ben Murdoch return; 1485b892326406927b709cdaf6c384d4ababf456332Ben Murdoch } 1495b892326406927b709cdaf6c384d4ababf456332Ben Murdoch 1505b892326406927b709cdaf6c384d4ababf456332Ben Murdoch ppapi::proxy::HostDispatcher* dispatcher = 1515b892326406927b709cdaf6c384d4ababf456332Ben Murdoch ppapi::proxy::HostDispatcher::GetForInstance(pp_instance()); 1525b892326406927b709cdaf6c384d4ababf456332Ben Murdoch if (!dispatcher) { 1535b892326406927b709cdaf6c384d4ababf456332Ben Murdoch SendGetFrameErrorReply(PP_ERROR_FAILED); 1545b892326406927b709cdaf6c384d4ababf456332Ben Murdoch return; 1555b892326406927b709cdaf6c384d4ababf456332Ben Murdoch } 1565b892326406927b709cdaf6c384d4ababf456332Ben Murdoch 1575b892326406927b709cdaf6c384d4ababf456332Ben Murdoch#if defined(OS_WIN) 1585b892326406927b709cdaf6c384d4ababf456332Ben Murdoch image_handle = dispatcher->ShareHandleWithRemote( 1595b892326406927b709cdaf6c384d4ababf456332Ben Murdoch reinterpret_cast<HANDLE>(static_cast<intptr_t>(local_fd)), false); 1605b892326406927b709cdaf6c384d4ababf456332Ben Murdoch#elif defined(OS_POSIX) 1615b892326406927b709cdaf6c384d4ababf456332Ben Murdoch image_handle = dispatcher->ShareHandleWithRemote(local_fd, false); 1625b892326406927b709cdaf6c384d4ababf456332Ben Murdoch#else 1635b892326406927b709cdaf6c384d4ababf456332Ben Murdoch#error Not implemented. 1645b892326406927b709cdaf6c384d4ababf456332Ben Murdoch#endif 1655b892326406927b709cdaf6c384d4ababf456332Ben Murdoch } else { 1665b892326406927b709cdaf6c384d4ababf456332Ben Murdoch // We need to allocate new shared memory. 1675b892326406927b709cdaf6c384d4ababf456332Ben Murdoch shared_image_ = NULL; // Release any previous image. 1685b892326406927b709cdaf6c384d4ababf456332Ben Murdoch 1695b892326406927b709cdaf6c384d4ababf456332Ben Murdoch ppapi::ScopedPPResource resource( 1705b892326406927b709cdaf6c384d4ababf456332Ben Murdoch ppapi::ScopedPPResource::PassRef(), 1715b892326406927b709cdaf6c384d4ababf456332Ben Murdoch ppapi::proxy::PPB_ImageData_Proxy::CreateImageData( 1725b892326406927b709cdaf6c384d4ababf456332Ben Murdoch pp_instance(), 1735b892326406927b709cdaf6c384d4ababf456332Ben Murdoch ppapi::PPB_ImageData_Shared::SIMPLE, 1745b892326406927b709cdaf6c384d4ababf456332Ben Murdoch PP_IMAGEDATAFORMAT_BGRA_PREMUL, 1755b892326406927b709cdaf6c384d4ababf456332Ben Murdoch PP_MakeSize(dst_width, dst_height), 1765b892326406927b709cdaf6c384d4ababf456332Ben Murdoch false /* init_to_zero */, 1775b892326406927b709cdaf6c384d4ababf456332Ben Murdoch &shared_image_desc_, 1785b892326406927b709cdaf6c384d4ababf456332Ben Murdoch &image_handle, 1795b892326406927b709cdaf6c384d4ababf456332Ben Murdoch &byte_count)); 1805b892326406927b709cdaf6c384d4ababf456332Ben Murdoch if (!resource) { 1815b892326406927b709cdaf6c384d4ababf456332Ben Murdoch SendGetFrameErrorReply(PP_ERROR_FAILED); 1825b892326406927b709cdaf6c384d4ababf456332Ben Murdoch return; 1835b892326406927b709cdaf6c384d4ababf456332Ben Murdoch } 1845b892326406927b709cdaf6c384d4ababf456332Ben Murdoch 1855b892326406927b709cdaf6c384d4ababf456332Ben Murdoch ppapi::thunk::EnterResourceNoLock<ppapi::thunk::PPB_ImageData_API> 1865b892326406927b709cdaf6c384d4ababf456332Ben Murdoch enter_resource(resource, false); 1875b892326406927b709cdaf6c384d4ababf456332Ben Murdoch if (enter_resource.failed()) { 1885b892326406927b709cdaf6c384d4ababf456332Ben Murdoch SendGetFrameErrorReply(PP_ERROR_FAILED); 1895b892326406927b709cdaf6c384d4ababf456332Ben Murdoch return; 1905b892326406927b709cdaf6c384d4ababf456332Ben Murdoch } 1915b892326406927b709cdaf6c384d4ababf456332Ben Murdoch 1925b892326406927b709cdaf6c384d4ababf456332Ben Murdoch shared_image_ = static_cast<PPB_ImageData_Impl*>(enter_resource.object()); 1935b892326406927b709cdaf6c384d4ababf456332Ben Murdoch if (!shared_image_.get()) { 1945b892326406927b709cdaf6c384d4ababf456332Ben Murdoch SendGetFrameErrorReply(PP_ERROR_FAILED); 1955b892326406927b709cdaf6c384d4ababf456332Ben Murdoch return; 1965b892326406927b709cdaf6c384d4ababf456332Ben Murdoch } 1975b892326406927b709cdaf6c384d4ababf456332Ben Murdoch 1985b892326406927b709cdaf6c384d4ababf456332Ben Murdoch DCHECK(!shared_image_->IsMapped()); // New memory should not be mapped. 1995b892326406927b709cdaf6c384d4ababf456332Ben Murdoch if (!shared_image_->Map() || !shared_image_->GetMappedBitmap() || 2005b892326406927b709cdaf6c384d4ababf456332Ben Murdoch !shared_image_->GetMappedBitmap()->getPixels()) { 2015b892326406927b709cdaf6c384d4ababf456332Ben Murdoch shared_image_ = NULL; 2025b892326406927b709cdaf6c384d4ababf456332Ben Murdoch SendGetFrameErrorReply(PP_ERROR_FAILED); 2035b892326406927b709cdaf6c384d4ababf456332Ben Murdoch return; 2045b892326406927b709cdaf6c384d4ababf456332Ben Murdoch } 205a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) } 206c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2075b892326406927b709cdaf6c384d4ababf456332Ben Murdoch const SkBitmap* bitmap = shared_image_->GetMappedBitmap(); 208a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (!bitmap) { 209a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) SendGetFrameErrorReply(PP_ERROR_FAILED); 210a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return; 211a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) } 2125b892326406927b709cdaf6c384d4ababf456332Ben Murdoch 213b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) uint8_t* bitmap_pixels = static_cast<uint8_t*>(bitmap->getPixels()); 214a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (!bitmap_pixels) { 215a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) SendGetFrameErrorReply(PP_ERROR_FAILED); 216a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) return; 217a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) } 218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 219c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Calculate that portion of the |frame| that should be copied into 220c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // |bitmap|. If |frame| has been cropped, 221c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // frame->coded_size() != frame->visible_rect(). 222c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const int src_width = frame->coded_size().width(); 223c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const int src_height = frame->coded_size().height(); 224c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(src_width >= dst_width && src_height >= dst_height); 225c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 226c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const int horiz_crop = frame->visible_rect().x(); 227c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const int vert_crop = frame->visible_rect().y(); 228c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 229c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const uint8* src_y = frame->data(media::VideoFrame::kYPlane) + 230a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch (src_width * vert_crop + horiz_crop); 231c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const int center = (src_width + 1) / 2; 232c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const uint8* src_u = frame->data(media::VideoFrame::kUPlane) + 233a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch (center * vert_crop + horiz_crop) / 2; 234c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch const uint8* src_v = frame->data(media::VideoFrame::kVPlane) + 235a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch (center * vert_crop + horiz_crop) / 2; 236c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 237c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch libyuv::I420ToBGRA(src_y, 238c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch frame->stride(media::VideoFrame::kYPlane), 239c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch src_u, 240c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch frame->stride(media::VideoFrame::kUPlane), 241c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch src_v, 242c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch frame->stride(media::VideoFrame::kVPlane), 243a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch bitmap_pixels, 244a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch bitmap->rowBytes(), 245a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch dst_width, 246a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch dst_height); 247b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 248a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) ppapi::HostResource host_resource; 2495b892326406927b709cdaf6c384d4ababf456332Ben Murdoch host_resource.SetHostResource(pp_instance(), shared_image_->GetReference()); 250b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 251c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Convert a video timestamp to a PP_TimeTicks (a double, in seconds). 2525b892326406927b709cdaf6c384d4ababf456332Ben Murdoch const PP_TimeTicks timestamp = frame->timestamp().InSecondsF(); 253a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 254a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) ppapi::proxy::SerializedHandle serialized_handle; 255a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) serialized_handle.set_shmem(image_handle, byte_count); 256a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) reply_context_.params.AppendHandle(serialized_handle); 257eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 258eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch host()->SendReply(reply_context_, 259a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch PpapiPluginMsg_VideoSource_GetFrameReply( 2605b892326406927b709cdaf6c384d4ababf456332Ben Murdoch host_resource, shared_image_desc_, timestamp)); 261a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 262a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) reply_context_ = ppapi::host::ReplyMessageContext(); 263b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 264b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 265a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)void PepperVideoSourceHost::SendGetFrameErrorReply(int32_t error) { 266a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) reply_context_.params.set_result(error); 267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) host()->SendReply( 268b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) reply_context_, 269a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch PpapiPluginMsg_VideoSource_GetFrameReply( 270a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch ppapi::HostResource(), PP_ImageDataDesc(), 0.0 /* timestamp */)); 271b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) reply_context_ = ppapi::host::ReplyMessageContext(); 272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 274b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)void PepperVideoSourceHost::Close() { 275a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) if (source_handler_.get() && !stream_url_.empty()) 2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) source_handler_->Close(frame_receiver_.get()); 277a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) 278a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) source_handler_.reset(NULL); 279a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) stream_url_.clear(); 2805b892326406927b709cdaf6c384d4ababf456332Ben Murdoch 2815b892326406927b709cdaf6c384d4ababf456332Ben Murdoch shared_image_ = NULL; 282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace content 285