Skip to content

Commit

Permalink
Revert r104043, which causes audio not to play smoothly on Chrome OS.
Browse files Browse the repository at this point in the history
BUG=chromium-os:21491

Review URL: http://codereview.chromium.org/8329004

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@105996 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
enal@chromium.org committed Oct 18, 2011
1 parent df31da4 commit 091a5b6
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 44 deletions.
52 changes: 16 additions & 36 deletions media/audio/linux/alsa_output.cc
Original file line number Diff line number Diff line change
Expand Up @@ -347,8 +347,7 @@ void AlsaPcmOutputStream::OpenTask() {
if (error < 0) {
LOG(ERROR) << "Failed to get playback buffer size from ALSA: "
<< wrapper_->StrError(error);
// Buffer size is at least twice of packet size.
alsa_buffer_frames_ = 2 * frames_per_packet_;
alsa_buffer_frames_ = frames_per_packet_;
} else {
alsa_buffer_frames_ = buffer_size;
}
Expand Down Expand Up @@ -598,44 +597,25 @@ void AlsaPcmOutputStream::ScheduleNextWrite(bool source_exhausted) {
return;
}

// Next write is initially scheduled for the moment when half of a packet
// has been played out.
uint32 minimal_frames_wanted = frames_per_packet_ / 2;
uint32 next_fill_time_ms = FramesToMillis(minimal_frames_wanted,
sample_rate_);

// Set existing_frames to be minimal_frames_wanted to avoid busy looping
// in case alsa_buffer_frames_ is smaller than available_freams.
// Next write is scheduled for the moment when half of the buffer is
// available.
uint32 frames_avail_wanted = alsa_buffer_frames_ / 2;
uint32 available_frames = GetAvailableFrames();
uint32 existing_frames = (alsa_buffer_frames_ >= available_frames) ?
(alsa_buffer_frames_ - available_frames) : minimal_frames_wanted;

// ALSA is full, schedule another write when some buffer is available.
// This helps reduce the CPU usage.
if (available_frames == 0) {
next_fill_time_ms = std::min(next_fill_time_ms, kNoDataSleepMilliseconds);
message_loop_->PostDelayedTask(
FROM_HERE,
base::Bind(&AlsaPcmOutputStream::ScheduleNextWrite,
weak_factory_.GetWeakPtr(), false),
next_fill_time_ms);
return;
}
uint32 next_fill_time_ms = 0;


// Re-schedule the next write for the moment when the available buffer is
// enough for a packet. Avoid back-to-back writing by setting
// kNoDataSleepMilliseconds as the minimal interval.
if (available_frames < frames_per_packet_) {
next_fill_time_ms = std::max(
kNoDataSleepMilliseconds,
FramesToMillis(frames_per_packet_ - available_frames,
sample_rate_));
// It's possible to have more frames available than what we want, in which
// case we'll leave our |next_fill_time_ms| at 0ms.
if (available_frames < frames_avail_wanted) {
uint32 frames_until_empty_enough = frames_avail_wanted - available_frames;
next_fill_time_ms =
FramesToMillis(frames_until_empty_enough, sample_rate_);
}
else if (existing_frames < minimal_frames_wanted) {
// If less than half of the packet in the buffer, invoke the write callback
// immediately to fill more data.

// Adjust for timer resolution issues.
if (next_fill_time_ms < kSleepErrorMilliseconds) {
next_fill_time_ms = 0;
} else {
next_fill_time_ms -= kSleepErrorMilliseconds;
}

// Avoid busy looping if the data source is exhausted.
Expand Down
15 changes: 7 additions & 8 deletions media/audio/linux/alsa_output_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,13 @@ TEST_F(AlsaPcmOutputStreamTest, StartStop) {
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, _))
.Times(2)
.WillOnce(Return(kTestPacketSize))
.WillOnce(Return(0));
EXPECT_CALL(mock_alsa_wrapper_, PcmWritei(kFakeHandle, _, _))
.WillOnce(Return(kTestFramesPerPacket));

// Expect scheduling.
EXPECT_CALL(mock_alsa_wrapper_, PcmAvailUpdate(kFakeHandle))
Expand All @@ -446,14 +453,6 @@ TEST_F(AlsaPcmOutputStreamTest, StartStop) {
&MessageLoop::QuitNow),
Return(0))); // Buffer is full.

EXPECT_CALL(mock_callback,
OnMoreData(test_stream_.get(), _, kTestPacketSize, _))
.Times(2)
.WillOnce(Return(kTestPacketSize))
.WillOnce(Return(0));
EXPECT_CALL(mock_alsa_wrapper_, PcmWritei(kFakeHandle, _, _))
.WillOnce(Return(kTestFramesPerPacket));

test_stream_->Start(&mock_callback);
message_loop_.RunAllPending();

Expand Down

0 comments on commit 091a5b6

Please sign in to comment.