diff options
-rw-r--r-- | camera/libcameraservice/CameraService.cpp | 49 | ||||
-rw-r--r-- | camera/libcameraservice/CameraService.h | 4 | ||||
-rw-r--r-- | include/ui/Overlay.h | 4 | ||||
-rw-r--r-- | libs/ui/Overlay.cpp | 21 |
4 files changed, 72 insertions, 6 deletions
diff --git a/camera/libcameraservice/CameraService.cpp b/camera/libcameraservice/CameraService.cpp index 96389dd..97b43a4 100644 --- a/camera/libcameraservice/CameraService.cpp +++ b/camera/libcameraservice/CameraService.cpp @@ -227,6 +227,8 @@ CameraService::Client::Client(const sp<CameraService>& cameraService, mMediaPlayerClick = newMediaPlayer("/system/media/audio/ui/camera_click.ogg"); mMediaPlayerBeep = newMediaPlayer("/system/media/audio/ui/VideoRecord.ogg"); + mOverlayW = 0; + mOverlayH = 0; // Callback is disabled by default mPreviewCallbackFlag = FRAME_CALLBACK_FLAG_NOOP; @@ -399,6 +401,11 @@ void CameraService::Client::disconnect() mHardware->cancelPicture(true, true, true); // Release the hardware resources. mHardware->release(); + // Release the held overlay resources. + if (mUseOverlay) + { + mOverlayRef = 0; + } mHardware.clear(); mCameraService->removeClient(mCameraClient); @@ -420,11 +427,21 @@ status_t CameraService::Client::setPreviewDisplay(const sp<ISurface>& surface) result = NO_ERROR; // asBinder() is safe on NULL (returns NULL) if (surface->asBinder() != mSurface->asBinder()) { - if (mSurface != 0 && !mUseOverlay) { + if (mSurface != 0) { LOGD("clearing old preview surface %p", mSurface.get()); - mSurface->unregisterBuffers(); + if ( !mUseOverlay) + { + mSurface->unregisterBuffers(); + } + else + { + // Force the destruction of any previous overlay + sp<Overlay> dummy; + mHardware->setOverlay( dummy ); + } } mSurface = surface; + mOverlayRef = 0; // If preview has been already started, set overlay or register preview // buffers now. if (mHardware->previewEnabled()) { @@ -520,8 +537,8 @@ status_t CameraService::Client::setOverlay() const char *format = params.getPreviewFormat(); int fmt; - if (!strcmp(format, "yuv422i")) - fmt = OVERLAY_FORMAT_YCbCr_422_I; + if (!strcmp(format, "yuv422i-yuyv")) + fmt = OVERLAY_FORMAT_YCbYCr_422_I; else if (!strcmp(format, "rgb565")) fmt = OVERLAY_FORMAT_RGB_565; else { @@ -529,16 +546,35 @@ status_t CameraService::Client::setOverlay() return -EINVAL; } + if ( w != mOverlayW || h != mOverlayH ) + { + // Force the destruction of any previous overlay + sp<Overlay> dummy; + mHardware->setOverlay( dummy ); + mOverlayRef = 0; + } + status_t ret = NO_ERROR; if (mSurface != 0) { - sp<OverlayRef> ref = mSurface->createOverlay(w, h, fmt); - ret = mHardware->setOverlay(new Overlay(ref)); + if (mOverlayRef.get() == NULL) { + mOverlayRef = mSurface->createOverlay(w, h, fmt); + if ( mOverlayRef.get() == NULL ) + { + LOGE("Overlay Creation Failed!"); + return -EINVAL; + } + ret = mHardware->setOverlay(new Overlay(mOverlayRef)); + } } else { ret = mHardware->setOverlay(NULL); } if (ret != NO_ERROR) { LOGE("mHardware->setOverlay() failed with status %d\n", ret); } + + mOverlayW = w; + mOverlayH = h; + return ret; } @@ -1092,6 +1128,7 @@ void CameraService::Client::postPreviewFrame(const sp<IMemory>& mem) ssize_t offset; size_t size; sp<IMemoryHeap> heap = mem->getMemory(&offset, &size); + if ( !mUseOverlay ) { Mutex::Autolock surfaceLock(mSurfaceLock); if (mSurface != NULL) { diff --git a/camera/libcameraservice/CameraService.h b/camera/libcameraservice/CameraService.h index ea93789..8a49fa6 100644 --- a/camera/libcameraservice/CameraService.h +++ b/camera/libcameraservice/CameraService.h @@ -189,6 +189,10 @@ private: sp<CameraHardwareInterface> mHardware; pid_t mClientPid; bool mUseOverlay; + + sp<OverlayRef> mOverlayRef; + int mOverlayW; + int mOverlayH; }; // ---------------------------------------------------------------------------- diff --git a/include/ui/Overlay.h b/include/ui/Overlay.h index 9ba2f7b..acc9bea 100644 --- a/include/ui/Overlay.h +++ b/include/ui/Overlay.h @@ -82,6 +82,10 @@ public: /* release the overlay buffer and post it */ status_t queueBuffer(overlay_buffer_t buffer); + status_t setCrop(uint32_t x, uint32_t y, uint32_t w, uint32_t h) ; + + status_t getCrop(uint32_t* x, uint32_t* y, uint32_t* w, uint32_t* h) ; + /* returns the address of a given buffer if supported, NULL otherwise. */ void* getBufferAddress(overlay_buffer_t buffer); diff --git a/libs/ui/Overlay.cpp b/libs/ui/Overlay.cpp index a092f8d..4854d6a 100644 --- a/libs/ui/Overlay.cpp +++ b/libs/ui/Overlay.cpp @@ -59,6 +59,18 @@ status_t Overlay::queueBuffer(overlay_buffer_t buffer) return mOverlayData->queueBuffer(mOverlayData, buffer); } +status_t Overlay::setCrop(uint32_t x, uint32_t y, uint32_t w, uint32_t h) +{ + if (mStatus != NO_ERROR) return mStatus; + return mOverlayData->setCrop(mOverlayData, x, y, w, h); +} + +status_t Overlay::getCrop(uint32_t* x, uint32_t* y, uint32_t* w, uint32_t* h) +{ + if (mStatus != NO_ERROR) return mStatus; + return mOverlayData->getCrop(mOverlayData, x, y, w, h); +} + int32_t Overlay::getBufferCount() const { if (mStatus != NO_ERROR) return mStatus; @@ -73,6 +85,15 @@ void* Overlay::getBufferAddress(overlay_buffer_t buffer) void Overlay::destroy() { if (mStatus != NO_ERROR) return; + + // Must delete the objects in reverse creation order, thus the + // data side must be closed first and then the destroy send to + // the control side. + if (mOverlayData) { + overlay_data_close(mOverlayData); + mOverlayData = NULL; + } + mOverlayRef->mOverlayChannel->destroy(); } |