OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 16 matching lines...) Expand all Loading... |
27 // If we are on Android, iOS and/or ARM, use a lower complexity setting as | 27 // If we are on Android, iOS and/or ARM, use a lower complexity setting as |
28 // default, to save encoder complexity. | 28 // default, to save encoder complexity. |
29 const int kDefaultComplexity = 5; | 29 const int kDefaultComplexity = 5; |
30 #else | 30 #else |
31 const int kDefaultComplexity = 9; | 31 const int kDefaultComplexity = 9; |
32 #endif | 32 #endif |
33 | 33 |
34 // We always encode at 48 kHz. | 34 // We always encode at 48 kHz. |
35 const int kSampleRateHz = 48000; | 35 const int kSampleRateHz = 48000; |
36 | 36 |
37 int16_t ClampInt16(size_t x) { | |
38 return static_cast<int16_t>( | |
39 std::min(x, static_cast<size_t>(std::numeric_limits<int16_t>::max()))); | |
40 } | |
41 | |
42 int16_t CastInt16(size_t x) { | |
43 DCHECK_LE(x, static_cast<size_t>(std::numeric_limits<int16_t>::max())); | |
44 return static_cast<int16_t>(x); | |
45 } | |
46 | |
47 } // namespace | 37 } // namespace |
48 | 38 |
49 AudioEncoderOpus::Config::Config() | 39 AudioEncoderOpus::Config::Config() |
50 : frame_size_ms(20), | 40 : frame_size_ms(20), |
51 num_channels(1), | 41 num_channels(1), |
52 payload_type(120), | 42 payload_type(120), |
53 application(kVoip), | 43 application(kVoip), |
54 bitrate_bps(64000), | 44 bitrate_bps(64000), |
55 fec_enabled(false), | 45 fec_enabled(false), |
56 max_playback_rate_hz(48000), | 46 max_playback_rate_hz(48000), |
57 complexity(kDefaultComplexity), | 47 complexity(kDefaultComplexity), |
58 dtx_enabled(false) { | 48 dtx_enabled(false) { |
59 } | 49 } |
60 | 50 |
61 bool AudioEncoderOpus::Config::IsOk() const { | 51 bool AudioEncoderOpus::Config::IsOk() const { |
62 if (frame_size_ms <= 0 || frame_size_ms % 10 != 0) | 52 if (frame_size_ms <= 0 || frame_size_ms % 10 != 0) |
63 return false; | 53 return false; |
64 if (num_channels != 1 && num_channels != 2) | 54 if (num_channels != 1 && num_channels != 2) |
65 return false; | 55 return false; |
66 if (bitrate_bps < kMinBitrateBps || bitrate_bps > kMaxBitrateBps) | 56 if (bitrate_bps < kMinBitrateBps || bitrate_bps > kMaxBitrateBps) |
67 return false; | 57 return false; |
68 if (complexity < 0 || complexity > 10) | 58 if (complexity < 0 || complexity > 10) |
69 return false; | 59 return false; |
70 return true; | 60 return true; |
71 } | 61 } |
72 | 62 |
73 AudioEncoderOpus::AudioEncoderOpus(const Config& config) | 63 AudioEncoderOpus::AudioEncoderOpus(const Config& config) |
74 : num_10ms_frames_per_packet_( | 64 : num_10ms_frames_per_packet_( |
75 rtc::CheckedDivExact(config.frame_size_ms, 10)), | 65 static_cast<size_t>(rtc::CheckedDivExact(config.frame_size_ms, 10))), |
76 num_channels_(config.num_channels), | 66 num_channels_(config.num_channels), |
77 payload_type_(config.payload_type), | 67 payload_type_(config.payload_type), |
78 application_(config.application), | 68 application_(config.application), |
79 dtx_enabled_(config.dtx_enabled), | 69 dtx_enabled_(config.dtx_enabled), |
80 samples_per_10ms_frame_(rtc::CheckedDivExact(kSampleRateHz, 100) * | 70 samples_per_10ms_frame_(static_cast<size_t>( |
81 num_channels_), | 71 rtc::CheckedDivExact(kSampleRateHz, 100) * num_channels_)), |
82 packet_loss_rate_(0.0) { | 72 packet_loss_rate_(0.0) { |
83 CHECK(config.IsOk()); | 73 CHECK(config.IsOk()); |
84 input_buffer_.reserve(num_10ms_frames_per_packet_ * samples_per_10ms_frame_); | 74 input_buffer_.reserve(num_10ms_frames_per_packet_ * samples_per_10ms_frame_); |
85 CHECK_EQ(0, WebRtcOpus_EncoderCreate(&inst_, num_channels_, application_)); | 75 CHECK_EQ(0, WebRtcOpus_EncoderCreate(&inst_, num_channels_, application_)); |
86 SetTargetBitrate(config.bitrate_bps); | 76 SetTargetBitrate(config.bitrate_bps); |
87 if (config.fec_enabled) { | 77 if (config.fec_enabled) { |
88 CHECK_EQ(0, WebRtcOpus_EnableFec(inst_)); | 78 CHECK_EQ(0, WebRtcOpus_EnableFec(inst_)); |
89 } else { | 79 } else { |
90 CHECK_EQ(0, WebRtcOpus_DisableFec(inst_)); | 80 CHECK_EQ(0, WebRtcOpus_DisableFec(inst_)); |
91 } | 81 } |
(...skipping 22 matching lines...) Expand all Loading... |
114 size_t AudioEncoderOpus::MaxEncodedBytes() const { | 104 size_t AudioEncoderOpus::MaxEncodedBytes() const { |
115 // Calculate the number of bytes we expect the encoder to produce, | 105 // Calculate the number of bytes we expect the encoder to produce, |
116 // then multiply by two to give a wide margin for error. | 106 // then multiply by two to give a wide margin for error. |
117 size_t bytes_per_millisecond = | 107 size_t bytes_per_millisecond = |
118 static_cast<size_t>(bitrate_bps_ / (1000 * 8) + 1); | 108 static_cast<size_t>(bitrate_bps_ / (1000 * 8) + 1); |
119 size_t approx_encoded_bytes = | 109 size_t approx_encoded_bytes = |
120 num_10ms_frames_per_packet_ * 10 * bytes_per_millisecond; | 110 num_10ms_frames_per_packet_ * 10 * bytes_per_millisecond; |
121 return 2 * approx_encoded_bytes; | 111 return 2 * approx_encoded_bytes; |
122 } | 112 } |
123 | 113 |
124 int AudioEncoderOpus::Num10MsFramesInNextPacket() const { | 114 size_t AudioEncoderOpus::Num10MsFramesInNextPacket() const { |
125 return num_10ms_frames_per_packet_; | 115 return num_10ms_frames_per_packet_; |
126 } | 116 } |
127 | 117 |
128 int AudioEncoderOpus::Max10MsFramesInAPacket() const { | 118 size_t AudioEncoderOpus::Max10MsFramesInAPacket() const { |
129 return num_10ms_frames_per_packet_; | 119 return num_10ms_frames_per_packet_; |
130 } | 120 } |
131 | 121 |
132 int AudioEncoderOpus::GetTargetBitrate() const { | 122 int AudioEncoderOpus::GetTargetBitrate() const { |
133 return bitrate_bps_; | 123 return bitrate_bps_; |
134 } | 124 } |
135 | 125 |
136 void AudioEncoderOpus::SetTargetBitrate(int bits_per_second) { | 126 void AudioEncoderOpus::SetTargetBitrate(int bits_per_second) { |
137 bitrate_bps_ = std::max(std::min(bits_per_second, kMaxBitrateBps), | 127 bitrate_bps_ = std::max(std::min(bits_per_second, kMaxBitrateBps), |
138 kMinBitrateBps); | 128 kMinBitrateBps); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
188 | 178 |
189 AudioEncoder::EncodedInfo AudioEncoderOpus::EncodeInternal( | 179 AudioEncoder::EncodedInfo AudioEncoderOpus::EncodeInternal( |
190 uint32_t rtp_timestamp, | 180 uint32_t rtp_timestamp, |
191 const int16_t* audio, | 181 const int16_t* audio, |
192 size_t max_encoded_bytes, | 182 size_t max_encoded_bytes, |
193 uint8_t* encoded) { | 183 uint8_t* encoded) { |
194 if (input_buffer_.empty()) | 184 if (input_buffer_.empty()) |
195 first_timestamp_in_buffer_ = rtp_timestamp; | 185 first_timestamp_in_buffer_ = rtp_timestamp; |
196 input_buffer_.insert(input_buffer_.end(), audio, | 186 input_buffer_.insert(input_buffer_.end(), audio, |
197 audio + samples_per_10ms_frame_); | 187 audio + samples_per_10ms_frame_); |
198 if (input_buffer_.size() < (static_cast<size_t>(num_10ms_frames_per_packet_) * | 188 if (input_buffer_.size() < |
199 samples_per_10ms_frame_)) { | 189 (num_10ms_frames_per_packet_ * samples_per_10ms_frame_)) { |
200 return EncodedInfo(); | 190 return EncodedInfo(); |
201 } | 191 } |
202 CHECK_EQ(input_buffer_.size(), | 192 CHECK_EQ(input_buffer_.size(), |
203 static_cast<size_t>(num_10ms_frames_per_packet_) * | 193 num_10ms_frames_per_packet_ * samples_per_10ms_frame_); |
204 samples_per_10ms_frame_); | |
205 int status = WebRtcOpus_Encode( | 194 int status = WebRtcOpus_Encode( |
206 inst_, &input_buffer_[0], | 195 inst_, &input_buffer_[0], |
207 rtc::CheckedDivExact(CastInt16(input_buffer_.size()), | 196 rtc::CheckedDivExact(input_buffer_.size(), |
208 static_cast<int16_t>(num_channels_)), | 197 static_cast<size_t>(num_channels_)), |
209 ClampInt16(max_encoded_bytes), encoded); | 198 max_encoded_bytes, encoded); |
210 CHECK_GE(status, 0); // Fails only if fed invalid data. | 199 CHECK_GE(status, 0); // Fails only if fed invalid data. |
211 input_buffer_.clear(); | 200 input_buffer_.clear(); |
212 EncodedInfo info; | 201 EncodedInfo info; |
213 info.encoded_bytes = static_cast<size_t>(status); | 202 info.encoded_bytes = static_cast<size_t>(status); |
214 info.encoded_timestamp = first_timestamp_in_buffer_; | 203 info.encoded_timestamp = first_timestamp_in_buffer_; |
215 info.payload_type = payload_type_; | 204 info.payload_type = payload_type_; |
216 info.send_even_if_empty = true; // Allows Opus to send empty packets. | 205 info.send_even_if_empty = true; // Allows Opus to send empty packets. |
217 info.speech = (status > 0); | 206 info.speech = (status > 0); |
218 return info; | 207 return info; |
219 } | 208 } |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
260 return Reconstruct(conf); | 249 return Reconstruct(conf); |
261 } | 250 } |
262 | 251 |
263 bool AudioEncoderMutableOpus::SetMaxPlaybackRate(int frequency_hz) { | 252 bool AudioEncoderMutableOpus::SetMaxPlaybackRate(int frequency_hz) { |
264 auto conf = config(); | 253 auto conf = config(); |
265 conf.max_playback_rate_hz = frequency_hz; | 254 conf.max_playback_rate_hz = frequency_hz; |
266 return Reconstruct(conf); | 255 return Reconstruct(conf); |
267 } | 256 } |
268 | 257 |
269 } // namespace webrtc | 258 } // namespace webrtc |
OLD | NEW |