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 |