Home | History | Annotate | Download | only in proxy
      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_source_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/proxy/ppb_image_data_proxy.h"
     13 #include "ppapi/shared_impl/ppapi_globals.h"
     14 #include "ppapi/shared_impl/resource_tracker.h"
     15 #include "ppapi/shared_impl/var.h"
     16 #include "ppapi/thunk/enter.h"
     17 
     18 using ppapi::thunk::EnterResourceNoLock;
     19 using ppapi::thunk::PPB_VideoSource_Private_API;
     20 
     21 namespace ppapi {
     22 namespace proxy {
     23 
     24 VideoSourceResource::VideoSourceResource(
     25     Connection connection,
     26     PP_Instance instance)
     27     : PluginResource(connection, instance),
     28       is_open_(false) {
     29   SendCreate(RENDERER, PpapiHostMsg_VideoSource_Create());
     30 }
     31 
     32 VideoSourceResource::~VideoSourceResource() {
     33 }
     34 
     35 PPB_VideoSource_Private_API*
     36     VideoSourceResource::AsPPB_VideoSource_Private_API() {
     37   return this;
     38 }
     39 
     40 int32_t VideoSourceResource::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_VideoSource_OpenReply>(RENDERER,
     54       PpapiHostMsg_VideoSource_Open(stream_url_var->value()),
     55       base::Bind(&VideoSourceResource::OnPluginMsgOpenComplete, this));
     56   return PP_OK_COMPLETIONPENDING;
     57 }
     58 
     59 int32_t VideoSourceResource::GetFrame(
     60     PP_VideoFrame_Private* frame,
     61     scoped_refptr<TrackedCallback> callback) {
     62   if (!is_open_)
     63     return PP_ERROR_FAILED;
     64 
     65   if (TrackedCallback::IsPending(get_frame_callback_))
     66     return PP_ERROR_INPROGRESS;
     67 
     68   get_frame_callback_ = callback;
     69   Call<PpapiPluginMsg_VideoSource_GetFrameReply>(RENDERER,
     70       PpapiHostMsg_VideoSource_GetFrame(),
     71       base::Bind(&VideoSourceResource::OnPluginMsgGetFrameComplete, this,
     72                  frame));
     73   return PP_OK_COMPLETIONPENDING;
     74 }
     75 
     76 void VideoSourceResource::Close() {
     77   Post(RENDERER, PpapiHostMsg_VideoSource_Close());
     78 
     79   if (TrackedCallback::IsPending(open_callback_))
     80     open_callback_->PostAbort();
     81   if (TrackedCallback::IsPending(get_frame_callback_))
     82     get_frame_callback_->PostAbort();
     83 }
     84 
     85 void VideoSourceResource::OnPluginMsgOpenComplete(
     86     const ResourceMessageReplyParams& reply_params) {
     87   if (TrackedCallback::IsPending(open_callback_)) {
     88     int32_t result = reply_params.result();
     89     if (result == PP_OK)
     90       is_open_ = true;
     91     open_callback_->Run(result);
     92   }
     93 }
     94 
     95 void VideoSourceResource::OnPluginMsgGetFrameComplete(
     96     PP_VideoFrame_Private* frame,
     97     const ResourceMessageReplyParams& reply_params,
     98     const HostResource& image_data,
     99     const PP_ImageDataDesc& image_desc,
    100     PP_TimeTicks timestamp) {
    101   // The callback may have been aborted by Close().
    102   if (TrackedCallback::IsPending(get_frame_callback_)) {
    103     int32_t result = reply_params.result();
    104     if (result == PP_OK &&
    105         PPB_ImageData_Shared::IsImageDataDescValid(image_desc)) {
    106       frame->timestamp = timestamp;
    107 
    108       base::SharedMemoryHandle handle;
    109       if (!reply_params.TakeSharedMemoryHandleAtIndex(0, &handle))
    110         frame->image_data = 0;
    111       frame->image_data =
    112           (new SimpleImageData(
    113               image_data, image_desc, handle))->GetReference();
    114     }
    115     get_frame_callback_->Run(result);
    116   }
    117 }
    118 
    119 }  // namespace proxy
    120 }  // namespace ppapi
    121