Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 288482b5 authored by Rebecca Schultz Zavin's avatar Rebecca Schultz Zavin
Browse files

Add support for camera preview to be in overlay surfaces.

parent 45fa004f
Loading
Loading
Loading
Loading
+38 −17
Original line number Original line Diff line number Diff line
@@ -158,6 +158,7 @@ CameraService::Client::Client(const sp<CameraService>& cameraService,
    mCameraClient = cameraClient;
    mCameraClient = cameraClient;
    mClientPid = clientPid;
    mClientPid = clientPid;
    mHardware = openCameraHardware();
    mHardware = openCameraHardware();
    mUseOverlay = mHardware->useOverlay();


    // Callback is disabled by default
    // Callback is disabled by default
    mFrameCallbackFlag = FRAME_CALLBACK_FLAG_NOOP;
    mFrameCallbackFlag = FRAME_CALLBACK_FLAG_NOOP;
@@ -233,7 +234,7 @@ CameraService::Client::~Client()
{
{
    // tear down client
    // tear down client
    LOGD("Client E destructor");
    LOGD("Client E destructor");
    if (mSurface != 0) {
    if (mSurface != 0 && !mUseOverlay) {
#if HAVE_ANDROID_OS
#if HAVE_ANDROID_OS
        pthread_t thr;
        pthread_t thr;
        // We unregister the buffers in a different thread because binder does
        // We unregister the buffers in a different thread because binder does
@@ -288,7 +289,7 @@ status_t CameraService::Client::setPreviewDisplay(const sp<ISurface>& surface)
    Mutex::Autolock surfaceLock(mSurfaceLock);
    Mutex::Autolock surfaceLock(mSurfaceLock);
    // 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) {
        if (mSurface != 0 && !mUseOverlay) {
            LOGD("clearing old preview surface %p", mSurface.get());
            LOGD("clearing old preview surface %p", mSurface.get());
            mSurface->unregisterBuffers();
            mSurface->unregisterBuffers();
        }
        }
@@ -341,17 +342,39 @@ status_t CameraService::Client::startPreview()
#if DEBUG_DUMP_PREVIEW_FRAME_TO_FILE
#if DEBUG_DUMP_PREVIEW_FRAME_TO_FILE
    debug_frame_cnt = 0;
    debug_frame_cnt = 0;
#endif
#endif

    status_t ret;
    status_t ret = mHardware->startPreview(previewCallback,
    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;
        }
        ret = mHardware->startPreview(NULL, mCameraService.get());
        if (ret != NO_ERROR)
            LOGE("mHardware->startPreview() failed with status %d\n", ret);
    } else {
        LOGD("Don't use Overlays");
        ret = mHardware->startPreview(previewCallback,
                                               mCameraService.get());
                                               mCameraService.get());
        if (ret == NO_ERROR) {
        if (ret == NO_ERROR) {
            mSurface->unregisterBuffers();
            mSurface->unregisterBuffers();
        mSurface->registerBuffers(w,h,w,h,
            mSurface->registerBuffers(w, h, w, h, PIXEL_FORMAT_YCbCr_420_SP,
                                  PIXEL_FORMAT_YCbCr_420_SP,
                                      mHardware->getPreviewHeap());
                                      mHardware->getPreviewHeap());
        }
        }
    else LOGE("mHardware->startPreview() failed with status %d\n",
        else LOGE("mHardware->startPreview() failed with status %d\n", ret);
              ret);
    }


    return ret;
    return ret;
}
}
@@ -372,7 +395,7 @@ void CameraService::Client::stopPreview()
    mHardware->stopPreview();
    mHardware->stopPreview();
    LOGD("stopPreview(), hardware stopped OK");
    LOGD("stopPreview(), hardware stopped OK");


    if (mSurface != 0) {
    if (mSurface != 0 && !mUseOverlay) {
        mSurface->unregisterBuffers();
        mSurface->unregisterBuffers();
    }
    }
    mPreviewBuffer.clear();
    mPreviewBuffer.clear();
@@ -520,7 +543,7 @@ status_t CameraService::Client::takePicture()
        return INVALID_OPERATION;
        return INVALID_OPERATION;
    }
    }


    if (mSurface != NULL)
    if (mSurface != NULL && !mUseOverlay)
        mSurface->unregisterBuffers();
        mSurface->unregisterBuffers();


    return mHardware->takePicture(shutterCallback,
    return mHardware->takePicture(shutterCallback,
@@ -573,7 +596,7 @@ void CameraService::Client::yuvPictureCallback(const sp<IMemory>& mem,
    params.getPictureSize(&w, &h);
    params.getPictureSize(&w, &h);


//  Mutex::Autolock clientLock(client->mLock);
//  Mutex::Autolock clientLock(client->mLock);
    if (client->mSurface != 0) {
    if (client->mSurface != 0 && !client->mUseOverlay) {
        client->mSurface->unregisterBuffers();
        client->mSurface->unregisterBuffers();
        client->mSurface->registerBuffers(w,h,w,h,
        client->mSurface->registerBuffers(w,h,w,h,
                                          PIXEL_FORMAT_YCbCr_420_SP, heap);
                                          PIXEL_FORMAT_YCbCr_420_SP, heap);
@@ -880,5 +903,3 @@ status_t CameraService::onTransact(
#endif // DEBUG_HEAP_LEAKS
#endif // DEBUG_HEAP_LEAKS


}; // namespace android
}; // namespace android

+1 −0
Original line number Original line Diff line number Diff line
@@ -159,6 +159,7 @@ private:
                    sp<ICameraClient>           mCameraClient;
                    sp<ICameraClient>           mCameraClient;
                    sp<CameraHardwareInterface> mHardware;
                    sp<CameraHardwareInterface> mHardware;
                    pid_t                       mClientPid;
                    pid_t                       mClientPid;
                    bool                        mUseOverlay;
    };
    };


// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
+6 −0
Original line number Original line Diff line number Diff line
@@ -20,6 +20,7 @@
#include <utils/IMemory.h>
#include <utils/IMemory.h>
#include <utils/RefBase.h>
#include <utils/RefBase.h>
#include <ui/CameraParameters.h>
#include <ui/CameraParameters.h>
#include <ui/Overlay.h>


namespace android {
namespace android {


@@ -89,6 +90,11 @@ public:
     * call back parameter may be null.
     * call back parameter may be null.
     */
     */
    virtual status_t    startPreview(preview_callback cb, void* user) = 0;
    virtual status_t    startPreview(preview_callback cb, void* user) = 0;
    /**
     * Only used if overlays are used for camera preview.
     */
    virtual bool useOverlay() {return false;}
    virtual status_t setOverlay(const sp<Overlay> &overlay) {return BAD_VALUE;}


    /**
    /**
     * Stop a previously started preview.
     * Stop a previously started preview.