Merge "MediaRecorder: only dequeue available buffers from MediaCodec" into lmp-dev
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index d225851..5270efc 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -966,6 +966,8 @@
ALOGV("Tear down audio offload, fall back to s/w path");
int64_t positionUs;
CHECK(msg->findInt64("positionUs", &positionUs));
+ int32_t reason;
+ CHECK(msg->findInt32("reason", &reason));
closeAudioSink();
mAudioDecoder.clear();
++mAudioDecoderGeneration;
@@ -977,7 +979,9 @@
mOffloadAudio = false;
performSeek(positionUs, false /* needNotify */);
- instantiateDecoder(true /* audio */, &mAudioDecoder);
+ if (reason == Renderer::kDueToError) {
+ instantiateDecoder(true /* audio */, &mAudioDecoder);
+ }
}
break;
}
@@ -1044,6 +1048,11 @@
} else {
ALOGW("resume called when source is gone or not set");
}
+ // |mAudioDecoder| may have been released due to the pause timeout, so try to re-create
+ // it if needed.
+ if (mFlushingAudio != SHUT_DOWN) {
+ instantiateDecoder(true /* audio */, &mAudioDecoder);
+ }
if (mRenderer != NULL) {
mRenderer->resume();
} else {
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index 7e5087f..d6bf1de 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -274,7 +274,7 @@
case kWhatAudioOffloadTearDown:
{
- onAudioOffloadTearDown();
+ onAudioOffloadTearDown(kDueToError);
break;
}
@@ -285,7 +285,8 @@
if (generation != mAudioOffloadPauseTimeoutGeneration) {
break;
}
- onAudioOffloadTearDown();
+ ALOGV("Audio Offload tear down due to pause timeout.");
+ onAudioOffloadTearDown(kDueToTimeout);
break;
}
@@ -1089,7 +1090,7 @@
return durationUs;
}
-void NuPlayer::Renderer::onAudioOffloadTearDown() {
+void NuPlayer::Renderer::onAudioOffloadTearDown(AudioOffloadTearDownReason reason) {
if (mAudioOffloadTornDown) {
return;
}
@@ -1110,6 +1111,7 @@
sp<AMessage> notify = mNotify->dup();
notify->setInt32("what", kWhatAudioOffloadTearDown);
notify->setInt64("positionUs", currentPositionUs);
+ notify->setInt32("reason", reason);
notify->post();
}
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
index 8e6112b..4237902 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
@@ -69,6 +69,11 @@
kWhatAudioOffloadPauseTimeout = 'aOPT',
};
+ enum AudioOffloadTearDownReason {
+ kDueToError = 0,
+ kDueToTimeout,
+ };
+
protected:
virtual ~Renderer();
@@ -157,7 +162,7 @@
void onPause();
void onResume();
void onSetVideoFrameRate(float fps);
- void onAudioOffloadTearDown();
+ void onAudioOffloadTearDown(AudioOffloadTearDownReason reason);
void notifyEOS(bool audio, status_t finalResult, int64_t delayUs = 0);
void notifyFlushComplete(bool audio);
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index e200857..e48af20 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1436,6 +1436,16 @@
IPCThreadState::self()->getCallingUid(),
flags, tid, &lStatus);
LOG_ALWAYS_FATAL_IF((lStatus == NO_ERROR) && (recordTrack == 0));
+
+ if (lStatus == NO_ERROR) {
+ // Check if one effect chain was awaiting for an AudioRecord to be created on this
+ // session and move it to this thread.
+ sp<EffectChain> chain = getOrphanEffectChain_l((audio_session_t)lSessionId);
+ if (chain != 0) {
+ Mutex::Autolock _l(thread->mLock);
+ thread->addEffectChain_l(chain);
+ }
+ }
}
if (lStatus != NO_ERROR) {
@@ -2034,14 +2044,41 @@
}
ALOGV("closeInput() %d", input);
+
+ // If we still have effect chains, it means that a client still holds a handle
+ // on at least one effect. We must either move the chain to an existing thread with the
+ // same session ID or put it aside in case a new record thread is opened for a
+ // new capture on the same session
+ sp<EffectChain> chain;
{
- // If we still have effect chains, it means that a client still holds a handle
- // on at least one effect. We must keep the chain alive in case a new record
- // thread is opened for a new capture on the same session
Mutex::Autolock _sl(thread->mLock);
Vector< sp<EffectChain> > effectChains = thread->getEffectChains_l();
- for (size_t i = 0; i < effectChains.size(); i++) {
- putOrphanEffectChain_l(effectChains[i]);
+ // Note: maximum one chain per record thread
+ if (effectChains.size() != 0) {
+ chain = effectChains[0];
+ }
+ }
+ if (chain != 0) {
+ // first check if a record thread is already opened with a client on the same session.
+ // This should only happen in case of overlap between one thread tear down and the
+ // creation of its replacement
+ size_t i;
+ for (i = 0; i < mRecordThreads.size(); i++) {
+ sp<RecordThread> t = mRecordThreads.valueAt(i);
+ if (t == thread) {
+ continue;
+ }
+ if (t->hasAudioSession(chain->sessionId()) != 0) {
+ Mutex::Autolock _l(t->mLock);
+ ALOGV("closeInput() found thread %d for effect session %d",
+ t->id(), chain->sessionId());
+ t->addEffectChain_l(chain);
+ break;
+ }
+ }
+ // put the chain aside if we could not find a record thread with the same session id.
+ if (i == mRecordThreads.size()) {
+ putOrphanEffectChain_l(chain);
}
}
audioConfigChanged(AudioSystem::INPUT_CLOSED, input, NULL);
@@ -2478,6 +2515,7 @@
// session and used it instead of creating a new one.
sp<EffectChain> chain = getOrphanEffectChain_l((audio_session_t)sessionId);
if (chain != 0) {
+ Mutex::Autolock _l(thread->mLock);
thread->addEffectChain_l(chain);
}
}
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index 4678880..bcaf8ae 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -440,6 +440,20 @@
return status;
}
+void AudioFlinger::EffectModule::addEffectToHal_l()
+{
+ if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_PRE_PROC ||
+ (mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_POST_PROC) {
+ sp<ThreadBase> thread = mThread.promote();
+ if (thread != 0) {
+ audio_stream_t *stream = thread->stream();
+ if (stream != NULL) {
+ stream->add_audio_effect(stream, mEffectInterface);
+ }
+ }
+ }
+}
+
status_t AudioFlinger::EffectModule::start()
{
Mutex::Autolock _l(mLock);
@@ -466,16 +480,7 @@
status = cmdStatus;
}
if (status == 0) {
- if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_PRE_PROC ||
- (mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_POST_PROC) {
- sp<ThreadBase> thread = mThread.promote();
- if (thread != 0) {
- audio_stream_t *stream = thread->stream();
- if (stream != NULL) {
- stream->add_audio_effect(stream, mEffectInterface);
- }
- }
- }
+ addEffectToHal_l();
sp<EffectChain> chain = mChain.promote();
if (chain != 0) {
chain->forceVolume();
@@ -1696,6 +1701,17 @@
return hasControl;
}
+void AudioFlinger::EffectChain::syncHalEffectsState()
+{
+ Mutex::Autolock _l(mLock);
+ for (size_t i = 0; i < mEffects.size(); i++) {
+ if (mEffects[i]->state() == EffectModule::ACTIVE ||
+ mEffects[i]->state() == EffectModule::STOPPING) {
+ mEffects[i]->addEffectToHal_l();
+ }
+ }
+}
+
void AudioFlinger::EffectChain::dump(int fd, const Vector<String16>& args)
{
const size_t SIZE = 256;
diff --git a/services/audioflinger/Effects.h b/services/audioflinger/Effects.h
index b87a1fd..6f93f81 100644
--- a/services/audioflinger/Effects.h
+++ b/services/audioflinger/Effects.h
@@ -119,6 +119,7 @@
{ return (mDescriptor.flags & EFFECT_FLAG_OFFLOAD_SUPPORTED) != 0; }
status_t setOffloaded(bool offloaded, audio_io_handle_t io);
bool isOffloaded() const;
+ void addEffectToHal_l();
void dump(int fd, const Vector<String16>& args);
@@ -325,6 +326,8 @@
// we are the only observers.
bool isVolumeForced() { return (android_atomic_acquire_cas(true, false, &mForceVolume) == 0); }
+ void syncHalEffectsState();
+
void dump(int fd, const Vector<String16>& args);
protected:
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index b1e9c07..44e34b7 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -6207,6 +6207,10 @@
checkSuspendOnAddEffectChain_l(chain);
+ // make sure enabled pre processing effects state is communicated to the HAL as we
+ // just moved them to a new input stream.
+ chain->syncHalEffectsState();
+
mEffectChains.add(chain);
return NO_ERROR;