diff options
author | Wu-cheng Li <wuchengli@google.com> | 2009-07-01 11:20:08 -0700 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-07-01 11:20:08 -0700 |
commit | 0795684839b60fc5e7edb14c301e7797b6645d05 (patch) | |
tree | 847d9538d5dd290d6cec29a00b3354206521c734 | |
parent | 9fa8914eac00fb4ecc68371824a4b1b47466c225 (diff) | |
parent | b8a10fe45657f2dcc50cae8a06805f8438a6937e (diff) | |
download | frameworks_base-0795684839b60fc5e7edb14c301e7797b6645d05.zip frameworks_base-0795684839b60fc5e7edb14c301e7797b6645d05.tar.gz frameworks_base-0795684839b60fc5e7edb14c301e7797b6645d05.tar.bz2 |
am b8a10fe4: Allow setPreviewDisplay after startPreview.
Merge commit 'b8a10fe45657f2dcc50cae8a06805f8438a6937e'
* commit 'b8a10fe45657f2dcc50cae8a06805f8438a6937e':
Allow setPreviewDisplay after startPreview.
-rw-r--r-- | camera/libcameraservice/CameraService.cpp | 139 | ||||
-rw-r--r-- | camera/libcameraservice/CameraService.h | 2 | ||||
-rw-r--r-- | core/java/android/hardware/Camera.java | 6 | ||||
-rw-r--r-- | core/jni/android_hardware_Camera.cpp | 5 | ||||
-rw-r--r-- | libs/ui/Camera.cpp | 16 |
5 files changed, 108 insertions, 60 deletions
diff --git a/camera/libcameraservice/CameraService.cpp b/camera/libcameraservice/CameraService.cpp index d8ca525..030d887 100644 --- a/camera/libcameraservice/CameraService.cpp +++ b/camera/libcameraservice/CameraService.cpp @@ -410,11 +410,14 @@ void CameraService::Client::disconnect() // pass the buffered ISurface to the camera service 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); status_t result = checkPid(); if (result != NO_ERROR) return result; + Mutex::Autolock surfaceLock(mSurfaceLock); + result = NO_ERROR; // asBinder() is safe on NULL (returns NULL) if (surface->asBinder() != mSurface->asBinder()) { if (mSurface != 0 && !mUseOverlay) { @@ -422,8 +425,17 @@ status_t CameraService::Client::setPreviewDisplay(const sp<ISurface>& surface) mSurface->unregisterBuffers(); } 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 @@ -436,7 +448,7 @@ void CameraService::Client::setPreviewCallbackFlag(int callback_flag) mPreviewCallbackFlag = callback_flag; } -// start preview mode, must call setPreviewDisplay first +// start preview mode status_t CameraService::Client::startCameraMode(camera_mode mode) { int callingPid = getCallingPid(); @@ -456,16 +468,18 @@ status_t CameraService::Client::startCameraMode(camera_mode mode) return INVALID_OPERATION; } - if (mSurface == 0) { - LOGE("setPreviewDisplay must be called before startCameraMode!"); - return INVALID_OPERATION; - } - switch(mode) { case CAMERA_RECORDING_MODE: + if (mSurface == 0) { + LOGE("setPreviewDisplay must be called before startRecordingMode."); + return INVALID_OPERATION; + } return startRecordingMode(); default: // CAMERA_PREVIEW_MODE + if (mSurface == 0) { + LOGD("mSurface is not set yet."); + } return startPreviewMode(); } } @@ -498,6 +512,62 @@ status_t CameraService::Client::startRecordingMode() return ret; } +status_t CameraService::Client::setOverlay() +{ + LOGD("setOverlay"); + int w, h; + CameraParameters params(mHardware->getParameters()); + params.getPreviewSize(&w, &h); + + const char *format = params.getPreviewFormat(); + int fmt; + if (!strcmp(format, "yuv422i")) + fmt = OVERLAY_FORMAT_YCbCr_422_I; + else if (!strcmp(format, "rgb565")) + fmt = OVERLAY_FORMAT_RGB_565; + else { + LOGE("Invalid preview format for overlays"); + return -EINVAL; + } + + status_t ret = NO_ERROR; + if (mSurface != 0) { + sp<OverlayRef> ref = mSurface->createOverlay(w, h, fmt); + ret = mHardware->setOverlay(new Overlay(ref)); + } else { + ret = mHardware->setOverlay(NULL); + } + if (ret != NO_ERROR) { + LOGE("mHardware->setOverlay() failed with status %d\n", ret); + } + return ret; +} + +status_t CameraService::Client::registerPreviewBuffers() +{ + int w, h; + CameraParameters params(mHardware->getParameters()); + params.getPreviewSize(&w, &h); + + uint32_t transform = 0; + if (params.getOrientation() == + CameraParameters::CAMERA_ORIENTATION_PORTRAIT) { + LOGV("portrait mode"); + transform = ISurface::BufferHeap::ROT_90; + } + ISurface::BufferHeap buffers(w, h, w, h, + PIXEL_FORMAT_YCbCr_420_SP, + transform, + 0, + mHardware->getPreviewHeap()); + + 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()); @@ -511,55 +581,24 @@ status_t CameraService::Client::startPreviewMode() #if DEBUG_DUMP_PREVIEW_FRAME_TO_FILE debug_frame_cnt = 0; #endif - status_t ret = UNKNOWN_ERROR; - int w, h; - CameraParameters params(mHardware->getParameters()); - params.getPreviewSize(&w, &h); + status_t ret = NO_ERROR; if (mUseOverlay) { - const char *format = params.getPreviewFormat(); - int fmt; - LOGD("Use Overlays"); - if (!strcmp(format, "yuv422i")) - fmt = OVERLAY_FORMAT_YCbCr_422_I; - else if (!strcmp(format, "rgb565")) - fmt = OVERLAY_FORMAT_RGB_565; - else { - LOGE("Invalid preview format for overlays"); - return -EINVAL; - } - sp<OverlayRef> ref = mSurface->createOverlay(w, h, fmt); - ret = mHardware->setOverlay(new Overlay(ref)); - if (ret != NO_ERROR) { - LOGE("mHardware->setOverlay() failed with status %d\n", ret); - return ret; + // 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()); - if (ret != NO_ERROR) - LOGE("mHardware->startPreview() failed with status %d\n", ret); - } else { ret = mHardware->startPreview(previewCallback, mCameraService.get()); - if (ret == NO_ERROR) { - - mSurface->unregisterBuffers(); - - uint32_t transform = 0; - if (params.getOrientation() == - CameraParameters::CAMERA_ORIENTATION_PORTRAIT) { - LOGV("portrait mode"); - transform = ISurface::BufferHeap::ROT_90; - } - ISurface::BufferHeap buffers(w, h, w, h, - PIXEL_FORMAT_YCbCr_420_SP, - transform, - 0, - mHardware->getPreviewHeap()); - - mSurface->registerBuffers(buffers); - } else { - LOGE("mHardware->startPreview() failed with status %d", ret); + 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; diff --git a/camera/libcameraservice/CameraService.h b/camera/libcameraservice/CameraService.h index 8b8b54c..0f07673 100644 --- a/camera/libcameraservice/CameraService.h +++ b/camera/libcameraservice/CameraService.h @@ -157,6 +157,8 @@ private: status_t startCameraMode(camera_mode mode); status_t startPreviewMode(); status_t startRecordingMode(); + status_t setOverlay(); + status_t registerPreviewBuffers(); // Ensures atomicity among the public methods mutable Mutex mLock; diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java index 09fbc97..3ce951f 100644 --- a/core/java/android/hardware/Camera.java +++ b/core/java/android/hardware/Camera.java @@ -155,7 +155,11 @@ public class Camera { * @throws IOException if the method fails. */ public final void setPreviewDisplay(SurfaceHolder holder) throws IOException { - setPreviewDisplay(holder.getSurface()); + if (holder != null) { + setPreviewDisplay(holder.getSurface()); + } else { + setPreviewDisplay((Surface)null); + } } private native final void setPreviewDisplay(Surface surface); diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp index 4955dc6..075caae 100644 --- a/core/jni/android_hardware_Camera.cpp +++ b/core/jni/android_hardware_Camera.cpp @@ -262,7 +262,10 @@ static void android_hardware_Camera_setPreviewDisplay(JNIEnv *env, jobject thiz, sp<Camera> camera = get_native_camera(env, thiz, NULL); 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) { jniThrowException(env, "java/io/IOException", "setPreviewDisplay failed"); } diff --git a/libs/ui/Camera.cpp b/libs/ui/Camera.cpp index 33b99b9..a72d2c9 100644 --- a/libs/ui/Camera.cpp +++ b/libs/ui/Camera.cpp @@ -149,21 +149,21 @@ status_t Camera::unlock() status_t Camera::setPreviewDisplay(const sp<Surface>& surface) { LOGV("setPreviewDisplay"); - if (surface == 0) { - LOGE("app passed NULL surface"); - return NO_INIT; - } sp <ICamera> c = mCamera; if (c == 0) return NO_INIT; - return c->setPreviewDisplay(surface->getISurface()); + if (surface != 0) { + return c->setPreviewDisplay(surface->getISurface()); + } else { + LOGD("app passed NULL surface"); + return c->setPreviewDisplay(0); + } } status_t Camera::setPreviewDisplay(const sp<ISurface>& surface) { LOGV("setPreviewDisplay"); if (surface == 0) { - LOGE("app passed NULL surface"); - return NO_INIT; + LOGD("app passed NULL surface"); } sp <ICamera> c = mCamera; 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() { LOGV("startPreview"); |