Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 27 matching lines...) Expand all Loading... | |
| 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 void SetCommonCodecParameters(vpx_codec_enc_cfg_t* config, | 42 void SetCommonCodecParameters(vpx_codec_enc_cfg_t* config, |
| 43 const webrtc::DesktopSize& size) { | 43 const webrtc::DesktopSize& size) { |
| 44 // Use millisecond granularity time base. | 44 // Use millisecond granularity time base. |
| 45 config->g_timebase.num = 1; | 45 config->g_timebase.num = 1; |
| 46 config->g_timebase.den = 1000; | 46 config->g_timebase.den = 1000; |
| 47 | 47 |
| 48 // Adjust default target bit-rate to account for actual desktop size. | |
| 49 config->rc_target_bitrate = size.width() * size.height() * | |
| 50 config->rc_target_bitrate / config->g_w / config->g_h; | |
| 51 | |
| 52 config->g_w = size.width(); | 48 config->g_w = size.width(); |
| 53 config->g_h = size.height(); | 49 config->g_h = size.height(); |
| 54 config->g_pass = VPX_RC_ONE_PASS; | 50 config->g_pass = VPX_RC_ONE_PASS; |
| 55 | 51 |
| 56 // Start emitting packets immediately. | 52 // Start emitting packets immediately. |
| 57 config->g_lag_in_frames = 0; | 53 config->g_lag_in_frames = 0; |
| 58 | 54 |
| 59 // Since the transport layer is reliable, keyframes should not be necessary. | 55 // Since the transport layer is reliable, keyframes should not be necessary. |
| 60 // However, due to crbug.com/440223, decoding fails after 30,000 non-key | 56 // However, due to crbug.com/440223, decoding fails after 30,000 non-key |
| 61 // frames, so take the hit of an "unnecessary" key-frame every 10,000 frames. | 57 // frames, so take the hit of an "unnecessary" key-frame every 10,000 frames. |
| 62 config->kf_min_dist = 10000; | 58 config->kf_min_dist = 10000; |
| 63 config->kf_max_dist = 10000; | 59 config->kf_max_dist = 10000; |
| 64 | 60 |
| 65 // Using 2 threads gives a great boost in performance for most systems with | 61 // Using 2 threads gives a great boost in performance for most systems with |
| 66 // adequate processing power. NB: Going to multiple threads on low end | 62 // adequate processing power. NB: Going to multiple threads on low end |
| 67 // windows systems can really hurt performance. | 63 // windows systems can really hurt performance. |
| 68 // http://crbug.com/99179 | 64 // http://crbug.com/99179 |
| 69 config->g_threads = (base::SysInfo::NumberOfProcessors() > 2) ? 2 : 1; | 65 config->g_threads = (base::SysInfo::NumberOfProcessors() > 2) ? 2 : 1; |
| 70 } | 66 } |
| 71 | 67 |
| 72 void SetVp8CodecParameters(vpx_codec_enc_cfg_t* config, | 68 void SetVp8CodecParameters(vpx_codec_enc_cfg_t* config, |
| 73 const webrtc::DesktopSize& size) { | 69 const webrtc::DesktopSize& size) { |
| 70 // Adjust default target bit-rate to account for actual desktop size. | |
| 71 config->rc_target_bitrate = size.width() * size.height() * | |
| 72 config->rc_target_bitrate / config->g_w / config->g_h; | |
| 73 | |
| 74 SetCommonCodecParameters(config, size); | 74 SetCommonCodecParameters(config, size); |
| 75 | 75 |
| 76 // Value of 2 means using the real time profile. This is basically a | 76 // Value of 2 means using the real time profile. This is basically a |
| 77 // redundant option since we explicitly select real time mode when doing | 77 // redundant option since we explicitly select real time mode when doing |
| 78 // encoding. | 78 // encoding. |
| 79 config->g_profile = 2; | 79 config->g_profile = 2; |
| 80 | 80 |
| 81 // Clamping the quantizer constrains the worst-case quality and CPU usage. | 81 // Clamping the quantizer constrains the worst-case quality and CPU usage. |
| 82 config->rc_min_quantizer = 20; | 82 config->rc_min_quantizer = 20; |
| 83 config->rc_max_quantizer = 30; | 83 config->rc_max_quantizer = 30; |
| 84 } | 84 } |
| 85 | 85 |
| 86 void SetVp9CodecParameters(vpx_codec_enc_cfg_t* config, | 86 void SetVp9CodecParameters(vpx_codec_enc_cfg_t* config, |
| 87 const webrtc::DesktopSize& size, | 87 const webrtc::DesktopSize& size, |
| 88 bool lossless_color, | 88 bool lossless_color, |
| 89 bool lossless_encode) { | 89 bool lossless_encode) { |
| 90 SetCommonCodecParameters(config, size); | 90 SetCommonCodecParameters(config, size); |
| 91 | 91 |
| 92 // Configure VP9 for I420 or I444 source frames. | 92 // Configure VP9 for I420 or I444 source frames. |
| 93 config->g_profile = | 93 config->g_profile = |
| 94 lossless_color ? kVp9I444ProfileNumber : kVp9I420ProfileNumber; | 94 lossless_color ? kVp9I444ProfileNumber : kVp9I420ProfileNumber; |
| 95 | 95 |
| 96 if (lossless_encode) { | 96 if (lossless_encode) { |
| 97 // Disable quantization entirely, putting the encoder in "lossless" mode. | 97 // Disable quantization entirely, putting the encoder in "lossless" mode. |
| 98 config->rc_min_quantizer = 0; | 98 config->rc_min_quantizer = 0; |
| 99 config->rc_max_quantizer = 0; | 99 config->rc_max_quantizer = 0; |
| 100 } else { | 100 } else { |
| 101 // Lossy encode using the same settings as for VP8. | 101 config->rc_min_quantizer = 4; |
| 102 config->rc_min_quantizer = 20; | |
| 103 config->rc_max_quantizer = 30; | 102 config->rc_max_quantizer = 30; |
| 103 config->rc_end_usage = VPX_CBR; | |
| 104 config->rc_target_bitrate = 500; | |
|
Wez
2015/04/18 00:00:23
nit: Please add a comment to indicate that we are
aconverse
2015/04/20 17:12:26
Done.
| |
| 104 } | 105 } |
| 105 } | 106 } |
| 106 | 107 |
| 107 void SetVp8CodecOptions(vpx_codec_ctx_t* codec) { | 108 void SetVp8CodecOptions(vpx_codec_ctx_t* codec) { |
| 108 // CPUUSED of 16 will have the smallest CPU load. This turns off sub-pixel | 109 // CPUUSED of 16 will have the smallest CPU load. This turns off sub-pixel |
| 109 // motion search. | 110 // motion search. |
| 110 vpx_codec_err_t ret = vpx_codec_control(codec, VP8E_SET_CPUUSED, 16); | 111 vpx_codec_err_t ret = vpx_codec_control(codec, VP8E_SET_CPUUSED, 16); |
| 111 DCHECK_EQ(VPX_CODEC_OK, ret) << "Failed to set CPUUSED"; | 112 DCHECK_EQ(VPX_CODEC_OK, ret) << "Failed to set CPUUSED"; |
| 112 | 113 |
| 113 // Use the lowest level of noise sensitivity so as to spend less time | 114 // Use the lowest level of noise sensitivity so as to spend less time |
| (...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 500 uint8* map = active_map_.get() + top * active_map_width_; | 501 uint8* map = active_map_.get() + top * active_map_width_; |
| 501 for (int y = top; y <= bottom; ++y) { | 502 for (int y = top; y <= bottom; ++y) { |
| 502 for (int x = left; x <= right; ++x) | 503 for (int x = left; x <= right; ++x) |
| 503 map[x] = 1; | 504 map[x] = 1; |
| 504 map += active_map_width_; | 505 map += active_map_width_; |
| 505 } | 506 } |
| 506 } | 507 } |
| 507 } | 508 } |
| 508 | 509 |
| 509 } // namespace remoting | 510 } // namespace remoting |
| OLD | NEW |