diff options
author | Jamie Gennis <jgennis@google.com> | 2011-07-13 15:13:14 -0700 |
---|---|---|
committer | Jamie Gennis <jgennis@google.com> | 2011-07-14 17:48:33 -0700 |
commit | 0ed3ec00d0242c9dc77532fe0cf0082645b6662c (patch) | |
tree | 26598624682ba4fa9b14e853d286517cba87fd0e /services/camera | |
parent | 61c7ef5bde2c7ed94a078396aa65da67b47e5402 (diff) | |
download | frameworks_av-0ed3ec00d0242c9dc77532fe0cf0082645b6662c.zip frameworks_av-0ed3ec00d0242c9dc77532fe0cf0082645b6662c.tar.gz frameworks_av-0ed3ec00d0242c9dc77532fe0cf0082645b6662c.tar.bz2 |
CameraService: (dis)connect from preview windows
This change makes CameraService connect and disconnect from preview
windows (Surfaces and SurfaceTextures) that get set.
Change-Id: I726971688367d5ce0d9aa90c44168037bce33deb
Diffstat (limited to 'services/camera')
-rw-r--r-- | services/camera/libcameraservice/CameraService.cpp | 97 | ||||
-rw-r--r-- | services/camera/libcameraservice/CameraService.h | 4 |
2 files changed, 55 insertions, 46 deletions
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp index 9b09983..0eff776 100644 --- a/services/camera/libcameraservice/CameraService.cpp +++ b/services/camera/libcameraservice/CameraService.cpp @@ -502,77 +502,82 @@ void CameraService::Client::disconnect() { // ---------------------------------------------------------------------------- -// 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()); +static void disconnectWindow(const sp<ANativeWindow>& window) { + if (window != 0) { + status_t result = native_window_disconnect(window.get(), + NATIVE_WINDOW_API_CAMERA); + if (result != NO_ERROR) { + LOGW("native_window_disconnect failed: %s (%d)", strerror(-result), + result); + } + } +} + +status_t CameraService::Client::setPreviewWindow(const sp<IBinder>& binder, + const sp<ANativeWindow>& window) { Mutex::Autolock lock(mLock); status_t result = checkPidAndHardware(); if (result != NO_ERROR) return result; - result = NO_ERROR; - // return if no change in surface. - sp<IBinder> binder(surface != 0 ? surface->asBinder() : 0); if (binder == mSurface) { - return result; + return NO_ERROR; } - if (mSurface != 0) { - LOG1("clearing old preview surface %p", mSurface.get()); + if (window != 0) { + result = native_window_connect(window.get(), NATIVE_WINDOW_API_CAMERA); + if (result != NO_ERROR) { + LOGE("native_window_connect failed: %s (%d)", strerror(-result), + result); + return result; + } } - mSurface = binder; - mPreviewWindow = surface; - // If preview has been already started, register preview - // buffers now. + // If preview has been already started, register preview buffers now. if (mHardware->previewEnabled()) { - if (mPreviewWindow != 0) { - native_window_set_buffers_transform(mPreviewWindow.get(), - mOrientation); - result = mHardware->setPreviewWindow(mPreviewWindow); + if (window != 0) { + native_window_set_buffers_transform(window.get(), mOrientation); + result = mHardware->setPreviewWindow(window); } } + if (result == NO_ERROR) { + // Everything has succeeded. Disconnect the old window and remember the + // new window. + disconnectWindow(mPreviewWindow); + mSurface = binder; + mPreviewWindow = window; + } else { + // Something went wrong after we connected to the new window, so + // disconnect here. + disconnectWindow(window); + } + return result; } +// 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()); + + sp<IBinder> binder(surface != 0 ? surface->asBinder() : 0); + sp<ANativeWindow> window(surface); + return setPreviewWindow(binder, window); +} + // 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(); + sp<IBinder> binder; + sp<ANativeWindow> window; 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); - } + binder = surfaceTexture->asBinder(); + window = new SurfaceTextureClient(surfaceTexture); } - - return result; + return setPreviewWindow(binder, window); } // set the preview callback flag to affect how the received frames from diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h index 5e2d571..c5fefb8 100644 --- a/services/camera/libcameraservice/CameraService.h +++ b/services/camera/libcameraservice/CameraService.h @@ -161,6 +161,10 @@ private: int getOrientation(int orientation, bool mirror); + status_t setPreviewWindow( + const sp<IBinder>& binder, + const sp<ANativeWindow>& window); + // these are initialized in the constructor. sp<CameraService> mCameraService; // immutable after constructor sp<ICameraClient> mCameraClient; |