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

Side by Side Diff: media/base/audio_converter.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 | « no previous file | media/base/audio_converter_unittest.cc » ('j') | 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 // AudioConverter implementation. Uses MultiChannelSincResampler for resampling 5 // AudioConverter implementation. Uses MultiChannelSincResampler for resampling
6 // audio, ChannelMixer for channel mixing, and AudioPullFifo for buffering. 6 // audio, ChannelMixer for channel mixing, and AudioPullFifo for buffering.
7 // 7 //
8 // Delay estimates are provided to InputCallbacks based on the frame delay 8 // Delay estimates are provided to InputCallbacks based on the frame delay
9 // information reported via the resampler and FIFO units. 9 // information reported via the resampler and FIFO units.
10 10
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 // since we'll mix into the AudioBus from the output stream. 49 // since we'll mix into the AudioBus from the output stream.
50 unmixed_audio_ = AudioBus::Create( 50 unmixed_audio_ = AudioBus::Create(
51 input_params.channels(), output_params.frames_per_buffer()); 51 input_params.channels(), output_params.frames_per_buffer());
52 } 52 }
53 } 53 }
54 54
55 // Only resample if necessary since it's expensive. 55 // Only resample if necessary since it's expensive.
56 if (input_params.sample_rate() != output_params.sample_rate()) { 56 if (input_params.sample_rate() != output_params.sample_rate()) {
57 DVLOG(1) << "Resampling from " << input_params.sample_rate() << " to " 57 DVLOG(1) << "Resampling from " << input_params.sample_rate() << " to "
58 << output_params.sample_rate(); 58 << output_params.sample_rate();
59 double io_sample_rate_ratio = input_params.sample_rate() / 59 const double io_sample_rate_ratio = input_params.sample_rate() /
60 static_cast<double>(output_params.sample_rate()); 60 static_cast<double>(output_params.sample_rate());
61 const int request_size = disable_fifo ? SincResampler::kDefaultRequestSize :
62 input_params.frames_per_buffer();
61 resampler_.reset(new MultiChannelResampler( 63 resampler_.reset(new MultiChannelResampler(
62 downmix_early_ ? output_params.channels() : 64 downmix_early_ ? output_params.channels() :
63 input_params.channels(), 65 input_params.channels(),
64 io_sample_rate_ratio, base::Bind( 66 io_sample_rate_ratio, request_size, base::Bind(
65 &AudioConverter::ProvideInput, base::Unretained(this)))); 67 &AudioConverter::ProvideInput, base::Unretained(this))));
66 } 68 }
67 69
68 input_frame_duration_ = base::TimeDelta::FromMicroseconds( 70 input_frame_duration_ = base::TimeDelta::FromMicroseconds(
69 base::Time::kMicrosecondsPerSecond / 71 base::Time::kMicrosecondsPerSecond /
70 static_cast<double>(input_params.sample_rate())); 72 static_cast<double>(input_params.sample_rate()));
71 output_frame_duration_ = base::TimeDelta::FromMicroseconds( 73 output_frame_duration_ = base::TimeDelta::FromMicroseconds(
72 base::Time::kMicrosecondsPerSecond / 74 base::Time::kMicrosecondsPerSecond /
73 static_cast<double>(output_params.sample_rate())); 75 static_cast<double>(output_params.sample_rate()));
74 76
75 if (disable_fifo) 77 // The resampler can be configured to work with a specific request size, so a
78 // FIFO is not necessary when resampling.
79 if (disable_fifo || resampler_)
76 return; 80 return;
77 81
78 // Since the resampler / output device may want a different buffer size than 82 // Since the output device may want a different buffer size than the caller
79 // the caller asked for, we need to use a FIFO to ensure that both sides 83 // asked for, we need to use a FIFO to ensure that both sides read in chunk
80 // read in chunk sizes they're configured for. 84 // sizes they're configured for.
81 if (resampler_.get() || 85 if (input_params.frames_per_buffer() != output_params.frames_per_buffer()) {
82 input_params.frames_per_buffer() != output_params.frames_per_buffer()) {
83 DVLOG(1) << "Rebuffering from " << input_params.frames_per_buffer() 86 DVLOG(1) << "Rebuffering from " << input_params.frames_per_buffer()
84 << " to " << output_params.frames_per_buffer(); 87 << " to " << output_params.frames_per_buffer();
85 audio_fifo_.reset(new AudioPullFifo( 88 audio_fifo_.reset(new AudioPullFifo(
86 downmix_early_ ? output_params.channels() : 89 downmix_early_ ? output_params.channels() :
87 input_params.channels(), 90 input_params.channels(),
88 input_params.frames_per_buffer(), base::Bind( 91 input_params.frames_per_buffer(), base::Bind(
89 &AudioConverter::SourceCallback, 92 &AudioConverter::SourceCallback,
90 base::Unretained(this)))); 93 base::Unretained(this))));
91 } 94 }
92 } 95 }
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 AudioBus* temp_dest = needs_mixing ? unmixed_audio_.get() : dest; 137 AudioBus* temp_dest = needs_mixing ? unmixed_audio_.get() : dest;
135 DCHECK(temp_dest); 138 DCHECK(temp_dest);
136 139
137 // Figure out which method to call based on whether we're resampling and 140 // Figure out which method to call based on whether we're resampling and
138 // rebuffering, just resampling, or just mixing. We want to avoid any extra 141 // rebuffering, just resampling, or just mixing. We want to avoid any extra
139 // steps when possible since we may be converting audio data in real time. 142 // steps when possible since we may be converting audio data in real time.
140 if (!resampler_ && !audio_fifo_) { 143 if (!resampler_ && !audio_fifo_) {
141 SourceCallback(0, temp_dest); 144 SourceCallback(0, temp_dest);
142 } else { 145 } else {
143 if (resampler_) 146 if (resampler_)
144 resampler_->Resample(temp_dest, temp_dest->frames()); 147 resampler_->Resample(temp_dest->frames(), temp_dest);
145 else 148 else
146 ProvideInput(0, temp_dest); 149 ProvideInput(0, temp_dest);
147 } 150 }
148 151
149 // Finally upmix the channels if we didn't do so earlier. 152 // Finally upmix the channels if we didn't do so earlier.
150 if (needs_mixing) { 153 if (needs_mixing) {
151 DCHECK_EQ(temp_dest->frames(), dest->frames()); 154 DCHECK_EQ(temp_dest->frames(), dest->frames());
152 channel_mixer_->Transform(temp_dest, dest); 155 channel_mixer_->Transform(temp_dest, dest);
153 } 156 }
154 } 157 }
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 238
236 void AudioConverter::ProvideInput(int resampler_frame_delay, AudioBus* dest) { 239 void AudioConverter::ProvideInput(int resampler_frame_delay, AudioBus* dest) {
237 resampler_frame_delay_ = resampler_frame_delay; 240 resampler_frame_delay_ = resampler_frame_delay;
238 if (audio_fifo_) 241 if (audio_fifo_)
239 audio_fifo_->Consume(dest, dest->frames()); 242 audio_fifo_->Consume(dest, dest->frames());
240 else 243 else
241 SourceCallback(0, dest); 244 SourceCallback(0, dest);
242 } 245 }
243 246
244 } // namespace media 247 } // namespace media
OLDNEW
« no previous file with comments | « no previous file | media/base/audio_converter_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698