summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorhclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-24 22:30:07 +0000
committerhclam@chromium.org <hclam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-08-24 22:30:07 +0000
commit9d3381548a57745b672e65fa4b487c61b0b7bf39 (patch)
treed12a7e03ca70bbce7a3a372e5969719e496e0193 /media
parent4748f54e887fc85f009e8d1df2288f7f3f984d0e (diff)
downloadchromium_src-9d3381548a57745b672e65fa4b487c61b0b7bf39.zip
chromium_src-9d3381548a57745b672e65fa4b487c61b0b7bf39.tar.gz
chromium_src-9d3381548a57745b672e65fa4b487c61b0b7bf39.tar.bz2
Provide unplayed bytes ALSA implementation of audio
BUG=19921 TEST=play an video track on linux, AV should be in sync. Use snd_pcm_delay() to provide the number of unplayed bytes in linux's audio implementation. This information will correct the sync problem for linux. Review URL: http://codereview.chromium.org/173288 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@24163 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r--media/audio/linux/alsa_output.cc22
-rw-r--r--media/audio/linux/alsa_output_unittest.cc8
-rw-r--r--media/audio/linux/alsa_wrapper.cc4
-rw-r--r--media/audio/linux/alsa_wrapper.h1
4 files changed, 32 insertions, 3 deletions
diff --git a/media/audio/linux/alsa_output.cc b/media/audio/linux/alsa_output.cc
index 8a59e33..96a2e4b 100644
--- a/media/audio/linux/alsa_output.cc
+++ b/media/audio/linux/alsa_output.cc
@@ -389,10 +389,28 @@ void AlsaPcmOutputStream::BufferPacket(Packet* packet) {
// Request more data if we don't have any cached.
if (packet->used >= packet->size) {
+ // Before making a request to source for data. We need to determine the
+ // delay (in bytes) for the requested data to be played.
+ snd_pcm_sframes_t delay;
+ int error = wrapper_->PcmDelay(playback_handle_, &delay);
+ if (error < 0) {
+ error = wrapper_->PcmRecover(playback_handle_,
+ error,
+ kPcmRecoverIsSilent);
+ if (error < 0) {
+ LOG(ERROR) << "Failed querying delay: " << wrapper_->StrError(error);
+ }
+
+ // TODO(hclam): If we cannot query the delay, we may want to stop
+ // the playback and report an error.
+ delay = 0;
+ } else {
+ delay *= bytes_per_frame_;
+ }
+
packet->used = 0;
- // TODO(hclam): Provide pending bytes.
packet->size = shared_data_.OnMoreData(this, packet->buffer.get(),
- packet->capacity, 0);
+ packet->capacity, delay);
CHECK(packet->size <= packet->capacity) << "Data source overran buffer.";
// This should not happen, but incase it does, drop any trailing bytes
diff --git a/media/audio/linux/alsa_output_unittest.cc b/media/audio/linux/alsa_output_unittest.cc
index d736d93..d13da89 100644
--- a/media/audio/linux/alsa_output_unittest.cc
+++ b/media/audio/linux/alsa_output_unittest.cc
@@ -24,6 +24,7 @@ class MockAlsaWrapper : public AlsaWrapper {
MOCK_METHOD1(PcmClose, int(snd_pcm_t* handle));
MOCK_METHOD1(PcmPrepare, 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,
const void* buffer,
snd_pcm_uframes_t size));
@@ -272,6 +273,9 @@ TEST_F(AlsaPcmOutputStreamTest, StartStop) {
// Expect the pre-roll.
MockAudioSourceCallback mock_callback;
+ EXPECT_CALL(mock_alsa_wrapper_, PcmDelay(kFakeHandle, _))
+ .Times(2)
+ .WillRepeatedly(DoAll(SetArgumentPointee<1>(0), Return(0)));
EXPECT_CALL(mock_callback,
OnMoreData(test_stream_.get(), _, kTestPacketSize, 0))
.Times(2)
@@ -361,9 +365,11 @@ TEST_F(AlsaPcmOutputStreamTest, BufferPacket) {
// Return a partially filled packet.
MockAudioSourceCallback mock_callback;
+ EXPECT_CALL(mock_alsa_wrapper_, PcmDelay(_, _))
+ .WillOnce(DoAll(SetArgumentPointee<1>(1), Return(0)));
EXPECT_CALL(mock_callback,
OnMoreData(test_stream_.get(), packet_.buffer.get(),
- packet_.capacity, 0))
+ packet_.capacity, kTestBytesPerFrame))
.WillOnce(Return(10));
test_stream_->shared_data_.set_source_callback(&mock_callback);
diff --git a/media/audio/linux/alsa_wrapper.cc b/media/audio/linux/alsa_wrapper.cc
index 9557cac..8463686 100644
--- a/media/audio/linux/alsa_wrapper.cc
+++ b/media/audio/linux/alsa_wrapper.cc
@@ -29,6 +29,10 @@ int AlsaWrapper::PcmDrop(snd_pcm_t* handle) {
return snd_pcm_drop(handle);
}
+int AlsaWrapper::PcmDelay(snd_pcm_t* handle, snd_pcm_sframes_t* delay) {
+ return snd_pcm_delay(handle, delay);
+}
+
snd_pcm_sframes_t AlsaWrapper::PcmWritei(snd_pcm_t* handle,
const void* buffer,
snd_pcm_uframes_t size) {
diff --git a/media/audio/linux/alsa_wrapper.h b/media/audio/linux/alsa_wrapper.h
index a3dafbb..d7686dd 100644
--- a/media/audio/linux/alsa_wrapper.h
+++ b/media/audio/linux/alsa_wrapper.h
@@ -20,6 +20,7 @@ class AlsaWrapper {
virtual int PcmClose(snd_pcm_t* handle);
virtual int PcmPrepare(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,
const void* buffer,
snd_pcm_uframes_t size);