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

Side by Side Diff: webrtc/media/base/videocapturer.cc

Issue 1934503002: Delete unused video capture code for cropping, non-square pixels, and ARGB. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Delete unused ARGB scaling logic. Created 4 years, 7 months 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 | « webrtc/media/base/videocapturer.h ('k') | webrtc/media/base/videocommon.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2010 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2010 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source 5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
(...skipping 12 matching lines...) Expand all
23 #include "webrtc/media/engine/webrtcvideoframefactory.h" 23 #include "webrtc/media/engine/webrtcvideoframefactory.h"
24 24
25 namespace cricket { 25 namespace cricket {
26 26
27 namespace { 27 namespace {
28 28
29 static const int64_t kMaxDistance = ~(static_cast<int64_t>(1) << 63); 29 static const int64_t kMaxDistance = ~(static_cast<int64_t>(1) << 63);
30 #ifdef WEBRTC_LINUX 30 #ifdef WEBRTC_LINUX
31 static const int kYU12Penalty = 16; // Needs to be higher than MJPG index. 31 static const int kYU12Penalty = 16; // Needs to be higher than MJPG index.
32 #endif 32 #endif
33 static const int kDefaultScreencastFps = 5;
34 33
35 } // namespace 34 } // namespace
36 35
37 ///////////////////////////////////////////////////////////////////// 36 /////////////////////////////////////////////////////////////////////
38 // Implementation of struct CapturedFrame 37 // Implementation of struct CapturedFrame
39 ///////////////////////////////////////////////////////////////////// 38 /////////////////////////////////////////////////////////////////////
40 CapturedFrame::CapturedFrame() 39 CapturedFrame::CapturedFrame()
41 : width(0), 40 : width(0),
42 height(0), 41 height(0),
43 fourcc(0), 42 fourcc(0),
(...skipping 15 matching lines...) Expand all
59 58
60 ///////////////////////////////////////////////////////////////////// 59 /////////////////////////////////////////////////////////////////////
61 // Implementation of class VideoCapturer 60 // Implementation of class VideoCapturer
62 ///////////////////////////////////////////////////////////////////// 61 /////////////////////////////////////////////////////////////////////
63 VideoCapturer::VideoCapturer() : apply_rotation_(false) { 62 VideoCapturer::VideoCapturer() : apply_rotation_(false) {
64 thread_checker_.DetachFromThread(); 63 thread_checker_.DetachFromThread();
65 Construct(); 64 Construct();
66 } 65 }
67 66
68 void VideoCapturer::Construct() { 67 void VideoCapturer::Construct() {
69 ratio_w_ = 0;
70 ratio_h_ = 0;
71 enable_camera_list_ = false; 68 enable_camera_list_ = false;
72 square_pixel_aspect_ratio_ = false;
73 capture_state_ = CS_STOPPED; 69 capture_state_ = CS_STOPPED;
74 SignalFrameCaptured.connect(this, &VideoCapturer::OnFrameCaptured); 70 SignalFrameCaptured.connect(this, &VideoCapturer::OnFrameCaptured);
75 scaled_width_ = 0; 71 scaled_width_ = 0;
76 scaled_height_ = 0; 72 scaled_height_ = 0;
77 enable_video_adapter_ = true; 73 enable_video_adapter_ = true;
78 // There are lots of video capturers out there that don't call 74 // There are lots of video capturers out there that don't call
79 // set_frame_factory. We can either go change all of them, or we 75 // set_frame_factory. We can either go change all of them, or we
80 // can set this default. 76 // can set this default.
81 // TODO(pthatcher): Remove this hack and require the frame factory 77 // TODO(pthatcher): Remove this hack and require the frame factory
82 // to be passed in the constructor. 78 // to be passed in the constructor.
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 wants.max_pixel_count_step_up); 213 wants.max_pixel_count_step_up);
218 } 214 }
219 } 215 }
220 216
221 void VideoCapturer::OnFrameCaptured(VideoCapturer*, 217 void VideoCapturer::OnFrameCaptured(VideoCapturer*,
222 const CapturedFrame* captured_frame) { 218 const CapturedFrame* captured_frame) {
223 if (!broadcaster_.frame_wanted()) { 219 if (!broadcaster_.frame_wanted()) {
224 return; 220 return;
225 } 221 }
226 222
227 // Use a temporary buffer to scale 223 int adapted_width = captured_frame->width;
228 std::unique_ptr<uint8_t[]> scale_buffer; 224 int adapted_height = captured_frame->height;
229 if (IsScreencast()) {
230 int scaled_width, scaled_height;
231 int desired_screencast_fps =
232 capture_format_.get()
233 ? VideoFormat::IntervalToFps(capture_format_->interval)
234 : kDefaultScreencastFps;
235 ComputeScale(captured_frame->width, captured_frame->height,
236 desired_screencast_fps, &scaled_width, &scaled_height);
237
238 if (FOURCC_ARGB == captured_frame->fourcc &&
239 (scaled_width != captured_frame->width ||
240 scaled_height != captured_frame->height)) {
241 if (scaled_width != scaled_width_ || scaled_height != scaled_height_) {
242 LOG(LS_INFO) << "Scaling Screencast from " << captured_frame->width
243 << "x" << captured_frame->height << " to " << scaled_width
244 << "x" << scaled_height;
245 scaled_width_ = scaled_width;
246 scaled_height_ = scaled_height;
247 }
248 CapturedFrame* modified_frame =
249 const_cast<CapturedFrame*>(captured_frame);
250 const int modified_frame_size = scaled_width * scaled_height * 4;
251 scale_buffer.reset(new uint8_t[modified_frame_size]);
252 // Compute new width such that width * height is less than maximum but
253 // maintains original captured frame aspect ratio.
254 // Round down width to multiple of 4 so odd width won't round up beyond
255 // maximum, and so chroma channel is even width to simplify spatial
256 // resampling.
257 libyuv::ARGBScale(reinterpret_cast<const uint8_t*>(captured_frame->data),
258 captured_frame->width * 4, captured_frame->width,
259 captured_frame->height, scale_buffer.get(),
260 scaled_width * 4, scaled_width, scaled_height,
261 libyuv::kFilterBilinear);
262 modified_frame->width = scaled_width;
263 modified_frame->height = scaled_height;
264 modified_frame->data_size = scaled_width * 4 * scaled_height;
265 modified_frame->data = scale_buffer.get();
266 }
267 }
268
269 const int kYuy2Bpp = 2;
270 const int kArgbBpp = 4;
271 // TODO(fbarchard): Make a helper function to adjust pixels to square.
272 // TODO(fbarchard): Hook up experiment to scaling.
273 // Temporary buffer is scoped here so it will persist until i420_frame.Init()
274 // makes a copy of the frame, converting to I420.
275 std::unique_ptr<uint8_t[]> temp_buffer;
276 // YUY2 can be scaled vertically using an ARGB scaler. Aspect ratio is only
277 // a problem on OSX. OSX always converts webcams to YUY2 or UYVY.
278 bool can_scale =
279 FOURCC_YUY2 == CanonicalFourCC(captured_frame->fourcc) ||
280 FOURCC_UYVY == CanonicalFourCC(captured_frame->fourcc);
281
282 // If pixels are not square, optionally use vertical scaling to make them
283 // square. Square pixels simplify the rest of the pipeline, including
284 // effects and rendering.
285 if (can_scale && square_pixel_aspect_ratio_ &&
286 captured_frame->pixel_width != captured_frame->pixel_height) {
287 int scaled_width, scaled_height;
288 // modified_frame points to the captured_frame but with const casted away
289 // so it can be modified.
290 CapturedFrame* modified_frame = const_cast<CapturedFrame*>(captured_frame);
291 // Compute the frame size that makes pixels square pixel aspect ratio.
292 ComputeScaleToSquarePixels(captured_frame->width, captured_frame->height,
293 captured_frame->pixel_width,
294 captured_frame->pixel_height,
295 &scaled_width, &scaled_height);
296
297 if (scaled_width != scaled_width_ || scaled_height != scaled_height_) {
298 LOG(LS_INFO) << "Scaling WebCam from "
299 << captured_frame->width << "x"
300 << captured_frame->height << " to "
301 << scaled_width << "x" << scaled_height
302 << " for PAR "
303 << captured_frame->pixel_width << "x"
304 << captured_frame->pixel_height;
305 scaled_width_ = scaled_width;
306 scaled_height_ = scaled_height;
307 }
308 const int modified_frame_size = scaled_width * scaled_height * kYuy2Bpp;
309 uint8_t* temp_buffer_data;
310 // Pixels are wide and short; Increasing height. Requires temporary buffer.
311 if (scaled_height > captured_frame->height) {
312 temp_buffer.reset(new uint8_t[modified_frame_size]);
313 temp_buffer_data = temp_buffer.get();
314 } else {
315 // Pixels are narrow and tall; Decreasing height. Scale will be done
316 // in place.
317 temp_buffer_data = reinterpret_cast<uint8_t*>(captured_frame->data);
318 }
319
320 // Use ARGBScaler to vertically scale the YUY2 image, adjusting for 16 bpp.
321 libyuv::ARGBScale(reinterpret_cast<const uint8_t*>(captured_frame->data),
322 captured_frame->width * kYuy2Bpp, // Stride for YUY2.
323 captured_frame->width * kYuy2Bpp / kArgbBpp, // Width.
324 abs(captured_frame->height), // Height.
325 temp_buffer_data,
326 scaled_width * kYuy2Bpp, // Stride for YUY2.
327 scaled_width * kYuy2Bpp / kArgbBpp, // Width.
328 abs(scaled_height), // New height.
329 libyuv::kFilterBilinear);
330 modified_frame->width = scaled_width;
331 modified_frame->height = scaled_height;
332 modified_frame->pixel_width = 1;
333 modified_frame->pixel_height = 1;
334 modified_frame->data_size = modified_frame_size;
335 modified_frame->data = temp_buffer_data;
336 }
337
338 // Size to crop captured frame to. This adjusts the captured frames
339 // aspect ratio to match the final view aspect ratio, considering pixel
340 // aspect ratio and rotation. The final size may be scaled down by video
341 // adapter to better match ratio_w_ x ratio_h_.
342 // Note that abs() of frame height is passed in, because source may be
343 // inverted, but output will be positive.
344 int cropped_width = captured_frame->width;
345 int cropped_height = captured_frame->height;
346
347 // TODO(fbarchard): Improve logic to pad or crop.
348 // MJPG can crop vertically, but not horizontally. This logic disables crop.
349 // Alternatively we could pad the image with black, or implement a 2 step
350 // crop.
351 bool can_crop = true;
352 if (captured_frame->fourcc == FOURCC_MJPG) {
353 float cam_aspect = static_cast<float>(captured_frame->width) /
354 static_cast<float>(captured_frame->height);
355 float view_aspect = static_cast<float>(ratio_w_) /
356 static_cast<float>(ratio_h_);
357 can_crop = cam_aspect <= view_aspect;
358 }
359 if (can_crop && !IsScreencast()) {
360 // TODO(ronghuawu): The capturer should always produce the native
361 // resolution and the cropping should be done in downstream code.
362 ComputeCrop(ratio_w_, ratio_h_, captured_frame->width,
363 abs(captured_frame->height), captured_frame->pixel_width,
364 captured_frame->pixel_height, captured_frame->rotation,
365 &cropped_width, &cropped_height);
366 }
367
368 int adapted_width = cropped_width;
369 int adapted_height = cropped_height;
370 if (enable_video_adapter_ && !IsScreencast()) { 225 if (enable_video_adapter_ && !IsScreencast()) {
371 const VideoFormat adapted_format = 226 const VideoFormat adapted_format =
372 video_adapter_.AdaptFrameResolution(cropped_width, cropped_height); 227 video_adapter_.AdaptFrameResolution(adapted_width, adapted_height);
373 if (adapted_format.IsSize0x0()) { 228 if (adapted_format.IsSize0x0()) {
374 // VideoAdapter dropped the frame. 229 // VideoAdapter dropped the frame.
375 return; 230 return;
376 } 231 }
377 adapted_width = adapted_format.width; 232 adapted_width = adapted_format.width;
378 adapted_height = adapted_format.height; 233 adapted_height = adapted_format.height;
379 } 234 }
380 235
381 if (!frame_factory_) { 236 if (!frame_factory_) {
382 LOG(LS_ERROR) << "No video frame factory."; 237 LOG(LS_ERROR) << "No video frame factory.";
383 return; 238 return;
384 } 239 }
385 240
386 std::unique_ptr<VideoFrame> adapted_frame( 241 // TODO(nisse): Reorganize frame factory methods, deleting crop
387 frame_factory_->CreateAliasedFrame(captured_frame, 242 // support there too.
388 cropped_width, cropped_height, 243 std::unique_ptr<VideoFrame> adapted_frame(frame_factory_->CreateAliasedFrame(
389 adapted_width, adapted_height)); 244 captured_frame, captured_frame->width, captured_frame->height,
245 adapted_width, adapted_height));
390 246
391 if (!adapted_frame) { 247 if (!adapted_frame) {
392 // TODO(fbarchard): LOG more information about captured frame attributes. 248 // TODO(fbarchard): LOG more information about captured frame attributes.
perkj_webrtc 2016/05/04 10:47:45 maybe remove this TODO too.
393 LOG(LS_ERROR) << "Couldn't convert to I420! " 249 LOG(LS_ERROR) << "Couldn't convert to I420! "
394 << "From " << ToString(captured_frame) << " To " 250 << "From " << ToString(captured_frame) << " To "
395 << cropped_width << " x " << cropped_height; 251 << adapted_width << " x " << adapted_height;
396 return; 252 return;
397 } 253 }
398 254
399 OnFrame(this, adapted_frame.get()); 255 OnFrame(this, adapted_frame.get());
400 UpdateInputSize(captured_frame); 256 UpdateInputSize(captured_frame);
401 } 257 }
402 258
403 void VideoCapturer::OnFrame(VideoCapturer* capturer, const VideoFrame* frame) { 259 void VideoCapturer::OnFrame(VideoCapturer* capturer, const VideoFrame* frame) {
404 broadcaster_.OnFrame(*frame); 260 broadcaster_.OnFrame(*frame);
405 } 261 }
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
545 void VideoCapturer::UpdateInputSize(const CapturedFrame* captured_frame) { 401 void VideoCapturer::UpdateInputSize(const CapturedFrame* captured_frame) {
546 // Update stats protected from fetches from different thread. 402 // Update stats protected from fetches from different thread.
547 rtc::CritScope cs(&frame_stats_crit_); 403 rtc::CritScope cs(&frame_stats_crit_);
548 404
549 input_size_valid_ = true; 405 input_size_valid_ = true;
550 input_width_ = captured_frame->width; 406 input_width_ = captured_frame->width;
551 input_height_ = captured_frame->height; 407 input_height_ = captured_frame->height;
552 } 408 }
553 409
554 } // namespace cricket 410 } // namespace cricket
OLDNEW
« no previous file with comments | « webrtc/media/base/videocapturer.h ('k') | webrtc/media/base/videocommon.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698