| 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/safe_numerics.h" | 8 #include "base/safe_numerics.h" |
| 9 #include "content/public/renderer/renderer_ppapi_host.h" | 9 #include "content/public/renderer/renderer_ppapi_host.h" |
| 10 #include "content/renderer/render_thread_impl.h" | 10 #include "content/renderer/render_thread_impl.h" |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 99 return PP_ERROR_BADARGUMENT; | 99 return PP_ERROR_BADARGUMENT; |
| 100 | 100 |
| 101 stream_url_ = gurl.spec(); | 101 stream_url_ = gurl.spec(); |
| 102 | 102 |
| 103 ReplyMessageContext reply_context = context->MakeReplyMessageContext(); | 103 ReplyMessageContext reply_context = context->MakeReplyMessageContext(); |
| 104 reply_context.params.set_result(PP_OK); | 104 reply_context.params.set_result(PP_OK); |
| 105 host()->SendReply(reply_context, PpapiPluginMsg_VideoSource_OpenReply()); | 105 host()->SendReply(reply_context, PpapiPluginMsg_VideoSource_OpenReply()); |
| 106 return PP_OK_COMPLETIONPENDING; | 106 return PP_OK_COMPLETIONPENDING; |
| 107 } | 107 } |
| 108 | 108 |
| 109 int32_t PepperVideoSourceHost::OnHostMsgGetFrame( | 109 int32_t PepperVideoSourceHost::OnHostMsgGetFrame(HostMessageContext* context) { |
| 110 HostMessageContext* context) { | |
| 111 if (!source_handler_.get()) | 110 if (!source_handler_.get()) |
| 112 return PP_ERROR_FAILED; | 111 return PP_ERROR_FAILED; |
| 113 if (get_frame_pending_) | 112 if (get_frame_pending_) |
| 114 return PP_ERROR_INPROGRESS; | 113 return PP_ERROR_INPROGRESS; |
| 115 | 114 |
| 116 reply_context_ = context->MakeReplyMessageContext(); | 115 reply_context_ = context->MakeReplyMessageContext(); |
| 117 get_frame_pending_ = true; | 116 get_frame_pending_ = true; |
| 118 | 117 |
| 119 // If a frame is ready, try to convert it and send the reply. | 118 // If a frame is ready, try to convert it and send the reply. |
| 120 if (last_frame_.get()) | 119 if (last_frame_.get()) |
| 121 SendGetFrameReply(); | 120 SendGetFrameReply(); |
| 122 | 121 |
| 123 return PP_OK_COMPLETIONPENDING; | 122 return PP_OK_COMPLETIONPENDING; |
| 124 } | 123 } |
| 125 | 124 |
| 126 int32_t PepperVideoSourceHost::OnHostMsgClose(HostMessageContext* context) { | 125 int32_t PepperVideoSourceHost::OnHostMsgClose(HostMessageContext* context) { |
| 127 Close(); | 126 Close(); |
| 128 return PP_OK; | 127 return PP_OK; |
| 129 } | 128 } |
| 130 | 129 |
| 131 void PepperVideoSourceHost::SendGetFrameReply() { | 130 void PepperVideoSourceHost::SendGetFrameReply() { |
| 132 DCHECK(get_frame_pending_); | 131 DCHECK(get_frame_pending_); |
| 133 get_frame_pending_ = false; | 132 get_frame_pending_ = false; |
| 134 | 133 |
| 135 DCHECK(last_frame_.get()); | 134 DCHECK(last_frame_.get()); |
| 136 scoped_ptr<cricket::VideoFrame> frame(last_frame_.release()); | 135 scoped_ptr<cricket::VideoFrame> frame(last_frame_.release()); |
| 137 | 136 |
| 138 int32_t width = base::checked_numeric_cast<int32_t>(frame->GetWidth()); | 137 int32_t width = base::checked_numeric_cast<int32_t>(frame->GetWidth()); |
| 139 int32_t height = base::checked_numeric_cast<int32_t>(frame->GetHeight()); | 138 int32_t height = base::checked_numeric_cast<int32_t>(frame->GetHeight()); |
| 140 // Create an image data resource to hold the frame pixels. | |
| 141 PP_ImageDataDesc image_desc; | 139 PP_ImageDataDesc image_desc; |
| 142 IPC::PlatformFileForTransit image_handle; | 140 IPC::PlatformFileForTransit image_handle; |
| 143 uint32_t byte_count; | 141 uint32_t byte_count; |
| 144 ppapi::ScopedPPResource resource( | 142 ppapi::ScopedPPResource resource( |
| 145 ppapi::ScopedPPResource::PassRef(), | 143 ppapi::ScopedPPResource::PassRef(), |
| 146 ppapi::proxy::PPB_ImageData_Proxy::CreateImageData( | 144 ppapi::proxy::PPB_ImageData_Proxy::CreateImageData( |
| 147 pp_instance(), | 145 pp_instance(), |
| 148 ppapi::PPB_ImageData_Shared::PLATFORM, | 146 ppapi::PPB_ImageData_Shared::SIMPLE, |
| 149 PP_IMAGEDATAFORMAT_BGRA_PREMUL, | 147 PP_IMAGEDATAFORMAT_BGRA_PREMUL, |
| 150 PP_MakeSize(width, height), | 148 PP_MakeSize(width, height), |
| 151 false /* init_to_zero */, | 149 false /* init_to_zero */, |
| 152 &image_desc, &image_handle, &byte_count)); | 150 &image_desc, &image_handle, &byte_count)); |
| 153 if (!resource.get()) { | 151 if (!resource.get()) { |
| 154 SendGetFrameErrorReply(PP_ERROR_FAILED); | 152 SendGetFrameErrorReply(PP_ERROR_FAILED); |
| 155 return; | 153 return; |
| 156 } | 154 } |
| 157 | 155 |
| 158 ppapi::thunk::EnterResourceNoLock<ppapi::thunk::PPB_ImageData_API> | 156 ppapi::thunk::EnterResourceNoLock<ppapi::thunk::PPB_ImageData_API> |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 190 ppapi::HostResource host_resource; | 188 ppapi::HostResource host_resource; |
| 191 host_resource.SetHostResource(pp_instance(), resource.get()); | 189 host_resource.SetHostResource(pp_instance(), resource.get()); |
| 192 | 190 |
| 193 // Convert a video timestamp (int64, in nanoseconds) to a time delta (int64, | 191 // Convert a video timestamp (int64, in nanoseconds) to a time delta (int64, |
| 194 // microseconds) and then to a PP_TimeTicks (a double, in seconds). All times | 192 // microseconds) and then to a PP_TimeTicks (a double, in seconds). All times |
| 195 // are relative to the Unix Epoch. | 193 // are relative to the Unix Epoch. |
| 196 base::TimeDelta time_delta = base::TimeDelta::FromMicroseconds( | 194 base::TimeDelta time_delta = base::TimeDelta::FromMicroseconds( |
| 197 frame->GetTimeStamp() / base::Time::kNanosecondsPerMicrosecond); | 195 frame->GetTimeStamp() / base::Time::kNanosecondsPerMicrosecond); |
| 198 PP_TimeTicks timestamp = time_delta.InSecondsF(); | 196 PP_TimeTicks timestamp = time_delta.InSecondsF(); |
| 199 | 197 |
| 200 reply_context_.params.set_result(PP_OK); | |
| 201 | |
| 202 #if defined(TOOLKIT_GTK) | |
| 203 // For GTK, we pass the SysV shared memory key in the message. | |
| 204 PpapiPluginMsg_VideoSource_GetFrameReply reply_msg(host_resource, | |
| 205 image_desc, | |
| 206 image_handle.fd, | |
| 207 timestamp); | |
| 208 #elif defined(OS_POSIX) || defined(OS_WIN) | |
| 209 ppapi::proxy::SerializedHandle serialized_handle; | 198 ppapi::proxy::SerializedHandle serialized_handle; |
| 210 PpapiPluginMsg_VideoSource_GetFrameReply reply_msg(host_resource, | |
| 211 image_desc, | |
| 212 0, | |
| 213 timestamp); | |
| 214 serialized_handle.set_shmem(image_handle, byte_count); | 199 serialized_handle.set_shmem(image_handle, byte_count); |
| 215 reply_context_.params.AppendHandle(serialized_handle); | 200 reply_context_.params.AppendHandle(serialized_handle); |
| 216 #else | |
| 217 // Not supported on other platforms. | |
| 218 // This is a stub reply_msg to not break the build. | |
| 219 PpapiPluginMsg_VideoSource_GetFrameReply reply_msg(host_resource, | |
| 220 image_desc, | |
| 221 0, | |
| 222 timestamp); | |
| 223 NOTIMPLEMENTED(); | |
| 224 SendGetFrameErrorReply(PP_ERROR_NOTSUPPORTED); | |
| 225 return; | |
| 226 #endif | |
| 227 | 201 |
| 228 host()->SendReply(reply_context_, reply_msg); | 202 host()->SendReply(reply_context_, |
| 203 PpapiPluginMsg_VideoSource_GetFrameReply(host_resource, |
| 204 image_desc, |
| 205 timestamp)); |
| 229 | 206 |
| 230 reply_context_ = ppapi::host::ReplyMessageContext(); | 207 reply_context_ = ppapi::host::ReplyMessageContext(); |
| 231 | 208 |
| 232 // Keep a reference once we know this method succeeds. | 209 // Keep a reference once we know this method succeeds. |
| 233 resource.Release(); | 210 resource.Release(); |
| 234 } | 211 } |
| 235 | 212 |
| 236 void PepperVideoSourceHost::SendGetFrameErrorReply(int32_t error) { | 213 void PepperVideoSourceHost::SendGetFrameErrorReply(int32_t error) { |
| 237 reply_context_.params.set_result(error); | 214 reply_context_.params.set_result(error); |
| 238 host()->SendReply( | 215 host()->SendReply( |
| 239 reply_context_, | 216 reply_context_, |
| 240 PpapiPluginMsg_VideoSource_GetFrameReply( | 217 PpapiPluginMsg_VideoSource_GetFrameReply(ppapi::HostResource(), |
| 241 ppapi::HostResource(), PP_ImageDataDesc(), -1, 0.0)); | 218 PP_ImageDataDesc(), |
| 219 0.0 /* timestamp */)); |
| 242 reply_context_ = ppapi::host::ReplyMessageContext(); | 220 reply_context_ = ppapi::host::ReplyMessageContext(); |
| 243 } | 221 } |
| 244 | 222 |
| 245 void PepperVideoSourceHost::Close() { | 223 void PepperVideoSourceHost::Close() { |
| 246 if (source_handler_.get() && !stream_url_.empty()) | 224 if (source_handler_.get() && !stream_url_.empty()) |
| 247 source_handler_->Close(stream_url_, frame_receiver_.get()); | 225 source_handler_->Close(stream_url_, frame_receiver_.get()); |
| 248 | 226 |
| 249 source_handler_.reset(NULL); | 227 source_handler_.reset(NULL); |
| 250 stream_url_.clear(); | 228 stream_url_.clear(); |
| 251 } | 229 } |
| 252 | 230 |
| 253 } // namespace content | 231 } // namespace content |
| OLD | NEW |