Commit 990eb43c authored by wjia@chromium.org's avatar wjia@chromium.org

Fix audio capture buffer handling on Android.

The buffer handling in OpenSL is:
1. enqueue the buffers;
2. wait for a callback;
3. inside the callback, read out the PCM data of current buffer and enqueue one buffer (it's the same buffer in this case).
4. go to step 2.

Current implementation has several problems:
a. When buffer #1 (not buffer #0) is read first time, it doesn't have PCM data recorded by the device. 
b. There are 2 buffer worth of time delay.
c. There are racing condtion since both OpenSL and AudioInputController hold the same buffer.

BUG=243506
R=xians@chromium.org

Review URL: https://codereview.chromium.org/15941002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@202581 0039d316-1c4b-4281-b951-d872f2087c98
parent 442c50b9
...@@ -71,7 +71,7 @@ void OpenSLESInputStream::Start(AudioInputCallback* callback) { ...@@ -71,7 +71,7 @@ void OpenSLESInputStream::Start(AudioInputCallback* callback) {
SLresult err = SL_RESULT_UNKNOWN_ERROR; SLresult err = SL_RESULT_UNKNOWN_ERROR;
// Enqueues |kNumOfQueuesInBuffer| zero buffers to get the ball rolling. // Enqueues |kNumOfQueuesInBuffer| zero buffers to get the ball rolling.
for (int i = 0; i < kNumOfQueuesInBuffer - 1; ++i) { for (int i = 0; i < kNumOfQueuesInBuffer; ++i) {
err = (*simple_buffer_queue_)->Enqueue( err = (*simple_buffer_queue_)->Enqueue(
simple_buffer_queue_, simple_buffer_queue_,
audio_data_[i], audio_data_[i],
...@@ -187,7 +187,7 @@ bool OpenSLESInputStream::CreateRecorder() { ...@@ -187,7 +187,7 @@ bool OpenSLESInputStream::CreateRecorder() {
// Audio sink configuration. // Audio sink configuration.
SLDataLocator_AndroidSimpleBufferQueue buffer_queue = { SLDataLocator_AndroidSimpleBufferQueue buffer_queue = {
SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, // Locator type. SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, // Locator type.
static_cast<SLuint32>(kNumOfQueuesInBuffer) // Number of buffers. static_cast<SLuint32>(kNumOfQueuesInBuffer) // Number of buffers.
}; };
SLDataSink audio_sink = { &buffer_queue, &format_ }; SLDataSink audio_sink = { &buffer_queue, &format_ };
...@@ -258,14 +258,6 @@ void OpenSLESInputStream::ReadBufferQueue() { ...@@ -258,14 +258,6 @@ void OpenSLESInputStream::ReadBufferQueue() {
if (!started_) if (!started_)
return; return;
// Get the enqueued buffer from the soundcard.
SLresult err = (*simple_buffer_queue_)->Enqueue(
simple_buffer_queue_,
audio_data_[active_queue_],
buffer_size_bytes_);
if (SL_RESULT_SUCCESS != err)
HandleError(err);
// TODO(xians): Get an accurate delay estimation. // TODO(xians): Get an accurate delay estimation.
callback_->OnData(this, callback_->OnData(this,
audio_data_[active_queue_], audio_data_[active_queue_],
...@@ -273,6 +265,14 @@ void OpenSLESInputStream::ReadBufferQueue() { ...@@ -273,6 +265,14 @@ void OpenSLESInputStream::ReadBufferQueue() {
buffer_size_bytes_, buffer_size_bytes_,
0.0); 0.0);
// Done with this buffer. Send it to device for recording.
SLresult err = (*simple_buffer_queue_)->Enqueue(
simple_buffer_queue_,
audio_data_[active_queue_],
buffer_size_bytes_);
if (SL_RESULT_SUCCESS != err)
HandleError(err);
active_queue_ = (active_queue_ + 1) % kNumOfQueuesInBuffer; active_queue_ = (active_queue_ + 1) % kNumOfQueuesInBuffer;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment