diff options
Diffstat (limited to 'camera')
| -rw-r--r-- | camera/libcameraservice/CameraHardwareStub.cpp | 37 | ||||
| -rw-r--r-- | camera/libcameraservice/CameraHardwareStub.h | 4 | ||||
| -rw-r--r-- | camera/libcameraservice/CameraService.cpp | 48 | ||||
| -rw-r--r-- | camera/libcameraservice/CameraService.h | 3 | 
4 files changed, 56 insertions, 36 deletions
| diff --git a/camera/libcameraservice/CameraHardwareStub.cpp b/camera/libcameraservice/CameraHardwareStub.cpp index 9a47705..0f1ae8e 100644 --- a/camera/libcameraservice/CameraHardwareStub.cpp +++ b/camera/libcameraservice/CameraHardwareStub.cpp @@ -29,7 +29,8 @@ namespace android {  CameraHardwareStub::CameraHardwareStub()                    : mParameters(), -                    mHeap(0), +                    mPreviewHeap(0), +                    mRawHeap(0),                      mFakeCamera(0),                      mPreviewFrameSize(0),                      mRawPictureCallback(0), @@ -62,13 +63,17 @@ void CameraHardwareStub::initDefaultParameters()  void CameraHardwareStub::initHeapLocked()  { -    int width, height; -    mParameters.getPreviewSize(&width, &height); +    // Create raw heap. +    int picture_width, picture_height; +    mParameters.getPictureSize(&picture_width, &picture_height); +    mRawHeap = new MemoryHeapBase(picture_width * 2 * picture_height); -    LOGD("initHeapLocked: preview size=%dx%d", width, height); +    int preview_width, preview_height; +    mParameters.getPreviewSize(&preview_width, &preview_height); +    LOGD("initHeapLocked: preview size=%dx%d", preview_width, preview_height);      // Note that we enforce yuv422 in setParameters(). -    int how_big = width * height * 2; +    int how_big = preview_width * preview_height * 2;      // If we are being reinitialized to the same size as before, no      // work needs to be done. @@ -79,15 +84,15 @@ void CameraHardwareStub::initHeapLocked()      // Make a new mmap'ed heap that can be shared across processes.       // use code below to test with pmem -    mHeap = new MemoryHeapBase(mPreviewFrameSize * kBufferCount); +    mPreviewHeap = new MemoryHeapBase(mPreviewFrameSize * kBufferCount);      // Make an IMemory for each frame so that we can reuse them in callbacks.      for (int i = 0; i < kBufferCount; i++) { -        mBuffers[i] = new MemoryBase(mHeap, i * mPreviewFrameSize, mPreviewFrameSize); +        mBuffers[i] = new MemoryBase(mPreviewHeap, i * mPreviewFrameSize, mPreviewFrameSize);      } - +          // Recreate the fake camera to reflect the current size.      delete mFakeCamera; -    mFakeCamera = new FakeCamera(width, height); +    mFakeCamera = new FakeCamera(preview_width, preview_height);  }  CameraHardwareStub::~CameraHardwareStub() @@ -99,7 +104,12 @@ CameraHardwareStub::~CameraHardwareStub()  sp<IMemoryHeap> CameraHardwareStub::getPreviewHeap() const  { -    return mHeap; +    return mPreviewHeap; +} + +sp<IMemoryHeap> CameraHardwareStub::getRawHeap() const +{ +    return mRawHeap;  }  // --------------------------------------------------------------------------- @@ -114,7 +124,7 @@ int CameraHardwareStub::previewThread()          // Find the offset within the heap of the current buffer.          ssize_t offset = mCurrentPreviewFrame * mPreviewFrameSize; -        sp<MemoryHeapBase> heap = mHeap; +        sp<MemoryHeapBase> heap = mPreviewHeap;          // this assumes the internal state of fake camera doesn't change          // (or is thread safe) @@ -255,10 +265,9 @@ int CameraHardwareStub::pictureThread()          // In the meantime just make another fake camera picture.          int w, h;          mParameters.getPictureSize(&w, &h); -        sp<MemoryHeapBase> heap = new MemoryHeapBase(w * 2 * h); -        sp<MemoryBase> mem = new MemoryBase(heap, 0, w * 2 * h); +        sp<MemoryBase> mem = new MemoryBase(mRawHeap, 0, w * 2 * h);          FakeCamera cam(w, h); -        cam.getNextFrameAsYuv422((uint8_t *)heap->base()); +        cam.getNextFrameAsYuv422((uint8_t *)mRawHeap->base());          if (mRawPictureCallback)              mRawPictureCallback(mem, mPictureCallbackCookie);      } diff --git a/camera/libcameraservice/CameraHardwareStub.h b/camera/libcameraservice/CameraHardwareStub.h index cdd6011..0d26d47 100644 --- a/camera/libcameraservice/CameraHardwareStub.h +++ b/camera/libcameraservice/CameraHardwareStub.h @@ -30,6 +30,7 @@ namespace android {  class CameraHardwareStub : public CameraHardwareInterface {  public:      virtual sp<IMemoryHeap> getPreviewHeap() const; +    virtual sp<IMemoryHeap> getRawHeap() const;      virtual status_t    startPreview(preview_callback cb, void* user);      virtual void        stopPreview(); @@ -93,7 +94,8 @@ private:      CameraParameters    mParameters; -    sp<MemoryHeapBase>  mHeap; +    sp<MemoryHeapBase>  mPreviewHeap; +    sp<MemoryHeapBase>  mRawHeap;      sp<MemoryBase>      mBuffers[kBufferCount];      FakeCamera          *mFakeCamera; diff --git a/camera/libcameraservice/CameraService.cpp b/camera/libcameraservice/CameraService.cpp index e5d4220..953e637 100644 --- a/camera/libcameraservice/CameraService.cpp +++ b/camera/libcameraservice/CameraService.cpp @@ -152,7 +152,7 @@ void CameraService::removeClient(const sp<ICameraClient>& cameraClient)  }  CameraService::Client::Client(const sp<CameraService>& cameraService, -        const sp<ICameraClient>& cameraClient, pid_t clientPid)  +        const sp<ICameraClient>& cameraClient, pid_t clientPid)  {      LOGD("Client E constructor");      mCameraService = cameraService; @@ -429,7 +429,7 @@ status_t CameraService::Client::startPreviewMode()          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()); @@ -684,13 +684,33 @@ status_t CameraService::Client::takePicture()          return INVALID_OPERATION;      } -    if (mSurface != NULL && !mUseOverlay) -        mSurface->unregisterBuffers(); -    return mHardware->takePicture(shutterCallback, +    Mutex::Autolock buffer_lock(mBufferLock); +    result = mHardware->takePicture(shutterCallback,                                    yuvPictureCallback,                                    jpegPictureCallback,                                    mCameraService.get()); + +    // It takes quite some time before yuvPicture callback to be called.  +    // Register the buffer for raw image here to reduce latency.   +    // But yuvPictureCallback is called from libcamera. So do not call into a +    // libcamera function here that gets another lock, which may cause deadlock. +    if (mSurface != 0 && !mUseOverlay) { +        int w, h; +        CameraParameters params(mHardware->getParameters()); +        params.getPictureSize(&w, &h); +        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->getRawHeap()); +        mSurface->registerBuffers(buffers); +    } + +    return result;  }  // picture callback - snapshot taken @@ -732,23 +752,9 @@ void CameraService::Client::yuvPictureCallback(const sp<IMemory>& mem,  #endif      // Put the YUV version of the snapshot in the preview display. -    int w, h; -    CameraParameters params(client->mHardware->getParameters()); -    params.getPictureSize(&w, &h); - -//  Mutex::Autolock clientLock(client->mLock); +    // Use lock to make sure buffer has been registered. +    Mutex::Autolock clientLock(client->mBufferLock);      if (client->mSurface != 0 && !client->mUseOverlay) { -        client->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, heap); -         -        client->mSurface->registerBuffers(buffers);          client->mSurface->postBuffer(offset);      } diff --git a/camera/libcameraservice/CameraService.h b/camera/libcameraservice/CameraService.h index d9b7927..812b928 100644 --- a/camera/libcameraservice/CameraService.h +++ b/camera/libcameraservice/CameraService.h @@ -172,6 +172,9 @@ private:          // for a callback from CameraHardwareInterface.  If this          // happens, it will cause a deadlock.          mutable     Mutex                       mSurfaceLock; +        // mBufferLock synchronizes buffer registration between takePicture()  +        // and yuvPictureCallback(). +        mutable     Mutex                       mBufferLock;          mutable     Condition                   mReady;                      sp<CameraService>           mCameraService;                      sp<ISurface>                mSurface; | 
