Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(823)

Side by Side Diff: remoting/codec/audio_encoder_opus.cc

Issue 14189035: Reduce jitter from uneven SincResampler buffer size requests. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Comments. Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « media/base/sinc_resampler_unittest.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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.h" 9 #include "base/time.h"
10 #include "media/base/audio_bus.h" 10 #include "media/base/audio_bus.h"
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 } 70 }
71 71
72 opus_encoder_ctl(encoder_, OPUS_SET_BITRATE(kOutputBitrateBps)); 72 opus_encoder_ctl(encoder_, OPUS_SET_BITRATE(kOutputBitrateBps));
73 73
74 frame_size_ = sampling_rate_ * kFrameSizeMs / 74 frame_size_ = sampling_rate_ * kFrameSizeMs /
75 base::Time::kMillisecondsPerSecond; 75 base::Time::kMillisecondsPerSecond;
76 76
77 if (sampling_rate_ != kOpusSamplingRate) { 77 if (sampling_rate_ != kOpusSamplingRate) {
78 resample_buffer_.reset( 78 resample_buffer_.reset(
79 new char[kFrameSamples * kBytesPerSample * channels_]); 79 new char[kFrameSamples * kBytesPerSample * channels_]);
80 // TODO(sergeyu): Figure out the right buffer size to use per packet instead
81 // of using media::SincResampler::kDefaultRequestSize.
80 resampler_.reset(new media::MultiChannelResampler( 82 resampler_.reset(new media::MultiChannelResampler(
81 channels_, 83 channels_,
82 static_cast<double>(sampling_rate_) / kOpusSamplingRate, 84 static_cast<double>(sampling_rate_) / kOpusSamplingRate,
85 media::SincResampler::kDefaultRequestSize,
83 base::Bind(&AudioEncoderOpus::FetchBytesToResample, 86 base::Bind(&AudioEncoderOpus::FetchBytesToResample,
84 base::Unretained(this)))); 87 base::Unretained(this))));
85 resampler_bus_ = media::AudioBus::Create(channels_, kFrameSamples); 88 resampler_bus_ = media::AudioBus::Create(channels_, kFrameSamples);
86 } 89 }
87 90
88 // Drop leftover data because it's for different sampling rate. 91 // Drop leftover data because it's for different sampling rate.
89 leftover_samples_ = 0; 92 leftover_samples_ = 0;
90 leftover_buffer_size_ = 93 leftover_buffer_size_ =
91 frame_size_ + media::SincResampler::kMaximumLookAheadSize; 94 frame_size_ + media::SincResampler::kDefaultRequestSize;
92 leftover_buffer_.reset( 95 leftover_buffer_.reset(
93 new int16[leftover_buffer_size_ * channels_]); 96 new int16[leftover_buffer_size_ * channels_]);
94 } 97 }
95 98
96 void AudioEncoderOpus::DestroyEncoder() { 99 void AudioEncoderOpus::DestroyEncoder() {
97 if (encoder_) { 100 if (encoder_) {
98 opus_encoder_destroy(encoder_); 101 opus_encoder_destroy(encoder_);
99 encoder_ = NULL; 102 encoder_ = NULL;
100 } 103 }
101 104
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 const int16* next_sample = 155 const int16* next_sample =
153 reinterpret_cast<const int16*>(packet->data(0).data()); 156 reinterpret_cast<const int16*>(packet->data(0).data());
154 157
155 // Create a new packet of encoded data. 158 // Create a new packet of encoded data.
156 scoped_ptr<AudioPacket> encoded_packet(new AudioPacket()); 159 scoped_ptr<AudioPacket> encoded_packet(new AudioPacket());
157 encoded_packet->set_encoding(AudioPacket::ENCODING_OPUS); 160 encoded_packet->set_encoding(AudioPacket::ENCODING_OPUS);
158 encoded_packet->set_sampling_rate(kOpusSamplingRate); 161 encoded_packet->set_sampling_rate(kOpusSamplingRate);
159 encoded_packet->set_channels(channels_); 162 encoded_packet->set_channels(channels_);
160 163
161 int prefetch_samples = 164 int prefetch_samples =
162 resampler_.get() ? media::SincResampler::kMaximumLookAheadSize : 0; 165 resampler_.get() ? media::SincResampler::kDefaultRequestSize : 0;
163 int samples_wanted = frame_size_ + prefetch_samples; 166 int samples_wanted = frame_size_ + prefetch_samples;
164 167
165 while (leftover_samples_ + samples_in_packet >= samples_wanted) { 168 while (leftover_samples_ + samples_in_packet >= samples_wanted) {
166 const int16* pcm_buffer = NULL; 169 const int16* pcm_buffer = NULL;
167 170
168 // Combine the packet with the leftover samples, if any. 171 // Combine the packet with the leftover samples, if any.
169 if (leftover_samples_ > 0) { 172 if (leftover_samples_ > 0) {
170 pcm_buffer = leftover_buffer_.get(); 173 pcm_buffer = leftover_buffer_.get();
171 int samples_to_copy = samples_wanted - leftover_samples_; 174 int samples_to_copy = samples_wanted - leftover_samples_;
172 memcpy(leftover_buffer_.get() + leftover_samples_ * channels_, 175 memcpy(leftover_buffer_.get() + leftover_samples_ * channels_,
173 next_sample, samples_to_copy * kBytesPerSample * channels_); 176 next_sample, samples_to_copy * kBytesPerSample * channels_);
174 } else { 177 } else {
175 pcm_buffer = next_sample; 178 pcm_buffer = next_sample;
176 } 179 }
177 180
178 // Resample data if necessary. 181 // Resample data if necessary.
179 int samples_consumed = 0; 182 int samples_consumed = 0;
180 if (resampler_.get()) { 183 if (resampler_.get()) {
181 resampling_data_ = reinterpret_cast<const char*>(pcm_buffer); 184 resampling_data_ = reinterpret_cast<const char*>(pcm_buffer);
182 resampling_data_pos_ = 0; 185 resampling_data_pos_ = 0;
183 resampling_data_size_ = samples_wanted * channels_ * kBytesPerSample; 186 resampling_data_size_ = samples_wanted * channels_ * kBytesPerSample;
184 resampler_->Resample(resampler_bus_.get(), kFrameSamples); 187 resampler_->Resample(kFrameSamples, resampler_bus_.get());
185 resampling_data_ = NULL; 188 resampling_data_ = NULL;
186 samples_consumed = resampling_data_pos_ / channels_ / kBytesPerSample; 189 samples_consumed = resampling_data_pos_ / channels_ / kBytesPerSample;
187 190
188 resampler_bus_->ToInterleaved(kFrameSamples, kBytesPerSample, 191 resampler_bus_->ToInterleaved(kFrameSamples, kBytesPerSample,
189 resample_buffer_.get()); 192 resample_buffer_.get());
190 pcm_buffer = reinterpret_cast<int16*>(resample_buffer_.get()); 193 pcm_buffer = reinterpret_cast<int16*>(resample_buffer_.get());
191 } else { 194 } else {
192 samples_consumed = frame_size_; 195 samples_consumed = frame_size_;
193 } 196 }
194 197
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
232 } 235 }
233 236
234 // Return NULL if there's nothing in the packet. 237 // Return NULL if there's nothing in the packet.
235 if (encoded_packet->data_size() == 0) 238 if (encoded_packet->data_size() == 0)
236 return scoped_ptr<AudioPacket>(); 239 return scoped_ptr<AudioPacket>();
237 240
238 return encoded_packet.Pass(); 241 return encoded_packet.Pass();
239 } 242 }
240 243
241 } // namespace remoting 244 } // namespace remoting
OLDNEW
« no previous file with comments | « media/base/sinc_resampler_unittest.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698