Loading camera/libcameraservice/CameraHardwareStub.cpp +23 −14 Original line number Original line Diff line number Diff line Loading @@ -29,7 +29,8 @@ namespace android { CameraHardwareStub::CameraHardwareStub() CameraHardwareStub::CameraHardwareStub() : mParameters(), : mParameters(), mHeap(0), mPreviewHeap(0), mRawHeap(0), mFakeCamera(0), mFakeCamera(0), mPreviewFrameSize(0), mPreviewFrameSize(0), mRawPictureCallback(0), mRawPictureCallback(0), Loading Loading @@ -62,13 +63,17 @@ void CameraHardwareStub::initDefaultParameters() void CameraHardwareStub::initHeapLocked() void CameraHardwareStub::initHeapLocked() { { int width, height; // Create raw heap. mParameters.getPreviewSize(&width, &height); 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(). // 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 // If we are being reinitialized to the same size as before, no // work needs to be done. // work needs to be done. Loading @@ -79,15 +84,15 @@ void CameraHardwareStub::initHeapLocked() // Make a new mmap'ed heap that can be shared across processes. // Make a new mmap'ed heap that can be shared across processes. // use code below to test with pmem // 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. // Make an IMemory for each frame so that we can reuse them in callbacks. for (int i = 0; i < kBufferCount; i++) { 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. // Recreate the fake camera to reflect the current size. delete mFakeCamera; delete mFakeCamera; mFakeCamera = new FakeCamera(width, height); mFakeCamera = new FakeCamera(preview_width, preview_height); } } CameraHardwareStub::~CameraHardwareStub() CameraHardwareStub::~CameraHardwareStub() Loading @@ -99,7 +104,12 @@ CameraHardwareStub::~CameraHardwareStub() sp<IMemoryHeap> CameraHardwareStub::getPreviewHeap() const sp<IMemoryHeap> CameraHardwareStub::getPreviewHeap() const { { return mHeap; return mPreviewHeap; } sp<IMemoryHeap> CameraHardwareStub::getRawHeap() const { return mRawHeap; } } // --------------------------------------------------------------------------- // --------------------------------------------------------------------------- Loading @@ -114,7 +124,7 @@ int CameraHardwareStub::previewThread() // Find the offset within the heap of the current buffer. // Find the offset within the heap of the current buffer. ssize_t offset = mCurrentPreviewFrame * mPreviewFrameSize; ssize_t offset = mCurrentPreviewFrame * mPreviewFrameSize; sp<MemoryHeapBase> heap = mHeap; sp<MemoryHeapBase> heap = mPreviewHeap; // this assumes the internal state of fake camera doesn't change // this assumes the internal state of fake camera doesn't change // (or is thread safe) // (or is thread safe) Loading Loading @@ -255,10 +265,9 @@ int CameraHardwareStub::pictureThread() // In the meantime just make another fake camera picture. // In the meantime just make another fake camera picture. int w, h; int w, h; mParameters.getPictureSize(&w, &h); mParameters.getPictureSize(&w, &h); sp<MemoryHeapBase> heap = new MemoryHeapBase(w * 2 * h); sp<MemoryBase> mem = new MemoryBase(mRawHeap, 0, w * 2 * h); sp<MemoryBase> mem = new MemoryBase(heap, 0, w * 2 * h); FakeCamera cam(w, h); FakeCamera cam(w, h); cam.getNextFrameAsYuv422((uint8_t *)heap->base()); cam.getNextFrameAsYuv422((uint8_t *)mRawHeap->base()); if (mRawPictureCallback) if (mRawPictureCallback) mRawPictureCallback(mem, mPictureCallbackCookie); mRawPictureCallback(mem, mPictureCallbackCookie); } } Loading camera/libcameraservice/CameraHardwareStub.h +3 −1 Original line number Original line Diff line number Diff line Loading @@ -30,6 +30,7 @@ namespace android { class CameraHardwareStub : public CameraHardwareInterface { class CameraHardwareStub : public CameraHardwareInterface { public: public: virtual sp<IMemoryHeap> getPreviewHeap() const; virtual sp<IMemoryHeap> getPreviewHeap() const; virtual sp<IMemoryHeap> getRawHeap() const; virtual status_t startPreview(preview_callback cb, void* user); virtual status_t startPreview(preview_callback cb, void* user); virtual void stopPreview(); virtual void stopPreview(); Loading Loading @@ -93,7 +94,8 @@ private: CameraParameters mParameters; CameraParameters mParameters; sp<MemoryHeapBase> mHeap; sp<MemoryHeapBase> mPreviewHeap; sp<MemoryHeapBase> mRawHeap; sp<MemoryBase> mBuffers[kBufferCount]; sp<MemoryBase> mBuffers[kBufferCount]; FakeCamera *mFakeCamera; FakeCamera *mFakeCamera; Loading camera/libcameraservice/CameraService.cpp +27 −21 Original line number Original line Diff line number Diff line Loading @@ -684,13 +684,33 @@ status_t CameraService::Client::takePicture() return INVALID_OPERATION; return INVALID_OPERATION; } } if (mSurface != NULL && !mUseOverlay) mSurface->unregisterBuffers(); return mHardware->takePicture(shutterCallback, Mutex::Autolock buffer_lock(mBufferLock); result = mHardware->takePicture(shutterCallback, yuvPictureCallback, yuvPictureCallback, jpegPictureCallback, jpegPictureCallback, mCameraService.get()); 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 // picture callback - snapshot taken Loading Loading @@ -732,23 +752,9 @@ void CameraService::Client::yuvPictureCallback(const sp<IMemory>& mem, #endif #endif // Put the YUV version of the snapshot in the preview display. // Put the YUV version of the snapshot in the preview display. int w, h; // Use lock to make sure buffer has been registered. CameraParameters params(client->mHardware->getParameters()); Mutex::Autolock clientLock(client->mBufferLock); params.getPictureSize(&w, &h); // Mutex::Autolock clientLock(client->mLock); if (client->mSurface != 0 && !client->mUseOverlay) { 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); client->mSurface->postBuffer(offset); } } Loading camera/libcameraservice/CameraService.h +3 −0 Original line number Original line Diff line number Diff line Loading @@ -172,6 +172,9 @@ private: // for a callback from CameraHardwareInterface. If this // for a callback from CameraHardwareInterface. If this // happens, it will cause a deadlock. // happens, it will cause a deadlock. mutable Mutex mSurfaceLock; mutable Mutex mSurfaceLock; // mBufferLock synchronizes buffer registration between takePicture() // and yuvPictureCallback(). mutable Mutex mBufferLock; mutable Condition mReady; mutable Condition mReady; sp<CameraService> mCameraService; sp<CameraService> mCameraService; sp<ISurface> mSurface; sp<ISurface> mSurface; Loading include/ui/CameraHardwareInterface.h +3 −0 Original line number Original line Diff line number Diff line Loading @@ -87,6 +87,9 @@ public: /** Return the IMemoryHeap for the preview image heap */ /** Return the IMemoryHeap for the preview image heap */ virtual sp<IMemoryHeap> getPreviewHeap() const = 0; virtual sp<IMemoryHeap> getPreviewHeap() const = 0; /** Return the IMemoryHeap for the raw image heap */ virtual sp<IMemoryHeap> getRawHeap() const = 0; /** /** * Start preview mode. When a preview image is available * Start preview mode. When a preview image is available * preview_callback is called with the user parameter. The * preview_callback is called with the user parameter. The Loading Loading
camera/libcameraservice/CameraHardwareStub.cpp +23 −14 Original line number Original line Diff line number Diff line Loading @@ -29,7 +29,8 @@ namespace android { CameraHardwareStub::CameraHardwareStub() CameraHardwareStub::CameraHardwareStub() : mParameters(), : mParameters(), mHeap(0), mPreviewHeap(0), mRawHeap(0), mFakeCamera(0), mFakeCamera(0), mPreviewFrameSize(0), mPreviewFrameSize(0), mRawPictureCallback(0), mRawPictureCallback(0), Loading Loading @@ -62,13 +63,17 @@ void CameraHardwareStub::initDefaultParameters() void CameraHardwareStub::initHeapLocked() void CameraHardwareStub::initHeapLocked() { { int width, height; // Create raw heap. mParameters.getPreviewSize(&width, &height); 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(). // 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 // If we are being reinitialized to the same size as before, no // work needs to be done. // work needs to be done. Loading @@ -79,15 +84,15 @@ void CameraHardwareStub::initHeapLocked() // Make a new mmap'ed heap that can be shared across processes. // Make a new mmap'ed heap that can be shared across processes. // use code below to test with pmem // 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. // Make an IMemory for each frame so that we can reuse them in callbacks. for (int i = 0; i < kBufferCount; i++) { 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. // Recreate the fake camera to reflect the current size. delete mFakeCamera; delete mFakeCamera; mFakeCamera = new FakeCamera(width, height); mFakeCamera = new FakeCamera(preview_width, preview_height); } } CameraHardwareStub::~CameraHardwareStub() CameraHardwareStub::~CameraHardwareStub() Loading @@ -99,7 +104,12 @@ CameraHardwareStub::~CameraHardwareStub() sp<IMemoryHeap> CameraHardwareStub::getPreviewHeap() const sp<IMemoryHeap> CameraHardwareStub::getPreviewHeap() const { { return mHeap; return mPreviewHeap; } sp<IMemoryHeap> CameraHardwareStub::getRawHeap() const { return mRawHeap; } } // --------------------------------------------------------------------------- // --------------------------------------------------------------------------- Loading @@ -114,7 +124,7 @@ int CameraHardwareStub::previewThread() // Find the offset within the heap of the current buffer. // Find the offset within the heap of the current buffer. ssize_t offset = mCurrentPreviewFrame * mPreviewFrameSize; ssize_t offset = mCurrentPreviewFrame * mPreviewFrameSize; sp<MemoryHeapBase> heap = mHeap; sp<MemoryHeapBase> heap = mPreviewHeap; // this assumes the internal state of fake camera doesn't change // this assumes the internal state of fake camera doesn't change // (or is thread safe) // (or is thread safe) Loading Loading @@ -255,10 +265,9 @@ int CameraHardwareStub::pictureThread() // In the meantime just make another fake camera picture. // In the meantime just make another fake camera picture. int w, h; int w, h; mParameters.getPictureSize(&w, &h); mParameters.getPictureSize(&w, &h); sp<MemoryHeapBase> heap = new MemoryHeapBase(w * 2 * h); sp<MemoryBase> mem = new MemoryBase(mRawHeap, 0, w * 2 * h); sp<MemoryBase> mem = new MemoryBase(heap, 0, w * 2 * h); FakeCamera cam(w, h); FakeCamera cam(w, h); cam.getNextFrameAsYuv422((uint8_t *)heap->base()); cam.getNextFrameAsYuv422((uint8_t *)mRawHeap->base()); if (mRawPictureCallback) if (mRawPictureCallback) mRawPictureCallback(mem, mPictureCallbackCookie); mRawPictureCallback(mem, mPictureCallbackCookie); } } Loading
camera/libcameraservice/CameraHardwareStub.h +3 −1 Original line number Original line Diff line number Diff line Loading @@ -30,6 +30,7 @@ namespace android { class CameraHardwareStub : public CameraHardwareInterface { class CameraHardwareStub : public CameraHardwareInterface { public: public: virtual sp<IMemoryHeap> getPreviewHeap() const; virtual sp<IMemoryHeap> getPreviewHeap() const; virtual sp<IMemoryHeap> getRawHeap() const; virtual status_t startPreview(preview_callback cb, void* user); virtual status_t startPreview(preview_callback cb, void* user); virtual void stopPreview(); virtual void stopPreview(); Loading Loading @@ -93,7 +94,8 @@ private: CameraParameters mParameters; CameraParameters mParameters; sp<MemoryHeapBase> mHeap; sp<MemoryHeapBase> mPreviewHeap; sp<MemoryHeapBase> mRawHeap; sp<MemoryBase> mBuffers[kBufferCount]; sp<MemoryBase> mBuffers[kBufferCount]; FakeCamera *mFakeCamera; FakeCamera *mFakeCamera; Loading
camera/libcameraservice/CameraService.cpp +27 −21 Original line number Original line Diff line number Diff line Loading @@ -684,13 +684,33 @@ status_t CameraService::Client::takePicture() return INVALID_OPERATION; return INVALID_OPERATION; } } if (mSurface != NULL && !mUseOverlay) mSurface->unregisterBuffers(); return mHardware->takePicture(shutterCallback, Mutex::Autolock buffer_lock(mBufferLock); result = mHardware->takePicture(shutterCallback, yuvPictureCallback, yuvPictureCallback, jpegPictureCallback, jpegPictureCallback, mCameraService.get()); 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 // picture callback - snapshot taken Loading Loading @@ -732,23 +752,9 @@ void CameraService::Client::yuvPictureCallback(const sp<IMemory>& mem, #endif #endif // Put the YUV version of the snapshot in the preview display. // Put the YUV version of the snapshot in the preview display. int w, h; // Use lock to make sure buffer has been registered. CameraParameters params(client->mHardware->getParameters()); Mutex::Autolock clientLock(client->mBufferLock); params.getPictureSize(&w, &h); // Mutex::Autolock clientLock(client->mLock); if (client->mSurface != 0 && !client->mUseOverlay) { 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); client->mSurface->postBuffer(offset); } } Loading
camera/libcameraservice/CameraService.h +3 −0 Original line number Original line Diff line number Diff line Loading @@ -172,6 +172,9 @@ private: // for a callback from CameraHardwareInterface. If this // for a callback from CameraHardwareInterface. If this // happens, it will cause a deadlock. // happens, it will cause a deadlock. mutable Mutex mSurfaceLock; mutable Mutex mSurfaceLock; // mBufferLock synchronizes buffer registration between takePicture() // and yuvPictureCallback(). mutable Mutex mBufferLock; mutable Condition mReady; mutable Condition mReady; sp<CameraService> mCameraService; sp<CameraService> mCameraService; sp<ISurface> mSurface; sp<ISurface> mSurface; Loading
include/ui/CameraHardwareInterface.h +3 −0 Original line number Original line Diff line number Diff line Loading @@ -87,6 +87,9 @@ public: /** Return the IMemoryHeap for the preview image heap */ /** Return the IMemoryHeap for the preview image heap */ virtual sp<IMemoryHeap> getPreviewHeap() const = 0; virtual sp<IMemoryHeap> getPreviewHeap() const = 0; /** Return the IMemoryHeap for the raw image heap */ virtual sp<IMemoryHeap> getRawHeap() const = 0; /** /** * Start preview mode. When a preview image is available * Start preview mode. When a preview image is available * preview_callback is called with the user parameter. The * preview_callback is called with the user parameter. The Loading