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