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