summaryrefslogtreecommitdiffstats
path: root/media/audio
diff options
context:
space:
mode:
authordgreid@chromium.org <dgreid@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-25 00:16:46 +0000
committerdgreid@chromium.org <dgreid@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-05-25 00:16:46 +0000
commit9a35a4a66fe67373145c3eb7169a23b0ae3a1800 (patch)
tree08634c1e8ff2822d44456ffd7d427cd9536130dd /media/audio
parentef59e6c4064973e58c923fbcfb51e68911cff8d8 (diff)
downloadchromium_src-9a35a4a66fe67373145c3eb7169a23b0ae3a1800.zip
chromium_src-9a35a4a66fe67373145c3eb7169a23b0ae3a1800.tar.gz
chromium_src-9a35a4a66fe67373145c3eb7169a23b0ae3a1800.tar.bz2
alsa_output: Drain and pause pcm when stopping.
Call snd_pcm_drain when the output's Stop() function is called. This will keep some alsa interfaces from repeating the last samples played until Close() is called. This will also guarantee that all samples are played back if Close() is called immediately following Stop(). BUG=chromium-os:31211 TEST=Manual, play and pause youtube, both FLASH and HTML5 videos using the following alsa plugins as a sink for alsa_output: plug, hw, dmix, pulse, cras, jack. Observe that pauses are clean without repeated samples. Review URL: https://chromiumcodereview.appspot.com/10413075 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@138939 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/audio')
-rw-r--r--media/audio/linux/alsa_output.cc3
-rw-r--r--media/audio/linux/alsa_output_unittest.cc5
-rw-r--r--media/audio/linux/alsa_wrapper.cc4
-rw-r--r--media/audio/linux/alsa_wrapper.h1
4 files changed, 13 insertions, 0 deletions
diff --git a/media/audio/linux/alsa_output.cc b/media/audio/linux/alsa_output.cc
index ce301ce..d8653a8 100644
--- a/media/audio/linux/alsa_output.cc
+++ b/media/audio/linux/alsa_output.cc
@@ -335,6 +335,9 @@ void AlsaPcmOutputStream::Stop() {
// Reset the callback, so that it is not called anymore.
set_source_callback(NULL);
+ // Finish playing samples and pause the pcm.
+ wrapper_->PcmDrain(playback_handle_);
+
TransitionTo(kIsStopped);
}
diff --git a/media/audio/linux/alsa_output_unittest.cc b/media/audio/linux/alsa_output_unittest.cc
index 4b314ce..5f9b4e7 100644
--- a/media/audio/linux/alsa_output_unittest.cc
+++ b/media/audio/linux/alsa_output_unittest.cc
@@ -43,6 +43,7 @@ class MockAlsaWrapper : public AlsaWrapper {
snd_pcm_stream_t stream, int mode));
MOCK_METHOD1(PcmClose, int(snd_pcm_t* handle));
MOCK_METHOD1(PcmPrepare, int(snd_pcm_t* handle));
+ MOCK_METHOD1(PcmDrain, int(snd_pcm_t* handle));
MOCK_METHOD1(PcmDrop, int(snd_pcm_t* handle));
MOCK_METHOD2(PcmDelay, int(snd_pcm_t* handle, snd_pcm_sframes_t* delay));
MOCK_METHOD3(PcmWritei, snd_pcm_sframes_t(snd_pcm_t* handle,
@@ -458,6 +459,10 @@ TEST_F(AlsaPcmOutputStreamTest, StartStop) {
test_stream->Start(&mock_callback);
message_loop_.RunAllPending();
+ EXPECT_CALL(mock_alsa_wrapper_, PcmDrain(kFakeHandle))
+ .WillOnce(Return(0));
+ test_stream->Stop();
+
EXPECT_CALL(mock_alsa_wrapper_, PcmClose(kFakeHandle))
.WillOnce(Return(0));
EXPECT_CALL(mock_alsa_wrapper_, PcmName(kFakeHandle))
diff --git a/media/audio/linux/alsa_wrapper.cc b/media/audio/linux/alsa_wrapper.cc
index 67331b4..06110f8 100644
--- a/media/audio/linux/alsa_wrapper.cc
+++ b/media/audio/linux/alsa_wrapper.cc
@@ -43,6 +43,10 @@ int AlsaWrapper::PcmPrepare(snd_pcm_t* handle) {
return snd_pcm_prepare(handle);
}
+int AlsaWrapper::PcmDrain(snd_pcm_t* handle) {
+ return snd_pcm_drain(handle);
+}
+
int AlsaWrapper::PcmDrop(snd_pcm_t* handle) {
return snd_pcm_drop(handle);
}
diff --git a/media/audio/linux/alsa_wrapper.h b/media/audio/linux/alsa_wrapper.h
index 30d9463..f6a810b 100644
--- a/media/audio/linux/alsa_wrapper.h
+++ b/media/audio/linux/alsa_wrapper.h
@@ -27,6 +27,7 @@ class MEDIA_EXPORT AlsaWrapper {
snd_pcm_stream_t stream, int mode);
virtual int PcmClose(snd_pcm_t* handle);
virtual int PcmPrepare(snd_pcm_t* handle);
+ virtual int PcmDrain(snd_pcm_t* handle);
virtual int PcmDrop(snd_pcm_t* handle);
virtual int PcmDelay(snd_pcm_t* handle, snd_pcm_sframes_t* delay);
virtual snd_pcm_sframes_t PcmWritei(snd_pcm_t* handle,