summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJamie Gennis <jgennis@google.com>2010-12-20 11:51:31 -0800
committerJamie Gennis <jgennis@google.com>2011-01-06 13:31:53 -0800
commitbfa33aae4f54c0020a0568b16a3acb7b30b6ca3d (patch)
tree3dae4190516dcddec996a2b7c51b5f192c3ed4ca
parent5de2001a5c3f854b63dbcea284e02f930881ca75 (diff)
downloadframeworks_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
-rw-r--r--camera/Android.mk3
-rw-r--r--camera/Camera.cpp14
-rw-r--r--camera/ICamera.cpp20
-rw-r--r--include/camera/Camera.h4
-rw-r--r--include/camera/ICamera.h5
-rw-r--r--services/camera/libcameraservice/Android.mk3
-rw-r--r--services/camera/libcameraservice/CameraService.cpp68
-rw-r--r--services/camera/libcameraservice/CameraService.h4
8 files changed, 95 insertions, 26 deletions
diff --git a/camera/Android.mk b/camera/Android.mk
index 03ff229..2f16923 100644
--- a/camera/Android.mk
+++ b/camera/Android.mk
@@ -14,7 +14,8 @@ LOCAL_SHARED_LIBRARIES := \
libbinder \
libhardware \
libsurfaceflinger_client \
- libui
+ libui \
+ libgui
LOCAL_MODULE:= libcamera_client
diff --git a/camera/Camera.cpp b/camera/Camera.cpp
index ab626ad..907f119 100644
--- a/camera/Camera.cpp
+++ b/camera/Camera.cpp
@@ -182,6 +182,20 @@ status_t Camera::setPreviewDisplay(const sp<Surface>& surface)
}
}
+// pass the buffered ISurfaceTexture to the camera service
+status_t Camera::setPreviewTexture(const sp<ISurfaceTexture>& surfaceTexture)
+{
+ LOGV("setPreviewTexture(%p)", surfaceTexture.get());
+ sp <ICamera> c = mCamera;
+ if (c == 0) return NO_INIT;
+ if (surfaceTexture != 0) {
+ return c->setPreviewTexture(surfaceTexture);
+ } else {
+ LOGD("app passed NULL surface");
+ return c->setPreviewTexture(0);
+ }
+}
+
// start preview mode
status_t Camera::startPreview()
{
diff --git a/camera/ICamera.cpp b/camera/ICamera.cpp
index 7ba8d12..0881d65 100644
--- a/camera/ICamera.cpp
+++ b/camera/ICamera.cpp
@@ -28,6 +28,7 @@ namespace android {
enum {
DISCONNECT = IBinder::FIRST_CALL_TRANSACTION,
SET_PREVIEW_DISPLAY,
+ SET_PREVIEW_TEXTURE,
SET_PREVIEW_CALLBACK_FLAG,
START_PREVIEW,
STOP_PREVIEW,
@@ -78,6 +79,18 @@ public:
return reply.readInt32();
}
+ // pass the buffered SurfaceTexture to the camera service
+ status_t setPreviewTexture(const sp<ISurfaceTexture>& surfaceTexture)
+ {
+ LOGV("setPreviewTexture");
+ Parcel data, reply;
+ data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
+ sp<IBinder> b(surfaceTexture->asBinder());
+ data.writeStrongBinder(b);
+ remote()->transact(SET_PREVIEW_TEXTURE, data, &reply);
+ return reply.readInt32();
+ }
+
// set the preview callback flag to affect how the received frames from
// preview are handled. See Camera.h for details.
void setPreviewCallbackFlag(int flag)
@@ -296,6 +309,13 @@ status_t BnCamera::onTransact(
reply->writeInt32(setPreviewDisplay(surface));
return NO_ERROR;
} break;
+ case SET_PREVIEW_TEXTURE: {
+ LOGV("SET_PREVIEW_TEXTURE");
+ CHECK_INTERFACE(ICamera, data, reply);
+ sp<ISurfaceTexture> st = interface_cast<ISurfaceTexture>(data.readStrongBinder());
+ reply->writeInt32(setPreviewTexture(st));
+ return NO_ERROR;
+ } break;
case SET_PREVIEW_CALLBACK_FLAG: {
LOGV("SET_PREVIEW_CALLBACK_TYPE");
CHECK_INTERFACE(ICamera, data, reply);
diff --git a/include/camera/Camera.h b/include/camera/Camera.h
index c95f31e..e5f7e62 100644
--- a/include/camera/Camera.h
+++ b/include/camera/Camera.h
@@ -19,6 +19,7 @@
#include <utils/Timers.h>
#include <camera/ICameraClient.h>
+#include <gui/ISurfaceTexture.h>
namespace android {
@@ -175,6 +176,9 @@ public:
// pass the buffered Surface to the camera service
status_t setPreviewDisplay(const sp<Surface>& surface);
+ // pass the buffered ISurfaceTexture to the camera service
+ status_t setPreviewTexture(const sp<ISurfaceTexture>& surfaceTexture);
+
// start preview mode, must call setPreviewDisplay first
status_t startPreview();
diff --git a/include/camera/ICamera.h b/include/camera/ICamera.h
index b69e075..b2310a6 100644
--- a/include/camera/ICamera.h
+++ b/include/camera/ICamera.h
@@ -24,6 +24,7 @@
#include <binder/IMemory.h>
#include <utils/String8.h>
#include <camera/Camera.h>
+#include <gui/ISurfaceTexture.h>
namespace android {
@@ -48,6 +49,10 @@ public:
// pass the buffered Surface to the camera service
virtual status_t setPreviewDisplay(const sp<Surface>& surface) = 0;
+ // pass the buffered ISurfaceTexture to the camera service
+ virtual status_t setPreviewTexture(
+ const sp<ISurfaceTexture>& surfaceTexture) = 0;
+
// set the preview callback flag to affect how the received frames from
// preview are handled.
virtual void setPreviewCallbackFlag(int flag) = 0;
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