Merge "stagefright: prevent allocating stale buffers for OMX decoders" into mnc-dev
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h
index 26cffa6..06116a5 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -408,8 +408,8 @@
AudioPolicyServiceClient() {
}
- status_t addAudioPortCallback(const sp<AudioPortCallback>& callback);
- status_t removeAudioPortCallback(const sp<AudioPortCallback>& callback);
+ int addAudioPortCallback(const sp<AudioPortCallback>& callback);
+ int removeAudioPortCallback(const sp<AudioPortCallback>& callback);
// DeathRecipient
virtual void binderDied(const wp<IBinder>& who);
diff --git a/include/media/IAudioPolicyService.h b/include/media/IAudioPolicyService.h
index ee462a0..6b93f6f 100644
--- a/include/media/IAudioPolicyService.h
+++ b/include/media/IAudioPolicyService.h
@@ -149,6 +149,8 @@
virtual void registerClient(const sp<IAudioPolicyServiceClient>& client) = 0;
+ virtual void setAudioPortCallbacksEnabled(bool enabled) = 0;
+
virtual status_t acquireSoundTriggerSession(audio_session_t *session,
audio_io_handle_t *ioHandle,
audio_devices_t *device) = 0;
diff --git a/include/media/stagefright/MediaCodecSource.h b/include/media/stagefright/MediaCodecSource.h
index a991b02..71f58a9 100644
--- a/include/media/stagefright/MediaCodecSource.h
+++ b/include/media/stagefright/MediaCodecSource.h
@@ -108,6 +108,9 @@
bool mStarted;
bool mStopping;
bool mDoMoreWorkPending;
+ bool mSetEncoderFormat;
+ int mEncoderFormat;
+ int mEncoderDataSpace;
sp<AMessage> mEncoderActivityNotify;
sp<IGraphicBufferProducer> mGraphicBufferProducer;
sp<IGraphicBufferConsumer> mGraphicBufferConsumer;
diff --git a/include/media/stagefright/MetaData.h b/include/media/stagefright/MetaData.h
index ca80123..726b197 100644
--- a/include/media/stagefright/MetaData.h
+++ b/include/media/stagefright/MetaData.h
@@ -70,7 +70,9 @@
kKeyDriftTime = 'dftT', // int64_t (usecs)
kKeyAnchorTime = 'ancT', // int64_t (usecs)
kKeyDuration = 'dura', // int64_t (usecs)
- kKeyColorFormat = 'colf',
+ kKeyPixelFormat = 'pixf', // int32_t
+ kKeyColorFormat = 'colf', // int32_t
+ kKeyColorSpace = 'cols', // int32_t
kKeyPlatformPrivate = 'priv', // pointer
kKeyDecoderComponent = 'decC', // cstring
kKeyBufferID = 'bfID',
diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp
index 6c2c226..f13bcf3 100644
--- a/media/libmedia/AudioSystem.cpp
+++ b/media/libmedia/AudioSystem.cpp
@@ -1043,7 +1043,11 @@
if (gAudioPolicyServiceClient == 0) {
return NO_INIT;
}
- return gAudioPolicyServiceClient->addAudioPortCallback(callback);
+ int ret = gAudioPolicyServiceClient->addAudioPortCallback(callback);
+ if (ret == 1) {
+ aps->setAudioPortCallbacksEnabled(true);
+ }
+ return (ret < 0) ? INVALID_OPERATION : NO_ERROR;
}
/*static*/
@@ -1056,7 +1060,11 @@
if (gAudioPolicyServiceClient == 0) {
return NO_INIT;
}
- return gAudioPolicyServiceClient->removeAudioPortCallback(callback);
+ int ret = gAudioPolicyServiceClient->removeAudioPortCallback(callback);
+ if (ret == 0) {
+ aps->setAudioPortCallbacksEnabled(false);
+ }
+ return (ret < 0) ? INVALID_OPERATION : NO_ERROR;
}
status_t AudioSystem::addAudioDeviceCallback(
@@ -1138,20 +1146,20 @@
// ---------------------------------------------------------------------------
-status_t AudioSystem::AudioPolicyServiceClient::addAudioPortCallback(
+int AudioSystem::AudioPolicyServiceClient::addAudioPortCallback(
const sp<AudioPortCallback>& callback)
{
Mutex::Autolock _l(mLock);
for (size_t i = 0; i < mAudioPortCallbacks.size(); i++) {
if (mAudioPortCallbacks[i] == callback) {
- return INVALID_OPERATION;
+ return -1;
}
}
mAudioPortCallbacks.add(callback);
- return NO_ERROR;
+ return mAudioPortCallbacks.size();
}
-status_t AudioSystem::AudioPolicyServiceClient::removeAudioPortCallback(
+int AudioSystem::AudioPolicyServiceClient::removeAudioPortCallback(
const sp<AudioPortCallback>& callback)
{
Mutex::Autolock _l(mLock);
@@ -1162,10 +1170,10 @@
}
}
if (i == mAudioPortCallbacks.size()) {
- return INVALID_OPERATION;
+ return -1;
}
mAudioPortCallbacks.removeAt(i);
- return NO_ERROR;
+ return mAudioPortCallbacks.size();
}
diff --git a/media/libmedia/IAudioPolicyService.cpp b/media/libmedia/IAudioPolicyService.cpp
index fd18f17..3348441 100644
--- a/media/libmedia/IAudioPolicyService.cpp
+++ b/media/libmedia/IAudioPolicyService.cpp
@@ -72,7 +72,8 @@
GET_PHONE_STATE,
REGISTER_POLICY_MIXES,
START_AUDIO_SOURCE,
- STOP_AUDIO_SOURCE
+ STOP_AUDIO_SOURCE,
+ SET_AUDIO_PORT_CALLBACK_ENABLED,
};
#define MAX_ITEMS_PER_LIST 1024
@@ -646,6 +647,14 @@
remote()->transact(REGISTER_CLIENT, data, &reply);
}
+ virtual void setAudioPortCallbacksEnabled(bool enabled)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+ data.writeInt32(enabled ? 1 : 0);
+ remote()->transact(SET_AUDIO_PORT_CALLBACK_ENABLED, data, &reply);
+ }
+
virtual status_t acquireSoundTriggerSession(audio_session_t *session,
audio_io_handle_t *ioHandle,
audio_devices_t *device)
@@ -1219,6 +1228,12 @@
return NO_ERROR;
} break;
+ case SET_AUDIO_PORT_CALLBACK_ENABLED: {
+ CHECK_INTERFACE(IAudioPolicyService, data, reply);
+ setAudioPortCallbacksEnabled(data.readInt32() == 1);
+ return NO_ERROR;
+ } break;
+
case ACQUIRE_SOUNDTRIGGER_SESSION: {
CHECK_INTERFACE(IAudioPolicyService, data, reply);
sp<IAudioPolicyServiceClient> client = interface_cast<IAudioPolicyServiceClient>(
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 383966f..7452e4b 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -1639,6 +1639,14 @@
if (mInputMetadataType == kMetadataBufferTypeGrallocSource) {
mInputMetadataType = kMetadataBufferTypeCameraSource;
}
+
+ uint32_t usageBits;
+ if (mOMX->getParameter(
+ mNode, (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
+ &usageBits, sizeof(usageBits)) == OK) {
+ inputFormat->setInt32(
+ "using-sw-read-often", !!(usageBits & GRALLOC_USAGE_SW_READ_OFTEN));
+ }
}
int32_t prependSPSPPS = 0;
@@ -5749,6 +5757,14 @@
}
}
+ uint32_t usageBits;
+ if (mCodec->mOMX->getParameter(
+ mCodec->mNode, (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits,
+ &usageBits, sizeof(usageBits)) == OK) {
+ mCodec->mInputFormat->setInt32(
+ "using-sw-read-often", !!(usageBits & GRALLOC_USAGE_SW_READ_OFTEN));
+ }
+
return OK;
}
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
index 2606e44..bc34bcf 100644
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
@@ -670,9 +670,13 @@
mNumInputBuffers = nBuffers;
}
- // TODO: Read in format/dataspace from somewhere
- // Uncomment to test SW encoders until TODO is resolved
- // mEncoderFormat = HAL_PIXEL_FORMAT_YCbCr_420_888;
+ // apply encoder color format if specified
+ if (meta->findInt32(kKeyPixelFormat, &mEncoderFormat)) {
+ ALOGV("Using encoder format: %#x", mEncoderFormat);
+ }
+ if (meta->findInt32(kKeyColorSpace, &mEncoderDataSpace)) {
+ ALOGV("Using encoder data space: %#x", mEncoderDataSpace);
+ }
}
status_t err;
diff --git a/media/libstagefright/MediaCodecList.cpp b/media/libstagefright/MediaCodecList.cpp
index 8993403..7ea5cbd 100644
--- a/media/libstagefright/MediaCodecList.cpp
+++ b/media/libstagefright/MediaCodecList.cpp
@@ -38,6 +38,7 @@
#include <sys/stat.h>
#include <utils/threads.h>
+#include <cutils/properties.h>
#include <libexpat/expat.h>
namespace android {
@@ -56,6 +57,11 @@
}
static bool isProfilingNeeded() {
+ int8_t value = property_get_bool("debug.stagefright.profilecodec", 0);
+ if (value == 0) {
+ return false;
+ }
+
bool profilingNeeded = true;
FILE *resultsFile = fopen(kProfilingResults, "r");
if (resultsFile) {
@@ -169,6 +175,7 @@
mUpdate(false),
mGlobalSettings(new AMessage()) {
parseTopLevelXMLFile("/etc/media_codecs.xml");
+ parseTopLevelXMLFile("/etc/media_codecs_performance.xml", true/* ignore_errors */);
parseTopLevelXMLFile(kProfilingResults, true/* ignore_errors */);
}
@@ -929,7 +936,7 @@
if (name == "aspect-ratio" || name == "bitrate" || name == "block-count"
|| name == "blocks-per-second" || name == "complexity"
|| name == "frame-rate" || name == "quality" || name == "size"
- || name == "measured-blocks-per-second" || name == "measured-frame-rate") {
+ || name == "measured-blocks-per-second" || name.startsWith("measured-frame-rate-")) {
AString min, max;
if (msg->findString("min", &min) && msg->findString("max", &max)) {
min.append("-");
@@ -1005,8 +1012,7 @@
return limitFoundMissingAttr(name, "ranges", found);
} else if (msg->contains("scale")) {
return limitFoundMissingAttr(name, "scale");
- } else if ((name == "alignment" || name == "block-size"
- || name == "max-supported-instances") ^
+ } else if ((name == "alignment" || name == "block-size") ^
(found = msg->findString("value", &value))) {
return limitFoundMissingAttr(name, "value", found);
}
diff --git a/media/libstagefright/MediaCodecSource.cpp b/media/libstagefright/MediaCodecSource.cpp
index e089c46..7f9f824 100644
--- a/media/libstagefright/MediaCodecSource.cpp
+++ b/media/libstagefright/MediaCodecSource.cpp
@@ -39,6 +39,9 @@
namespace android {
+const int kDefaultSwVideoEncoderFormat = HAL_PIXEL_FORMAT_YCbCr_420_888;
+const int kDefaultSwVideoEncoderDataSpace = HAL_DATASPACE_BT709;
+
struct MediaCodecSource::Puller : public AHandler {
Puller(const sp<MediaSource> &source);
@@ -341,6 +344,9 @@
mStarted(false),
mStopping(false),
mDoMoreWorkPending(false),
+ mSetEncoderFormat(false),
+ mEncoderFormat(0),
+ mEncoderDataSpace(0),
mGraphicBufferConsumer(consumer),
mFirstSampleTimeUs(-1ll),
mEncoderReachedEOS(false),
@@ -438,6 +444,18 @@
}
}
+ sp<AMessage> inputFormat;
+ int32_t usingSwReadOften;
+ mSetEncoderFormat = false;
+ if (mEncoder->getInputFormat(&inputFormat) == OK
+ && inputFormat->findInt32("using-sw-read-often", &usingSwReadOften)
+ && usingSwReadOften) {
+ // this is a SW encoder; signal source to allocate SW readable buffers
+ mSetEncoderFormat = true;
+ mEncoderFormat = kDefaultSwVideoEncoderFormat;
+ mEncoderDataSpace = kDefaultSwVideoEncoderDataSpace;
+ }
+
err = mEncoder->start();
if (err != OK) {
@@ -632,8 +650,17 @@
resume(startTimeUs);
} else {
CHECK(mPuller != NULL);
+ sp<MetaData> meta = params;
+ if (mSetEncoderFormat) {
+ if (meta == NULL) {
+ meta = new MetaData;
+ }
+ meta->setInt32(kKeyPixelFormat, mEncoderFormat);
+ meta->setInt32(kKeyColorSpace, mEncoderDataSpace);
+ }
+
sp<AMessage> notify = new AMessage(kWhatPullerNotify, mReflector);
- err = mPuller->start(params, notify);
+ err = mPuller->start(meta.get(), notify);
if (err != OK) {
return err;
}
diff --git a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
index 5396022..f743b1c 100644
--- a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
+++ b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
@@ -283,6 +283,11 @@
} else {
// This is recoverable, just ignore the current frame and
// play silence instead.
+
+ // TODO: should we skip silence (and consume input data)
+ // if mIsFirst is true as we may not have a valid
+ // mConfig->samplingRate and mConfig->num_channels?
+ ALOGV_IF(mIsFirst, "insufficient data for first frame, sending silence");
memset(outHeader->pBuffer,
0,
mConfig->outputFrameSize * sizeof(int16_t));
@@ -317,8 +322,7 @@
}
outHeader->nTimeStamp =
- mAnchorTimeUs
- + (mNumFramesOutput * 1000000ll) / mConfig->samplingRate;
+ mAnchorTimeUs + (mNumFramesOutput * 1000000ll) / mSamplingRate;
if (inHeader) {
CHECK_GE(inHeader->nFilledLen, mConfig->inputBufferUsedLength);
diff --git a/media/libstagefright/omx/GraphicBufferSource.cpp b/media/libstagefright/omx/GraphicBufferSource.cpp
index ac64685..1a7dc9d 100644
--- a/media/libstagefright/omx/GraphicBufferSource.cpp
+++ b/media/libstagefright/omx/GraphicBufferSource.cpp
@@ -23,6 +23,7 @@
#include "GraphicBufferSource.h"
#include <OMX_Core.h>
+#include <OMX_IndexExt.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
@@ -110,6 +111,7 @@
uint32_t bufferWidth,
uint32_t bufferHeight,
uint32_t bufferCount,
+ uint32_t consumerUsage,
const sp<IGraphicBufferConsumer> &consumer) :
mInitCheck(UNKNOWN_ERROR),
mNodeInstance(nodeInstance),
@@ -152,7 +154,12 @@
BufferQueue::createBufferQueue(&mProducer, &mConsumer);
mConsumer->setConsumerName(name);
- mConsumer->setConsumerUsageBits(GRALLOC_USAGE_HW_VIDEO_ENCODER);
+
+ // use consumer usage bits queried from encoder, but always add HW_VIDEO_ENCODER
+ // for backward compatibility.
+ consumerUsage |= GRALLOC_USAGE_HW_VIDEO_ENCODER;
+ mConsumer->setConsumerUsageBits(consumerUsage);
+
mInitCheck = mConsumer->setMaxAcquiredBufferCount(bufferCount);
if (mInitCheck != NO_ERROR) {
ALOGE("Unable to set BQ max acquired buffer count to %u: %d",
diff --git a/media/libstagefright/omx/GraphicBufferSource.h b/media/libstagefright/omx/GraphicBufferSource.h
index 3f64088..2f929d9 100644
--- a/media/libstagefright/omx/GraphicBufferSource.h
+++ b/media/libstagefright/omx/GraphicBufferSource.h
@@ -55,6 +55,7 @@
uint32_t bufferWidth,
uint32_t bufferHeight,
uint32_t bufferCount,
+ uint32_t consumerUsage,
const sp<IGraphicBufferConsumer> &consumer = NULL
);
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index 147aae7..9f1c5d8 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -834,7 +834,8 @@
}
CLOG_BUFFER(updateGraphicBufferInMeta, "%s:%u, %#x := %p",
- portString(portIndex), portIndex, buffer, graphicBuffer->handle);
+ portString(portIndex), portIndex, buffer,
+ graphicBuffer == NULL ? NULL : graphicBuffer->handle);
return OK;
}
@@ -885,10 +886,18 @@
return INVALID_OPERATION;
}
+ uint32_t usageBits;
+ oerr = OMX_GetParameter(
+ mHandle, (OMX_INDEXTYPE)OMX_IndexParamConsumerUsageBits, &usageBits);
+ if (oerr != OMX_ErrorNone) {
+ usageBits = 0;
+ }
+
sp<GraphicBufferSource> bufferSource = new GraphicBufferSource(this,
def.format.video.nFrameWidth,
def.format.video.nFrameHeight,
def.nBufferCountActual,
+ usageBits,
bufferConsumer);
if ((err = bufferSource->initCheck()) != OK) {
@@ -1607,7 +1616,12 @@
return NULL;
}
Mutex::Autolock autoLock(mBufferIDLock);
- return mBufferIDToBufferHeader.valueFor(buffer);
+ ssize_t index = mBufferIDToBufferHeader.indexOfKey(buffer);
+ if (index < 0) {
+ CLOGW("findBufferHeader: buffer %u not found", buffer);
+ return NULL;
+ }
+ return mBufferIDToBufferHeader.valueAt(index);
}
OMX::buffer_id OMXNodeInstance::findBufferID(OMX_BUFFERHEADERTYPE *bufferHeader) {
@@ -1615,7 +1629,12 @@
return 0;
}
Mutex::Autolock autoLock(mBufferIDLock);
- return mBufferHeaderToBufferID.valueFor(bufferHeader);
+ ssize_t index = mBufferHeaderToBufferID.indexOfKey(bufferHeader);
+ if (index < 0) {
+ CLOGW("findBufferID: bufferHeader %p not found", bufferHeader);
+ return 0;
+ }
+ return mBufferHeaderToBufferID.valueAt(index);
}
void OMXNodeInstance::invalidateBufferID(OMX::buffer_id buffer) {
@@ -1623,8 +1642,13 @@
return;
}
Mutex::Autolock autoLock(mBufferIDLock);
- mBufferHeaderToBufferID.removeItem(mBufferIDToBufferHeader.valueFor(buffer));
- mBufferIDToBufferHeader.removeItem(buffer);
+ ssize_t index = mBufferIDToBufferHeader.indexOfKey(buffer);
+ if (index < 0) {
+ CLOGW("invalidateBufferID: buffer %u not found", buffer);
+ return;
+ }
+ mBufferHeaderToBufferID.removeItem(mBufferIDToBufferHeader.valueAt(index));
+ mBufferIDToBufferHeader.removeItemsAt(index);
}
} // namespace android
diff --git a/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp b/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp
index 9dd26fb..8ea7a6e 100644
--- a/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp
+++ b/media/libstagefright/omx/SoftVideoEncoderOMXComponent.cpp
@@ -34,6 +34,8 @@
#include <ui/GraphicBuffer.h>
#include <ui/GraphicBufferMapper.h>
+#include <OMX_IndexExt.h>
+
namespace android {
const static OMX_COLOR_FORMATTYPE kSupportedColorFormats[] = {
@@ -293,7 +295,7 @@
OMX_ERRORTYPE SoftVideoEncoderOMXComponent::internalGetParameter(
OMX_INDEXTYPE index, OMX_PTR param) {
- switch (index) {
+ switch ((int)index) {
case OMX_IndexParamVideoErrorCorrection:
{
return OMX_ErrorNotImplemented;
@@ -343,6 +345,13 @@
return OMX_ErrorNone;
}
+ case OMX_IndexParamConsumerUsageBits:
+ {
+ OMX_U32 *usageBits = (OMX_U32 *)param;
+ *usageBits = GRALLOC_USAGE_SW_READ_OFTEN;
+ return OMX_ErrorNone;
+ }
+
default:
return SimpleSoftOMXComponent::internalGetParameter(index, param);
}
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 410fff5..c8f9be0 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -530,7 +530,7 @@
// RecordThread::readInputParameters_l()
//FIXME: mStandby should be true here. Is this some kind of hack?
mStandby(false), mOutDevice(outDevice), mInDevice(inDevice),
- mAudioSource(AUDIO_SOURCE_DEFAULT), mId(id),
+ mPrevInDevice(AUDIO_DEVICE_NONE), mAudioSource(AUDIO_SOURCE_DEFAULT), mId(id),
// mName will be set by concrete (non-virtual) subclass
mDeathRecipient(new PMDeathRecipient(this)),
mSystemReady(systemReady)
@@ -3131,6 +3131,7 @@
for (size_t i = 0; i < mEffectChains.size(); i++) {
mEffectChains[i]->setDevice_l(type);
}
+ bool configChanged = mOutDevice != type;
mOutDevice = type;
mPatch = *patch;
@@ -3159,7 +3160,9 @@
param.toString().string());
*handle = AUDIO_PATCH_HANDLE_NONE;
}
- sendIoConfigEvent_l(AUDIO_OUTPUT_CONFIG_CHANGED);
+ if (configChanged) {
+ sendIoConfigEvent_l(AUDIO_OUTPUT_CONFIG_CHANGED);
+ }
return status;
}
@@ -6796,6 +6799,9 @@
status = BAD_VALUE;
} else {
mInDevice = value;
+ if (value != AUDIO_DEVICE_NONE) {
+ mPrevInDevice = value;
+ }
// disable AEC and NS if the device is a BT SCO headset supporting those
// pre processings
if (mTracks.size() > 0) {
@@ -7079,7 +7085,10 @@
*handle = AUDIO_PATCH_HANDLE_NONE;
}
- sendIoConfigEvent_l(AUDIO_INPUT_CONFIG_CHANGED);
+ if (mInDevice != mPrevInDevice) {
+ sendIoConfigEvent_l(AUDIO_INPUT_CONFIG_CHANGED);
+ mPrevInDevice = mInDevice;
+ }
return status;
}
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index b12b091..0783371 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -436,6 +436,7 @@
bool mStandby; // Whether thread is currently in standby.
audio_devices_t mOutDevice; // output device
audio_devices_t mInDevice; // input device
+ audio_devices_t mPrevInDevice; // previous input device
struct audio_patch mPatch;
audio_source_t mAudioSource;
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index c5f4fb7..fbe4f18 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -166,6 +166,17 @@
}
}
+void AudioPolicyService::setAudioPortCallbacksEnabled(bool enabled)
+{
+ Mutex::Autolock _l(mNotificationClientsLock);
+
+ uid_t uid = IPCThreadState::self()->getCallingUid();
+ if (mNotificationClients.indexOfKey(uid) < 0) {
+ return;
+ }
+ mNotificationClients.valueFor(uid)->setAudioPortCallbacksEnabled(enabled);
+}
+
// removeNotificationClient() is called when the client process dies.
void AudioPolicyService::removeNotificationClient(uid_t uid)
{
@@ -246,7 +257,8 @@
AudioPolicyService::NotificationClient::NotificationClient(const sp<AudioPolicyService>& service,
const sp<IAudioPolicyServiceClient>& client,
uid_t uid)
- : mService(service), mUid(uid), mAudioPolicyServiceClient(client)
+ : mService(service), mUid(uid), mAudioPolicyServiceClient(client),
+ mAudioPortCallbacksEnabled(false)
{
}
@@ -265,14 +277,14 @@
void AudioPolicyService::NotificationClient::onAudioPortListUpdate()
{
- if (mAudioPolicyServiceClient != 0) {
+ if (mAudioPolicyServiceClient != 0 && mAudioPortCallbacksEnabled) {
mAudioPolicyServiceClient->onAudioPortListUpdate();
}
}
void AudioPolicyService::NotificationClient::onAudioPatchListUpdate()
{
- if (mAudioPolicyServiceClient != 0) {
+ if (mAudioPolicyServiceClient != 0 && mAudioPortCallbacksEnabled) {
mAudioPolicyServiceClient->onAudioPatchListUpdate();
}
}
@@ -285,6 +297,12 @@
}
}
+void AudioPolicyService::NotificationClient::setAudioPortCallbacksEnabled(bool enabled)
+{
+ mAudioPortCallbacksEnabled = enabled;
+}
+
+
void AudioPolicyService::binderDied(const wp<IBinder>& who) {
ALOGW("binderDied() %p, calling pid %d", who.unsafe_get(),
IPCThreadState::self()->getCallingPid());
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index eb50cdd..a0d5aa2 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -185,6 +185,8 @@
virtual void registerClient(const sp<IAudioPolicyServiceClient>& client);
+ virtual void setAudioPortCallbacksEnabled(bool enabled);
+
virtual status_t acquireSoundTriggerSession(audio_session_t *session,
audio_io_handle_t *ioHandle,
audio_devices_t *device);
@@ -507,6 +509,7 @@
void onAudioPortListUpdate();
void onAudioPatchListUpdate();
void onDynamicPolicyMixStateUpdate(String8 regId, int32_t state);
+ void setAudioPortCallbacksEnabled(bool enabled);
// IBinder::DeathRecipient
virtual void binderDied(const wp<IBinder>& who);
@@ -518,6 +521,7 @@
const wp<AudioPolicyService> mService;
const uid_t mUid;
const sp<IAudioPolicyServiceClient> mAudioPolicyServiceClient;
+ bool mAudioPortCallbacksEnabled;
};
// Internal dump utilities.
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 4b55dad..9e73b5c 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -164,9 +164,17 @@
return res;
}
- /** Start up request queue thread */
+ bool aeLockAvailable = false;
+ camera_metadata_ro_entry aeLockAvailableEntry;
+ res = find_camera_metadata_ro_entry(info.static_camera_characteristics,
+ ANDROID_CONTROL_AE_LOCK_AVAILABLE, &aeLockAvailableEntry);
+ if (res == OK && aeLockAvailableEntry.count > 0) {
+ aeLockAvailable = (aeLockAvailableEntry.data.u8[0] ==
+ ANDROID_CONTROL_AE_LOCK_AVAILABLE_TRUE);
+ }
- mRequestThread = new RequestThread(this, mStatusTracker, device);
+ /** Start up request queue thread */
+ mRequestThread = new RequestThread(this, mStatusTracker, device, aeLockAvailable);
res = mRequestThread->run(String8::format("C3Dev-%d-ReqQueue", mId).string());
if (res != OK) {
SET_ERR_L("Unable to start request queue thread: %s (%d)",
@@ -2472,7 +2480,8 @@
Camera3Device::RequestThread::RequestThread(wp<Camera3Device> parent,
sp<StatusTracker> statusTracker,
- camera3_device_t *hal3Device) :
+ camera3_device_t *hal3Device,
+ bool aeLockAvailable) :
Thread(/*canCallJava*/false),
mParent(parent),
mStatusTracker(statusTracker),
@@ -2485,19 +2494,9 @@
mLatestRequestId(NAME_NOT_FOUND),
mCurrentAfTriggerId(0),
mCurrentPreCaptureTriggerId(0),
- mRepeatingLastFrameNumber(NO_IN_FLIGHT_REPEATING_FRAMES) {
+ mRepeatingLastFrameNumber(NO_IN_FLIGHT_REPEATING_FRAMES),
+ mAeLockAvailable(aeLockAvailable) {
mStatusId = statusTracker->addComponent();
-
- mAeLockAvailable = false;
- sp<Camera3Device> p = parent.promote();
- if (p != NULL) {
- camera_metadata_ro_entry aeLockAvailable =
- p->info().find(ANDROID_CONTROL_AE_LOCK_AVAILABLE);
- if (aeLockAvailable.count > 0) {
- mAeLockAvailable = (aeLockAvailable.data.u8[0] ==
- ANDROID_CONTROL_AE_LOCK_AVAILABLE_TRUE);
- }
- }
}
void Camera3Device::RequestThread::setNotificationListener(
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index bb4bcc4..31b6132 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -389,7 +389,8 @@
RequestThread(wp<Camera3Device> parent,
sp<camera3::StatusTracker> statusTracker,
- camera3_device_t *hal3Device);
+ camera3_device_t *hal3Device,
+ bool aeLockAvailable);
void setNotificationListener(NotificationListener *listener);