// Copyright (c) 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "ppapi/proxy/video_destination_resource.h" #include "base/bind.h" #include "ipc/ipc_message.h" #include "ppapi/c/pp_errors.h" #include "ppapi/c/private/pp_video_frame_private.h" #include "ppapi/proxy/ppapi_messages.h" #include "ppapi/shared_impl/ppapi_globals.h" #include "ppapi/shared_impl/resource_tracker.h" #include "ppapi/shared_impl/var.h" #include "ppapi/thunk/enter.h" #include "ppapi/thunk/ppb_image_data_api.h" using ppapi::thunk::EnterResourceNoLock; using ppapi::thunk::PPB_VideoDestination_Private_API; namespace ppapi { namespace proxy { VideoDestinationResource::VideoDestinationResource( Connection connection, PP_Instance instance) : PluginResource(connection, instance), is_open_(false) { SendCreate(RENDERER, PpapiHostMsg_VideoDestination_Create()); } VideoDestinationResource::~VideoDestinationResource() { } PPB_VideoDestination_Private_API* VideoDestinationResource::AsPPB_VideoDestination_Private_API() { return this; } int32_t VideoDestinationResource::Open( const PP_Var& stream_url, scoped_refptr callback) { if (TrackedCallback::IsPending(open_callback_)) return PP_ERROR_INPROGRESS; open_callback_ = callback; scoped_refptr stream_url_var = StringVar::FromPPVar(stream_url); const uint32_t kMaxStreamIdSizeInBytes = 16384; if (!stream_url_var.get() || stream_url_var->value().size() > kMaxStreamIdSizeInBytes) return PP_ERROR_BADARGUMENT; Call(RENDERER, PpapiHostMsg_VideoDestination_Open(stream_url_var->value()), base::Bind(&VideoDestinationResource::OnPluginMsgOpenComplete, this)); return PP_OK_COMPLETIONPENDING; } int32_t VideoDestinationResource::PutFrame( const PP_VideoFrame_Private& frame) { if (!is_open_) return PP_ERROR_FAILED; thunk::EnterResourceNoLock enter_image( frame.image_data, true); if (enter_image.failed()) return PP_ERROR_BADRESOURCE; // Check that the PP_Instance matches. Resource* image_object = PpapiGlobals::Get()->GetResourceTracker()->GetResource(frame.image_data); if (!image_object || pp_instance() != image_object->pp_instance()) { Log(PP_LOGLEVEL_ERROR, "VideoDestinationPrivateResource.PutFrame: Bad image resource."); return PP_ERROR_BADRESOURCE; } Post(RENDERER, PpapiHostMsg_VideoDestination_PutFrame(image_object->host_resource(), frame.timestamp)); return PP_OK; } void VideoDestinationResource::Close() { Post(RENDERER, PpapiHostMsg_VideoDestination_Close()); if (TrackedCallback::IsPending(open_callback_)) open_callback_->PostAbort(); } void VideoDestinationResource::OnPluginMsgOpenComplete( const ResourceMessageReplyParams& params) { if (TrackedCallback::IsPending(open_callback_)) { int32_t result = params.result(); if (result == PP_OK) is_open_ = true; open_callback_->Run(result); } } } // namespace proxy } // namespace ppapi