Commit d6c547b8 authored by Thomas Guilbert's avatar Thomas Guilbert Committed by Commit Bot

Play resampled audio until EOS

When nearing the EOS using a resampler to play audio, we sometimes omit
the last few frames. This happens when we send all remaining audio
buffers to the resampler and partially fill it with silence, but we
don't know if we have completely consumed the non-silence frames.

This CL fixes the issue by first checking that we have completely filed
the resampler with silence, before declaring there is nothing else to
play. By doing so, we play silence after the last valid frames, but we
will at least play all valid frames.

Change-Id: I8ea4d504907746b2ea170ca55169718aee6d8586
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2276526
Auto-Submit: Thomas Guilbert <tguilbert@chromium.org>
Commit-Queue: Dale Curtis <dalecurtis@chromium.org>
Reviewed-by: default avatarDale Curtis <dalecurtis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#784197}
parent f540729a
...@@ -173,6 +173,8 @@ void AudioRendererAlgorithm::OnResamplerRead(int frame_delay, ...@@ -173,6 +173,8 @@ void AudioRendererAlgorithm::OnResamplerRead(int frame_delay,
DCHECK(reached_end_of_stream_); DCHECK(reached_end_of_stream_);
audio_bus->ZeroFramesPartial(read_frames, requested_frames - read_frames); audio_bus->ZeroFramesPartial(read_frames, requested_frames - read_frames);
} }
resampler_only_has_silence_ = !read_frames;
} }
void AudioRendererAlgorithm::MarkEndOfStream() { void AudioRendererAlgorithm::MarkEndOfStream() {
...@@ -190,12 +192,11 @@ int AudioRendererAlgorithm::ResampleAndFill(AudioBus* dest, ...@@ -190,12 +192,11 @@ int AudioRendererAlgorithm::ResampleAndFill(AudioBus* dest,
base::Unretained(this))); base::Unretained(this)));
} }
if (reached_end_of_stream_ && !audio_buffer_.frames()) { if (reached_end_of_stream_ && resampler_only_has_silence_ &&
!audio_buffer_.frames()) {
// Previous calls to ResampleAndFill() and OnResamplerRead() have used all // Previous calls to ResampleAndFill() and OnResamplerRead() have used all
// of the available buffers from |audio_buffer_|. Some valid input buffers // of the available buffers from |audio_buffer_|. We have also played out
// might be stuck in |resampler_.BufferedFrames()|, but the rest is silence. // all remaining frames, and |resampler_| only contains silence.
// Forgo the few remaining valid buffers, or else we will keep playing out
// silence forever and never trigger any "ended" events.
return 0; return 0;
} }
......
...@@ -258,6 +258,11 @@ class MEDIA_EXPORT AudioRendererAlgorithm { ...@@ -258,6 +258,11 @@ class MEDIA_EXPORT AudioRendererAlgorithm {
// changing the pitch of the audio. // changing the pitch of the audio.
std::unique_ptr<MultiChannelResampler> resampler_; std::unique_ptr<MultiChannelResampler> resampler_;
// True when the last call to OnResamplerRead() only gave silence to
// |resampler_|. Used to determine whether or not we have played out all the
// valid audio from |resampler.BufferedFrames()|.
bool resampler_only_has_silence_ = false;
// This stores a part of the output that is created but couldn't be rendered. // This stores a part of the output that is created but couldn't be rendered.
// Output is generated frame-by-frame which at some point might exceed the // Output is generated frame-by-frame which at some point might exceed the
// number of requested samples. Furthermore, due to overlap-and-add, // number of requested samples. Furthermore, due to overlap-and-add,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment