| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/renderer/pepper/pepper_video_source_host.h" | 5 #include "content/renderer/pepper/pepper_video_source_host.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/numerics/safe_conversions.h" | 8 #include "base/numerics/safe_conversions.h" |
| 9 #include "content/public/renderer/renderer_ppapi_host.h" | 9 #include "content/public/renderer/renderer_ppapi_host.h" |
| 10 #include "content/renderer/pepper/ppb_image_data_impl.h" | 10 #include "content/renderer/pepper/ppb_image_data_impl.h" |
| (...skipping 10 matching lines...) Expand all Loading... |
| 21 #include "third_party/skia/include/core/SkBitmap.h" | 21 #include "third_party/skia/include/core/SkBitmap.h" |
| 22 | 22 |
| 23 using ppapi::host::HostMessageContext; | 23 using ppapi::host::HostMessageContext; |
| 24 using ppapi::host::ReplyMessageContext; | 24 using ppapi::host::ReplyMessageContext; |
| 25 | 25 |
| 26 namespace content { | 26 namespace content { |
| 27 | 27 |
| 28 PepperVideoSourceHost::FrameReceiver::FrameReceiver( | 28 PepperVideoSourceHost::FrameReceiver::FrameReceiver( |
| 29 const base::WeakPtr<PepperVideoSourceHost>& host) | 29 const base::WeakPtr<PepperVideoSourceHost>& host) |
| 30 : host_(host), | 30 : host_(host), |
| 31 main_message_loop_proxy_(base::MessageLoopProxy::current()) { | 31 main_message_loop_proxy_(base::MessageLoopProxy::current()) {} |
| 32 } | |
| 33 | 32 |
| 34 PepperVideoSourceHost::FrameReceiver::~FrameReceiver() { | 33 PepperVideoSourceHost::FrameReceiver::~FrameReceiver() {} |
| 35 } | |
| 36 | 34 |
| 37 bool PepperVideoSourceHost::FrameReceiver::GotFrame( | 35 bool PepperVideoSourceHost::FrameReceiver::GotFrame( |
| 38 const scoped_refptr<media::VideoFrame>& frame) { | 36 const scoped_refptr<media::VideoFrame>& frame) { |
| 39 // It's not safe to access the host from this thread, so post a task to our | 37 // It's not safe to access the host from this thread, so post a task to our |
| 40 // main thread to transfer the new frame. | 38 // main thread to transfer the new frame. |
| 41 main_message_loop_proxy_->PostTask( | 39 main_message_loop_proxy_->PostTask( |
| 42 FROM_HERE, | 40 FROM_HERE, base::Bind(&FrameReceiver::OnGotFrame, this, frame)); |
| 43 base::Bind(&FrameReceiver::OnGotFrame, | |
| 44 this, | |
| 45 frame)); | |
| 46 | 41 |
| 47 return true; | 42 return true; |
| 48 } | 43 } |
| 49 | 44 |
| 50 void PepperVideoSourceHost::FrameReceiver::OnGotFrame( | 45 void PepperVideoSourceHost::FrameReceiver::OnGotFrame( |
| 51 const scoped_refptr<media::VideoFrame>& frame) { | 46 const scoped_refptr<media::VideoFrame>& frame) { |
| 52 if (host_.get()) { | 47 if (host_.get()) { |
| 53 // Hold a reference to the new frame and release the previous. | 48 // Hold a reference to the new frame and release the previous. |
| 54 host_->last_frame_ = frame; | 49 host_->last_frame_ = frame; |
| 55 | 50 |
| 56 if (host_->get_frame_pending_) | 51 if (host_->get_frame_pending_) |
| 57 host_->SendGetFrameReply(); | 52 host_->SendGetFrameReply(); |
| 58 } | 53 } |
| 59 } | 54 } |
| 60 | 55 |
| 61 PepperVideoSourceHost::PepperVideoSourceHost( | 56 PepperVideoSourceHost::PepperVideoSourceHost(RendererPpapiHost* host, |
| 62 RendererPpapiHost* host, | 57 PP_Instance instance, |
| 63 PP_Instance instance, | 58 PP_Resource resource) |
| 64 PP_Resource resource) | |
| 65 : ResourceHost(host->GetPpapiHost(), instance, resource), | 59 : ResourceHost(host->GetPpapiHost(), instance, resource), |
| 66 renderer_ppapi_host_(host), | 60 renderer_ppapi_host_(host), |
| 67 source_handler_(new VideoSourceHandler(NULL)), | 61 source_handler_(new VideoSourceHandler(NULL)), |
| 68 get_frame_pending_(false), | 62 get_frame_pending_(false), |
| 69 weak_factory_(this) { | 63 weak_factory_(this) { |
| 70 frame_receiver_ = new FrameReceiver(weak_factory_.GetWeakPtr()); | 64 frame_receiver_ = new FrameReceiver(weak_factory_.GetWeakPtr()); |
| 71 } | 65 } |
| 72 | 66 |
| 73 PepperVideoSourceHost::~PepperVideoSourceHost() { | 67 PepperVideoSourceHost::~PepperVideoSourceHost() { Close(); } |
| 74 Close(); | |
| 75 } | |
| 76 | 68 |
| 77 int32_t PepperVideoSourceHost::OnResourceMessageReceived( | 69 int32_t PepperVideoSourceHost::OnResourceMessageReceived( |
| 78 const IPC::Message& msg, | 70 const IPC::Message& msg, |
| 79 HostMessageContext* context) { | 71 HostMessageContext* context) { |
| 80 IPC_BEGIN_MESSAGE_MAP(PepperVideoSourceHost, msg) | 72 IPC_BEGIN_MESSAGE_MAP(PepperVideoSourceHost, msg) |
| 81 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_VideoSource_Open, | 73 PPAPI_DISPATCH_HOST_RESOURCE_CALL(PpapiHostMsg_VideoSource_Open, |
| 82 OnHostMsgOpen) | 74 OnHostMsgOpen) |
| 83 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_VideoSource_GetFrame, | 75 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_VideoSource_GetFrame, |
| 84 OnHostMsgGetFrame) | 76 OnHostMsgGetFrame) |
| 85 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_VideoSource_Close, | 77 PPAPI_DISPATCH_HOST_RESOURCE_CALL_0(PpapiHostMsg_VideoSource_Close, |
| 86 OnHostMsgClose) | 78 OnHostMsgClose) |
| 87 IPC_END_MESSAGE_MAP() | 79 IPC_END_MESSAGE_MAP() |
| 88 return PP_ERROR_FAILED; | 80 return PP_ERROR_FAILED; |
| 89 } | 81 } |
| 90 | 82 |
| 91 int32_t PepperVideoSourceHost::OnHostMsgOpen(HostMessageContext* context, | 83 int32_t PepperVideoSourceHost::OnHostMsgOpen(HostMessageContext* context, |
| 92 const std::string& stream_url) { | 84 const std::string& stream_url) { |
| 93 GURL gurl(stream_url); | 85 GURL gurl(stream_url); |
| 94 if (!gurl.is_valid()) | 86 if (!gurl.is_valid()) |
| 95 return PP_ERROR_BADARGUMENT; | 87 return PP_ERROR_BADARGUMENT; |
| 96 | 88 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 141 IPC::PlatformFileForTransit image_handle; | 133 IPC::PlatformFileForTransit image_handle; |
| 142 uint32_t byte_count; | 134 uint32_t byte_count; |
| 143 ppapi::ScopedPPResource resource( | 135 ppapi::ScopedPPResource resource( |
| 144 ppapi::ScopedPPResource::PassRef(), | 136 ppapi::ScopedPPResource::PassRef(), |
| 145 ppapi::proxy::PPB_ImageData_Proxy::CreateImageData( | 137 ppapi::proxy::PPB_ImageData_Proxy::CreateImageData( |
| 146 pp_instance(), | 138 pp_instance(), |
| 147 ppapi::PPB_ImageData_Shared::SIMPLE, | 139 ppapi::PPB_ImageData_Shared::SIMPLE, |
| 148 PP_IMAGEDATAFORMAT_BGRA_PREMUL, | 140 PP_IMAGEDATAFORMAT_BGRA_PREMUL, |
| 149 PP_MakeSize(dst_width, dst_height), | 141 PP_MakeSize(dst_width, dst_height), |
| 150 false /* init_to_zero */, | 142 false /* init_to_zero */, |
| 151 &image_desc, &image_handle, &byte_count)); | 143 &image_desc, |
| 144 &image_handle, |
| 145 &byte_count)); |
| 152 if (!resource.get()) { | 146 if (!resource.get()) { |
| 153 SendGetFrameErrorReply(PP_ERROR_FAILED); | 147 SendGetFrameErrorReply(PP_ERROR_FAILED); |
| 154 return; | 148 return; |
| 155 } | 149 } |
| 156 | 150 |
| 157 ppapi::thunk::EnterResourceNoLock<ppapi::thunk::PPB_ImageData_API> | 151 ppapi::thunk::EnterResourceNoLock<ppapi::thunk::PPB_ImageData_API> |
| 158 enter_resource(resource, false); | 152 enter_resource(resource, false); |
| 159 if (enter_resource.failed()) { | 153 if (enter_resource.failed()) { |
| 160 SendGetFrameErrorReply(PP_ERROR_FAILED); | 154 SendGetFrameErrorReply(PP_ERROR_FAILED); |
| 161 return; | 155 return; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 184 // |bitmap|. If |frame| has been cropped, | 178 // |bitmap|. If |frame| has been cropped, |
| 185 // frame->coded_size() != frame->visible_rect(). | 179 // frame->coded_size() != frame->visible_rect(). |
| 186 const int src_width = frame->coded_size().width(); | 180 const int src_width = frame->coded_size().width(); |
| 187 const int src_height = frame->coded_size().height(); | 181 const int src_height = frame->coded_size().height(); |
| 188 DCHECK(src_width >= dst_width && src_height >= dst_height); | 182 DCHECK(src_width >= dst_width && src_height >= dst_height); |
| 189 | 183 |
| 190 const int horiz_crop = frame->visible_rect().x(); | 184 const int horiz_crop = frame->visible_rect().x(); |
| 191 const int vert_crop = frame->visible_rect().y(); | 185 const int vert_crop = frame->visible_rect().y(); |
| 192 | 186 |
| 193 const uint8* src_y = frame->data(media::VideoFrame::kYPlane) + | 187 const uint8* src_y = frame->data(media::VideoFrame::kYPlane) + |
| 194 (src_width * vert_crop + horiz_crop); | 188 (src_width * vert_crop + horiz_crop); |
| 195 const int center = (src_width + 1) / 2; | 189 const int center = (src_width + 1) / 2; |
| 196 const uint8* src_u = frame->data(media::VideoFrame::kUPlane) + | 190 const uint8* src_u = frame->data(media::VideoFrame::kUPlane) + |
| 197 (center * vert_crop + horiz_crop) / 2; | 191 (center * vert_crop + horiz_crop) / 2; |
| 198 const uint8* src_v = frame->data(media::VideoFrame::kVPlane) + | 192 const uint8* src_v = frame->data(media::VideoFrame::kVPlane) + |
| 199 (center * vert_crop + horiz_crop) / 2; | 193 (center * vert_crop + horiz_crop) / 2; |
| 200 | 194 |
| 201 libyuv::I420ToBGRA(src_y, | 195 libyuv::I420ToBGRA(src_y, |
| 202 frame->stride(media::VideoFrame::kYPlane), | 196 frame->stride(media::VideoFrame::kYPlane), |
| 203 src_u, | 197 src_u, |
| 204 frame->stride(media::VideoFrame::kUPlane), | 198 frame->stride(media::VideoFrame::kUPlane), |
| 205 src_v, | 199 src_v, |
| 206 frame->stride(media::VideoFrame::kVPlane), | 200 frame->stride(media::VideoFrame::kVPlane), |
| 207 bitmap_pixels, bitmap->rowBytes(), | 201 bitmap_pixels, |
| 208 dst_width, dst_height); | 202 bitmap->rowBytes(), |
| 203 dst_width, |
| 204 dst_height); |
| 209 | 205 |
| 210 ppapi::HostResource host_resource; | 206 ppapi::HostResource host_resource; |
| 211 host_resource.SetHostResource(pp_instance(), resource.get()); | 207 host_resource.SetHostResource(pp_instance(), resource.get()); |
| 212 | 208 |
| 213 // Convert a video timestamp to a PP_TimeTicks (a double, in seconds). | 209 // Convert a video timestamp to a PP_TimeTicks (a double, in seconds). |
| 214 PP_TimeTicks timestamp = frame->timestamp().InSecondsF(); | 210 PP_TimeTicks timestamp = frame->timestamp().InSecondsF(); |
| 215 | 211 |
| 216 ppapi::proxy::SerializedHandle serialized_handle; | 212 ppapi::proxy::SerializedHandle serialized_handle; |
| 217 serialized_handle.set_shmem(image_handle, byte_count); | 213 serialized_handle.set_shmem(image_handle, byte_count); |
| 218 reply_context_.params.AppendHandle(serialized_handle); | 214 reply_context_.params.AppendHandle(serialized_handle); |
| 219 | 215 |
| 220 host()->SendReply(reply_context_, | 216 host()->SendReply(reply_context_, |
| 221 PpapiPluginMsg_VideoSource_GetFrameReply(host_resource, | 217 PpapiPluginMsg_VideoSource_GetFrameReply( |
| 222 image_desc, | 218 host_resource, image_desc, timestamp)); |
| 223 timestamp)); | |
| 224 | 219 |
| 225 reply_context_ = ppapi::host::ReplyMessageContext(); | 220 reply_context_ = ppapi::host::ReplyMessageContext(); |
| 226 | 221 |
| 227 // Keep a reference once we know this method succeeds. | 222 // Keep a reference once we know this method succeeds. |
| 228 resource.Release(); | 223 resource.Release(); |
| 229 } | 224 } |
| 230 | 225 |
| 231 void PepperVideoSourceHost::SendGetFrameErrorReply(int32_t error) { | 226 void PepperVideoSourceHost::SendGetFrameErrorReply(int32_t error) { |
| 232 reply_context_.params.set_result(error); | 227 reply_context_.params.set_result(error); |
| 233 host()->SendReply( | 228 host()->SendReply( |
| 234 reply_context_, | 229 reply_context_, |
| 235 PpapiPluginMsg_VideoSource_GetFrameReply(ppapi::HostResource(), | 230 PpapiPluginMsg_VideoSource_GetFrameReply( |
| 236 PP_ImageDataDesc(), | 231 ppapi::HostResource(), PP_ImageDataDesc(), 0.0 /* timestamp */)); |
| 237 0.0 /* timestamp */)); | |
| 238 reply_context_ = ppapi::host::ReplyMessageContext(); | 232 reply_context_ = ppapi::host::ReplyMessageContext(); |
| 239 } | 233 } |
| 240 | 234 |
| 241 void PepperVideoSourceHost::Close() { | 235 void PepperVideoSourceHost::Close() { |
| 242 if (source_handler_.get() && !stream_url_.empty()) | 236 if (source_handler_.get() && !stream_url_.empty()) |
| 243 source_handler_->Close(frame_receiver_.get()); | 237 source_handler_->Close(frame_receiver_.get()); |
| 244 | 238 |
| 245 source_handler_.reset(NULL); | 239 source_handler_.reset(NULL); |
| 246 stream_url_.clear(); | 240 stream_url_.clear(); |
| 247 } | 241 } |
| 248 | 242 |
| 249 } // namespace content | 243 } // namespace content |
| OLD | NEW |