diff options
| author | Wu-cheng Li <wuchengli@google.com> | 2009-06-23 23:37:36 +0800 | 
|---|---|---|
| committer | Wu-cheng Li <wuchengli@google.com> | 2009-07-01 01:41:25 +0800 | 
| commit | b8a10fe45657f2dcc50cae8a06805f8438a6937e (patch) | |
| tree | 4391154a42118f9872199fa4467f966c623e29a5 | |
| parent | 33a7030f56d83126baa656820bf884ea02772751 (diff) | |
| download | frameworks_base-b8a10fe45657f2dcc50cae8a06805f8438a6937e.zip frameworks_base-b8a10fe45657f2dcc50cae8a06805f8438a6937e.tar.gz frameworks_base-b8a10fe45657f2dcc50cae8a06805f8438a6937e.tar.bz2 | |
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 105d4d2..022fe5a 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 8e48b38..3550716 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 bb22dab..a481ce7 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"); | 
