Allow setPreviewDisplay after startPreview.
This commit is contained in:
@ -410,11 +410,14 @@ void CameraService::Client::disconnect()
|
|||||||
// pass the buffered ISurface to the camera service
|
// pass the buffered ISurface to the camera service
|
||||||
status_t CameraService::Client::setPreviewDisplay(const sp<ISurface>& surface)
|
status_t CameraService::Client::setPreviewDisplay(const sp<ISurface>& surface)
|
||||||
{
|
{
|
||||||
LOGD("setPreviewDisplay(%p) (pid %d)", surface.get(), getCallingPid());
|
LOGD("setPreviewDisplay(%p) (pid %d)",
|
||||||
|
((surface == NULL) ? NULL : surface.get()), getCallingPid());
|
||||||
Mutex::Autolock lock(mLock);
|
Mutex::Autolock lock(mLock);
|
||||||
status_t result = checkPid();
|
status_t result = checkPid();
|
||||||
if (result != NO_ERROR) return result;
|
if (result != NO_ERROR) return result;
|
||||||
|
|
||||||
Mutex::Autolock surfaceLock(mSurfaceLock);
|
Mutex::Autolock surfaceLock(mSurfaceLock);
|
||||||
|
result = NO_ERROR;
|
||||||
// asBinder() is safe on NULL (returns NULL)
|
// asBinder() is safe on NULL (returns NULL)
|
||||||
if (surface->asBinder() != mSurface->asBinder()) {
|
if (surface->asBinder() != mSurface->asBinder()) {
|
||||||
if (mSurface != 0 && !mUseOverlay) {
|
if (mSurface != 0 && !mUseOverlay) {
|
||||||
@ -422,8 +425,17 @@ status_t CameraService::Client::setPreviewDisplay(const sp<ISurface>& surface)
|
|||||||
mSurface->unregisterBuffers();
|
mSurface->unregisterBuffers();
|
||||||
}
|
}
|
||||||
mSurface = surface;
|
mSurface = surface;
|
||||||
|
// If preview has been already started, set overlay or register preview
|
||||||
|
// buffers now.
|
||||||
|
if (mHardware->previewEnabled()) {
|
||||||
|
if (mUseOverlay) {
|
||||||
|
result = setOverlay();
|
||||||
|
} else if (mSurface != 0) {
|
||||||
|
result = registerPreviewBuffers();
|
||||||
}
|
}
|
||||||
return NO_ERROR;
|
}
|
||||||
|
}
|
||||||
|
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
|
||||||
@ -436,7 +448,7 @@ void CameraService::Client::setPreviewCallbackFlag(int callback_flag)
|
|||||||
mPreviewCallbackFlag = callback_flag;
|
mPreviewCallbackFlag = callback_flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
// start preview mode, must call setPreviewDisplay first
|
// start preview mode
|
||||||
status_t CameraService::Client::startCameraMode(camera_mode mode)
|
status_t CameraService::Client::startCameraMode(camera_mode mode)
|
||||||
{
|
{
|
||||||
int callingPid = getCallingPid();
|
int callingPid = getCallingPid();
|
||||||
@ -456,16 +468,18 @@ status_t CameraService::Client::startCameraMode(camera_mode mode)
|
|||||||
return INVALID_OPERATION;
|
return INVALID_OPERATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mSurface == 0) {
|
|
||||||
LOGE("setPreviewDisplay must be called before startCameraMode!");
|
|
||||||
return INVALID_OPERATION;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(mode) {
|
switch(mode) {
|
||||||
case CAMERA_RECORDING_MODE:
|
case CAMERA_RECORDING_MODE:
|
||||||
|
if (mSurface == 0) {
|
||||||
|
LOGE("setPreviewDisplay must be called before startRecordingMode.");
|
||||||
|
return INVALID_OPERATION;
|
||||||
|
}
|
||||||
return startRecordingMode();
|
return startRecordingMode();
|
||||||
|
|
||||||
default: // CAMERA_PREVIEW_MODE
|
default: // CAMERA_PREVIEW_MODE
|
||||||
|
if (mSurface == 0) {
|
||||||
|
LOGD("mSurface is not set yet.");
|
||||||
|
}
|
||||||
return startPreviewMode();
|
return startPreviewMode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -498,28 +512,15 @@ status_t CameraService::Client::startRecordingMode()
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t CameraService::Client::startPreviewMode()
|
status_t CameraService::Client::setOverlay()
|
||||||
{
|
{
|
||||||
LOGD("startPreviewMode (pid %d)", getCallingPid());
|
LOGD("setOverlay");
|
||||||
|
|
||||||
// if preview has been enabled, nothing needs to be done
|
|
||||||
if (mHardware->previewEnabled()) {
|
|
||||||
return NO_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
// start preview mode
|
|
||||||
#if DEBUG_DUMP_PREVIEW_FRAME_TO_FILE
|
|
||||||
debug_frame_cnt = 0;
|
|
||||||
#endif
|
|
||||||
status_t ret = UNKNOWN_ERROR;
|
|
||||||
int w, h;
|
int w, h;
|
||||||
CameraParameters params(mHardware->getParameters());
|
CameraParameters params(mHardware->getParameters());
|
||||||
params.getPreviewSize(&w, &h);
|
params.getPreviewSize(&w, &h);
|
||||||
|
|
||||||
if (mUseOverlay) {
|
|
||||||
const char *format = params.getPreviewFormat();
|
const char *format = params.getPreviewFormat();
|
||||||
int fmt;
|
int fmt;
|
||||||
LOGD("Use Overlays");
|
|
||||||
if (!strcmp(format, "yuv422i"))
|
if (!strcmp(format, "yuv422i"))
|
||||||
fmt = OVERLAY_FORMAT_YCbCr_422_I;
|
fmt = OVERLAY_FORMAT_YCbCr_422_I;
|
||||||
else if (!strcmp(format, "rgb565"))
|
else if (!strcmp(format, "rgb565"))
|
||||||
@ -528,22 +529,25 @@ status_t CameraService::Client::startPreviewMode()
|
|||||||
LOGE("Invalid preview format for overlays");
|
LOGE("Invalid preview format for overlays");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status_t ret = NO_ERROR;
|
||||||
|
if (mSurface != 0) {
|
||||||
sp<OverlayRef> ref = mSurface->createOverlay(w, h, fmt);
|
sp<OverlayRef> ref = mSurface->createOverlay(w, h, fmt);
|
||||||
ret = mHardware->setOverlay(new Overlay(ref));
|
ret = mHardware->setOverlay(new Overlay(ref));
|
||||||
|
} else {
|
||||||
|
ret = mHardware->setOverlay(NULL);
|
||||||
|
}
|
||||||
if (ret != NO_ERROR) {
|
if (ret != NO_ERROR) {
|
||||||
LOGE("mHardware->setOverlay() failed with status %d\n", ret);
|
LOGE("mHardware->setOverlay() failed with status %d\n", ret);
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
ret = mHardware->startPreview(NULL, mCameraService.get());
|
return ret;
|
||||||
if (ret != NO_ERROR)
|
}
|
||||||
LOGE("mHardware->startPreview() failed with status %d\n", ret);
|
|
||||||
|
|
||||||
} else {
|
status_t CameraService::Client::registerPreviewBuffers()
|
||||||
ret = mHardware->startPreview(previewCallback,
|
{
|
||||||
mCameraService.get());
|
int w, h;
|
||||||
if (ret == NO_ERROR) {
|
CameraParameters params(mHardware->getParameters());
|
||||||
|
params.getPreviewSize(&w, &h);
|
||||||
mSurface->unregisterBuffers();
|
|
||||||
|
|
||||||
uint32_t transform = 0;
|
uint32_t transform = 0;
|
||||||
if (params.getOrientation() ==
|
if (params.getOrientation() ==
|
||||||
@ -557,9 +561,44 @@ status_t CameraService::Client::startPreviewMode()
|
|||||||
0,
|
0,
|
||||||
mHardware->getPreviewHeap());
|
mHardware->getPreviewHeap());
|
||||||
|
|
||||||
mSurface->registerBuffers(buffers);
|
status_t ret = mSurface->registerBuffers(buffers);
|
||||||
|
if (ret != NO_ERROR) {
|
||||||
|
LOGE("registerBuffers failed with status %d", ret);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
status_t CameraService::Client::startPreviewMode()
|
||||||
|
{
|
||||||
|
LOGD("startPreviewMode (pid %d)", getCallingPid());
|
||||||
|
|
||||||
|
// if preview has been enabled, nothing needs to be done
|
||||||
|
if (mHardware->previewEnabled()) {
|
||||||
|
return NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// start preview mode
|
||||||
|
#if DEBUG_DUMP_PREVIEW_FRAME_TO_FILE
|
||||||
|
debug_frame_cnt = 0;
|
||||||
|
#endif
|
||||||
|
status_t ret = NO_ERROR;
|
||||||
|
|
||||||
|
if (mUseOverlay) {
|
||||||
|
// If preview display has been set, set overlay now.
|
||||||
|
if (mSurface != 0) {
|
||||||
|
ret = setOverlay();
|
||||||
|
}
|
||||||
|
if (ret != NO_ERROR) return ret;
|
||||||
|
ret = mHardware->startPreview(NULL, mCameraService.get());
|
||||||
} else {
|
} else {
|
||||||
LOGE("mHardware->startPreview() failed with status %d", ret);
|
ret = mHardware->startPreview(previewCallback,
|
||||||
|
mCameraService.get());
|
||||||
|
if (ret != NO_ERROR) return ret;
|
||||||
|
// If preview display has been set, register preview buffers now.
|
||||||
|
if (mSurface != 0) {
|
||||||
|
// Unregister here because the surface registered with raw heap.
|
||||||
|
mSurface->unregisterBuffers();
|
||||||
|
ret = registerPreviewBuffers();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -157,6 +157,8 @@ private:
|
|||||||
status_t startCameraMode(camera_mode mode);
|
status_t startCameraMode(camera_mode mode);
|
||||||
status_t startPreviewMode();
|
status_t startPreviewMode();
|
||||||
status_t startRecordingMode();
|
status_t startRecordingMode();
|
||||||
|
status_t setOverlay();
|
||||||
|
status_t registerPreviewBuffers();
|
||||||
|
|
||||||
// Ensures atomicity among the public methods
|
// Ensures atomicity among the public methods
|
||||||
mutable Mutex mLock;
|
mutable Mutex mLock;
|
||||||
|
@ -155,7 +155,11 @@ public class Camera {
|
|||||||
* @throws IOException if the method fails.
|
* @throws IOException if the method fails.
|
||||||
*/
|
*/
|
||||||
public final void setPreviewDisplay(SurfaceHolder holder) throws IOException {
|
public final void setPreviewDisplay(SurfaceHolder holder) throws IOException {
|
||||||
|
if (holder != null) {
|
||||||
setPreviewDisplay(holder.getSurface());
|
setPreviewDisplay(holder.getSurface());
|
||||||
|
} else {
|
||||||
|
setPreviewDisplay((Surface)null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private native final void setPreviewDisplay(Surface surface);
|
private native final void setPreviewDisplay(Surface surface);
|
||||||
|
@ -262,7 +262,10 @@ static void android_hardware_Camera_setPreviewDisplay(JNIEnv *env, jobject thiz,
|
|||||||
sp<Camera> camera = get_native_camera(env, thiz, NULL);
|
sp<Camera> camera = get_native_camera(env, thiz, NULL);
|
||||||
if (camera == 0) return;
|
if (camera == 0) return;
|
||||||
|
|
||||||
sp<Surface> surface = reinterpret_cast<Surface*>(env->GetIntField(jSurface, fields.surface));
|
sp<Surface> surface = NULL;
|
||||||
|
if (jSurface != NULL) {
|
||||||
|
surface = reinterpret_cast<Surface*>(env->GetIntField(jSurface, fields.surface));
|
||||||
|
}
|
||||||
if (camera->setPreviewDisplay(surface) != NO_ERROR) {
|
if (camera->setPreviewDisplay(surface) != NO_ERROR) {
|
||||||
jniThrowException(env, "java/io/IOException", "setPreviewDisplay failed");
|
jniThrowException(env, "java/io/IOException", "setPreviewDisplay failed");
|
||||||
}
|
}
|
||||||
|
@ -149,21 +149,21 @@ status_t Camera::unlock()
|
|||||||
status_t Camera::setPreviewDisplay(const sp<Surface>& surface)
|
status_t Camera::setPreviewDisplay(const sp<Surface>& surface)
|
||||||
{
|
{
|
||||||
LOGV("setPreviewDisplay");
|
LOGV("setPreviewDisplay");
|
||||||
if (surface == 0) {
|
|
||||||
LOGE("app passed NULL surface");
|
|
||||||
return NO_INIT;
|
|
||||||
}
|
|
||||||
sp <ICamera> c = mCamera;
|
sp <ICamera> c = mCamera;
|
||||||
if (c == 0) return NO_INIT;
|
if (c == 0) return NO_INIT;
|
||||||
|
if (surface != 0) {
|
||||||
return c->setPreviewDisplay(surface->getISurface());
|
return c->setPreviewDisplay(surface->getISurface());
|
||||||
|
} else {
|
||||||
|
LOGD("app passed NULL surface");
|
||||||
|
return c->setPreviewDisplay(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t Camera::setPreviewDisplay(const sp<ISurface>& surface)
|
status_t Camera::setPreviewDisplay(const sp<ISurface>& surface)
|
||||||
{
|
{
|
||||||
LOGV("setPreviewDisplay");
|
LOGV("setPreviewDisplay");
|
||||||
if (surface == 0) {
|
if (surface == 0) {
|
||||||
LOGE("app passed NULL surface");
|
LOGD("app passed NULL surface");
|
||||||
return NO_INIT;
|
|
||||||
}
|
}
|
||||||
sp <ICamera> c = mCamera;
|
sp <ICamera> c = mCamera;
|
||||||
if (c == 0) return NO_INIT;
|
if (c == 0) return NO_INIT;
|
||||||
@ -171,7 +171,7 @@ status_t Camera::setPreviewDisplay(const sp<ISurface>& surface)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// start preview mode, must call setPreviewDisplay first
|
// start preview mode
|
||||||
status_t Camera::startPreview()
|
status_t Camera::startPreview()
|
||||||
{
|
{
|
||||||
LOGV("startPreview");
|
LOGV("startPreview");
|
||||||
|
Reference in New Issue
Block a user