From 2d199fe082312963edd1ac198197280a4f18ca21 Mon Sep 17 00:00:00 2001 From: Stewart Miles Date: Thu, 1 May 2014 09:03:27 -0700 Subject: [PATCH] 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 --- modules/audio_remote_submix/audio_hw.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/modules/audio_remote_submix/audio_hw.cpp b/modules/audio_remote_submix/audio_hw.cpp index 8014d189..7c16ad1e 100644 --- a/modules/audio_remote_submix/audio_hw.cpp +++ b/modules/audio_remote_submix/audio_hw.cpp @@ -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 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);