diff options
| -rw-r--r-- | camera/Camera.cpp | 4 | ||||
| -rw-r--r-- | camera/ICameraService.cpp | 10 | ||||
| -rw-r--r-- | include/camera/Camera.h | 2 | ||||
| -rw-r--r-- | include/camera/ICameraService.h | 2 | ||||
| -rw-r--r-- | include/media/AudioEffect.h | 21 | ||||
| -rw-r--r-- | include/media/Visualizer.h | 11 | ||||
| -rw-r--r-- | media/libeffects/visualizer/EffectVisualizer.cpp | 91 | ||||
| -rw-r--r-- | media/libmedia/Visualizer.cpp | 45 | ||||
| -rwxr-xr-x | media/libstagefright/CameraSource.cpp | 2 | ||||
| -rw-r--r-- | media/libstagefright/codecs/aacdec/Android.mk | 5 | ||||
| -rw-r--r-- | media/libstagefright/codecs/aacdec/SoftAAC2.cpp | 42 | ||||
| -rw-r--r-- | media/libstagefright/codecs/aacdec/SoftAAC2.h | 1 | ||||
| -rw-r--r-- | services/camera/libcameraservice/CameraService.cpp | 141 | ||||
| -rw-r--r-- | services/camera/libcameraservice/CameraService.h | 15 |
14 files changed, 178 insertions, 214 deletions
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 @@ status_t Camera::getCameraInfo(int cameraId, 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 @@ public: } // 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 @@ status_t BnCameraService::onTransact( 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 @@ public: 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 @@ public: 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 @@ protected: 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 @@ private: 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 @@ public: // 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 @@ public: // 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 @@ private: 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 @@ struct VisualizerContext { 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 @@ int Visualizer_init(VisualizerContext *pContext) 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 @@ int Visualizer_process( } // all code below assumes stereo 16 bit PCM output and input - - // 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; - } - // 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; + int32_t shift; + + 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; } - // 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 @@ int Visualizer_command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize, 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 @@ int Visualizer_command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize, } *(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; + } + 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;; } - pContext->mCaptureSize = *((uint32_t *)p->data + 1); - ALOGV("set mCaptureSize = %d", pContext->mCaptureSize); } 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 @@ Visualizer::Visualizer (int32_t priority, mCaptureRate(CAPTURE_RATE_DEF), mCaptureSize(CAPTURE_SIZE_DEF), mSampleRate(44100000), + mScalingMode(VISUALIZER_SCALING_MODE_NORMALIZED), mCaptureCallBack(NULL), mCaptureCbkUser(NULL) { @@ -146,9 +147,38 @@ status_t Visualizer::setCaptureSize(uint32_t size) 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 @@ uint32_t Visualizer::initCaptureSize() 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 @@ status_t CameraSource::isCameraAvailable( 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 @@ ifeq ($(AAC_LIBRARY), fraunhofer) 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 @@ ifeq ($(AAC_LIBRARY), fraunhofer) 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 @@ SoftAAC2::SoftAAC2( 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 @@ void SoftAAC2::initPorts() { 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 @@ OMX_ERRORTYPE SoftAAC2::internalGetParameter( 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 @@ void SoftAAC2::onQueueFilled(OMX_U32 portIndex) { 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::onQueueFilled(OMX_U32 portIndex) { 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 @@ private: 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 @@ static int getCallingUid() { 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 @@ status_t CameraService::getCameraInfo(int cameraId, } 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 @@ sp<ICamera> CameraService::connect( 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 @@ sp<ICamera> CameraService::connect( 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 @@ void CameraService::playSound(sound_kind kind) { 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 @@ CameraService::Client::Client(const sp<CameraService>& cameraService, mCameraId = cameraId; mCameraFacing = cameraFacing; mClientPid = clientPid; - mKeep = keep; mMsgEnabled = 0; mSurface = 0; mPreviewWindow = 0; @@ -544,24 +480,18 @@ static void disconnectWindow(const sp<ANativeWindow>& window) { } 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 @@ void CameraService::Client::disconnectInternal(bool needCheckPid) { 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 @@ int CameraService::Client::getOrientation(int degrees, bool mirror) { 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 @@ public: 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 @@ private: const sp<CameraHardwareInterface>& hardware, int cameraId, int cameraFacing, - int clientPid, - bool keep); + int clientPid); ~Client(); // return our camera client @@ -179,19 +177,12 @@ private: 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 @@ private: // 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; |
