summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenny Wong <Benny.Wong@motorola.com>2009-07-15 18:44:27 -0500
committerRebecca Schultz Zavin <rebecca@android.com>2009-07-16 14:31:20 -0700
commit6d2090e2148996f98a5e9bc7e359e41c226f4efb (patch)
treef585f655447a5df7b791fe01f26b97c836cc5014
parentf47042614e80891a3439d418e7061f642d9d593d (diff)
downloadframeworks_base-6d2090e2148996f98a5e9bc7e359e41c226f4efb.zip
frameworks_base-6d2090e2148996f98a5e9bc7e359e41c226f4efb.tar.gz
frameworks_base-6d2090e2148996f98a5e9bc7e359e41c226f4efb.tar.bz2
Hardware overlay support
Enable hardware overlay support for camera and video playback use cases
-rw-r--r--camera/libcameraservice/CameraService.cpp49
-rw-r--r--camera/libcameraservice/CameraService.h4
-rw-r--r--include/ui/Overlay.h4
-rw-r--r--libs/ui/Overlay.cpp21
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();
}