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

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: Add basic tests for unchanged frames Created 5 years, 6 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 (!use_vp9_ || lossless_encode_) {
270 // Neither VP8 nor VP9-lossless support top-off, so ignore unchanged frames.
271 if (frame.updated_region().is_empty())
272 return nullptr;
273 } else {
274 // Let VP9-lossy mode top-off, by continuing to pass it unchanged frames
275 // for a short while.
276 if (frame.updated_region().is_empty()) {
277 if (topoff_frame_count_ > 0) {
278 topoff_frame_count_--;
279 } else {
280 return nullptr;
281 }
282 } else {
283 topoff_frame_count_ = 2;
284 }
285 }
286
271 base::TimeTicks encode_start_time = base::TimeTicks::Now(); 287 base::TimeTicks encode_start_time = base::TimeTicks::Now();
272 288
273 // Create or reconfigure the codec to match the size of |frame|. 289 // Create or reconfigure the codec to match the size of |frame|.
274 if (!codec_ || 290 if (!codec_ ||
275 (image_ && 291 (image_ &&
276 !frame.size().equals(webrtc::DesktopSize(image_->w, image_->h)))) { 292 !frame.size().equals(webrtc::DesktopSize(image_->w, image_->h)))) {
277 Configure(frame.size()); 293 Configure(frame.size());
278 } 294 }
279 295
280 // Convert the updated capture data ready for encode. 296 // Convert the updated capture data ready for encode.
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 } 352 }
337 } 353 }
338 354
339 // Note the time taken to encode the pixel data. 355 // Note the time taken to encode the pixel data.
340 packet->set_encode_time_ms( 356 packet->set_encode_time_ms(
341 (base::TimeTicks::Now() - encode_start_time).InMillisecondsRoundedUp()); 357 (base::TimeTicks::Now() - encode_start_time).InMillisecondsRoundedUp());
342 358
343 return packet.Pass(); 359 return packet.Pass();
344 } 360 }
345 361
346 VideoEncoderVpx::VideoEncoderVpx(bool use_vp9) 362 VideoEncoderVpx::VideoEncoderVpx(bool use_vp9) : use_vp9_(use_vp9) {
347 : use_vp9_(use_vp9),
348 lossless_encode_(false),
349 lossless_color_(false),
350 active_map_width_(0),
351 active_map_height_(0) {
352 if (use_vp9_) {
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 } 363 }
360 364
361 void VideoEncoderVpx::Configure(const webrtc::DesktopSize& size) { 365 void VideoEncoderVpx::Configure(const webrtc::DesktopSize& size) {
362 DCHECK(use_vp9_ || !lossless_color_); 366 DCHECK(use_vp9_ || !lossless_color_);
363 DCHECK(use_vp9_ || !lossless_encode_); 367 DCHECK(use_vp9_ || !lossless_encode_);
364 368
365 // Tear down |image_| if it no longer matches the size and color settings. 369 // 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 370 // PrepareImage() will then create a new buffer of the required dimensions if
367 // |image_| is not allocated. 371 // |image_| is not allocated.
368 FreeImageIfMismatched(lossless_color_, size, &image_, &image_buffer_); 372 FreeImageIfMismatched(lossless_color_, size, &image_, &image_buffer_);
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
543 kMacroBlockSize * (y + 1))); 547 kMacroBlockSize * (y + 1)));
544 } 548 }
545 x0 = x1 + 1; 549 x0 = x1 + 1;
546 } 550 }
547 } 551 }
548 updated_region->IntersectWith( 552 updated_region->IntersectWith(
549 webrtc::DesktopRect::MakeWH(image_->w, image_->h)); 553 webrtc::DesktopRect::MakeWH(image_->w, image_->h));
550 } 554 }
551 555
552 } // namespace remoting 556 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698