diff options
author | Benny Wong <Benny.Wong@motorola.com> | 2009-08-12 12:01:27 -0500 |
---|---|---|
committer | James Dong <jdong@google.com> | 2009-08-13 10:46:28 -0700 |
commit | da83f4674a564007baac03db062a289c8158d940 (patch) | |
tree | c1476d13a17ddff1bbd3769d3406ab3d639318d2 /camera/libcameraservice | |
parent | ddb79c9fd53893aa126599330a9289497e5f5c93 (diff) | |
download | frameworks_base-da83f4674a564007baac03db062a289c8158d940.zip frameworks_base-da83f4674a564007baac03db062a289c8158d940.tar.gz frameworks_base-da83f4674a564007baac03db062a289c8158d940.tar.bz2 |
Modified the camera HAL interface to use the same generic callback architecture as camera services
Diffstat (limited to 'camera/libcameraservice')
-rw-r--r-- | camera/libcameraservice/CameraHardwareStub.cpp | 100 | ||||
-rw-r--r-- | camera/libcameraservice/CameraHardwareStub.h | 39 | ||||
-rw-r--r-- | camera/libcameraservice/CameraService.cpp | 420 | ||||
-rw-r--r-- | camera/libcameraservice/CameraService.h | 24 |
4 files changed, 292 insertions, 291 deletions
diff --git a/camera/libcameraservice/CameraHardwareStub.cpp b/camera/libcameraservice/CameraHardwareStub.cpp index a7af57c..24496bb 100644 --- a/camera/libcameraservice/CameraHardwareStub.cpp +++ b/camera/libcameraservice/CameraHardwareStub.cpp @@ -33,13 +33,11 @@ CameraHardwareStub::CameraHardwareStub() mRawHeap(0), mFakeCamera(0), mPreviewFrameSize(0), - mRawPictureCallback(0), - mJpegPictureCallback(0), - mPictureCallbackCookie(0), - mPreviewCallback(0), - mPreviewCallbackCookie(0), - mAutoFocusCallback(0), - mAutoFocusCallbackCookie(0), + mNotifyCb(0), + mDataCb(0), + mDataCbTimestamp(0), + mCallbackCookie(0), + mMsgEnabled(0), mCurrentPreviewFrame(0) { initDefaultParameters(); @@ -112,6 +110,36 @@ sp<IMemoryHeap> CameraHardwareStub::getRawHeap() const return mRawHeap; } +void CameraHardwareStub::setCallbacks(notify_callback notify_cb, + data_callback data_cb, + data_callback_timestamp data_cb_timestamp, + void* user) +{ + Mutex::Autolock lock(mLock); + mNotifyCb = notify_cb; + mDataCb = data_cb; + mDataCbTimestamp = data_cb_timestamp; + mCallbackCookie = user; +} + +void CameraHardwareStub::enableMsgType(int32_t msgType) +{ + Mutex::Autolock lock(mLock); + mMsgEnabled |= msgType; +} + +void CameraHardwareStub::disableMsgType(int32_t msgType) +{ + Mutex::Autolock lock(mLock); + mMsgEnabled &= ~msgType; +} + +bool CameraHardwareStub::msgTypeEnabled(int32_t msgType) +{ + Mutex::Autolock lock(mLock); + return (mMsgEnabled & msgType); +} + // --------------------------------------------------------------------------- int CameraHardwareStub::previewThread() @@ -150,7 +178,8 @@ int CameraHardwareStub::previewThread() //LOGV("previewThread: generated frame to buffer %d", mCurrentPreviewFrame); // Notify the client of a new frame. - mPreviewCallback(buffer, mPreviewCallbackCookie); + if (mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME) + mDataCb(CAMERA_MSG_PREVIEW_FRAME, buffer, mCallbackCookie); // Advance the buffer pointer. mCurrentPreviewFrame = (mCurrentPreviewFrame + 1) % kBufferCount; @@ -162,15 +191,13 @@ int CameraHardwareStub::previewThread() return NO_ERROR; } -status_t CameraHardwareStub::startPreview(preview_callback cb, void* user) +status_t CameraHardwareStub::startPreview() { Mutex::Autolock lock(mLock); if (mPreviewThread != 0) { // already running return INVALID_OPERATION; } - mPreviewCallback = cb; - mPreviewCallbackCookie = user; mPreviewThread = new PreviewThread(this); return NO_ERROR; } @@ -197,7 +224,7 @@ bool CameraHardwareStub::previewEnabled() { return mPreviewThread != 0; } -status_t CameraHardwareStub::startRecording(recording_callback cb, void* user) +status_t CameraHardwareStub::startRecording() { return UNKNOWN_ERROR; } @@ -225,25 +252,14 @@ int CameraHardwareStub::beginAutoFocusThread(void *cookie) int CameraHardwareStub::autoFocusThread() { - if (mAutoFocusCallback != NULL) { - mAutoFocusCallback(true, mAutoFocusCallbackCookie); - mAutoFocusCallback = NULL; - return NO_ERROR; - } - return UNKNOWN_ERROR; + if (mMsgEnabled & CAMERA_MSG_FOCUS) + mNotifyCb(CAMERA_MSG_FOCUS, true, 0, mCallbackCookie); + return NO_ERROR; } -status_t CameraHardwareStub::autoFocus(autofocus_callback af_cb, - void *user) +status_t CameraHardwareStub::autoFocus() { Mutex::Autolock lock(mLock); - - if (mAutoFocusCallback != NULL) { - return mAutoFocusCallback == af_cb ? NO_ERROR : INVALID_OPERATION; - } - - mAutoFocusCallback = af_cb; - mAutoFocusCallbackCookie = user; if (createThread(beginAutoFocusThread, this) == false) return UNKNOWN_ERROR; return NO_ERROR; @@ -257,10 +273,10 @@ status_t CameraHardwareStub::autoFocus(autofocus_callback af_cb, int CameraHardwareStub::pictureThread() { - if (mShutterCallback) - mShutterCallback(mPictureCallbackCookie); + if (mMsgEnabled & CAMERA_MSG_SHUTTER) + mNotifyCb(CAMERA_MSG_SHUTTER, 0, 0, mCallbackCookie); - if (mRawPictureCallback) { + if (mMsgEnabled & CAMERA_MSG_RAW_IMAGE) { //FIXME: use a canned YUV image! // In the meantime just make another fake camera picture. int w, h; @@ -268,42 +284,28 @@ int CameraHardwareStub::pictureThread() sp<MemoryBase> mem = new MemoryBase(mRawHeap, 0, w * 2 * h); FakeCamera cam(w, h); cam.getNextFrameAsYuv422((uint8_t *)mRawHeap->base()); - if (mRawPictureCallback) - mRawPictureCallback(mem, mPictureCallbackCookie); + mDataCb(CAMERA_MSG_RAW_IMAGE, mem, mCallbackCookie); } - if (mJpegPictureCallback) { + if (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE) { sp<MemoryHeapBase> heap = new MemoryHeapBase(kCannedJpegSize); sp<MemoryBase> mem = new MemoryBase(heap, 0, kCannedJpegSize); memcpy(heap->base(), kCannedJpeg, kCannedJpegSize); - if (mJpegPictureCallback) - mJpegPictureCallback(mem, mPictureCallbackCookie); + mDataCb(CAMERA_MSG_COMPRESSED_IMAGE, mem, mCallbackCookie); } return NO_ERROR; } -status_t CameraHardwareStub::takePicture(shutter_callback shutter_cb, - raw_callback raw_cb, - jpeg_callback jpeg_cb, - void* user) +status_t CameraHardwareStub::takePicture() { stopPreview(); - mShutterCallback = shutter_cb; - mRawPictureCallback = raw_cb; - mJpegPictureCallback = jpeg_cb; - mPictureCallbackCookie = user; if (createThread(beginPictureThread, this) == false) return -1; return NO_ERROR; } -status_t CameraHardwareStub::cancelPicture(bool cancel_shutter, - bool cancel_raw, - bool cancel_jpeg) +status_t CameraHardwareStub::cancelPicture() { - if (cancel_shutter) mShutterCallback = NULL; - if (cancel_raw) mRawPictureCallback = NULL; - if (cancel_jpeg) mJpegPictureCallback = NULL; return NO_ERROR; } diff --git a/camera/libcameraservice/CameraHardwareStub.h b/camera/libcameraservice/CameraHardwareStub.h index dd3c706..000906a 100644 --- a/camera/libcameraservice/CameraHardwareStub.h +++ b/camera/libcameraservice/CameraHardwareStub.h @@ -32,23 +32,27 @@ public: virtual sp<IMemoryHeap> getPreviewHeap() const; virtual sp<IMemoryHeap> getRawHeap() const; - virtual status_t startPreview(preview_callback cb, void* user); + virtual void setCallbacks(notify_callback notify_cb, + data_callback data_cb, + data_callback_timestamp data_cb_timestamp, + void* user); + + virtual void enableMsgType(int32_t msgType); + virtual void disableMsgType(int32_t msgType); + virtual bool msgTypeEnabled(int32_t msgType); + + virtual status_t startPreview(); virtual void stopPreview(); virtual bool previewEnabled(); - virtual status_t startRecording(recording_callback cb, void* user); + virtual status_t startRecording(); virtual void stopRecording(); virtual bool recordingEnabled(); virtual void releaseRecordingFrame(const sp<IMemory>& mem); - virtual status_t autoFocus(autofocus_callback, void *user); - virtual status_t takePicture(shutter_callback, - raw_callback, - jpeg_callback, - void* user); - virtual status_t cancelPicture(bool cancel_shutter, - bool cancel_raw, - bool cancel_jpeg); + virtual status_t autoFocus(); + virtual status_t takePicture(); + virtual status_t cancelPicture(); virtual status_t dump(int fd, const Vector<String16>& args) const; virtual status_t setParameters(const CameraParameters& params); virtual CameraParameters getParameters() const; @@ -109,18 +113,15 @@ private: bool mPreviewRunning; int mPreviewFrameSize; - shutter_callback mShutterCallback; - raw_callback mRawPictureCallback; - jpeg_callback mJpegPictureCallback; - void *mPictureCallbackCookie; - // protected by mLock sp<PreviewThread> mPreviewThread; - preview_callback mPreviewCallback; - void *mPreviewCallbackCookie; - autofocus_callback mAutoFocusCallback; - void *mAutoFocusCallbackCookie; + notify_callback mNotifyCb; + data_callback mDataCb; + data_callback_timestamp mDataCbTimestamp; + void *mCallbackCookie; + + int32_t mMsgEnabled; // only used from PreviewThread int mCurrentPreviewFrame; diff --git a/camera/libcameraservice/CameraService.cpp b/camera/libcameraservice/CameraService.cpp index e7c1fbb..e66b00f 100644 --- a/camera/libcameraservice/CameraService.cpp +++ b/camera/libcameraservice/CameraService.cpp @@ -59,6 +59,7 @@ extern "C" { #define DEBUG_DUMP_PREVIEW_FRAME_TO_FILE 0 /* n-th frame to write */ #define DEBUG_DUMP_JPEG_SNAPSHOT_TO_FILE 0 #define DEBUG_DUMP_YUV_SNAPSHOT_TO_FILE 0 +#define DEBUG_DUMP_POSTVIEW_SNAPSHOT_TO_FILE 0 #if DEBUG_DUMP_PREVIEW_FRAME_TO_FILE static int debug_frame_cnt; @@ -218,6 +219,16 @@ CameraService::Client::Client(const sp<CameraService>& cameraService, mHardware = openCameraHardware(); mUseOverlay = mHardware->useOverlay(); + mHardware->setCallbacks(notifyCallback, + dataCallback, + dataCallbackTimestamp, + mCameraService.get()); + + // Enable zoom, error, and focus messages by default + mHardware->enableMsgType(CAMERA_MSG_ERROR | + CAMERA_MSG_ZOOM | + CAMERA_MSG_FOCUS); + mMediaPlayerClick = newMediaPlayer("/system/media/audio/ui/camera_click.ogg"); mMediaPlayerBeep = newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg"); mOverlayW = 0; @@ -391,7 +402,13 @@ void CameraService::Client::disconnect() // idle state. mHardware->stopPreview(); // Cancel all picture callbacks. - mHardware->cancelPicture(true, true, true); + mHardware->disableMsgType(CAMERA_MSG_SHUTTER | + CAMERA_MSG_POSTVIEW_FRAME | + CAMERA_MSG_RAW_IMAGE | + CAMERA_MSG_COMPRESSED_IMAGE); + mHardware->cancelPicture(); + // Turn off remaining messages. + mHardware->disableMsgType(CAMERA_MSG_ALL_MSGS); // Release the hardware resources. mHardware->release(); // Release the held overlay resources. @@ -456,6 +473,13 @@ void CameraService::Client::setPreviewCallbackFlag(int callback_flag) Mutex::Autolock lock(mLock); if (checkPid() != NO_ERROR) return; mPreviewCallbackFlag = callback_flag; + + if(mUseOverlay) { + if(mPreviewCallbackFlag & FRAME_CALLBACK_FLAG_ENABLE_MASK) + mHardware->enableMsgType(CAMERA_MSG_PREVIEW_FRAME); + else + mHardware->disableMsgType(CAMERA_MSG_PREVIEW_FRAME); + } } // start preview mode @@ -514,7 +538,7 @@ status_t CameraService::Client::startRecordingMode() } // start recording mode - ret = mHardware->startRecording(recordingCallback, mCameraService.get()); + ret = mHardware->startRecording(); if (ret != NO_ERROR) { LOGE("mHardware->startRecording() failed with status %d", ret); } @@ -617,10 +641,10 @@ status_t CameraService::Client::startPreviewMode() ret = setOverlay(); } if (ret != NO_ERROR) return ret; - ret = mHardware->startPreview(NULL, mCameraService.get()); + ret = mHardware->startPreview(); } else { - ret = mHardware->startPreview(previewCallback, - mCameraService.get()); + mHardware->enableMsgType(CAMERA_MSG_PREVIEW_FRAME); + ret = mHardware->startPreview(); if (ret != NO_ERROR) return ret; // If preview display has been set, register preview buffers now. if (mSurface != 0) { @@ -647,6 +671,9 @@ status_t CameraService::Client::startRecording() mMediaPlayerBeep->seekTo(0); mMediaPlayerBeep->start(); } + + mHardware->enableMsgType(CAMERA_MSG_VIDEO_FRAME); + return startCameraMode(CAMERA_RECORDING_MODE); } @@ -664,6 +691,7 @@ void CameraService::Client::stopPreview() } mHardware->stopPreview(); + mHardware->disableMsgType(CAMERA_MSG_PREVIEW_FRAME); LOGD("stopPreview(), hardware stopped OK"); if (mSurface != 0 && !mUseOverlay) { @@ -689,8 +717,11 @@ void CameraService::Client::stopRecording() mMediaPlayerBeep->seekTo(0); mMediaPlayerBeep->start(); } + mHardware->stopRecording(); + mHardware->disableMsgType(CAMERA_MSG_VIDEO_FRAME); LOGD("stopRecording(), hardware stopped OK"); + mPreviewBuffer.clear(); } @@ -778,65 +809,6 @@ static void dump_to_file(const char *fname, } #endif -// preview callback - frame buffer update -void CameraService::Client::previewCallback(const sp<IMemory>& mem, void* user) -{ - LOGV("previewCallback()"); - sp<Client> client = getClientFromCookie(user); - if (client == 0) { - return; - } - -#if DEBUG_HEAP_LEAKS && 0 // debugging - if (gWeakHeap == NULL) { - ssize_t offset; - size_t size; - sp<IMemoryHeap> heap = mem->getMemory(&offset, &size); - if (gWeakHeap != heap) { - LOGD("SETTING PREVIEW HEAP"); - heap->trackMe(true, true); - gWeakHeap = heap; - } - } -#endif - -#if DEBUG_DUMP_PREVIEW_FRAME_TO_FILE - { - if (debug_frame_cnt++ == DEBUG_DUMP_PREVIEW_FRAME_TO_FILE) { - ssize_t offset; - size_t size; - sp<IMemoryHeap> heap = mem->getMemory(&offset, &size); - dump_to_file("/data/preview.yuv", - (uint8_t *)heap->base() + offset, size); - } - } -#endif - - // The strong pointer guarantees the client will exist, but no lock is held. - client->postPreviewFrame(mem); - -#if DEBUG_CLIENT_REFERENCES - //**** if the client's refcount is 1, then we are about to destroy it here, - // which is bad--print all refcounts. - if (client->getStrongCount() == 1) { - LOGE("++++++++++++++++ (PREVIEW) THIS WILL CAUSE A LOCKUP!"); - client->printRefs(); - } -#endif -} - -// recording callback -void CameraService::Client::recordingCallback(nsecs_t timestamp, const sp<IMemory>& mem, void* user) -{ - LOGV("recordingCallback"); - sp<Client> client = getClientFromCookie(user); - if (client == 0) { - return; - } - // The strong pointer guarantees the client will exist, but no lock is held. - client->postRecordingFrame(timestamp, mem); -} - // take a picture - image is returned in callback status_t CameraService::Client::autoFocus() { @@ -851,8 +823,7 @@ status_t CameraService::Client::autoFocus() return INVALID_OPERATION; } - return mHardware->autoFocus(autoFocusCallback, - mCameraService.get()); + return mHardware->autoFocus(); } // take a picture - image is returned in callback @@ -869,38 +840,36 @@ status_t CameraService::Client::takePicture() return INVALID_OPERATION; } - return mHardware->takePicture(shutterCallback, - yuvPictureCallback, - jpegPictureCallback, - mCameraService.get()); + mHardware->enableMsgType(CAMERA_MSG_SHUTTER | + CAMERA_MSG_POSTVIEW_FRAME | + CAMERA_MSG_RAW_IMAGE | + CAMERA_MSG_COMPRESSED_IMAGE); + + return mHardware->takePicture(); } -// picture callback - snapshot taken -void CameraService::Client::shutterCallback(void *user) +// snapshot taken +void CameraService::Client::handleShutter() { - sp<Client> client = getClientFromCookie(user); - if (client == 0) { - return; - } - // Play shutter sound. - if (client->mMediaPlayerClick.get() != NULL) { - client->mMediaPlayerClick->seekTo(0); - client->mMediaPlayerClick->start(); + if (mMediaPlayerClick.get() != NULL) { + mMediaPlayerClick->seekTo(0); + mMediaPlayerClick->start(); } // Screen goes black after the buffer is unregistered. - if (client->mSurface != 0 && !client->mUseOverlay) { - client->mSurface->unregisterBuffers(); + if (mSurface != 0 && !mUseOverlay) { + mSurface->unregisterBuffers(); } - client->postShutter(); + mCameraClient->notifyCallback(CAMERA_MSG_SHUTTER, 0, 0); + mHardware->disableMsgType(CAMERA_MSG_SHUTTER); // It takes some time before yuvPicture callback to be called. // Register the buffer for raw image here to reduce latency. - if (client->mSurface != 0 && !client->mUseOverlay) { + if (mSurface != 0 && !mUseOverlay) { int w, h; - CameraParameters params(client->mHardware->getParameters()); + CameraParameters params(mHardware->getParameters()); params.getPictureSize(&w, &h); uint32_t transform = 0; if (params.getOrientation() == CameraParameters::CAMERA_ORIENTATION_PORTRAIT) { @@ -908,26 +877,92 @@ void CameraService::Client::shutterCallback(void *user) transform = ISurface::BufferHeap::ROT_90; } ISurface::BufferHeap buffers(w, h, w, h, - PIXEL_FORMAT_YCbCr_420_SP, transform, 0, client->mHardware->getRawHeap()); + PIXEL_FORMAT_YCbCr_420_SP, transform, 0, mHardware->getRawHeap()); - client->mSurface->registerBuffers(buffers); + mSurface->registerBuffers(buffers); } } -// picture callback - raw image ready -void CameraService::Client::yuvPictureCallback(const sp<IMemory>& mem, - void *user) +// preview callback - frame buffer update +void CameraService::Client::handlePreviewData(const sp<IMemory>& mem) { - sp<Client> client = getClientFromCookie(user); - if (client == 0) { - return; + ssize_t offset; + size_t size; + sp<IMemoryHeap> heap = mem->getMemory(&offset, &size); + +#if DEBUG_HEAP_LEAKS && 0 // debugging + if (gWeakHeap == NULL) { + if (gWeakHeap != heap) { + LOGD("SETTING PREVIEW HEAP"); + heap->trackMe(true, true); + gWeakHeap = heap; + } } - if (mem == NULL) { - client->postRaw(NULL); - client->postError(UNKNOWN_ERROR); +#endif +#if DEBUG_DUMP_PREVIEW_FRAME_TO_FILE + { + if (debug_frame_cnt++ == DEBUG_DUMP_PREVIEW_FRAME_TO_FILE) { + dump_to_file("/data/preview.yuv", + (uint8_t *)heap->base() + offset, size); + } + } +#endif + + if (!mUseOverlay) + { + Mutex::Autolock surfaceLock(mSurfaceLock); + if (mSurface != NULL) { + mSurface->postBuffer(offset); + } + } + + // Is the callback enabled or not? + if (!(mPreviewCallbackFlag & FRAME_CALLBACK_FLAG_ENABLE_MASK)) { + // If the enable bit is off, the copy-out and one-shot bits are ignored + LOGV("frame callback is diabled"); return; } + // Is the received frame copied out or not? + if (mPreviewCallbackFlag & FRAME_CALLBACK_FLAG_COPY_OUT_MASK) { + LOGV("frame is copied out"); + copyFrameAndPostCopiedFrame(heap, offset, size); + } else { + LOGV("frame is directly sent out without copying"); + mCameraClient->dataCallback(CAMERA_MSG_PREVIEW_FRAME, mem); + } + + // Is this is one-shot only? + if (mPreviewCallbackFlag & FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) { + LOGV("One-shot only, thus clear the bits and disable frame callback"); + mPreviewCallbackFlag &= ~(FRAME_CALLBACK_FLAG_ONE_SHOT_MASK | + FRAME_CALLBACK_FLAG_COPY_OUT_MASK | + FRAME_CALLBACK_FLAG_ENABLE_MASK); + if (mUseOverlay) + mHardware->disableMsgType(CAMERA_MSG_PREVIEW_FRAME); + } +} + +// picture callback - postview image ready +void CameraService::Client::handlePostview(const sp<IMemory>& mem) +{ +#if DEBUG_DUMP_POSTVIEW_SNAPSHOT_TO_FILE // for testing pursposes only + { + ssize_t offset; + size_t size; + sp<IMemoryHeap> heap = mem->getMemory(&offset, &size); + dump_to_file("/data/postview.yuv", + (uint8_t *)heap->base() + offset, size); + } +#endif + + mCameraClient->dataCallback(CAMERA_MSG_POSTVIEW_FRAME, mem); + mHardware->disableMsgType(CAMERA_MSG_POSTVIEW_FRAME); +} + +// picture callback - raw image ready +void CameraService::Client::handleRawPicture(const sp<IMemory>& mem) +{ ssize_t offset; size_t size; sp<IMemoryHeap> heap = mem->getMemory(&offset, &size); @@ -935,80 +970,128 @@ void CameraService::Client::yuvPictureCallback(const sp<IMemory>& mem, gWeakHeap = heap; // debugging #endif - //LOGV("yuvPictureCallback(%d, %d, %p)", offset, size, user); + //LOGV("handleRawPicture(%d, %d)", offset, size); #if DEBUG_DUMP_YUV_SNAPSHOT_TO_FILE // for testing pursposes only dump_to_file("/data/photo.yuv", (uint8_t *)heap->base() + offset, size); #endif // Put the YUV version of the snapshot in the preview display. - if (client->mSurface != 0 && !client->mUseOverlay) { - client->mSurface->postBuffer(offset); + if (mSurface != 0 && !mUseOverlay) { + mSurface->postBuffer(offset); } - client->postRaw(mem); + mCameraClient->dataCallback(CAMERA_MSG_RAW_IMAGE, mem); + mHardware->disableMsgType(CAMERA_MSG_RAW_IMAGE); +} + +// picture callback - compressed picture ready +void CameraService::Client::handleCompressedPicture(const sp<IMemory>& mem) +{ +#if DEBUG_DUMP_JPEG_SNAPSHOT_TO_FILE // for testing pursposes only + { + ssize_t offset; + size_t size; + sp<IMemoryHeap> heap = mem->getMemory(&offset, &size); + dump_to_file("/data/photo.jpg", + (uint8_t *)heap->base() + offset, size); + } +#endif + + mCameraClient->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE, mem); + mHardware->disableMsgType(CAMERA_MSG_COMPRESSED_IMAGE); +} + +void CameraService::Client::notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2, void* user) +{ + LOGV("notifyCallback(%d)", msgType); + + sp<Client> client = getClientFromCookie(user); + if (client == 0) { + return; + } + + switch (msgType) { + case CAMERA_MSG_SHUTTER: + client->handleShutter(); + break; + default: + client->mCameraClient->notifyCallback(msgType, ext1, ext2); + break; + } #if DEBUG_CLIENT_REFERENCES - //**** if the client's refcount is 1, then we are about to destroy it here, - // which is bad--print all refcounts. if (client->getStrongCount() == 1) { - LOGE("++++++++++++++++ (RAW) THIS WILL CAUSE A LOCKUP!"); + LOGE("++++++++++++++++ (NOTIFY CALLBACK) THIS WILL CAUSE A LOCKUP!"); client->printRefs(); } #endif } -// picture callback - jpeg ready -void CameraService::Client::jpegPictureCallback(const sp<IMemory>& mem, void *user) +void CameraService::Client::dataCallback(int32_t msgType, const sp<IMemory>& dataPtr, void* user) { + LOGV("dataCallback(%d)", msgType); + sp<Client> client = getClientFromCookie(user); if (client == 0) { return; } - if (mem == NULL) { - client->postJpeg(NULL); - client->postError(UNKNOWN_ERROR); + + if (dataPtr == NULL) { + LOGE("Null data returned in data callback"); + client->mCameraClient->notifyCallback(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0); + client->mCameraClient->dataCallback(msgType, NULL); return; } - /** We absolutely CANNOT call into user code with a lock held **/ - -#if DEBUG_DUMP_JPEG_SNAPSHOT_TO_FILE // for testing pursposes only - { - ssize_t offset; - size_t size; - sp<IMemoryHeap> heap = mem->getMemory(&offset, &size); - dump_to_file("/data/photo.jpg", - (uint8_t *)heap->base() + offset, size); + switch (msgType) { + case CAMERA_MSG_PREVIEW_FRAME: + client->handlePreviewData(dataPtr); + break; + case CAMERA_MSG_POSTVIEW_FRAME: + client->handlePostview(dataPtr); + break; + case CAMERA_MSG_RAW_IMAGE: + client->handleRawPicture(dataPtr); + break; + case CAMERA_MSG_COMPRESSED_IMAGE: + client->handleCompressedPicture(dataPtr); + break; + default: + client->mCameraClient->dataCallback(msgType, dataPtr); + break; } -#endif - - client->postJpeg(mem); #if DEBUG_CLIENT_REFERENCES - //**** if the client's refcount is 1, then we are about to destroy it here, - // which is bad--print all refcounts. if (client->getStrongCount() == 1) { - LOGE("++++++++++++++++ (JPEG) THIS WILL CAUSE A LOCKUP!"); + LOGE("++++++++++++++++ (DATA CALLBACK) THIS WILL CAUSE A LOCKUP!"); client->printRefs(); } #endif } -void CameraService::Client::autoFocusCallback(bool focused, void *user) +void CameraService::Client::dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, + const sp<IMemory>& dataPtr, void* user) { - LOGV("autoFocusCallback"); + LOGV("dataCallbackTimestamp(%d)", msgType); sp<Client> client = getClientFromCookie(user); if (client == 0) { return; } - client->postAutoFocus(focused); + if (dataPtr == NULL) { + LOGE("Null data returned in data with timestamp callback"); + client->mCameraClient->notifyCallback(CAMERA_MSG_ERROR, UNKNOWN_ERROR, 0); + client->mCameraClient->dataCallbackTimestamp(0, msgType, NULL); + return; + } + + client->mCameraClient->dataCallbackTimestamp(timestamp, msgType, dataPtr); #if DEBUG_CLIENT_REFERENCES if (client->getStrongCount() == 1) { - LOGE("++++++++++++++++ (AUTOFOCUS) THIS WILL CAUSE A LOCKUP!"); + LOGE("++++++++++++++++ (DATA CALLBACK TIMESTAMP) THIS WILL CAUSE A LOCKUP!"); client->printRefs(); } #endif @@ -1048,30 +1131,6 @@ String8 CameraService::Client::getParameters() const return params; } -void CameraService::Client::postAutoFocus(bool focused) -{ - LOGV("postAutoFocus"); - mCameraClient->notifyCallback(CAMERA_MSG_FOCUS, (int32_t)focused, 0); -} - -void CameraService::Client::postShutter() -{ - LOGD("postShutter"); - mCameraClient->notifyCallback(CAMERA_MSG_SHUTTER, 0, 0); -} - -void CameraService::Client::postRaw(const sp<IMemory>& mem) -{ - LOGD("postRaw"); - mCameraClient->dataCallback(CAMERA_MSG_RAW_IMAGE, mem); -} - -void CameraService::Client::postJpeg(const sp<IMemory>& mem) -{ - LOGD("postJpeg"); - mCameraClient->dataCallback(CAMERA_MSG_COMPRESSED_IMAGE, mem); -} - void CameraService::Client::copyFrameAndPostCopiedFrame(sp<IMemoryHeap> heap, size_t offset, size_t size) { LOGV("copyFrameAndPostCopiedFrame"); @@ -1100,65 +1159,6 @@ void CameraService::Client::copyFrameAndPostCopiedFrame(sp<IMemoryHeap> heap, si mCameraClient->dataCallback(CAMERA_MSG_PREVIEW_FRAME, frame); } -void CameraService::Client::postRecordingFrame(nsecs_t timestamp, const sp<IMemory>& frame) -{ - LOGV("postRecordingFrame"); - if (frame == 0) { - LOGW("frame is a null pointer"); - return; - } - mCameraClient->dataCallbackTimestamp(timestamp, CAMERA_MSG_VIDEO_FRAME, frame); -} - -void CameraService::Client::postPreviewFrame(const sp<IMemory>& mem) -{ - LOGV("postPreviewFrame"); - if (mem == 0) { - LOGW("mem is a null pointer"); - return; - } - - ssize_t offset; - size_t size; - sp<IMemoryHeap> heap = mem->getMemory(&offset, &size); - if ( !mUseOverlay ) - { - Mutex::Autolock surfaceLock(mSurfaceLock); - if (mSurface != NULL) { - mSurface->postBuffer(offset); - } - } - - // Is the callback enabled or not? - if (!(mPreviewCallbackFlag & FRAME_CALLBACK_FLAG_ENABLE_MASK)) { - // If the enable bit is off, the copy-out and one-shot bits are ignored - LOGV("frame callback is diabled"); - return; - } - - // Is the received frame copied out or not? - if (mPreviewCallbackFlag & FRAME_CALLBACK_FLAG_COPY_OUT_MASK) { - LOGV("frame is copied out"); - copyFrameAndPostCopiedFrame(heap, offset, size); - } else { - LOGV("frame is directly sent out without copying"); - mCameraClient->dataCallback(CAMERA_MSG_PREVIEW_FRAME, mem); - } - - // Is this is one-shot only? - if (mPreviewCallbackFlag & FRAME_CALLBACK_FLAG_ONE_SHOT_MASK) { - LOGV("One-shot only, thus clear the bits and disable frame callback"); - mPreviewCallbackFlag &= ~(FRAME_CALLBACK_FLAG_ONE_SHOT_MASK | - FRAME_CALLBACK_FLAG_COPY_OUT_MASK | - FRAME_CALLBACK_FLAG_ENABLE_MASK); - } -} - -void CameraService::Client::postError(status_t error) -{ - mCameraClient->notifyCallback(CAMERA_MSG_ERROR, error, 0); -} - status_t CameraService::dump(int fd, const Vector<String16>& args) { const size_t SIZE = 256; diff --git a/camera/libcameraservice/CameraService.h b/camera/libcameraservice/CameraService.h index 8a49fa6..f8c7216 100644 --- a/camera/libcameraservice/CameraService.h +++ b/camera/libcameraservice/CameraService.h @@ -132,22 +132,20 @@ private: status_t checkPid(); - static void recordingCallback(nsecs_t timestamp, const sp<IMemory>& mem, void* user); - static void previewCallback(const sp<IMemory>& mem, void* user); - static void shutterCallback(void *user); - static void yuvPictureCallback(const sp<IMemory>& mem, void* user); - static void jpegPictureCallback(const sp<IMemory>& mem, void* user); - static void autoFocusCallback(bool focused, void* user); + static void notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2, void* user); + static void dataCallback(int32_t msgType, const sp<IMemory>& dataPtr, void* user); + static void dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, + const sp<IMemory>& dataPtr, void* user); + static sp<Client> getClientFromCookie(void* user); - void postShutter(); - void postRaw(const sp<IMemory>& mem); - void postJpeg(const sp<IMemory>& mem); - void postPreviewFrame(const sp<IMemory>& mem); - void postRecordingFrame(nsecs_t timestamp, const sp<IMemory>& frame); + void handlePreviewData(const sp<IMemory>&); + void handleShutter(); + void handlePostview(const sp<IMemory>&); + void handleRawPicture(const sp<IMemory>&); + void handleCompressedPicture(const sp<IMemory>&); + void copyFrameAndPostCopiedFrame(sp<IMemoryHeap> heap, size_t offset, size_t size); - void postError(status_t error); - void postAutoFocus(bool focused); // camera operation mode enum camera_mode { |