Modified submix HAL to drop data to the output stream if the pipe could block.

Since it's possible to open an output stream on the submix HAL before the input
stream is open, writes to the output stream that fill the shared pipe result in
indefinitely blocking the thread writing to the stream.  This change modifies
the behavior of writes to a submix output stream such that if a write would
result in blocking the thread and an input isn't open, the pipe is flushed
of the appropriate amount of data such that the write will not block.

Bug: 11273000
Change-Id: Ic81c50e4b44b777273191a1bc8cdf52181c3d2a0
This commit is contained in:
Stewart Miles 2014-05-01 09:03:27 -07:00
parent c1e0179a95
commit 2d199fe082

View file

@ -624,6 +624,25 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer,
return 0;
}
// If the write to the sink would block when no input stream is present, flush enough frames
// from the pipe to make space to write the most recent data.
{
const size_t availableToWrite = sink->availableToWrite();
sp<MonoPipeReader> source = rsxadev->rsxSource;
if (rsxadev->input == NULL && availableToWrite < frames) {
static uint8_t flush_buffer[64];
const size_t flushBufferSizeFrames = sizeof(flush_buffer) / frame_size;
size_t frames_to_flush_from_source = frames - availableToWrite;
SUBMIX_ALOGV("out_write(): flushing %d frames from the pipe to avoid blocking",
frames_to_flush_from_source);
while (frames_to_flush_from_source) {
const size_t flush_size = min(frames_to_flush_from_source, flushBufferSizeFrames);
frames_to_flush_from_source -= flush_size;
source->read(flush_buffer, flush_size, AudioBufferProvider::kInvalidPTS);
}
}
}
pthread_mutex_unlock(&rsxadev->lock);
written_frames = sink->write(buffer, frames);