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 |