diff options
author | Jamie Gennis <jgennis@google.com> | 2010-12-20 11:51:31 -0800 |
---|---|---|
committer | Jamie Gennis <jgennis@google.com> | 2011-01-06 13:31:53 -0800 |
commit | bfa33aae4f54c0020a0568b16a3acb7b30b6ca3d (patch) | |
tree | 3dae4190516dcddec996a2b7c51b5f192c3ed4ca /services | |
parent | 5de2001a5c3f854b63dbcea284e02f930881ca75 (diff) | |
download | frameworks_av-bfa33aae4f54c0020a0568b16a3acb7b30b6ca3d.zip frameworks_av-bfa33aae4f54c0020a0568b16a3acb7b30b6ca3d.tar.gz frameworks_av-bfa33aae4f54c0020a0568b16a3acb7b30b6ca3d.tar.bz2 |
Add camera service support for SurfaceTexture.
This change enables the use of a SurfaceTexture in place of a Surface as
the destination of camera preview frames.
Change-Id: Ic70d404c8fe261e9d5da6f1de93d6babb5b191cb
Diffstat (limited to 'services')
-rw-r--r-- | services/camera/libcameraservice/Android.mk | 3 | ||||
-rw-r--r-- | services/camera/libcameraservice/CameraService.cpp | 68 | ||||
-rw-r--r-- | services/camera/libcameraservice/CameraService.h | 4 |
3 files changed, 50 insertions, 25 deletions
diff --git a/services/camera/libcameraservice/Android.mk b/services/camera/libcameraservice/Android.mk index 87975af..b52fc69 100644 --- a/services/camera/libcameraservice/Android.mk +++ b/services/camera/libcameraservice/Android.mk @@ -49,7 +49,8 @@ LOCAL_SHARED_LIBRARIES:= \ libcutils \ libmedia \ libcamera_client \ - libsurfaceflinger_client + libsurfaceflinger_client \ + libgui LOCAL_MODULE:= libcameraservice diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp index 15f6a44..3d8ca7a 100644 --- a/services/camera/libcameraservice/CameraService.cpp +++ b/services/camera/libcameraservice/CameraService.cpp @@ -27,6 +27,7 @@ #include <binder/MemoryHeapBase.h> #include <cutils/atomic.h> #include <cutils/properties.h> +#include <gui/SurfaceTextureClient.h> #include <hardware/hardware.h> #include <media/AudioSystem.h> #include <media/mediaplayer.h> @@ -306,6 +307,8 @@ CameraService::Client::Client(const sp<CameraService>& cameraService, mCameraFacing = cameraFacing; mClientPid = clientPid; mMsgEnabled = 0; + mSurface = 0; + mPreviewWindow = 0; mHardware->setCallbacks(notifyCallback, dataCallback, dataCallbackTimestamp, @@ -470,19 +473,16 @@ status_t CameraService::Client::setPreviewDisplay(const sp<Surface>& surface) { // return if no change in surface. // asBinder() is safe on NULL (returns NULL) - if (getISurface(surface)->asBinder() == mSurface->asBinder()) { + if (getISurface(surface)->asBinder() == mSurface) { return result; } if (mSurface != 0) { LOG1("clearing old preview surface %p", mSurface.get()); } - if (surface != 0) { - mSurface = getISurface(surface); - } else { - mSurface = 0; - } + mSurface = getISurface(surface)->asBinder(); mPreviewWindow = surface; + // If preview has been already started, register preview // buffers now. if (mHardware->previewEnabled()) { @@ -496,6 +496,45 @@ status_t CameraService::Client::setPreviewDisplay(const sp<Surface>& surface) { return result; } +// set the SurfaceTexture that the preview will use +status_t CameraService::Client::setPreviewTexture( + const sp<ISurfaceTexture>& surfaceTexture) { + LOG1("setPreviewTexture(%p) (pid %d)", surfaceTexture.get(), + getCallingPid()); + Mutex::Autolock lock(mLock); + status_t result = checkPidAndHardware(); + if (result != NO_ERROR) return result; + + // return if no change in surface. + // asBinder() is safe on NULL (returns NULL) + if (surfaceTexture->asBinder() == mSurface) { + return result; + } + + if (mSurface != 0) { + LOG1("clearing old preview surface %p", mSurface.get()); + } + mSurface = surfaceTexture->asBinder(); + if (surfaceTexture != 0) { + mPreviewWindow = new SurfaceTextureClient(surfaceTexture); + } else { + mPreviewWindow = 0; + } + + // If preview has been already started, set overlay or register preview + // buffers now. + if (mHardware->previewEnabled()) { + // XXX: What if the new preview window is 0? + if (mPreviewWindow != 0) { + native_window_set_buffers_transform(mPreviewWindow.get(), + mOrientation); + result = mHardware->setPreviewWindow(mPreviewWindow); + } + } + + return result; +} + // set the preview callback flag to affect how the received frames from // preview are handled. void CameraService::Client::setPreviewCallbackFlag(int callback_flag) { @@ -960,23 +999,6 @@ void CameraService::Client::handleShutter(image_rect_type *size) { } 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 (mSurface != 0) { - int w, h; - CameraParameters params(mHardware->getParameters()); - if (size == NULL) { - params.getPictureSize(&w, &h); - } else { - w = size->width; - h = size->height; - w &= ~1; - h &= ~1; - LOG1("Snapshot image width=%d, height=%d", w, h); - } - IPCThreadState::self()->flushCommands(); - } - mLock.unlock(); } diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h index d78d7e5..ccb9cf7 100644 --- a/services/camera/libcameraservice/CameraService.h +++ b/services/camera/libcameraservice/CameraService.h @@ -94,6 +94,7 @@ private: virtual status_t lock(); virtual status_t unlock(); virtual status_t setPreviewDisplay(const sp<Surface>& surface); + virtual status_t setPreviewTexture(const sp<ISurfaceTexture>& surfaceTexture); virtual void setPreviewCallbackFlag(int flag); virtual status_t startPreview(); virtual void stopPreview(); @@ -180,7 +181,8 @@ private: // Ensures atomicity among the public methods mutable Mutex mLock; - sp<ISurface> mSurface; + // This is a binder of Surface or SurfaceTexture. + sp<IBinder> mSurface; sp<ANativeWindow> mPreviewWindow; // If the user want us to return a copy of the preview frame (instead |