Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(45)

Side by Side Diff: content/renderer/pepper/pepper_video_source_host.cc

Issue 736033002: PepperVideoSourceHost: Use natural_size instead of visible_rect.size (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: bbudge@s comments Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « content/renderer/pepper/pepper_video_source_host.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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"
11 #include "content/renderer/render_thread_impl.h" 11 #include "content/renderer/render_thread_impl.h"
12 #include "ppapi/c/pp_errors.h" 12 #include "ppapi/c/pp_errors.h"
13 #include "ppapi/host/dispatch_host_message.h" 13 #include "ppapi/host/dispatch_host_message.h"
14 #include "ppapi/host/ppapi_host.h" 14 #include "ppapi/host/ppapi_host.h"
15 #include "ppapi/proxy/host_dispatcher.h" 15 #include "ppapi/proxy/host_dispatcher.h"
16 #include "ppapi/proxy/ppapi_messages.h" 16 #include "ppapi/proxy/ppapi_messages.h"
17 #include "ppapi/proxy/ppb_image_data_proxy.h" 17 #include "ppapi/proxy/ppb_image_data_proxy.h"
18 #include "ppapi/shared_impl/scoped_pp_resource.h" 18 #include "ppapi/shared_impl/scoped_pp_resource.h"
19 #include "ppapi/thunk/enter.h" 19 #include "ppapi/thunk/enter.h"
20 #include "ppapi/thunk/ppb_image_data_api.h" 20 #include "ppapi/thunk/ppb_image_data_api.h"
21 #include "third_party/libyuv/include/libyuv/convert.h" 21 #include "third_party/libyuv/include/libyuv/convert.h"
22 #include "third_party/libyuv/include/libyuv/scale.h"
22 #include "third_party/skia/include/core/SkBitmap.h" 23 #include "third_party/skia/include/core/SkBitmap.h"
23 24
24 using ppapi::host::HostMessageContext; 25 using ppapi::host::HostMessageContext;
25 using ppapi::host::ReplyMessageContext; 26 using ppapi::host::ReplyMessageContext;
26 27
27 namespace content { 28 namespace content {
28 29
29 PepperVideoSourceHost::FrameReceiver::FrameReceiver( 30 PepperVideoSourceHost::FrameReceiver::FrameReceiver(
30 const base::WeakPtr<PepperVideoSourceHost>& host) 31 const base::WeakPtr<PepperVideoSourceHost>& host)
31 : host_(host) {} 32 : host_(host) {}
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 int32_t PepperVideoSourceHost::OnHostMsgClose(HostMessageContext* context) { 109 int32_t PepperVideoSourceHost::OnHostMsgClose(HostMessageContext* context) {
109 Close(); 110 Close();
110 return PP_OK; 111 return PP_OK;
111 } 112 }
112 113
113 void PepperVideoSourceHost::SendGetFrameReply() { 114 void PepperVideoSourceHost::SendGetFrameReply() {
114 DCHECK(get_frame_pending_); 115 DCHECK(get_frame_pending_);
115 get_frame_pending_ = false; 116 get_frame_pending_ = false;
116 117
117 DCHECK(last_frame_.get()); 118 DCHECK(last_frame_.get());
118 scoped_refptr<media::VideoFrame> frame(last_frame_); 119 const gfx::Size dst_size = last_frame_->natural_size();
119 last_frame_ = NULL;
120
121 const int dst_width = frame->visible_rect().width();
122 const int dst_height = frame->visible_rect().height();
123 120
124 // Note: We try to reuse the shared memory for the previous frame here. This 121 // Note: We try to reuse the shared memory for the previous frame here. This
125 // means that the previous frame may be overwritten and is no longer valid 122 // means that the previous frame may be overwritten and is no longer valid
126 // after calling this function again. 123 // after calling this function again.
127 IPC::PlatformFileForTransit image_handle; 124 IPC::PlatformFileForTransit image_handle;
128 uint32_t byte_count; 125 uint32_t byte_count;
129 if (shared_image_.get() && dst_width == shared_image_->width() && 126 if (shared_image_.get() && dst_size.width() == shared_image_->width() &&
130 dst_height == shared_image_->height()) { 127 dst_size.height() == shared_image_->height()) {
131 // We have already allocated the correct size in shared memory. We need to 128 // We have already allocated the correct size in shared memory. We need to
132 // duplicate the handle for IPC however, which will close down the 129 // duplicate the handle for IPC however, which will close down the
133 // duplicated handle when it's done. 130 // duplicated handle when it's done.
134 int local_fd = 0; 131 int local_fd = 0;
135 if (shared_image_->GetSharedMemory(&local_fd, &byte_count) != PP_OK) { 132 if (shared_image_->GetSharedMemory(&local_fd, &byte_count) != PP_OK) {
136 SendGetFrameErrorReply(PP_ERROR_FAILED); 133 SendGetFrameErrorReply(PP_ERROR_FAILED);
137 return; 134 return;
138 } 135 }
139 136
140 ppapi::proxy::HostDispatcher* dispatcher = 137 ppapi::proxy::HostDispatcher* dispatcher =
(...skipping 14 matching lines...) Expand all
155 } else { 152 } else {
156 // We need to allocate new shared memory. 153 // We need to allocate new shared memory.
157 shared_image_ = NULL; // Release any previous image. 154 shared_image_ = NULL; // Release any previous image.
158 155
159 ppapi::ScopedPPResource resource( 156 ppapi::ScopedPPResource resource(
160 ppapi::ScopedPPResource::PassRef(), 157 ppapi::ScopedPPResource::PassRef(),
161 ppapi::proxy::PPB_ImageData_Proxy::CreateImageData( 158 ppapi::proxy::PPB_ImageData_Proxy::CreateImageData(
162 pp_instance(), 159 pp_instance(),
163 ppapi::PPB_ImageData_Shared::SIMPLE, 160 ppapi::PPB_ImageData_Shared::SIMPLE,
164 PP_IMAGEDATAFORMAT_BGRA_PREMUL, 161 PP_IMAGEDATAFORMAT_BGRA_PREMUL,
165 PP_MakeSize(dst_width, dst_height), 162 PP_MakeSize(dst_size.width(), dst_size.height()),
166 false /* init_to_zero */, 163 false /* init_to_zero */,
167 &shared_image_desc_, 164 &shared_image_desc_,
168 &image_handle, 165 &image_handle,
169 &byte_count)); 166 &byte_count));
170 if (!resource) { 167 if (!resource) {
171 SendGetFrameErrorReply(PP_ERROR_FAILED); 168 SendGetFrameErrorReply(PP_ERROR_FAILED);
172 return; 169 return;
173 } 170 }
174 171
175 ppapi::thunk::EnterResourceNoLock<ppapi::thunk::PPB_ImageData_API> 172 ppapi::thunk::EnterResourceNoLock<ppapi::thunk::PPB_ImageData_API>
(...skipping 23 matching lines...) Expand all
199 SendGetFrameErrorReply(PP_ERROR_FAILED); 196 SendGetFrameErrorReply(PP_ERROR_FAILED);
200 return; 197 return;
201 } 198 }
202 199
203 uint8_t* bitmap_pixels = static_cast<uint8_t*>(bitmap->getPixels()); 200 uint8_t* bitmap_pixels = static_cast<uint8_t*>(bitmap->getPixels());
204 if (!bitmap_pixels) { 201 if (!bitmap_pixels) {
205 SendGetFrameErrorReply(PP_ERROR_FAILED); 202 SendGetFrameErrorReply(PP_ERROR_FAILED);
206 return; 203 return;
207 } 204 }
208 205
209 // Calculate that portion of the |frame| that should be copied into 206 // Calculate the portion of the |last_frame_| that should be copied into
210 // |bitmap|. If |frame| has been cropped, 207 // |bitmap|. If |last_frame_| is lazily scaled, then
211 // frame->coded_size() != frame->visible_rect(). 208 // last_frame_->visible_rect()._size() != last_frame_.natural_size().
212 const int src_width = frame->coded_size().width(); 209 scoped_refptr<media::VideoFrame> frame;
213 const int src_height = frame->coded_size().height(); 210 if (dst_size == last_frame_->visible_rect().size()) {
214 DCHECK(src_width >= dst_width && src_height >= dst_height); 211 // No scaling is needed, convert directly from last_frame_.
215 212 frame = last_frame_;
216 const int horiz_crop = frame->visible_rect().x(); 213 // Frame resolution doesn't change frequently, so don't keep any unnecessary
217 const int vert_crop = frame->visible_rect().y(); 214 // buffers around.
218 215 scaled_frame_ = NULL;
219 const uint8* src_y = frame->data(media::VideoFrame::kYPlane) + 216 } else {
220 (src_width * vert_crop + horiz_crop); 217 // We need to create an intermediate scaled frame. Make sure we have
221 const int center = (src_width + 1) / 2; 218 // allocated one of correct size.
222 const uint8* src_u = frame->data(media::VideoFrame::kUPlane) + 219 if (!scaled_frame_.get() || scaled_frame_->coded_size() != dst_size) {
223 (center * vert_crop + horiz_crop) / 2; 220 scaled_frame_ = media::VideoFrame::CreateFrame(
224 const uint8* src_v = frame->data(media::VideoFrame::kVPlane) + 221 media::VideoFrame::I420, dst_size, gfx::Rect(dst_size), dst_size,
225 (center * vert_crop + horiz_crop) / 2; 222 last_frame_->timestamp());
223 if (!scaled_frame_.get()) {
224 LOG(ERROR) << "Failed to allocate a media::VideoFrame";
225 SendGetFrameErrorReply(PP_ERROR_FAILED);
226 return;
227 }
228 }
229 libyuv::I420Scale(last_frame_->visible_data(media::VideoFrame::kYPlane),
230 last_frame_->stride(media::VideoFrame::kYPlane),
231 last_frame_->visible_data(media::VideoFrame::kUPlane),
232 last_frame_->stride(media::VideoFrame::kUPlane),
233 last_frame_->visible_data(media::VideoFrame::kVPlane),
234 last_frame_->stride(media::VideoFrame::kVPlane),
235 last_frame_->visible_rect().width(),
236 last_frame_->visible_rect().height(),
237 scaled_frame_->data(media::VideoFrame::kYPlane),
238 scaled_frame_->stride(media::VideoFrame::kYPlane),
239 scaled_frame_->data(media::VideoFrame::kUPlane),
240 scaled_frame_->stride(media::VideoFrame::kUPlane),
241 scaled_frame_->data(media::VideoFrame::kVPlane),
242 scaled_frame_->stride(media::VideoFrame::kVPlane),
243 dst_size.width(),
244 dst_size.height(),
245 libyuv::kFilterBilinear);
246 frame = scaled_frame_;
247 }
248 last_frame_ = NULL;
226 249
227 // TODO(magjed): Chrome OS is not ready for switching from BGRA to ARGB. 250 // TODO(magjed): Chrome OS is not ready for switching from BGRA to ARGB.
228 // Remove this once http://crbug/434007 is fixed. We have a corresponding 251 // Remove this once http://crbug/434007 is fixed. We have a corresponding
229 // problem when we receive frames from the effects plugin in PpFrameWriter. 252 // problem when we receive frames from the effects plugin in PpFrameWriter.
230 #if defined(OS_CHROMEOS) 253 #if defined(OS_CHROMEOS)
231 auto libyuv_i420_to_xxxx = &libyuv::I420ToBGRA; 254 auto libyuv_i420_to_xxxx = &libyuv::I420ToBGRA;
232 #else 255 #else
233 auto libyuv_i420_to_xxxx = &libyuv::I420ToARGB; 256 auto libyuv_i420_to_xxxx = &libyuv::I420ToARGB;
234 #endif 257 #endif
235 libyuv_i420_to_xxxx(src_y, 258 libyuv_i420_to_xxxx(frame->visible_data(media::VideoFrame::kYPlane),
236 frame->stride(media::VideoFrame::kYPlane), 259 frame->stride(media::VideoFrame::kYPlane),
237 src_u, 260 frame->visible_data(media::VideoFrame::kUPlane),
238 frame->stride(media::VideoFrame::kUPlane), 261 frame->stride(media::VideoFrame::kUPlane),
239 src_v, 262 frame->visible_data(media::VideoFrame::kVPlane),
240 frame->stride(media::VideoFrame::kVPlane), 263 frame->stride(media::VideoFrame::kVPlane),
241 bitmap_pixels, 264 bitmap_pixels,
242 bitmap->rowBytes(), 265 bitmap->rowBytes(),
243 dst_width, 266 dst_size.width(),
244 dst_height); 267 dst_size.height());
245 268
246 ppapi::HostResource host_resource; 269 ppapi::HostResource host_resource;
247 host_resource.SetHostResource(pp_instance(), shared_image_->GetReference()); 270 host_resource.SetHostResource(pp_instance(), shared_image_->GetReference());
248 271
249 // Convert a video timestamp to a PP_TimeTicks (a double, in seconds). 272 // Convert a video timestamp to a PP_TimeTicks (a double, in seconds).
250 const PP_TimeTicks timestamp = frame->timestamp().InSecondsF(); 273 const PP_TimeTicks timestamp = frame->timestamp().InSecondsF();
251 274
252 ppapi::proxy::SerializedHandle serialized_handle; 275 ppapi::proxy::SerializedHandle serialized_handle;
253 serialized_handle.set_shmem(image_handle, byte_count); 276 serialized_handle.set_shmem(image_handle, byte_count);
254 reply_context_.params.AppendHandle(serialized_handle); 277 reply_context_.params.AppendHandle(serialized_handle);
(...skipping 18 matching lines...) Expand all
273 if (source_handler_.get() && !stream_url_.empty()) 296 if (source_handler_.get() && !stream_url_.empty())
274 source_handler_->Close(frame_receiver_.get()); 297 source_handler_->Close(frame_receiver_.get());
275 298
276 source_handler_.reset(NULL); 299 source_handler_.reset(NULL);
277 stream_url_.clear(); 300 stream_url_.clear();
278 301
279 shared_image_ = NULL; 302 shared_image_ = NULL;
280 } 303 }
281 304
282 } // namespace content 305 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/pepper/pepper_video_source_host.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698