Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(889)

Unified Diff: media/audio/android/opensles_input.cc

Issue 23296008: Adding audio unit tests for Android (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Now supports Start,Stop,Start Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « media/audio/android/opensles_input.h ('k') | media/audio/android/opensles_output.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/audio/android/opensles_input.cc
diff --git a/media/audio/android/opensles_input.cc b/media/audio/android/opensles_input.cc
index 15c3eac3726389bb7f8d0a7f37ee4b8d35a82f91..3a543ff06c809ad9e2d85ef6da7c87192c3534d0 100644
--- a/media/audio/android/opensles_input.cc
+++ b/media/audio/android/opensles_input.cc
@@ -27,6 +27,7 @@ OpenSLESInputStream::OpenSLESInputStream(AudioManagerAndroid* audio_manager,
active_queue_(0),
buffer_size_bytes_(0),
started_(false) {
+ DVLOG(2) << "OpenSLESInputStream::OpenSLESInputStream()";
format_.formatType = SL_DATAFORMAT_PCM;
format_.numChannels = static_cast<SLuint32>(params.channels());
// Provides sampling rate in milliHertz to OpenSLES.
@@ -47,6 +48,8 @@ OpenSLESInputStream::OpenSLESInputStream(AudioManagerAndroid* audio_manager,
}
OpenSLESInputStream::~OpenSLESInputStream() {
+ DVLOG(2) << "OpenSLESInputStream::~OpenSLESInputStream()";
+ DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(!recorder_object_.Get());
DCHECK(!engine_object_.Get());
DCHECK(!recorder_);
@@ -55,6 +58,8 @@ OpenSLESInputStream::~OpenSLESInputStream() {
}
bool OpenSLESInputStream::Open() {
+ DVLOG(2) << "OpenSLESInputStream::Open()";
+ DCHECK(thread_checker_.CalledOnValidThread());
if (engine_object_.Get())
return false;
@@ -67,9 +72,13 @@ bool OpenSLESInputStream::Open() {
}
void OpenSLESInputStream::Start(AudioInputCallback* callback) {
+ DVLOG(2) << "OpenSLESInputStream::Start()";
+ DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(callback);
DCHECK(recorder_);
DCHECK(simple_buffer_queue_);
+
+ base::AutoLock lock(lock_);
if (started_)
tommi (sloooow) - chröme 2013/08/30 12:43:34 now that you don't touch started_ in the callback,
henrika (OOO until Aug 14) 2013/08/30 14:20:37 oops, thanks
return;
@@ -78,26 +87,47 @@ void OpenSLESInputStream::Start(AudioInputCallback* callback) {
active_queue_ = 0;
started_ = true;
- SLresult err = SL_RESULT_UNKNOWN_ERROR;
- // Enqueues |kNumOfQueuesInBuffer| zero buffers to get the ball rolling.
- for (int i = 0; i < kNumOfQueuesInBuffer; ++i) {
- err = (*simple_buffer_queue_)->Enqueue(
- simple_buffer_queue_,
- audio_data_[i],
- buffer_size_bytes_);
- if (SL_RESULT_SUCCESS != err) {
- HandleError(err);
- return;
+
+ SLAndroidSimpleBufferQueueState buffer_queue_state;
+ SLresult err = (*simple_buffer_queue_)->GetState(simple_buffer_queue_,
+ &buffer_queue_state);
+ if (SL_RESULT_SUCCESS != err) {
+ HandleError(err);
tommi (sloooow) - chröme 2013/08/30 12:43:34 set started_ to false? alternatively don't set st
henrika (OOO until Aug 14) 2013/08/30 14:20:37 Moved it to the end since we don't check it in the
+ return;
+ }
+
+ // Enqueues |kNumOfQueuesInBuffer| zero buffers to get the ball rolling
+ // but only if the queue is empty. It can be non-empty if Stop has been
+ // called followed by a new call to Start. We do clear the queue in Stop,
+ // and the buffer state should then be cleared, but for some reason it is
+ // not. Using this approach enables call sequences like: Start, Stop, Start,
+ // even if there might be some old data remaining at the second call to
+ // Start.
+ if (buffer_queue_state.index == 0) {
+ for (int i = 0; i < kNumOfQueuesInBuffer; ++i) {
+ err = (*simple_buffer_queue_)->Enqueue(
+ simple_buffer_queue_,
+ audio_data_[i],
+ buffer_size_bytes_);
+ if (SL_RESULT_SUCCESS != err) {
+ HandleError(err);
+ return;
+ }
}
}
// Start the recording by setting the state to |SL_RECORDSTATE_RECORDING|.
err = (*recorder_)->SetRecordState(recorder_, SL_RECORDSTATE_RECORDING);
- if (SL_RESULT_SUCCESS != err)
+ if (SL_RESULT_SUCCESS != err) {
HandleError(err);
+ }
}
void OpenSLESInputStream::Stop() {
+ DVLOG(2) << "OpenSLESInputStream::Stop()";
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ base::AutoLock lock(lock_);
tommi (sloooow) - chröme 2013/08/30 12:43:34 same here
henrika (OOO until Aug 14) 2013/08/30 14:20:37 Done.
if (!started_)
return;
@@ -114,17 +144,31 @@ void OpenSLESInputStream::Stop() {
}
void OpenSLESInputStream::Close() {
+ DVLOG(2) << "OpenSLESInputStream::Close()";
+ DCHECK(thread_checker_.CalledOnValidThread());
+
// Stop the stream if it is still recording.
Stop();
- // Explicitly free the player objects and invalidate their associated
- // interfaces. They have to be done in the correct order.
- recorder_object_.Reset();
- engine_object_.Reset();
- simple_buffer_queue_ = NULL;
- recorder_ = NULL;
+ {
+ base::AutoLock lock(lock_);
+
+ if (callback_) {
+ callback_->OnClose(this);
+ callback_ = NULL;
+ }
- ReleaseAudioBuffer();
+ // Destroy the buffer queue recorder object and invalidate all associated
+ // interfaces.
+ recorder_object_.Reset();
+ simple_buffer_queue_ = NULL;
+ recorder_ = NULL;
+
+ // Destroy the engine object. We don't store any associated interface for
+ // this object.
+ engine_object_.Reset();
+ ReleaseAudioBuffer();
+ }
audio_manager_->ReleaseInputStream(this);
}
@@ -153,6 +197,12 @@ bool OpenSLESInputStream::GetAutomaticGainControl() {
}
bool OpenSLESInputStream::CreateRecorder() {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK(!engine_object_.Get());
+ DCHECK(!recorder_object_.Get());
+ DCHECK(!recorder_);
+ DCHECK(!simple_buffer_queue_);
+
// Initializes the engine object with specific option. After working with the
// object, we need to free the object and its resources.
SLEngineOption option[] = {
@@ -201,6 +251,7 @@ bool OpenSLESInputStream::CreateRecorder() {
SL_BOOLEAN_TRUE,
SL_BOOLEAN_TRUE
};
+
// Create AudioRecorder and specify SL_IID_ANDROIDCONFIGURATION.
LOG_ON_FAILURE_AND_RETURN(
(*engine)->CreateAudioRecorder(engine,
@@ -265,8 +316,17 @@ void OpenSLESInputStream::SimpleBufferQueueCallback(
}
void OpenSLESInputStream::ReadBufferQueue() {
- if (!started_)
+ base::AutoLock lock(lock_);
+
+ // Verify that we are in a recording state.
+ SLuint32 state;
+ SLresult err = (*recorder_)->GetRecordState(recorder_, &state);
+ if (SL_RESULT_SUCCESS != err)
+ HandleError(err);
tommi (sloooow) - chröme 2013/08/30 12:43:34 missing return?
henrika (OOO until Aug 14) 2013/08/30 14:20:37 Done.
+ if (state != SL_RECORDSTATE_RECORDING) {
+ DLOG(WARNING) << "Invalid callback in non-recording state";
tommi (sloooow) - chröme 2013/08/30 12:43:34 nit: s/Invalid/Received
henrika (OOO until Aug 14) 2013/08/30 14:20:37 Done.
return;
+ }
// TODO(xians): Get an accurate delay estimation.
callback_->OnData(this,
@@ -276,7 +336,7 @@ void OpenSLESInputStream::ReadBufferQueue() {
0.0);
// Done with this buffer. Send it to device for recording.
- SLresult err = (*simple_buffer_queue_)->Enqueue(
+ err = (*simple_buffer_queue_)->Enqueue(
simple_buffer_queue_,
audio_data_[active_queue_],
buffer_size_bytes_);
@@ -287,6 +347,7 @@ void OpenSLESInputStream::ReadBufferQueue() {
}
void OpenSLESInputStream::SetupAudioBuffer() {
+ DCHECK(thread_checker_.CalledOnValidThread());
DCHECK(!audio_data_[0]);
for (int i = 0; i < kNumOfQueuesInBuffer; ++i) {
audio_data_[i] = new uint8[buffer_size_bytes_];
@@ -294,6 +355,7 @@ void OpenSLESInputStream::SetupAudioBuffer() {
}
void OpenSLESInputStream::ReleaseAudioBuffer() {
+ DCHECK(thread_checker_.CalledOnValidThread());
if (audio_data_[0]) {
for (int i = 0; i < kNumOfQueuesInBuffer; ++i) {
delete [] audio_data_[i];
@@ -303,7 +365,7 @@ void OpenSLESInputStream::ReleaseAudioBuffer() {
}
void OpenSLESInputStream::HandleError(SLresult error) {
- DLOG(FATAL) << "OpenSLES Input error " << error;
+ DLOG(ERROR) << "OpenSLES Input error " << error;
if (callback_)
callback_->OnError(this);
}
« no previous file with comments | « media/audio/android/opensles_input.h ('k') | media/audio/android/opensles_output.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698