1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "ppapi/proxy/video_destination_resource.h" 6 7 #include "base/bind.h" 8 #include "ipc/ipc_message.h" 9 #include "ppapi/c/pp_errors.h" 10 #include "ppapi/c/private/pp_video_frame_private.h" 11 #include "ppapi/proxy/ppapi_messages.h" 12 #include "ppapi/shared_impl/ppapi_globals.h" 13 #include "ppapi/shared_impl/resource_tracker.h" 14 #include "ppapi/shared_impl/var.h" 15 #include "ppapi/thunk/enter.h" 16 #include "ppapi/thunk/ppb_image_data_api.h" 17 18 using ppapi::thunk::EnterResourceNoLock; 19 using ppapi::thunk::PPB_VideoDestination_Private_API; 20 21 namespace ppapi { 22 namespace proxy { 23 24 VideoDestinationResource::VideoDestinationResource( 25 Connection connection, 26 PP_Instance instance) 27 : PluginResource(connection, instance), 28 is_open_(false) { 29 SendCreate(RENDERER, PpapiHostMsg_VideoDestination_Create()); 30 } 31 32 VideoDestinationResource::~VideoDestinationResource() { 33 } 34 35 PPB_VideoDestination_Private_API* 36 VideoDestinationResource::AsPPB_VideoDestination_Private_API() { 37 return this; 38 } 39 40 int32_t VideoDestinationResource::Open( 41 const PP_Var& stream_url, 42 scoped_refptr<TrackedCallback> callback) { 43 if (TrackedCallback::IsPending(open_callback_)) 44 return PP_ERROR_INPROGRESS; 45 46 open_callback_ = callback; 47 48 scoped_refptr<StringVar> stream_url_var = StringVar::FromPPVar(stream_url); 49 const uint32_t kMaxStreamIdSizeInBytes = 16384; 50 if (!stream_url_var.get() || 51 stream_url_var->value().size() > kMaxStreamIdSizeInBytes) 52 return PP_ERROR_BADARGUMENT; 53 Call<PpapiPluginMsg_VideoDestination_OpenReply>(RENDERER, 54 PpapiHostMsg_VideoDestination_Open(stream_url_var->value()), 55 base::Bind(&VideoDestinationResource::OnPluginMsgOpenComplete, this)); 56 return PP_OK_COMPLETIONPENDING; 57 } 58 59 int32_t VideoDestinationResource::PutFrame( 60 const PP_VideoFrame_Private& frame) { 61 if (!is_open_) 62 return PP_ERROR_FAILED; 63 64 thunk::EnterResourceNoLock<thunk::PPB_ImageData_API> enter_image( 65 frame.image_data, true); 66 if (enter_image.failed()) 67 return PP_ERROR_BADRESOURCE; 68 69 // Check that the PP_Instance matches. 70 Resource* image_object = 71 PpapiGlobals::Get()->GetResourceTracker()->GetResource(frame.image_data); 72 if (!image_object || pp_instance() != image_object->pp_instance()) { 73 Log(PP_LOGLEVEL_ERROR, 74 "VideoDestinationPrivateResource.PutFrame: Bad image resource."); 75 return PP_ERROR_BADRESOURCE; 76 } 77 78 Post(RENDERER, 79 PpapiHostMsg_VideoDestination_PutFrame(image_object->host_resource(), 80 frame.timestamp)); 81 return PP_OK; 82 } 83 84 void VideoDestinationResource::Close() { 85 Post(RENDERER, PpapiHostMsg_VideoDestination_Close()); 86 87 if (TrackedCallback::IsPending(open_callback_)) 88 open_callback_->PostAbort(); 89 } 90 91 void VideoDestinationResource::OnPluginMsgOpenComplete( 92 const ResourceMessageReplyParams& params) { 93 if (TrackedCallback::IsPending(open_callback_)) { 94 int32_t result = params.result(); 95 if (result == PP_OK) 96 is_open_ = true; 97 open_callback_->Run(result); 98 } 99 } 100 101 } // namespace proxy 102 } // namespace ppapi 103