OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/audio_encoder_opus.h" | 5 #include "remoting/codec/audio_encoder_opus.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/time/time.h" | 9 #include "base/time/time.h" |
10 #include "media/base/audio_bus.h" | 10 #include "media/base/audio_bus.h" |
(...skipping 24 matching lines...) Expand all Loading... |
35 | 35 |
36 bool IsSupportedSampleRate(int rate) { | 36 bool IsSupportedSampleRate(int rate) { |
37 return rate == 44100 || rate == 48000; | 37 return rate == 44100 || rate == 48000; |
38 } | 38 } |
39 | 39 |
40 } // namespace | 40 } // namespace |
41 | 41 |
42 AudioEncoderOpus::AudioEncoderOpus() | 42 AudioEncoderOpus::AudioEncoderOpus() |
43 : sampling_rate_(0), | 43 : sampling_rate_(0), |
44 channels_(AudioPacket::CHANNELS_STEREO), | 44 channels_(AudioPacket::CHANNELS_STEREO), |
45 encoder_(NULL), | 45 encoder_(nullptr), |
46 frame_size_(0), | 46 frame_size_(0), |
47 resampling_data_(NULL), | 47 resampling_data_(nullptr), |
48 resampling_data_size_(0), | 48 resampling_data_size_(0), |
49 resampling_data_pos_(0) { | 49 resampling_data_pos_(0) { |
50 } | 50 } |
51 | 51 |
52 AudioEncoderOpus::~AudioEncoderOpus() { | 52 AudioEncoderOpus::~AudioEncoderOpus() { |
53 DestroyEncoder(); | 53 DestroyEncoder(); |
54 } | 54 } |
55 | 55 |
56 void AudioEncoderOpus::InitEncoder() { | 56 void AudioEncoderOpus::InitEncoder() { |
57 DCHECK(!encoder_); | 57 DCHECK(!encoder_); |
(...skipping 28 matching lines...) Expand all Loading... |
86 leftover_samples_ = 0; | 86 leftover_samples_ = 0; |
87 leftover_buffer_size_ = | 87 leftover_buffer_size_ = |
88 frame_size_ + media::SincResampler::kDefaultRequestSize; | 88 frame_size_ + media::SincResampler::kDefaultRequestSize; |
89 leftover_buffer_.reset( | 89 leftover_buffer_.reset( |
90 new int16[leftover_buffer_size_ * channels_]); | 90 new int16[leftover_buffer_size_ * channels_]); |
91 } | 91 } |
92 | 92 |
93 void AudioEncoderOpus::DestroyEncoder() { | 93 void AudioEncoderOpus::DestroyEncoder() { |
94 if (encoder_) { | 94 if (encoder_) { |
95 opus_encoder_destroy(encoder_); | 95 opus_encoder_destroy(encoder_); |
96 encoder_ = NULL; | 96 encoder_ = nullptr; |
97 } | 97 } |
98 | 98 |
99 resampler_.reset(); | 99 resampler_.reset(); |
100 } | 100 } |
101 | 101 |
102 bool AudioEncoderOpus::ResetForPacket(AudioPacket* packet) { | 102 bool AudioEncoderOpus::ResetForPacket(AudioPacket* packet) { |
103 if (packet->channels() != channels_ || | 103 if (packet->channels() != channels_ || |
104 packet->sampling_rate() != sampling_rate_) { | 104 packet->sampling_rate() != sampling_rate_) { |
105 DestroyEncoder(); | 105 DestroyEncoder(); |
106 | 106 |
107 channels_ = packet->channels(); | 107 channels_ = packet->channels(); |
108 sampling_rate_ = packet->sampling_rate(); | 108 sampling_rate_ = packet->sampling_rate(); |
109 | 109 |
110 if (channels_ <= 0 || channels_ > 2 || | 110 if (channels_ <= 0 || channels_ > 2 || |
111 !IsSupportedSampleRate(sampling_rate_)) { | 111 !IsSupportedSampleRate(sampling_rate_)) { |
112 LOG(WARNING) << "Unsupported OPUS parameters: " | 112 LOG(WARNING) << "Unsupported OPUS parameters: " |
113 << channels_ << " channels with " | 113 << channels_ << " channels with " |
114 << sampling_rate_ << " samples per second."; | 114 << sampling_rate_ << " samples per second."; |
115 return false; | 115 return false; |
116 } | 116 } |
117 | 117 |
118 InitEncoder(); | 118 InitEncoder(); |
119 } | 119 } |
120 | 120 |
121 return encoder_ != NULL; | 121 return encoder_ != nullptr; |
122 } | 122 } |
123 | 123 |
124 void AudioEncoderOpus::FetchBytesToResample(int resampler_frame_delay, | 124 void AudioEncoderOpus::FetchBytesToResample(int resampler_frame_delay, |
125 media::AudioBus* audio_bus) { | 125 media::AudioBus* audio_bus) { |
126 DCHECK(resampling_data_); | 126 DCHECK(resampling_data_); |
127 int samples_left = (resampling_data_size_ - resampling_data_pos_) / | 127 int samples_left = (resampling_data_size_ - resampling_data_pos_) / |
128 kBytesPerSample / channels_; | 128 kBytesPerSample / channels_; |
129 DCHECK_LE(audio_bus->frames(), samples_left); | 129 DCHECK_LE(audio_bus->frames(), samples_left); |
130 audio_bus->FromInterleaved( | 130 audio_bus->FromInterleaved( |
131 resampling_data_ + resampling_data_pos_, | 131 resampling_data_ + resampling_data_pos_, |
(...skipping 25 matching lines...) Expand all Loading... |
157 scoped_ptr<AudioPacket> encoded_packet(new AudioPacket()); | 157 scoped_ptr<AudioPacket> encoded_packet(new AudioPacket()); |
158 encoded_packet->set_encoding(AudioPacket::ENCODING_OPUS); | 158 encoded_packet->set_encoding(AudioPacket::ENCODING_OPUS); |
159 encoded_packet->set_sampling_rate(kOpusSamplingRate); | 159 encoded_packet->set_sampling_rate(kOpusSamplingRate); |
160 encoded_packet->set_channels(channels_); | 160 encoded_packet->set_channels(channels_); |
161 | 161 |
162 int prefetch_samples = | 162 int prefetch_samples = |
163 resampler_.get() ? media::SincResampler::kDefaultRequestSize : 0; | 163 resampler_.get() ? media::SincResampler::kDefaultRequestSize : 0; |
164 int samples_wanted = frame_size_ + prefetch_samples; | 164 int samples_wanted = frame_size_ + prefetch_samples; |
165 | 165 |
166 while (leftover_samples_ + samples_in_packet >= samples_wanted) { | 166 while (leftover_samples_ + samples_in_packet >= samples_wanted) { |
167 const int16* pcm_buffer = NULL; | 167 const int16* pcm_buffer = nullptr; |
168 | 168 |
169 // Combine the packet with the leftover samples, if any. | 169 // Combine the packet with the leftover samples, if any. |
170 if (leftover_samples_ > 0) { | 170 if (leftover_samples_ > 0) { |
171 pcm_buffer = leftover_buffer_.get(); | 171 pcm_buffer = leftover_buffer_.get(); |
172 int samples_to_copy = samples_wanted - leftover_samples_; | 172 int samples_to_copy = samples_wanted - leftover_samples_; |
173 memcpy(leftover_buffer_.get() + leftover_samples_ * channels_, | 173 memcpy(leftover_buffer_.get() + leftover_samples_ * channels_, |
174 next_sample, samples_to_copy * kBytesPerSample * channels_); | 174 next_sample, samples_to_copy * kBytesPerSample * channels_); |
175 } else { | 175 } else { |
176 pcm_buffer = next_sample; | 176 pcm_buffer = next_sample; |
177 } | 177 } |
178 | 178 |
179 // Resample data if necessary. | 179 // Resample data if necessary. |
180 int samples_consumed = 0; | 180 int samples_consumed = 0; |
181 if (resampler_.get()) { | 181 if (resampler_.get()) { |
182 resampling_data_ = reinterpret_cast<const char*>(pcm_buffer); | 182 resampling_data_ = reinterpret_cast<const char*>(pcm_buffer); |
183 resampling_data_pos_ = 0; | 183 resampling_data_pos_ = 0; |
184 resampling_data_size_ = samples_wanted * channels_ * kBytesPerSample; | 184 resampling_data_size_ = samples_wanted * channels_ * kBytesPerSample; |
185 resampler_->Resample(kFrameSamples, resampler_bus_.get()); | 185 resampler_->Resample(kFrameSamples, resampler_bus_.get()); |
186 resampling_data_ = NULL; | 186 resampling_data_ = nullptr; |
187 samples_consumed = resampling_data_pos_ / channels_ / kBytesPerSample; | 187 samples_consumed = resampling_data_pos_ / channels_ / kBytesPerSample; |
188 | 188 |
189 resampler_bus_->ToInterleaved(kFrameSamples, kBytesPerSample, | 189 resampler_bus_->ToInterleaved(kFrameSamples, kBytesPerSample, |
190 resample_buffer_.get()); | 190 resample_buffer_.get()); |
191 pcm_buffer = reinterpret_cast<int16*>(resample_buffer_.get()); | 191 pcm_buffer = reinterpret_cast<int16*>(resample_buffer_.get()); |
192 } else { | 192 } else { |
193 samples_consumed = frame_size_; | 193 samples_consumed = frame_size_; |
194 } | 194 } |
195 | 195 |
196 // Initialize output buffer. | 196 // Initialize output buffer. |
(...skipping 28 matching lines...) Expand all Loading... |
225 } | 225 } |
226 | 226 |
227 // Store the leftover samples. | 227 // Store the leftover samples. |
228 if (samples_in_packet > 0) { | 228 if (samples_in_packet > 0) { |
229 DCHECK_LE(leftover_samples_ + samples_in_packet, leftover_buffer_size_); | 229 DCHECK_LE(leftover_samples_ + samples_in_packet, leftover_buffer_size_); |
230 memmove(leftover_buffer_.get() + leftover_samples_ * channels_, | 230 memmove(leftover_buffer_.get() + leftover_samples_ * channels_, |
231 next_sample, samples_in_packet * kBytesPerSample * channels_); | 231 next_sample, samples_in_packet * kBytesPerSample * channels_); |
232 leftover_samples_ += samples_in_packet; | 232 leftover_samples_ += samples_in_packet; |
233 } | 233 } |
234 | 234 |
235 // Return NULL if there's nothing in the packet. | 235 // Return nullptr if there's nothing in the packet. |
236 if (encoded_packet->data_size() == 0) | 236 if (encoded_packet->data_size() == 0) |
237 return nullptr; | 237 return nullptr; |
238 | 238 |
239 return encoded_packet.Pass(); | 239 return encoded_packet.Pass(); |
240 } | 240 } |
241 | 241 |
242 } // namespace remoting | 242 } // namespace remoting |
OLD | NEW |