diff options
| author | Jamie Gennis <jgennis@google.com> | 2010-08-10 16:37:53 -0700 |
|---|---|---|
| committer | Jamie Gennis <jgennis@google.com> | 2010-08-23 14:31:30 -0700 |
| commit | 85cfdd011241a5f2fb7fabc65b5943a39af7e1de (patch) | |
| tree | 556bd6f34ae8d300d9fa05fe46bb0dc4d8aa43e0 /services/camera/libcameraservice/CameraService.cpp | |
| parent | 7fdaa2329e755c0e5c25724a43b8c361b88e9623 (diff) | |
| download | frameworks_base-85cfdd011241a5f2fb7fabc65b5943a39af7e1de.zip frameworks_base-85cfdd011241a5f2fb7fabc65b5943a39af7e1de.tar.gz frameworks_base-85cfdd011241a5f2fb7fabc65b5943a39af7e1de.tar.bz2 | |
Change the framework to use the new camera preview path.
This change makes the camera HAL interface take an ANativeWindow interface from
which all the camera preview buffers will be allocated. The framework code
running in application processes now passes a Surface object rather than an
ISurface to the camera server via Binder when setting the preview surface. The
camera server then forwards that Surface object (which implements the
ANativeWindow interface) to the camera HAL, which uses it to communicate with
SurfaceFlinger to allocate the camera preview buffers.
Change-Id: Ie438f721559cd7de5e4f848a26d96360dda07b5f
Diffstat (limited to 'services/camera/libcameraservice/CameraService.cpp')
| -rw-r--r-- | services/camera/libcameraservice/CameraService.cpp | 102 |
1 files changed, 33 insertions, 69 deletions
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp index ea2c5d4..c6a9909 100644 --- a/services/camera/libcameraservice/CameraService.cpp +++ b/services/camera/libcameraservice/CameraService.cpp @@ -336,16 +336,9 @@ CameraService::Client::~Client() { int callingPid = getCallingPid(); LOG1("Client::~Client E (pid %d, this %p)", callingPid, this); - if (mSurface != 0 && !mUseOverlay) { - pthread_t thr; - // We unregister the buffers in a different thread because binder does - // not let us make sychronous transactions in a binder destructor (that - // is, upon our reaching a refcount of zero.) - pthread_create(&thr, - NULL, // attr - unregister_surface, - mSurface.get()); - pthread_join(thr, NULL); + // Clean up the ANativeWindow + if (mSurface != 0) { + setPreviewDisplay(0); } // set mClientPid to let disconnet() tear down the hardware @@ -465,6 +458,11 @@ void CameraService::Client::disconnect() { if (mUseOverlay) { mOverlayRef = 0; } + // Release the held ANativeWindow resources. + if (mPreviewWindow != 0) { + mPreviewWindow = 0; + mHardware->setPreviewWindow(mPreviewWindow); + } mHardware.clear(); mCameraService->removeClient(mCameraClient); @@ -475,8 +473,8 @@ void CameraService::Client::disconnect() { // ---------------------------------------------------------------------------- -// set the ISurface that the preview will use -status_t CameraService::Client::setPreviewDisplay(const sp<ISurface>& surface) { +// set the Surface that the preview will use +status_t CameraService::Client::setPreviewDisplay(const sp<Surface>& surface) { LOG1("setPreviewDisplay(%p) (pid %d)", surface.get(), getCallingPid()); Mutex::Autolock lock(mLock); status_t result = checkPidAndHardware(); @@ -486,7 +484,7 @@ status_t CameraService::Client::setPreviewDisplay(const sp<ISurface>& surface) { // return if no change in surface. // asBinder() is safe on NULL (returns NULL) - if (surface->asBinder() == mSurface->asBinder()) { + if (getISurface(surface)->asBinder() == mSurface->asBinder()) { return result; } @@ -496,44 +494,28 @@ status_t CameraService::Client::setPreviewDisplay(const sp<ISurface>& surface) { // Force the destruction of any previous overlay sp<Overlay> dummy; mHardware->setOverlay(dummy); - } else { - mSurface->unregisterBuffers(); } } - mSurface = surface; + if (surface != 0) { + mSurface = getISurface(surface); + } else { + mSurface = 0; + } + mPreviewWindow = surface; mOverlayRef = 0; // 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(); + } else if (mPreviewWindow != 0) { + result = mHardware->setPreviewWindow(mPreviewWindow); } } return result; } -status_t CameraService::Client::registerPreviewBuffers() { - int w, h; - CameraParameters params(mHardware->getParameters()); - params.getPreviewSize(&w, &h); - - // FIXME: don't use a hardcoded format here. - ISurface::BufferHeap buffers(w, h, w, h, - HAL_PIXEL_FORMAT_YCrCb_420_SP, - mOrientation, - 0, - mHardware->getPreviewHeap()); - - status_t result = mSurface->registerBuffers(buffers); - if (result != NO_ERROR) { - LOGE("registerBuffers failed with status %d", result); - } - return result; -} - status_t CameraService::Client::setOverlay() { int w, h; CameraParameters params(mHardware->getParameters()); @@ -624,14 +606,14 @@ status_t CameraService::Client::startCameraMode(camera_mode mode) { switch(mode) { case CAMERA_PREVIEW_MODE: - if (mSurface == 0) { + if (mSurface == 0 && mPreviewWindow == 0) { LOG1("mSurface is not set yet."); // still able to start preview in this case. } return startPreviewMode(); case CAMERA_RECORDING_MODE: - if (mSurface == 0) { - LOGE("mSurface must be set before startRecordingMode."); + if (mSurface == 0 && mPreviewWindow == 0) { + LOGE("mSurface or mPreviewWindow must be set before startRecordingMode."); return INVALID_OPERATION; } return startRecordingMode(); @@ -657,16 +639,10 @@ status_t CameraService::Client::startPreviewMode() { if (result != NO_ERROR) return result; result = mHardware->startPreview(); } else { + // XXX: Set the orientation of the ANativeWindow. + mHardware->setPreviewWindow(mPreviewWindow); enableMsgType(CAMERA_MSG_PREVIEW_FRAME); result = mHardware->startPreview(); - if (result != NO_ERROR) return result; - // If preview display has been set, register preview buffers now. - if (mSurface != 0) { - // Unregister here because the surface may be previously registered - // with the raw (snapshot) heap. - mSurface->unregisterBuffers(); - result = registerPreviewBuffers(); - } } return result; } @@ -704,13 +680,10 @@ void CameraService::Client::stopPreview() { Mutex::Autolock lock(mLock); if (checkPidAndHardware() != NO_ERROR) return; + disableMsgType(CAMERA_MSG_PREVIEW_FRAME); mHardware->stopPreview(); - if (mSurface != 0 && !mUseOverlay) { - mSurface->unregisterBuffers(); - } - mPreviewBuffer.clear(); } @@ -998,11 +971,6 @@ void CameraService::Client::dataCallbackTimestamp(nsecs_t timestamp, void CameraService::Client::handleShutter(image_rect_type *size) { mCameraService->playSound(SOUND_SHUTTER); - // Screen goes black after the buffer is unregistered. - if (mSurface != 0 && !mUseOverlay) { - mSurface->unregisterBuffers(); - } - sp<ICameraClient> c = mCameraClient; if (c != 0) { mLock.unlock(); @@ -1030,7 +998,6 @@ void CameraService::Client::handleShutter(image_rect_type *size) { HAL_PIXEL_FORMAT_YCrCb_420_SP, mOrientation, 0, mHardware->getRawHeap()); - mSurface->registerBuffers(buffers); IPCThreadState::self()->flushCommands(); } @@ -1043,12 +1010,6 @@ void CameraService::Client::handlePreviewData(const sp<IMemory>& mem) { size_t size; sp<IMemoryHeap> heap = mem->getMemory(&offset, &size); - if (!mUseOverlay) { - if (mSurface != 0) { - mSurface->postBuffer(offset); - } - } - // local copy of the callback flags int flags = mPreviewCallbackFlag; @@ -1108,11 +1069,6 @@ void CameraService::Client::handleRawPicture(const sp<IMemory>& mem) { size_t size; sp<IMemoryHeap> heap = mem->getMemory(&offset, &size); - // Put the YUV version of the snapshot in the preview display. - if (mSurface != 0 && !mUseOverlay) { - mSurface->postBuffer(offset); - } - sp<ICameraClient> c = mCameraClient; mLock.unlock(); if (c != 0) { @@ -1270,4 +1226,12 @@ status_t CameraService::dump(int fd, const Vector<String16>& args) { return NO_ERROR; } +sp<ISurface> CameraService::getISurface(const sp<Surface>& surface) { + if (surface != 0) { + return surface->getISurface(); + } else { + return sp<ISurface>(0); + } +} + }; // namespace android |
