| 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 |
| 11 #ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_AUDIO_ENCODER_ISAC_T_IMPL_H_ | 11 #ifndef WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_AUDIO_ENCODER_ISAC_T_IMPL_H_ |
| 12 #define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_AUDIO_ENCODER_ISAC_T_IMPL_H_ | 12 #define WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_AUDIO_ENCODER_ISAC_T_IMPL_H_ |
| 13 | 13 |
| 14 #include "webrtc/modules/audio_coding/codecs/isac/main/interface/audio_encoder_i
sac.h" | 14 #include "webrtc/modules/audio_coding/codecs/isac/main/interface/audio_encoder_i
sac.h" |
| 15 | 15 |
| 16 #include <algorithm> | 16 #include <algorithm> |
| 17 | 17 |
| 18 #include "webrtc/base/checks.h" | 18 #include "webrtc/base/checks.h" |
| 19 #include "webrtc/modules/audio_coding/codecs/isac/main/interface/isac.h" | 19 #include "webrtc/modules/audio_coding/codecs/isac/main/interface/isac.h" |
| 20 | 20 |
| 21 namespace webrtc { | 21 namespace webrtc { |
| 22 | 22 |
| 23 const int kIsacPayloadType = 103; | |
| 24 const int kDefaultBitRate = 32000; | |
| 25 | |
| 26 template <typename T> | 23 template <typename T> |
| 27 AudioEncoderIsacT<T>::Config::Config() | 24 typename AudioEncoderIsacT<T>::Config CreateIsacConfig( |
| 28 : bwinfo(nullptr), | 25 const CodecInst& codec_inst, |
| 29 payload_type(kIsacPayloadType), | 26 LockedIsacBandwidthInfo* bwinfo) { |
| 30 sample_rate_hz(16000), | 27 typename AudioEncoderIsacT<T>::Config config; |
| 31 frame_size_ms(30), | 28 config.bwinfo = bwinfo; |
| 32 bit_rate(kDefaultBitRate), | 29 config.payload_type = codec_inst.pltype; |
| 33 max_payload_size_bytes(-1), | 30 config.sample_rate_hz = codec_inst.plfreq; |
| 34 max_bit_rate(-1), | 31 config.frame_size_ms = |
| 35 adaptive_mode(false), | 32 rtc::CheckedDivExact(1000 * codec_inst.pacsize, config.sample_rate_hz); |
| 36 enforce_frame_size(false) { | 33 config.adaptive_mode = (codec_inst.rate == -1); |
| 34 if (codec_inst.rate != -1) |
| 35 config.bit_rate = codec_inst.rate; |
| 36 return config; |
| 37 } | 37 } |
| 38 | 38 |
| 39 template <typename T> | 39 template <typename T> |
| 40 bool AudioEncoderIsacT<T>::Config::IsOk() const { | 40 bool AudioEncoderIsacT<T>::Config::IsOk() const { |
| 41 if (max_bit_rate < 32000 && max_bit_rate != -1) | 41 if (max_bit_rate < 32000 && max_bit_rate != -1) |
| 42 return false; | 42 return false; |
| 43 if (max_payload_size_bytes < 120 && max_payload_size_bytes != -1) | 43 if (max_payload_size_bytes < 120 && max_payload_size_bytes != -1) |
| 44 return false; | 44 return false; |
| 45 if (adaptive_mode && !bwinfo) | 45 if (adaptive_mode && !bwinfo) |
| 46 return false; | 46 return false; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 60 return false; | 60 return false; |
| 61 return T::has_swb && | 61 return T::has_swb && |
| 62 (frame_size_ms == 30 && | 62 (frame_size_ms == 30 && |
| 63 (bit_rate == 0 || (bit_rate >= 10000 && bit_rate <= 56000))); | 63 (bit_rate == 0 || (bit_rate >= 10000 && bit_rate <= 56000))); |
| 64 default: | 64 default: |
| 65 return false; | 65 return false; |
| 66 } | 66 } |
| 67 } | 67 } |
| 68 | 68 |
| 69 template <typename T> | 69 template <typename T> |
| 70 AudioEncoderIsacT<T>::AudioEncoderIsacT(const Config& config) | 70 AudioEncoderIsacT<T>::AudioEncoderIsacT(const Config& config) { |
| 71 : payload_type_(config.payload_type), | 71 RecreateEncoderInstance(config); |
| 72 bwinfo_(config.bwinfo), | 72 } |
| 73 packet_in_progress_(false), | |
| 74 target_bitrate_bps_(config.adaptive_mode ? -1 : (config.bit_rate == 0 | |
| 75 ? kDefaultBitRate | |
| 76 : config.bit_rate)) { | |
| 77 CHECK(config.IsOk()); | |
| 78 CHECK_EQ(0, T::Create(&isac_state_)); | |
| 79 CHECK_EQ(0, T::EncoderInit(isac_state_, config.adaptive_mode ? 0 : 1)); | |
| 80 CHECK_EQ(0, T::SetEncSampRate(isac_state_, config.sample_rate_hz)); | |
| 81 const int bit_rate = config.bit_rate == 0 ? kDefaultBitRate : config.bit_rate; | |
| 82 if (config.adaptive_mode) { | |
| 83 CHECK_EQ(0, T::ControlBwe(isac_state_, bit_rate, config.frame_size_ms, | |
| 84 config.enforce_frame_size)); | |
| 85 } else { | |
| 86 CHECK_EQ(0, T::Control(isac_state_, bit_rate, config.frame_size_ms)); | |
| 87 } | |
| 88 if (config.max_payload_size_bytes != -1) | |
| 89 CHECK_EQ(0, | |
| 90 T::SetMaxPayloadSize(isac_state_, config.max_payload_size_bytes)); | |
| 91 if (config.max_bit_rate != -1) | |
| 92 CHECK_EQ(0, T::SetMaxRate(isac_state_, config.max_bit_rate)); | |
| 93 | 73 |
| 94 // When config.sample_rate_hz is set to 48000 Hz (iSAC-fb), the decoder is | 74 template <typename T> |
| 95 // still set to 32000 Hz, since there is no full-band mode in the decoder. | 75 AudioEncoderIsacT<T>::AudioEncoderIsacT(const CodecInst& codec_inst, |
| 96 const int decoder_sample_rate_hz = std::min(config.sample_rate_hz, 32000); | 76 LockedIsacBandwidthInfo* bwinfo) |
| 97 | 77 : AudioEncoderIsacT(CreateIsacConfig<T>(codec_inst, bwinfo)) {} |
| 98 // Set the decoder sample rate even though we just use the encoder. This | |
| 99 // doesn't appear to be necessary to produce a valid encoding, but without it | |
| 100 // we get an encoding that isn't bit-for-bit identical with what a combined | |
| 101 // encoder+decoder object produces. | |
| 102 CHECK_EQ(0, T::SetDecSampRate(isac_state_, decoder_sample_rate_hz)); | |
| 103 } | |
| 104 | 78 |
| 105 template <typename T> | 79 template <typename T> |
| 106 AudioEncoderIsacT<T>::~AudioEncoderIsacT() { | 80 AudioEncoderIsacT<T>::~AudioEncoderIsacT() { |
| 107 CHECK_EQ(0, T::Free(isac_state_)); | 81 CHECK_EQ(0, T::Free(isac_state_)); |
| 108 } | 82 } |
| 109 | 83 |
| 110 template <typename T> | 84 template <typename T> |
| 85 size_t AudioEncoderIsacT<T>::MaxEncodedBytes() const { |
| 86 return kSufficientEncodeBufferSizeBytes; |
| 87 } |
| 88 |
| 89 template <typename T> |
| 111 int AudioEncoderIsacT<T>::SampleRateHz() const { | 90 int AudioEncoderIsacT<T>::SampleRateHz() const { |
| 112 return T::EncSampRate(isac_state_); | 91 return T::EncSampRate(isac_state_); |
| 113 } | 92 } |
| 114 | 93 |
| 115 template <typename T> | 94 template <typename T> |
| 116 int AudioEncoderIsacT<T>::NumChannels() const { | 95 int AudioEncoderIsacT<T>::NumChannels() const { |
| 117 return 1; | 96 return 1; |
| 118 } | 97 } |
| 119 | 98 |
| 120 template <typename T> | 99 template <typename T> |
| 121 size_t AudioEncoderIsacT<T>::MaxEncodedBytes() const { | |
| 122 return kSufficientEncodeBufferSizeBytes; | |
| 123 } | |
| 124 | |
| 125 template <typename T> | |
| 126 size_t AudioEncoderIsacT<T>::Num10MsFramesInNextPacket() const { | 100 size_t AudioEncoderIsacT<T>::Num10MsFramesInNextPacket() const { |
| 127 const int samples_in_next_packet = T::GetNewFrameLen(isac_state_); | 101 const int samples_in_next_packet = T::GetNewFrameLen(isac_state_); |
| 128 return static_cast<size_t>( | 102 return static_cast<size_t>( |
| 129 rtc::CheckedDivExact(samples_in_next_packet, | 103 rtc::CheckedDivExact(samples_in_next_packet, |
| 130 rtc::CheckedDivExact(SampleRateHz(), 100))); | 104 rtc::CheckedDivExact(SampleRateHz(), 100))); |
| 131 } | 105 } |
| 132 | 106 |
| 133 template <typename T> | 107 template <typename T> |
| 134 size_t AudioEncoderIsacT<T>::Max10MsFramesInAPacket() const { | 108 size_t AudioEncoderIsacT<T>::Max10MsFramesInAPacket() const { |
| 135 return 6; // iSAC puts at most 60 ms in a packet. | 109 return 6; // iSAC puts at most 60 ms in a packet. |
| 136 } | 110 } |
| 137 | 111 |
| 138 template <typename T> | 112 template <typename T> |
| 139 int AudioEncoderIsacT<T>::GetTargetBitrate() const { | 113 int AudioEncoderIsacT<T>::GetTargetBitrate() const { |
| 140 return target_bitrate_bps_; | 114 if (config_.adaptive_mode) |
| 115 return -1; |
| 116 return config_.bit_rate == 0 ? kDefaultBitRate : config_.bit_rate; |
| 141 } | 117 } |
| 142 | 118 |
| 143 template <typename T> | 119 template <typename T> |
| 144 AudioEncoder::EncodedInfo AudioEncoderIsacT<T>::EncodeInternal( | 120 AudioEncoder::EncodedInfo AudioEncoderIsacT<T>::EncodeInternal( |
| 145 uint32_t rtp_timestamp, | 121 uint32_t rtp_timestamp, |
| 146 const int16_t* audio, | 122 const int16_t* audio, |
| 147 size_t max_encoded_bytes, | 123 size_t max_encoded_bytes, |
| 148 uint8_t* encoded) { | 124 uint8_t* encoded) { |
| 149 if (!packet_in_progress_) { | 125 if (!packet_in_progress_) { |
| 150 // Starting a new packet; remember the timestamp for later. | 126 // Starting a new packet; remember the timestamp for later. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 165 | 141 |
| 166 if (r == 0) | 142 if (r == 0) |
| 167 return EncodedInfo(); | 143 return EncodedInfo(); |
| 168 | 144 |
| 169 // Got enough input to produce a packet. Return the saved timestamp from | 145 // Got enough input to produce a packet. Return the saved timestamp from |
| 170 // the first chunk of input that went into the packet. | 146 // the first chunk of input that went into the packet. |
| 171 packet_in_progress_ = false; | 147 packet_in_progress_ = false; |
| 172 EncodedInfo info; | 148 EncodedInfo info; |
| 173 info.encoded_bytes = r; | 149 info.encoded_bytes = r; |
| 174 info.encoded_timestamp = packet_timestamp_; | 150 info.encoded_timestamp = packet_timestamp_; |
| 175 info.payload_type = payload_type_; | 151 info.payload_type = config_.payload_type; |
| 176 return info; | 152 return info; |
| 177 } | 153 } |
| 178 | 154 |
| 179 template <typename T> | 155 template <typename T> |
| 156 void AudioEncoderIsacT<T>::Reset() { |
| 157 RecreateEncoderInstance(config_); |
| 158 } |
| 159 |
| 160 template <typename T> |
| 161 void AudioEncoderIsacT<T>::SetMaxPayloadSize(int max_payload_size_bytes) { |
| 162 auto conf = config_; |
| 163 conf.max_payload_size_bytes = max_payload_size_bytes; |
| 164 RecreateEncoderInstance(conf); |
| 165 } |
| 166 |
| 167 template <typename T> |
| 168 void AudioEncoderIsacT<T>::SetMaxBitrate(int max_rate_bps) { |
| 169 auto conf = config_; |
| 170 conf.max_bit_rate = max_rate_bps; |
| 171 RecreateEncoderInstance(conf); |
| 172 } |
| 173 |
| 174 template <typename T> |
| 175 void AudioEncoderIsacT<T>::RecreateEncoderInstance(const Config& config) { |
| 176 CHECK(config.IsOk()); |
| 177 packet_in_progress_ = false; |
| 178 bwinfo_ = config.bwinfo; |
| 179 if (isac_state_) |
| 180 CHECK_EQ(0, T::Free(isac_state_)); |
| 181 CHECK_EQ(0, T::Create(&isac_state_)); |
| 182 CHECK_EQ(0, T::EncoderInit(isac_state_, config.adaptive_mode ? 0 : 1)); |
| 183 CHECK_EQ(0, T::SetEncSampRate(isac_state_, config.sample_rate_hz)); |
| 184 const int bit_rate = config.bit_rate == 0 ? kDefaultBitRate : config.bit_rate; |
| 185 if (config.adaptive_mode) { |
| 186 CHECK_EQ(0, T::ControlBwe(isac_state_, bit_rate, config.frame_size_ms, |
| 187 config.enforce_frame_size)); |
| 188 } else { |
| 189 CHECK_EQ(0, T::Control(isac_state_, bit_rate, config.frame_size_ms)); |
| 190 } |
| 191 if (config.max_payload_size_bytes != -1) |
| 192 CHECK_EQ(0, |
| 193 T::SetMaxPayloadSize(isac_state_, config.max_payload_size_bytes)); |
| 194 if (config.max_bit_rate != -1) |
| 195 CHECK_EQ(0, T::SetMaxRate(isac_state_, config.max_bit_rate)); |
| 196 |
| 197 // When config.sample_rate_hz is set to 48000 Hz (iSAC-fb), the decoder is |
| 198 // still set to 32000 Hz, since there is no full-band mode in the decoder. |
| 199 const int decoder_sample_rate_hz = std::min(config.sample_rate_hz, 32000); |
| 200 |
| 201 // Set the decoder sample rate even though we just use the encoder. This |
| 202 // doesn't appear to be necessary to produce a valid encoding, but without it |
| 203 // we get an encoding that isn't bit-for-bit identical with what a combined |
| 204 // encoder+decoder object produces. |
| 205 CHECK_EQ(0, T::SetDecSampRate(isac_state_, decoder_sample_rate_hz)); |
| 206 |
| 207 config_ = config; |
| 208 } |
| 209 |
| 210 template <typename T> |
| 180 AudioDecoderIsacT<T>::AudioDecoderIsacT() | 211 AudioDecoderIsacT<T>::AudioDecoderIsacT() |
| 181 : AudioDecoderIsacT(nullptr) { | 212 : AudioDecoderIsacT(nullptr) {} |
| 182 } | |
| 183 | 213 |
| 184 template <typename T> | 214 template <typename T> |
| 185 AudioDecoderIsacT<T>::AudioDecoderIsacT(LockedIsacBandwidthInfo* bwinfo) | 215 AudioDecoderIsacT<T>::AudioDecoderIsacT(LockedIsacBandwidthInfo* bwinfo) |
| 186 : bwinfo_(bwinfo), decoder_sample_rate_hz_(-1) { | 216 : bwinfo_(bwinfo), decoder_sample_rate_hz_(-1) { |
| 187 CHECK_EQ(0, T::Create(&isac_state_)); | 217 CHECK_EQ(0, T::Create(&isac_state_)); |
| 188 T::DecoderInit(isac_state_); | 218 T::DecoderInit(isac_state_); |
| 189 if (bwinfo_) { | 219 if (bwinfo_) { |
| 190 IsacBandwidthInfo bi; | 220 IsacBandwidthInfo bi; |
| 191 T::GetBandwidthInfo(isac_state_, &bi); | 221 T::GetBandwidthInfo(isac_state_, &bi); |
| 192 bwinfo_->Set(bi); | 222 bwinfo_->Set(bi); |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 259 } | 289 } |
| 260 | 290 |
| 261 template <typename T> | 291 template <typename T> |
| 262 size_t AudioDecoderIsacT<T>::Channels() const { | 292 size_t AudioDecoderIsacT<T>::Channels() const { |
| 263 return 1; | 293 return 1; |
| 264 } | 294 } |
| 265 | 295 |
| 266 } // namespace webrtc | 296 } // namespace webrtc |
| 267 | 297 |
| 268 #endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_AUDIO_ENCODER_ISAC_T_IMPL_H_ | 298 #endif // WEBRTC_MODULES_AUDIO_CODING_CODECS_ISAC_AUDIO_ENCODER_ISAC_T_IMPL_H_ |
| OLD | NEW |