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

Side by Side Diff: remoting/codec/video_encoder_vpx.cc

Issue 1150163002: Update VideoFramePump to pass un-changed frames to encoders. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Tweak comments Created 5 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
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 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 "remoting/codec/video_encoder_vpx.h" 5 #include "remoting/codec/video_encoder_vpx.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/command_line.h"
9 #include "base/logging.h" 8 #include "base/logging.h"
10 #include "base/sys_info.h" 9 #include "base/sys_info.h"
11 #include "remoting/base/util.h" 10 #include "remoting/base/util.h"
12 #include "remoting/proto/video.pb.h" 11 #include "remoting/proto/video.pb.h"
13 #include "third_party/libyuv/include/libyuv/convert_from_argb.h" 12 #include "third_party/libyuv/include/libyuv/convert_from_argb.h"
14 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" 13 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
15 #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h" 14 #include "third_party/webrtc/modules/desktop_capture/desktop_geometry.h"
16 #include "third_party/webrtc/modules/desktop_capture/desktop_region.h" 15 #include "third_party/webrtc/modules/desktop_capture/desktop_region.h"
17 16
18 extern "C" { 17 extern "C" {
19 #define VPX_CODEC_DISABLE_COMPAT 1 18 #define VPX_CODEC_DISABLE_COMPAT 1
20 #include "third_party/libvpx/source/libvpx/vpx/vpx_encoder.h" 19 #include "third_party/libvpx/source/libvpx/vpx/vpx_encoder.h"
21 #include "third_party/libvpx/source/libvpx/vpx/vp8cx.h" 20 #include "third_party/libvpx/source/libvpx/vpx/vp8cx.h"
22 } 21 }
23 22
24 namespace remoting { 23 namespace remoting {
25 24
26 namespace { 25 namespace {
27 26
28 // Name of command-line flag to enable VP9 to use I444 by default.
29 const char kEnableI444SwitchName[] = "enable-i444";
30
31 // Number of bytes in an RGBx pixel. 27 // Number of bytes in an RGBx pixel.
32 const int kBytesPerRgbPixel = 4; 28 const int kBytesPerRgbPixel = 4;
33 29
34 // Defines the dimension of a macro block. This is used to compute the active 30 // Defines the dimension of a macro block. This is used to compute the active
35 // map for the encoder. 31 // map for the encoder.
36 const int kMacroBlockSize = 16; 32 const int kMacroBlockSize = 16;
37 33
38 // Magic encoder profile numbers for I420 and I444 input formats. 34 // Magic encoder profile numbers for I420 and I444 input formats.
39 const int kVp9I420ProfileNumber = 0; 35 const int kVp9I420ProfileNumber = 0;
40 const int kVp9I444ProfileNumber = 1; 36 const int kVp9I444ProfileNumber = 1;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
96 // Configure VP9 for I420 or I444 source frames. 92 // Configure VP9 for I420 or I444 source frames.
97 config->g_profile = 93 config->g_profile =
98 lossless_color ? kVp9I444ProfileNumber : kVp9I420ProfileNumber; 94 lossless_color ? kVp9I444ProfileNumber : kVp9I420ProfileNumber;
99 95
100 if (lossless_encode) { 96 if (lossless_encode) {
101 // Disable quantization entirely, putting the encoder in "lossless" mode. 97 // Disable quantization entirely, putting the encoder in "lossless" mode.
102 config->rc_min_quantizer = 0; 98 config->rc_min_quantizer = 0;
103 config->rc_max_quantizer = 0; 99 config->rc_max_quantizer = 0;
104 config->rc_end_usage = VPX_VBR; 100 config->rc_end_usage = VPX_VBR;
105 } else { 101 } else {
106 config->rc_min_quantizer = 4; 102 // TODO(wez): Set quantization range to 4-40, once the libvpx encoder is
103 // updated not to output any bits if nothing needs topping-off.
104 config->rc_min_quantizer = 20;
107 config->rc_max_quantizer = 30; 105 config->rc_max_quantizer = 30;
108 config->rc_end_usage = VPX_CBR; 106 config->rc_end_usage = VPX_CBR;
109 // In the absence of a good bandwidth estimator set the target bitrate to a 107 // In the absence of a good bandwidth estimator set the target bitrate to a
110 // conservative default. 108 // conservative default.
111 config->rc_target_bitrate = 500; 109 config->rc_target_bitrate = 500;
112 } 110 }
113 } 111 }
114 112
115 void SetVp8CodecOptions(vpx_codec_ctx_t* codec) { 113 void SetVp8CodecOptions(vpx_codec_ctx_t* codec) {
116 // CPUUSED of 16 will have the smallest CPU load. This turns off sub-pixel 114 // CPUUSED of 16 will have the smallest CPU load. This turns off sub-pixel
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 // codec_->config.enc->g_h)); 259 // codec_->config.enc->g_h));
262 codec_.reset(); 260 codec_.reset();
263 } 261 }
264 } 262 }
265 263
266 scoped_ptr<VideoPacket> VideoEncoderVpx::Encode( 264 scoped_ptr<VideoPacket> VideoEncoderVpx::Encode(
267 const webrtc::DesktopFrame& frame) { 265 const webrtc::DesktopFrame& frame) {
268 DCHECK_LE(32, frame.size().width()); 266 DCHECK_LE(32, frame.size().width());
269 DCHECK_LE(32, frame.size().height()); 267 DCHECK_LE(32, frame.size().height());
270 268
269 // If nothing has changed, then only encode data to top-off from lossy to
270 // lossless quantization.
271 if (frame.updated_region().is_empty()) {
272 // VP8 doesn't support top-off, and VP9's lossless mode doesn't need it.
273 if (!use_vp9_ || lossless_encode_)
274 return nullptr;
275 if (!--topoff_frame_count_) {
Sergey Ulanov 2015/05/26 21:57:22 nit: --topoff_frame_count > 0 (or != 0) would be m
Wez 2015/06/09 01:46:20 Plus, in cleaning it up, I fixed a bug in my imple
276 return nullptr;
277 }
278 } else {
279 // Just allow a couple of fully empty frames' worth of top-off.
280 topoff_frame_count_ = 2;
Sergey Ulanov 2015/05/26 21:57:22 topoff_frame_count_ is set even when using VP8, bu
Wez 2015/06/09 01:46:20 Done.
281 }
282
271 base::TimeTicks encode_start_time = base::TimeTicks::Now(); 283 base::TimeTicks encode_start_time = base::TimeTicks::Now();
272 284
273 // Create or reconfigure the codec to match the size of |frame|. 285 // Create or reconfigure the codec to match the size of |frame|.
274 if (!codec_ || 286 if (!codec_ ||
275 (image_ && 287 (image_ &&
276 !frame.size().equals(webrtc::DesktopSize(image_->w, image_->h)))) { 288 !frame.size().equals(webrtc::DesktopSize(image_->w, image_->h)))) {
277 Configure(frame.size()); 289 Configure(frame.size());
278 } 290 }
279 291
280 // Convert the updated capture data ready for encode. 292 // Convert the updated capture data ready for encode.
281 webrtc::DesktopRegion updated_region; 293 webrtc::DesktopRegion updated_region;
282 PrepareImage(frame, &updated_region); 294 PrepareImage(frame, &updated_region);
283 295
284 // Update active map based on updated region. 296 // Update active map based on updated region.
285 SetActiveMapFromRegion(updated_region); 297 SetActiveMapFromRegion(updated_region);
Sergey Ulanov 2015/05/26 21:57:22 Do we need to supply active map for top-off, or do
Wez 2015/06/09 01:46:20 Cyclic Refresh will top-off even during "active" f
286 298
287 // Apply active map to the encoder. 299 // Apply active map to the encoder.
288 vpx_active_map_t act_map; 300 vpx_active_map_t act_map;
289 act_map.rows = active_map_height_; 301 act_map.rows = active_map_height_;
290 act_map.cols = active_map_width_; 302 act_map.cols = active_map_width_;
291 act_map.active_map = active_map_.get(); 303 act_map.active_map = active_map_.get();
292 if (vpx_codec_control(codec_.get(), VP8E_SET_ACTIVEMAP, &act_map)) { 304 if (vpx_codec_control(codec_.get(), VP8E_SET_ACTIVEMAP, &act_map)) {
293 LOG(ERROR) << "Unable to apply active map"; 305 LOG(ERROR) << "Unable to apply active map";
294 } 306 }
295 307
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 (base::TimeTicks::Now() - encode_start_time).InMillisecondsRoundedUp()); 353 (base::TimeTicks::Now() - encode_start_time).InMillisecondsRoundedUp());
342 354
343 return packet.Pass(); 355 return packet.Pass();
344 } 356 }
345 357
346 VideoEncoderVpx::VideoEncoderVpx(bool use_vp9) 358 VideoEncoderVpx::VideoEncoderVpx(bool use_vp9)
347 : use_vp9_(use_vp9), 359 : use_vp9_(use_vp9),
348 lossless_encode_(false), 360 lossless_encode_(false),
349 lossless_color_(false), 361 lossless_color_(false),
350 active_map_width_(0), 362 active_map_width_(0),
351 active_map_height_(0) { 363 active_map_height_(0),
352 if (use_vp9_) { 364 topoff_frame_count_(0) {
353 // Use I444 colour space, by default, if specified on the command-line.
354 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
355 kEnableI444SwitchName)) {
356 SetLosslessColor(true);
357 }
358 }
359 } 365 }
360 366
361 void VideoEncoderVpx::Configure(const webrtc::DesktopSize& size) { 367 void VideoEncoderVpx::Configure(const webrtc::DesktopSize& size) {
362 DCHECK(use_vp9_ || !lossless_color_); 368 DCHECK(use_vp9_ || !lossless_color_);
363 DCHECK(use_vp9_ || !lossless_encode_); 369 DCHECK(use_vp9_ || !lossless_encode_);
364 370
365 // Tear down |image_| if it no longer matches the size and color settings. 371 // Tear down |image_| if it no longer matches the size and color settings.
366 // PrepareImage() will then create a new buffer of the required dimensions if 372 // PrepareImage() will then create a new buffer of the required dimensions if
367 // |image_| is not allocated. 373 // |image_| is not allocated.
368 FreeImageIfMismatched(lossless_color_, size, &image_, &image_buffer_); 374 FreeImageIfMismatched(lossless_color_, size, &image_, &image_buffer_);
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
543 kMacroBlockSize * (y + 1))); 549 kMacroBlockSize * (y + 1)));
544 } 550 }
545 x0 = x1 + 1; 551 x0 = x1 + 1;
546 } 552 }
547 } 553 }
548 updated_region->IntersectWith( 554 updated_region->IntersectWith(
549 webrtc::DesktopRect::MakeWH(image_->w, image_->h)); 555 webrtc::DesktopRect::MakeWH(image_->w, image_->h));
550 } 556 }
551 557
552 } // namespace remoting 558 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698