Home | History | Annotate | Download | only in pepper
      1 // Copyright 2014 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 "content/renderer/pepper/pepper_media_stream_track_host_base.h"
      6 
      7 #include "base/logging.h"
      8 #include "base/numerics/safe_math.h"
      9 #include "content/public/renderer/render_thread.h"
     10 #include "content/public/renderer/renderer_ppapi_host.h"
     11 #include "ppapi/c/pp_errors.h"
     12 #include "ppapi/host/dispatch_host_message.h"
     13 #include "ppapi/host/host_message_context.h"
     14 #include "ppapi/host/ppapi_host.h"
     15 #include "ppapi/proxy/ppapi_messages.h"
     16 #include "ppapi/shared_impl/media_stream_buffer.h"
     17 
     18 using ppapi::host::HostMessageContext;
     19 using ppapi::proxy::SerializedHandle;
     20 
     21 namespace content {
     22 
     23 PepperMediaStreamTrackHostBase::PepperMediaStreamTrackHostBase(
     24     RendererPpapiHost* host,
     25     PP_Instance instance,
     26     PP_Resource resource)
     27     : ResourceHost(host->GetPpapiHost(), instance, resource),
     28       host_(host),
     29       buffer_manager_(this) {}
     30 
     31 PepperMediaStreamTrackHostBase::~PepperMediaStreamTrackHostBase() {}
     32 
     33 bool PepperMediaStreamTrackHostBase::InitBuffers(int32_t number_of_buffers,
     34                                                  int32_t buffer_size,
     35                                                  TrackType track_type) {
     36   DCHECK_GT(number_of_buffers, 0);
     37   DCHECK_GT(buffer_size,
     38             static_cast<int32_t>(sizeof(ppapi::MediaStreamBuffer::Header)));
     39   // Make each buffer 4 byte aligned.
     40   base::CheckedNumeric<int32_t> buffer_size_aligned = buffer_size;
     41   buffer_size_aligned += (4 - buffer_size % 4);
     42 
     43   // TODO(penghuang): |HostAllocateSharedMemoryBuffer| uses sync IPC. We should
     44   // avoid it.
     45   base::CheckedNumeric<int32_t> size = number_of_buffers * buffer_size_aligned;
     46   if (!size.IsValid())
     47     return false;
     48 
     49   content::RenderThread* render_thread = content::RenderThread::Get();
     50   scoped_ptr<base::SharedMemory> shm(
     51       render_thread->HostAllocateSharedMemoryBuffer(size.ValueOrDie()).Pass());
     52   if (!shm)
     53     return false;
     54 
     55   base::SharedMemoryHandle shm_handle = shm->handle();
     56   if (!buffer_manager_.SetBuffers(number_of_buffers,
     57                                   buffer_size_aligned.ValueOrDie(),
     58                                   shm.Pass(),
     59                                   true)) {
     60     return false;
     61   }
     62 
     63   base::PlatformFile platform_file =
     64 #if defined(OS_WIN)
     65       shm_handle;
     66 #elif defined(OS_POSIX)
     67       shm_handle.fd;
     68 #else
     69 #error Not implemented.
     70 #endif
     71   SerializedHandle handle(host_->ShareHandleWithRemote(platform_file, false),
     72                           size.ValueOrDie());
     73   bool readonly = (track_type == kRead);
     74   host()->SendUnsolicitedReplyWithHandles(
     75       pp_resource(),
     76       PpapiPluginMsg_MediaStreamTrack_InitBuffers(
     77           number_of_buffers,
     78           buffer_size_aligned.ValueOrDie(),
     79           readonly),
     80       std::vector<SerializedHandle>(1, handle));
     81   return true;
     82 }
     83 
     84 void PepperMediaStreamTrackHostBase::SendEnqueueBufferMessageToPlugin(
     85     int32_t index) {
     86   DCHECK_GE(index, 0);
     87   DCHECK_LT(index, buffer_manager_.number_of_buffers());
     88   host()->SendUnsolicitedReply(
     89       pp_resource(), PpapiPluginMsg_MediaStreamTrack_EnqueueBuffer(index));
     90 }
     91 
     92 void PepperMediaStreamTrackHostBase::SendEnqueueBuffersMessageToPlugin(
     93     const std::vector<int32_t>& indices) {
     94   DCHECK_GE(indices.size(), 0U);
     95   host()->SendUnsolicitedReply(pp_resource(),
     96       PpapiPluginMsg_MediaStreamTrack_EnqueueBuffers(indices));
     97 }
     98 
     99 int32_t PepperMediaStreamTrackHostBase::OnResourceMessageReceived(
    100     const IPC::Message& msg,
    101     HostMessageContext* context) {
    102   PPAPI_BEGIN_MESSAGE_MAP(PepperMediaStreamTrackHostBase, msg)
    103     PPAPI_DISPATCH_HOST_RESOURCE_CALL(
    104         PpapiHostMsg_MediaStreamTrack_EnqueueBuffer, OnHostMsgEnqueueBuffer)
    105     PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_MediaStreamTrack_Close,
    106                                         OnHostMsgClose)
    107   PPAPI_END_MESSAGE_MAP()
    108   return ppapi::host::ResourceHost::OnResourceMessageReceived(msg, context);
    109 }
    110 
    111 int32_t PepperMediaStreamTrackHostBase::OnHostMsgEnqueueBuffer(
    112     HostMessageContext* context,
    113     int32_t index) {
    114   buffer_manager_.EnqueueBuffer(index);
    115   return PP_OK;
    116 }
    117 
    118 int32_t PepperMediaStreamTrackHostBase::OnHostMsgClose(
    119     HostMessageContext* context) {
    120   OnClose();
    121   return PP_OK;
    122 }
    123 
    124 }  // namespace content
    125