Merge "Turn off debug in downmix effect"
diff --git a/camera/Camera.cpp b/camera/Camera.cpp
index b81fe86..d43cb0b 100644
--- a/camera/Camera.cpp
+++ b/camera/Camera.cpp
@@ -116,13 +116,13 @@
return cs->getCameraInfo(cameraId, cameraInfo);
}
-sp<Camera> Camera::connect(int cameraId, bool force, bool keep)
+sp<Camera> Camera::connect(int cameraId)
{
ALOGV("connect");
sp<Camera> c = new Camera();
const sp<ICameraService>& cs = getCameraService();
if (cs != 0) {
- c->mCamera = cs->connect(c, cameraId, force, keep);
+ c->mCamera = cs->connect(c, cameraId);
}
if (c->mCamera != 0) {
c->mCamera->asBinder()->linkToDeath(c);
diff --git a/camera/ICameraService.cpp b/camera/ICameraService.cpp
index c74298a..f2d367e 100644
--- a/camera/ICameraService.cpp
+++ b/camera/ICameraService.cpp
@@ -56,15 +56,12 @@
}
// connect to camera service
- virtual sp<ICamera> connect(const sp<ICameraClient>& cameraClient, int cameraId,
- bool force, bool keep)
+ virtual sp<ICamera> connect(const sp<ICameraClient>& cameraClient, int cameraId)
{
Parcel data, reply;
data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
data.writeStrongBinder(cameraClient->asBinder());
data.writeInt32(cameraId);
- data.writeInt32(force);
- data.writeInt32(keep);
remote()->transact(BnCameraService::CONNECT, data, &reply);
return interface_cast<ICamera>(reply.readStrongBinder());
}
@@ -96,10 +93,7 @@
case CONNECT: {
CHECK_INTERFACE(ICameraService, data, reply);
sp<ICameraClient> cameraClient = interface_cast<ICameraClient>(data.readStrongBinder());
- const int cameraId = data.readInt32();
- const int force = data.readInt32();
- const int keep = data.readInt32();
- sp<ICamera> camera = connect(cameraClient, cameraId, force, keep);
+ sp<ICamera> camera = connect(cameraClient, data.readInt32());
reply->writeStrongBinder(camera->asBinder());
return NO_ERROR;
} break;
diff --git a/include/camera/Camera.h b/include/camera/Camera.h
index 3fedea0..234e165 100644
--- a/include/camera/Camera.h
+++ b/include/camera/Camera.h
@@ -72,7 +72,7 @@
static int32_t getNumberOfCameras();
static status_t getCameraInfo(int cameraId,
struct CameraInfo* cameraInfo);
- static sp<Camera> connect(int cameraId, bool force, bool keep);
+ static sp<Camera> connect(int cameraId);
virtual ~Camera();
void init();
diff --git a/include/camera/ICameraService.h b/include/camera/ICameraService.h
index 97e3169..7d70c1e 100644
--- a/include/camera/ICameraService.h
+++ b/include/camera/ICameraService.h
@@ -42,7 +42,7 @@
virtual status_t getCameraInfo(int cameraId,
struct CameraInfo* cameraInfo) = 0;
virtual sp<ICamera> connect(const sp<ICameraClient>& cameraClient,
- int cameraId, bool force, bool keep) = 0;
+ int cameraId) = 0;
};
// ----------------------------------------------------------------------------
diff --git a/include/media/AudioEffect.h b/include/media/AudioEffect.h
index 02dfc1b..05d834d 100644
--- a/include/media/AudioEffect.h
+++ b/include/media/AudioEffect.h
@@ -402,6 +402,15 @@
int32_t mId; // system wide unique effect engine instance ID
Mutex mLock; // Mutex for mEnabled access
+ // IEffectClient
+ virtual void controlStatusChanged(bool controlGranted);
+ virtual void enableStatusChanged(bool enabled);
+ virtual void commandExecuted(uint32_t cmdCode,
+ uint32_t cmdSize,
+ void *pCmdData,
+ uint32_t replySize,
+ void *pReplyData);
+
private:
// Implements the IEffectClient interface
@@ -433,20 +442,8 @@
AudioEffect *mEffect;
};
-
- friend class EffectClient;
-
- // IEffectClient
- void controlStatusChanged(bool controlGranted);
- void enableStatusChanged(bool enabled);
- void commandExecuted(uint32_t cmdCode,
- uint32_t cmdSize,
- void *pCmdData,
- uint32_t replySize,
- void *pReplyData);
void binderDied();
-
sp<IEffect> mIEffect; // IEffect binder interface
sp<EffectClient> mIEffectClient; // IEffectClient implementation
sp<IMemory> mCblkMemory; // shared memory for deferred parameter setting
diff --git a/include/media/Visualizer.h b/include/media/Visualizer.h
index 60fa15b..fdec5ee 100644
--- a/include/media/Visualizer.h
+++ b/include/media/Visualizer.h
@@ -108,6 +108,12 @@
// returns the sampling rate of the audio being captured
uint32_t getSamplingRate() { return mSampleRate; }
+ // set the way volume affects the captured data
+ // mode must one of VISUALIZER_SCALING_MODE_NORMALIZED,
+ // VISUALIZER_SCALING_MODE_AS_PLAYED
+ status_t setScalingMode(uint32_t mode);
+ uint32_t getScalingMode() { return mScalingMode; }
+
// return a capture in PCM 8 bit unsigned format. The size of the capture is equal to
// getCaptureSize()
status_t getWaveForm(uint8_t *waveform);
@@ -117,6 +123,10 @@
// are returned
status_t getFft(uint8_t *fft);
+protected:
+ // from IEffectClient
+ virtual void controlStatusChanged(bool controlGranted);
+
private:
static const uint32_t CAPTURE_RATE_MAX = 20000;
@@ -147,6 +157,7 @@
uint32_t mCaptureRate;
uint32_t mCaptureSize;
uint32_t mSampleRate;
+ uint32_t mScalingMode;
capture_cbk_t mCaptureCallBack;
void *mCaptureCbkUser;
sp<CaptureThread> mCaptureThread;
diff --git a/media/libeffects/visualizer/EffectVisualizer.cpp b/media/libeffects/visualizer/EffectVisualizer.cpp
index bdb1a1c..44d05cd 100644
--- a/media/libeffects/visualizer/EffectVisualizer.cpp
+++ b/media/libeffects/visualizer/EffectVisualizer.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#define LOG_TAG "Visualizer"
+#define LOG_TAG "EffectVisualizer"
//#define LOG_NDEBUG 0
#include <cutils/log.h>
#include <assert.h>
@@ -57,6 +57,7 @@
effect_config_t mConfig;
uint32_t mCaptureIdx;
uint32_t mCaptureSize;
+ uint32_t mScalingMode;
uint8_t mState;
uint8_t mCurrentBuf;
uint8_t mLastBuf;
@@ -164,6 +165,7 @@
pContext->mConfig.outputCfg.mask = EFFECT_CONFIG_ALL;
pContext->mCaptureSize = VISUALIZER_CAPTURE_SIZE_MAX;
+ pContext->mScalingMode = VISUALIZER_SCALING_MODE_NORMALIZED;
Visualizer_setConfig(pContext, &pContext->mConfig);
@@ -285,26 +287,32 @@
}
// all code below assumes stereo 16 bit PCM output and input
+ int32_t shift;
- // derive capture scaling factor from peak value in current buffer
- // this gives more interesting captures for display.
- int32_t shift = 32;
- int len = inBuffer->frameCount * 2;
- for (int i = 0; i < len; i++) {
- int32_t smp = inBuffer->s16[i];
- if (smp < 0) smp = -smp - 1; // take care to keep the max negative in range
- int32_t clz = __builtin_clz(smp);
- if (shift > clz) shift = clz;
+ if (pContext->mScalingMode == VISUALIZER_SCALING_MODE_NORMALIZED) {
+ // derive capture scaling factor from peak value in current buffer
+ // this gives more interesting captures for display.
+ shift = 32;
+ int len = inBuffer->frameCount * 2;
+ for (int i = 0; i < len; i++) {
+ int32_t smp = inBuffer->s16[i];
+ if (smp < 0) smp = -smp - 1; // take care to keep the max negative in range
+ int32_t clz = __builtin_clz(smp);
+ if (shift > clz) shift = clz;
+ }
+ // A maximum amplitude signal will have 17 leading zeros, which we want to
+ // translate to a shift of 8 (for converting 16 bit to 8 bit)
+ shift = 25 - shift;
+ // Never scale by less than 8 to avoid returning unaltered PCM signal.
+ if (shift < 3) {
+ shift = 3;
+ }
+ // add one to combine the division by 2 needed after summing left and right channels below
+ shift++;
+ } else {
+ assert(pContext->mScalingMode == VISUALIZER_SCALING_MODE_AS_PLAYED);
+ shift = 9;
}
- // A maximum amplitude signal will have 17 leading zeros, which we want to
- // translate to a shift of 8 (for converting 16 bit to 8 bit)
- shift = 25 - shift;
- // Never scale by less than 8 to avoid returning unaltered PCM signal.
- if (shift < 3) {
- shift = 3;
- }
- // add one to combine the division by 2 needed after summing left and right channels below
- shift++;
uint32_t captIdx;
uint32_t inIdx;
@@ -414,15 +422,26 @@
effect_param_t *p = (effect_param_t *)pReplyData;
p->status = 0;
*replySize = sizeof(effect_param_t) + sizeof(uint32_t);
- if (p->psize != sizeof(uint32_t) ||
- *(uint32_t *)p->data != VISUALIZER_PARAM_CAPTURE_SIZE) {
+ if (p->psize != sizeof(uint32_t)) {
p->status = -EINVAL;
break;
}
- ALOGV("get mCaptureSize = %d", pContext->mCaptureSize);
- *((uint32_t *)p->data + 1) = pContext->mCaptureSize;
- p->vsize = sizeof(uint32_t);
- *replySize += sizeof(uint32_t);
+ switch (*(uint32_t *)p->data) {
+ case VISUALIZER_PARAM_CAPTURE_SIZE:
+ ALOGV("get mCaptureSize = %d", pContext->mCaptureSize);
+ *((uint32_t *)p->data + 1) = pContext->mCaptureSize;
+ p->vsize = sizeof(uint32_t);
+ *replySize += sizeof(uint32_t);
+ break;
+ case VISUALIZER_PARAM_SCALING_MODE:
+ ALOGV("get mScalingMode = %d", pContext->mScalingMode);
+ *((uint32_t *)p->data + 1) = pContext->mScalingMode;
+ p->vsize = sizeof(uint32_t);
+ *replySize += sizeof(uint32_t);
+ break;
+ default:
+ p->status = -EINVAL;
+ }
} break;
case EFFECT_CMD_SET_PARAM: {
if (pCmdData == NULL ||
@@ -432,14 +451,22 @@
}
*(int32_t *)pReplyData = 0;
effect_param_t *p = (effect_param_t *)pCmdData;
- if (p->psize != sizeof(uint32_t) ||
- p->vsize != sizeof(uint32_t) ||
- *(uint32_t *)p->data != VISUALIZER_PARAM_CAPTURE_SIZE) {
+ if (p->psize != sizeof(uint32_t) || p->vsize != sizeof(uint32_t)) {
*(int32_t *)pReplyData = -EINVAL;
- break;;
+ break;
}
- pContext->mCaptureSize = *((uint32_t *)p->data + 1);
- ALOGV("set mCaptureSize = %d", pContext->mCaptureSize);
+ switch (*(uint32_t *)p->data) {
+ case VISUALIZER_PARAM_CAPTURE_SIZE:
+ pContext->mCaptureSize = *((uint32_t *)p->data + 1);
+ ALOGV("set mCaptureSize = %d", pContext->mCaptureSize);
+ break;
+ case VISUALIZER_PARAM_SCALING_MODE:
+ pContext->mScalingMode = *((uint32_t *)p->data + 1);
+ ALOGV("set mScalingMode = %d", pContext->mScalingMode);
+ break;
+ default:
+ *(int32_t *)pReplyData = -EINVAL;
+ }
} break;
case EFFECT_CMD_SET_DEVICE:
case EFFECT_CMD_SET_VOLUME:
diff --git a/media/libmedia/Visualizer.cpp b/media/libmedia/Visualizer.cpp
index bcd6ae4..de0bf7d 100644
--- a/media/libmedia/Visualizer.cpp
+++ b/media/libmedia/Visualizer.cpp
@@ -41,6 +41,7 @@
mCaptureRate(CAPTURE_RATE_DEF),
mCaptureSize(CAPTURE_SIZE_DEF),
mSampleRate(44100000),
+ mScalingMode(VISUALIZER_SCALING_MODE_NORMALIZED),
mCaptureCallBack(NULL),
mCaptureCbkUser(NULL)
{
@@ -146,9 +147,38 @@
if (status == NO_ERROR) {
status = p->status;
+ if (status == NO_ERROR) {
+ mCaptureSize = size;
+ }
}
+
+ return status;
+}
+
+status_t Visualizer::setScalingMode(uint32_t mode) {
+ if ((mode != VISUALIZER_SCALING_MODE_NORMALIZED)
+ && (mode != VISUALIZER_SCALING_MODE_AS_PLAYED)) {
+ return BAD_VALUE;
+ }
+
+ Mutex::Autolock _l(mCaptureLock);
+
+ uint32_t buf32[sizeof(effect_param_t) / sizeof(uint32_t) + 2];
+ effect_param_t *p = (effect_param_t *)buf32;
+
+ p->psize = sizeof(uint32_t);
+ p->vsize = sizeof(uint32_t);
+ *(int32_t *)p->data = VISUALIZER_PARAM_SCALING_MODE;
+ *((int32_t *)p->data + 1)= mode;
+ status_t status = setParameter(p);
+
+ ALOGV("setScalingMode mode %d status %d p->status %d", mode, status, p->status);
+
if (status == NO_ERROR) {
- mCaptureSize = size;
+ status = p->status;
+ if (status == NO_ERROR) {
+ mScalingMode = mode;
+ }
}
return status;
@@ -289,6 +319,19 @@
return size;
}
+void Visualizer::controlStatusChanged(bool controlGranted) {
+ if (controlGranted) {
+ // this Visualizer instance regained control of the effect, reset the scaling mode
+ // and capture size as has been cached through it.
+ ALOGV("controlStatusChanged(true) causes effect parameter reset:");
+ ALOGV(" scaling mode reset to %d", mScalingMode);
+ setScalingMode(mScalingMode);
+ ALOGV(" capture size reset to %d", mCaptureSize);
+ setCaptureSize(mCaptureSize);
+ }
+ AudioEffect::controlStatusChanged(controlGranted);
+}
+
//-------------------------------------------------------------------------
Visualizer::CaptureThread::CaptureThread(Visualizer& receiver, uint32_t captureRate, bool bCanCallJava)
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
index fd3f892..3ddad93 100755
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
@@ -182,7 +182,7 @@
int32_t cameraId) {
if (camera == 0) {
- mCamera = Camera::connect(cameraId, false, false);
+ mCamera = Camera::connect(cameraId);
if (mCamera == 0) return -EBUSY;
mCameraFlags &= ~FLAGS_HOT_CAMERA;
} else {
diff --git a/media/libstagefright/codecs/aacdec/Android.mk b/media/libstagefright/codecs/aacdec/Android.mk
index 5b3d216..2808745 100644
--- a/media/libstagefright/codecs/aacdec/Android.mk
+++ b/media/libstagefright/codecs/aacdec/Android.mk
@@ -12,7 +12,8 @@
frameworks/av/media/libstagefright/include \
frameworks/native/include/media/openmax \
external/aac/libAACdec/include \
- external/aac/libCDK/include \
+ external/aac/libPCMutils/include \
+ external/aac/libFDK/include \
external/aac/libMpegTPDec/include \
external/aac/libSBRdec/include \
external/aac/libSYS/include
@@ -20,7 +21,7 @@
LOCAL_CFLAGS :=
LOCAL_STATIC_LIBRARIES := \
- libAACdec libMpegTPDec libSBRdec libCDK libSYS
+ libAACdec libMpegTPDec libSBRdec libPCMutils libFDK libSYS
LOCAL_SHARED_LIBRARIES := \
libstagefright_omx libstagefright_foundation libutils
diff --git a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
index 4589d37..27cf5b9 100644
--- a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
+++ b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
@@ -26,23 +26,6 @@
namespace android {
-static Mutex gAACLibraryLock;
-static int gAACLibraryCount = 0;
-
-void initializeAACLibrary() {
- Mutex::Autolock autoLock(gAACLibraryLock);
- if (gAACLibraryCount++ == 0) {
- CDKprolog();
- }
-}
-
-void cleanupAACLibrary() {
- Mutex::Autolock autoLock(gAACLibraryLock);
- if (--gAACLibraryCount == 0) {
- CDKepilog();
- }
-}
-
template<class T>
static void InitOMXParams(T *params) {
params->nSize = sizeof(T);
@@ -63,17 +46,16 @@
mIsADTS(false),
mInputBufferCount(0),
mSignalledError(false),
+ mInputDiscontinuity(false),
mAnchorTimeUs(0),
mNumSamplesOutput(0),
mOutputPortSettingsChange(NONE) {
- initializeAACLibrary();
initPorts();
CHECK_EQ(initDecoder(), (status_t)OK);
}
SoftAAC2::~SoftAAC2() {
aacDecoder_Close(mAACDecoder);
- cleanupAACLibrary();
}
void SoftAAC2::initPorts() {
@@ -102,7 +84,7 @@
def.eDir = OMX_DirOutput;
def.nBufferCountMin = kNumBuffers;
def.nBufferCountActual = def.nBufferCountMin;
- def.nBufferSize = 8192;
+ def.nBufferSize = 8192 * 2;
def.bEnabled = OMX_TRUE;
def.bPopulated = OMX_FALSE;
def.eDomain = OMX_PortDomainAudio;
@@ -183,6 +165,10 @@
pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear;
pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF;
pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF;
+ pcmParams->eChannelMapping[2] = OMX_AUDIO_ChannelCF;
+ pcmParams->eChannelMapping[3] = OMX_AUDIO_ChannelLFE;
+ pcmParams->eChannelMapping[4] = OMX_AUDIO_ChannelLS;
+ pcmParams->eChannelMapping[5] = OMX_AUDIO_ChannelRS;
if (!isConfigured()) {
pcmParams->nChannels = 1;
@@ -360,15 +346,17 @@
INT_PCM *outBuffer = reinterpret_cast<INT_PCM *>(outHeader->pBuffer + outHeader->nOffset);
bytesValid[0] = inBufferLength[0];
+ int flags = mInputDiscontinuity ? AACDEC_INTR : 0;
int prevSampleRate = mStreamInfo->sampleRate;
decoderErr = aacDecoder_Fill(mAACDecoder,
- inBuffer,
- inBufferLength,
- bytesValid);
+ inBuffer,
+ inBufferLength,
+ bytesValid);
decoderErr = aacDecoder_DecodeFrame(mAACDecoder,
outBuffer,
outHeader->nAllocLen,
- /* flags */ 0);
+ flags);
+ mInputDiscontinuity = false;
/*
* AAC+/eAAC+ streams can be signalled in two ways: either explicitly
@@ -447,13 +435,9 @@
void SoftAAC2::onPortFlushCompleted(OMX_U32 portIndex) {
if (portIndex == 0) {
-
// Make sure that the next buffer output does not still
// depend on fragments from the last one decoded.
- aacDecoder_DecodeFrame(mAACDecoder,
- NULL,
- 0,
- AACDEC_FLUSH);
+ mInputDiscontinuity = true;
}
}
diff --git a/media/libstagefright/codecs/aacdec/SoftAAC2.h b/media/libstagefright/codecs/aacdec/SoftAAC2.h
index 828b34e..d93685c 100644
--- a/media/libstagefright/codecs/aacdec/SoftAAC2.h
+++ b/media/libstagefright/codecs/aacdec/SoftAAC2.h
@@ -52,6 +52,7 @@
bool mIsADTS;
size_t mInputBufferCount;
bool mSignalledError;
+ bool mInputDiscontinuity;
int64_t mAnchorTimeUs;
int64_t mNumSamplesOutput;
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index dc3f083..92d1223 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -21,7 +21,6 @@
#include <stdio.h>
#include <sys/types.h>
#include <pthread.h>
-#include <time.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
@@ -34,7 +33,6 @@
#include <hardware/hardware.h>
#include <media/AudioSystem.h>
#include <media/mediaplayer.h>
-#include <utils/Condition.h>
#include <utils/Errors.h>
#include <utils/Log.h>
#include <utils/String16.h>
@@ -44,8 +42,6 @@
namespace android {
-#define WAIT_RELEASE_TIMEOUT 250 // 250ms
-
// ----------------------------------------------------------------------------
// Logging support -- this is for debugging only
// Use "adb shell dumpsys media.camera -v 1" to change it.
@@ -68,13 +64,6 @@
return IPCThreadState::self()->getCallingUid();
}
-static long long getTimeInMs() {
- struct timeval t;
- t.tv_sec = t.tv_usec = 0;
- gettimeofday(&t, NULL);
- return t.tv_sec * 1000LL + t.tv_usec / 1000;
-}
-
// ----------------------------------------------------------------------------
// This is ugly and only safe if we never re-create the CameraService, but
@@ -142,7 +131,7 @@
}
sp<ICamera> CameraService::connect(
- const sp<ICameraClient>& cameraClient, int cameraId, bool force, bool keep) {
+ const sp<ICameraClient>& cameraClient, int cameraId) {
int callingPid = getCallingPid();
sp<CameraHardwareInterface> hardware = NULL;
@@ -168,73 +157,27 @@
return NULL;
}
- if (keep && !checkCallingPermission(String16("android.permission.KEEP_CAMERA"))) {
- ALOGE("connect X (pid %d) rejected (no KEEP_CAMERA permission).", callingPid);
- return NULL;
- }
-
Mutex::Autolock lock(mServiceLock);
- // Check if there is an existing client.
- client = mClient[cameraId].promote();
- if (client != 0 &&
- cameraClient->asBinder() == client->getCameraClient()->asBinder()) {
- LOG1("connect X (pid %d) (the same client)", callingPid);
- return client;
- }
-
- if (!force) {
- if (mClient[cameraId].promote() != 0) {
- ALOGW("connect X (pid %d) rejected (existing client).", callingPid);
- return NULL;
- }
- mClient[cameraId].clear();
- if (mBusy[cameraId]) {
- ALOGW("connect X (pid %d) rejected (camera %d is still busy).",
- callingPid, cameraId);
- return NULL;
- }
- } else { // force == true
- int i = 0;
- long long start_time = getTimeInMs();
- while (i < mNumberOfCameras) {
- if (getTimeInMs() - start_time >= 3000LL) {
- ALOGE("connect X (pid %d) rejected (timeout 3s)", callingPid);
+ if (mClient[cameraId] != 0) {
+ client = mClient[cameraId].promote();
+ if (client != 0) {
+ if (cameraClient->asBinder() == client->getCameraClient()->asBinder()) {
+ LOG1("CameraService::connect X (pid %d) (the same client)",
+ callingPid);
+ return client;
+ } else {
+ ALOGW("CameraService::connect X (pid %d) rejected (existing client).",
+ callingPid);
return NULL;
}
-
- client = mClient[i].promote();
- if (client != 0) {
- if (client->keep()) {
- ALOGW("connect X (pid %d) rejected (existing client wants to keeps the camera)",
- callingPid);
- return NULL;
- } else {
- ALOGW("New client (pid %d, id=%d). Disconnect the existing client (id=%d).",
- callingPid, cameraId, i);
- // Do not hold mServiceLock because disconnect will try to get it.
- mServiceLock.unlock();
- client->notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_RELEASED, 0, &i);
- client->waitRelease(WAIT_RELEASE_TIMEOUT);
- client->disconnectInternal(false);
- mServiceLock.lock();
- // Restart from the first client because a new client may have connected
- // when mServiceLock is unlocked.
- i = 0;
- continue;
- }
- }
-
- if (mBusy[i]) {
- // Give the client a chance to release the hardware.
- mServiceLock.unlock();
- usleep(10 * 1000);
- mServiceLock.lock();
- i = 0; // Restart from the first client
- continue;
- }
-
- i++;
}
+ mClient[cameraId].clear();
+ }
+
+ if (mBusy[cameraId]) {
+ ALOGW("CameraService::connect X (pid %d) rejected"
+ " (camera %d is still busy).", callingPid, cameraId);
+ return NULL;
}
struct camera_info info;
@@ -252,13 +195,7 @@
return NULL;
}
- client = new Client(this, cameraClient, hardware, cameraId, info.facing,
- callingPid, keep);
- // We need to clear the hardware here. After the destructor of mServiceLock
- // finishes, a new client may connect and disconnect this client. If this
- // reference is not cleared, the destructor of CameraHardwareInterface
- // cannot run. The new client will not be able to connect.
- hardware.clear();
+ client = new Client(this, cameraClient, hardware, cameraId, info.facing, callingPid);
mClient[cameraId] = client;
LOG1("CameraService::connect X (id %d)", cameraId);
return client;
@@ -399,7 +336,7 @@
CameraService::Client::Client(const sp<CameraService>& cameraService,
const sp<ICameraClient>& cameraClient,
const sp<CameraHardwareInterface>& hardware,
- int cameraId, int cameraFacing, int clientPid, bool keep) {
+ int cameraId, int cameraFacing, int clientPid) {
int callingPid = getCallingPid();
LOG1("Client::Client E (pid %d, id %d)", callingPid, cameraId);
@@ -409,7 +346,6 @@
mCameraId = cameraId;
mCameraFacing = cameraFacing;
mClientPid = clientPid;
- mKeep = keep;
mMsgEnabled = 0;
mSurface = 0;
mPreviewWindow = 0;
@@ -544,24 +480,18 @@
}
void CameraService::Client::disconnect() {
- disconnectInternal(true);
-}
-
-void CameraService::Client::disconnectInternal(bool needCheckPid) {
int callingPid = getCallingPid();
- LOG1("disconnectInternal E (pid %d)", callingPid);
+ LOG1("disconnect E (pid %d)", callingPid);
Mutex::Autolock lock(mLock);
- if (needCheckPid) {
- if (checkPid() != NO_ERROR) {
- ALOGW("different client - don't disconnect");
- return;
- }
+ if (checkPid() != NO_ERROR) {
+ ALOGW("different client - don't disconnect");
+ return;
+ }
- if (mClientPid <= 0) {
- LOG1("camera is unlocked (mClientPid = %d), don't tear down hardware", mClientPid);
- return;
- }
+ if (mClientPid <= 0) {
+ LOG1("camera is unlocked (mClientPid = %d), don't tear down hardware", mClientPid);
+ return;
}
// Make sure disconnect() is done once and once only, whether it is called
@@ -588,16 +518,8 @@
mCameraService->removeClient(mCameraClient);
mCameraService->setCameraFree(mCameraId);
- mReleaseCondition.signal();
- LOG1("disconnectInternal X (pid %d)", callingPid);
-}
-
-void CameraService::Client::waitRelease(int ms) {
- Mutex::Autolock lock(mLock);
- if (mHardware != 0) {
- mReleaseCondition.waitRelative(mLock, ms * 1000000);
- }
+ LOG1("disconnect X (pid %d)", callingPid);
}
// ----------------------------------------------------------------------------
@@ -1330,11 +1252,6 @@
return -1;
}
-// Whether the client wants to keep the camera from taking
-bool CameraService::Client::keep() const {
- return mKeep;
-}
-
// ----------------------------------------------------------------------------
static const int kDumpLockRetries = 50;
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 7972201..5b63399 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -46,8 +46,7 @@
virtual int32_t getNumberOfCameras();
virtual status_t getCameraInfo(int cameraId,
struct CameraInfo* cameraInfo);
- virtual sp<ICamera> connect(const sp<ICameraClient>& cameraClient, int cameraId,
- bool force, bool keep);
+ virtual sp<ICamera> connect(const sp<ICameraClient>& cameraClient, int cameraId);
virtual void removeClient(const sp<ICameraClient>& cameraClient);
// returns plain pointer of client. Note that mClientLock should be acquired to
// prevent the client from destruction. The result can be NULL.
@@ -119,8 +118,7 @@
const sp<CameraHardwareInterface>& hardware,
int cameraId,
int cameraFacing,
- int clientPid,
- bool keep);
+ int clientPid);
~Client();
// return our camera client
@@ -179,19 +177,12 @@
const sp<IBinder>& binder,
const sp<ANativeWindow>& window);
- void disconnectInternal(bool needCheckPid);
- bool keep() const;
- void waitRelease(int ms);
-
-
// these are initialized in the constructor.
sp<CameraService> mCameraService; // immutable after constructor
sp<ICameraClient> mCameraClient;
int mCameraId; // immutable after constructor
int mCameraFacing; // immutable after constructor
pid_t mClientPid;
- // Client wants to keep the camera from taking by other clients.
- bool mKeep;
sp<CameraHardwareInterface> mHardware; // cleared after disconnect()
int mPreviewCallbackFlag;
int mOrientation; // Current display orientation
@@ -199,8 +190,6 @@
// Ensures atomicity among the public methods
mutable Mutex mLock;
- // This will get notified when the hardware is released.
- Condition mReleaseCondition;
// This is a binder of Surface or SurfaceTexture.
sp<IBinder> mSurface;
sp<ANativeWindow> mPreviewWindow;