am 478353e2: Merge "Add camera service support for SurfaceTexture." into honeycomb

* commit '478353e23188cdd6f3dd3674f122b50ec37438b4':
  Add camera service support for SurfaceTexture.
This commit is contained in:
Jamie Gennis
2011-01-07 00:27:24 -08:00
committed by Android Git Automerger
8 changed files with 95 additions and 26 deletions

View File

@@ -19,6 +19,7 @@
#include <utils/Timers.h> #include <utils/Timers.h>
#include <camera/ICameraClient.h> #include <camera/ICameraClient.h>
#include <gui/ISurfaceTexture.h>
namespace android { namespace android {
@@ -175,6 +176,9 @@ public:
// pass the buffered Surface to the camera service // pass the buffered Surface to the camera service
status_t setPreviewDisplay(const sp<Surface>& surface); 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 // start preview mode, must call setPreviewDisplay first
status_t startPreview(); status_t startPreview();

View File

@@ -24,6 +24,7 @@
#include <binder/IMemory.h> #include <binder/IMemory.h>
#include <utils/String8.h> #include <utils/String8.h>
#include <camera/Camera.h> #include <camera/Camera.h>
#include <gui/ISurfaceTexture.h>
namespace android { namespace android {
@@ -48,6 +49,10 @@ public:
// pass the buffered Surface to the camera service // pass the buffered Surface to the camera service
virtual status_t setPreviewDisplay(const sp<Surface>& surface) = 0; 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 // set the preview callback flag to affect how the received frames from
// preview are handled. // preview are handled.
virtual void setPreviewCallbackFlag(int flag) = 0; virtual void setPreviewCallbackFlag(int flag) = 0;

View File

@@ -14,7 +14,8 @@ LOCAL_SHARED_LIBRARIES := \
libbinder \ libbinder \
libhardware \ libhardware \
libsurfaceflinger_client \ libsurfaceflinger_client \
libui libui \
libgui
LOCAL_MODULE:= libcamera_client LOCAL_MODULE:= libcamera_client

View File

@@ -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 // start preview mode
status_t Camera::startPreview() status_t Camera::startPreview()
{ {

View File

@@ -28,6 +28,7 @@ namespace android {
enum { enum {
DISCONNECT = IBinder::FIRST_CALL_TRANSACTION, DISCONNECT = IBinder::FIRST_CALL_TRANSACTION,
SET_PREVIEW_DISPLAY, SET_PREVIEW_DISPLAY,
SET_PREVIEW_TEXTURE,
SET_PREVIEW_CALLBACK_FLAG, SET_PREVIEW_CALLBACK_FLAG,
START_PREVIEW, START_PREVIEW,
STOP_PREVIEW, STOP_PREVIEW,
@@ -78,6 +79,18 @@ public:
return reply.readInt32(); 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 // set the preview callback flag to affect how the received frames from
// preview are handled. See Camera.h for details. // preview are handled. See Camera.h for details.
void setPreviewCallbackFlag(int flag) void setPreviewCallbackFlag(int flag)
@@ -296,6 +309,13 @@ status_t BnCamera::onTransact(
reply->writeInt32(setPreviewDisplay(surface)); reply->writeInt32(setPreviewDisplay(surface));
return NO_ERROR; return NO_ERROR;
} break; } 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: { case SET_PREVIEW_CALLBACK_FLAG: {
LOGV("SET_PREVIEW_CALLBACK_TYPE"); LOGV("SET_PREVIEW_CALLBACK_TYPE");
CHECK_INTERFACE(ICamera, data, reply); CHECK_INTERFACE(ICamera, data, reply);

View File

@@ -49,7 +49,8 @@ LOCAL_SHARED_LIBRARIES:= \
libcutils \ libcutils \
libmedia \ libmedia \
libcamera_client \ libcamera_client \
libsurfaceflinger_client libsurfaceflinger_client \
libgui
LOCAL_MODULE:= libcameraservice LOCAL_MODULE:= libcameraservice

View File

@@ -27,6 +27,7 @@
#include <binder/MemoryHeapBase.h> #include <binder/MemoryHeapBase.h>
#include <cutils/atomic.h> #include <cutils/atomic.h>
#include <cutils/properties.h> #include <cutils/properties.h>
#include <gui/SurfaceTextureClient.h>
#include <hardware/hardware.h> #include <hardware/hardware.h>
#include <media/AudioSystem.h> #include <media/AudioSystem.h>
#include <media/mediaplayer.h> #include <media/mediaplayer.h>
@@ -306,6 +307,8 @@ CameraService::Client::Client(const sp<CameraService>& cameraService,
mCameraFacing = cameraFacing; mCameraFacing = cameraFacing;
mClientPid = clientPid; mClientPid = clientPid;
mMsgEnabled = 0; mMsgEnabled = 0;
mSurface = 0;
mPreviewWindow = 0;
mHardware->setCallbacks(notifyCallback, mHardware->setCallbacks(notifyCallback,
dataCallback, dataCallback,
dataCallbackTimestamp, dataCallbackTimestamp,
@@ -470,19 +473,16 @@ status_t CameraService::Client::setPreviewDisplay(const sp<Surface>& surface) {
// return if no change in surface. // return if no change in surface.
// asBinder() is safe on NULL (returns NULL) // asBinder() is safe on NULL (returns NULL)
if (getISurface(surface)->asBinder() == mSurface->asBinder()) { if (getISurface(surface)->asBinder() == mSurface) {
return result; return result;
} }
if (mSurface != 0) { if (mSurface != 0) {
LOG1("clearing old preview surface %p", mSurface.get()); LOG1("clearing old preview surface %p", mSurface.get());
} }
if (surface != 0) { mSurface = getISurface(surface)->asBinder();
mSurface = getISurface(surface);
} else {
mSurface = 0;
}
mPreviewWindow = surface; mPreviewWindow = surface;
// If preview has been already started, register preview // If preview has been already started, register preview
// buffers now. // buffers now.
if (mHardware->previewEnabled()) { if (mHardware->previewEnabled()) {
@@ -496,6 +496,45 @@ status_t CameraService::Client::setPreviewDisplay(const sp<Surface>& surface) {
return result; 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 // set the preview callback flag to affect how the received frames from
// preview are handled. // preview are handled.
void CameraService::Client::setPreviewCallbackFlag(int callback_flag) { void CameraService::Client::setPreviewCallbackFlag(int callback_flag) {
@@ -960,23 +999,6 @@ void CameraService::Client::handleShutter(image_rect_type *size) {
} }
disableMsgType(CAMERA_MSG_SHUTTER); 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(); mLock.unlock();
} }

View File

@@ -94,6 +94,7 @@ private:
virtual status_t lock(); virtual status_t lock();
virtual status_t unlock(); virtual status_t unlock();
virtual status_t setPreviewDisplay(const sp<Surface>& surface); virtual status_t setPreviewDisplay(const sp<Surface>& surface);
virtual status_t setPreviewTexture(const sp<ISurfaceTexture>& surfaceTexture);
virtual void setPreviewCallbackFlag(int flag); virtual void setPreviewCallbackFlag(int flag);
virtual status_t startPreview(); virtual status_t startPreview();
virtual void stopPreview(); virtual void stopPreview();
@@ -180,7 +181,8 @@ private:
// Ensures atomicity among the public methods // Ensures atomicity among the public methods
mutable Mutex mLock; mutable Mutex mLock;
sp<ISurface> mSurface; // This is a binder of Surface or SurfaceTexture.
sp<IBinder> mSurface;
sp<ANativeWindow> mPreviewWindow; sp<ANativeWindow> mPreviewWindow;
// If the user want us to return a copy of the preview frame (instead // If the user want us to return a copy of the preview frame (instead