Merge "Add camera service support for SurfaceTexture." into honeycomb
This commit is contained in:
@@ -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();
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user