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

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

Issue 1092813003: Enable Cyclic Refresh for VP9. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@chromium_vp9_6_1
Patch Set: Created 5 years, 8 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" 8 #include "base/command_line.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/sys_info.h" 10 #include "base/sys_info.h"
(...skipping 21 matching lines...) Expand all
32 const int kBytesPerRgbPixel = 4; 32 const int kBytesPerRgbPixel = 4;
33 33
34 // Defines the dimension of a macro block. This is used to compute the active 34 // Defines the dimension of a macro block. This is used to compute the active
35 // map for the encoder. 35 // map for the encoder.
36 const int kMacroBlockSize = 16; 36 const int kMacroBlockSize = 16;
37 37
38 // Magic encoder profile numbers for I420 and I444 input formats. 38 // Magic encoder profile numbers for I420 and I444 input formats.
39 const int kVp9I420ProfileNumber = 0; 39 const int kVp9I420ProfileNumber = 0;
40 const int kVp9I444ProfileNumber = 1; 40 const int kVp9I444ProfileNumber = 1;
41 41
42 // Magic encoder constants for adaptive quantization strategy
43 const int kVp9AqNone = 0;
44 const int kVp9AqCyclicRefresh = 3;
Wez 2015/04/18 00:17:54 nit: Suggest these start kVp9AqMode, for consisten
aconverse 2015/04/20 18:32:38 Done.
45
42 void SetCommonCodecParameters(vpx_codec_enc_cfg_t* config, 46 void SetCommonCodecParameters(vpx_codec_enc_cfg_t* config,
43 const webrtc::DesktopSize& size) { 47 const webrtc::DesktopSize& size) {
44 // Use millisecond granularity time base. 48 // Use millisecond granularity time base.
45 config->g_timebase.num = 1; 49 config->g_timebase.num = 1;
46 config->g_timebase.den = 1000; 50 config->g_timebase.den = 1000;
47 51
48 config->g_w = size.width(); 52 config->g_w = size.width();
49 config->g_h = size.height(); 53 config->g_h = size.height();
50 config->g_pass = VPX_RC_ONE_PASS; 54 config->g_pass = VPX_RC_ONE_PASS;
51 55
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 131
128 // Use the lowest level of noise sensitivity so as to spend less time 132 // Use the lowest level of noise sensitivity so as to spend less time
129 // on motion estimation and inter-prediction mode. 133 // on motion estimation and inter-prediction mode.
130 ret = vpx_codec_control(codec, VP9E_SET_NOISE_SENSITIVITY, 0); 134 ret = vpx_codec_control(codec, VP9E_SET_NOISE_SENSITIVITY, 0);
131 DCHECK_EQ(VPX_CODEC_OK, ret) << "Failed to set noise sensitivity"; 135 DCHECK_EQ(VPX_CODEC_OK, ret) << "Failed to set noise sensitivity";
132 136
133 // Configure the codec to tune it for screen media. 137 // Configure the codec to tune it for screen media.
134 ret = vpx_codec_control( 138 ret = vpx_codec_control(
135 codec, VP9E_SET_TUNE_CONTENT, VP9E_CONTENT_SCREEN); 139 codec, VP9E_SET_TUNE_CONTENT, VP9E_CONTENT_SCREEN);
136 DCHECK_EQ(VPX_CODEC_OK, ret) << "Failed to set screen content mode"; 140 DCHECK_EQ(VPX_CODEC_OK, ret) << "Failed to set screen content mode";
141
142 // Set cyclic refresh for lossy encode
Wez 2015/04/18 00:17:54 nit: missing . Suggest "Enable cyclic refresh (ak
aconverse 2015/04/20 18:32:38 Done.
143 int aq_mode = lossless_encode ? kVp9AqNone : kVp9AqCyclicRefresh;
144 ret = vpx_codec_control(codec, VP9E_SET_AQ_MODE, aq_mode);
145 DCHECK_EQ(VPX_CODEC_OK, ret) << "Failed to set aq mode";
137 } 146 }
138 147
139 void FreeImageIfMismatched(bool use_i444, 148 void FreeImageIfMismatched(bool use_i444,
140 const webrtc::DesktopSize& size, 149 const webrtc::DesktopSize& size,
141 scoped_ptr<vpx_image_t>* out_image, 150 scoped_ptr<vpx_image_t>* out_image,
142 scoped_ptr<uint8[]>* out_image_buffer) { 151 scoped_ptr<uint8[]>* out_image_buffer) {
143 if (*out_image) { 152 if (*out_image) {
144 const vpx_img_fmt_t desired_fmt = 153 const vpx_img_fmt_t desired_fmt =
145 use_i444 ? VPX_IMG_FMT_I444 : VPX_IMG_FMT_I420; 154 use_i444 ? VPX_IMG_FMT_I444 : VPX_IMG_FMT_I420;
146 if (!size.equals(webrtc::DesktopSize((*out_image)->w, (*out_image)->h)) || 155 if (!size.equals(webrtc::DesktopSize((*out_image)->w, (*out_image)->h)) ||
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 292
284 // Do the actual encoding. 293 // Do the actual encoding.
285 int timestamp = (encode_start_time - timestamp_base_).InMilliseconds(); 294 int timestamp = (encode_start_time - timestamp_base_).InMilliseconds();
286 vpx_codec_err_t ret = vpx_codec_encode( 295 vpx_codec_err_t ret = vpx_codec_encode(
287 codec_.get(), image_.get(), timestamp, 1, 0, VPX_DL_REALTIME); 296 codec_.get(), image_.get(), timestamp, 1, 0, VPX_DL_REALTIME);
288 DCHECK_EQ(ret, VPX_CODEC_OK) 297 DCHECK_EQ(ret, VPX_CODEC_OK)
289 << "Encoding error: " << vpx_codec_err_to_string(ret) << "\n" 298 << "Encoding error: " << vpx_codec_err_to_string(ret) << "\n"
290 << "Details: " << vpx_codec_error(codec_.get()) << "\n" 299 << "Details: " << vpx_codec_error(codec_.get()) << "\n"
291 << vpx_codec_error_detail(codec_.get()); 300 << vpx_codec_error_detail(codec_.get());
292 301
302 if (use_vp9_) {
303 if (vpx_codec_control(codec_.get(), VP9E_GET_ACTIVEMAP, &act_map) ==
304 VPX_CODEC_OK) {
Wez 2015/04/18 00:17:54 Is there any point calling this if we are already
aconverse 2015/04/20 18:32:39 Done.
305 UpdateActiveMap(&updated_region);
306 } else {
307 LOG(ERROR) << "Failed to fetch active map";
308 updated_region.Clear();
309 updated_region.AddRect(webrtc::DesktopRect::MakeWH(image_->w, image_->h));
Wez 2015/04/18 00:17:54 Under what circumstances can the get call fail? Sh
aconverse 2015/04/20 18:32:39 I was following the example of SET_ACTIVEMAP. Neit
Wez 2015/04/21 01:29:18 Ah, OK; we should probably have SET_ACTIVEMAP erro
310 }
311 }
312
293 // Read the encoded data. 313 // Read the encoded data.
294 vpx_codec_iter_t iter = NULL; 314 vpx_codec_iter_t iter = NULL;
295 bool got_data = false; 315 bool got_data = false;
296 316
297 // TODO(hclam): Make sure we get exactly one frame from the packet. 317 // TODO(hclam): Make sure we get exactly one frame from the packet.
298 // TODO(hclam): We should provide the output buffer to avoid one copy. 318 // TODO(hclam): We should provide the output buffer to avoid one copy.
299 scoped_ptr<VideoPacket> packet( 319 scoped_ptr<VideoPacket> packet(
300 helper_.CreateVideoPacketWithUpdatedRegion(frame, updated_region)); 320 helper_.CreateVideoPacketWithUpdatedRegion(frame, updated_region));
301 packet->mutable_format()->set_encoding(VideoPacketFormat::ENCODING_VP8); 321 packet->mutable_format()->set_encoding(VideoPacketFormat::ENCODING_VP8);
302 322
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
500 520
501 uint8* map = active_map_.get() + top * active_map_width_; 521 uint8* map = active_map_.get() + top * active_map_width_;
502 for (int y = top; y <= bottom; ++y) { 522 for (int y = top; y <= bottom; ++y) {
503 for (int x = left; x <= right; ++x) 523 for (int x = left; x <= right; ++x)
504 map[x] = 1; 524 map[x] = 1;
505 map += active_map_width_; 525 map += active_map_width_;
506 } 526 }
507 } 527 }
508 } 528 }
509 529
530 void VideoEncoderVpx::UpdateActiveMap(webrtc::DesktopRegion *updated_region) {
531 uint8* map = active_map_.get();
532 // Mark active areas updated.
Wez 2015/04/18 00:17:54 nit: This comment doesn't fit this function; we're
aconverse 2015/04/20 18:32:38 We've already fetched the areas. We are marking th
Wez 2015/04/21 01:29:18 OK; suggest "Add areas marked active to |updated_r
533 for (int r = 0; r < active_map_height_; ++r) {
Wez 2015/04/18 00:17:54 Suggest r -> y
aconverse 2015/04/20 18:32:39 Done.
534 int c1;
Wez 2015/04/18 00:17:54 Move this inside the c0 loop?
aconverse 2015/04/20 18:32:38 This is used in the iteration condition so that we
Wez 2015/04/21 01:29:18 Gotcha; I think it might be more readable to decla
aconverse 2015/04/28 17:03:56 Done. lmk if I misunderstood
535 for (int c0 = 0; c0 < active_map_height_; c0 = c1 + 1) {
Wez 2015/04/18 00:17:54 Suggest c0 -> x0
Wez 2015/04/18 00:17:54 Looks like this should be |active_map_width_|?
aconverse 2015/04/20 18:32:39 Done.
aconverse 2015/04/20 18:32:39 Done.
536 for (c1 = c0; c1 < active_map_height_; ++c1) {
Wez 2015/04/18 00:17:54 Ditto.
aconverse 2015/04/20 18:32:38 Done.
537 if (map[c1] == 0)
aconverse 2015/04/20 18:32:39 Big oops on this line as well. [not taking row int
Wez 2015/04/21 01:29:18 Yes and no; no, we can't remove this, because we d
aconverse 2015/04/28 17:03:56 I should give this a try before we move forward.
538 break;
539 }
540 if (c1 > c0) {
541 updated_region->AddRect(webrtc::DesktopRect::MakeLTRB(
542 kMacroBlockSize * c0,
543 kMacroBlockSize * r,
544 kMacroBlockSize * c1,
545 kMacroBlockSize * (r + 1)));
546 }
547 }
548 }
549 updated_region->IntersectWith(
550 webrtc::DesktopRect::MakeWH(image_->w, image_->h));
551 }
552
510 } // namespace remoting 553 } // namespace remoting
OLDNEW
« remoting/codec/video_encoder_vpx.h ('K') | « remoting/codec/video_encoder_vpx.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698