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 |