| 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 |