From 81d754306ecd4a587459015da5168270c2a5c167 Mon Sep 17 00:00:00 2001 From: Zhijun He Date: Tue, 26 Nov 2013 15:11:05 -0800 Subject: DO NOT MERGE: camera2/3: Add protection for still capture path Jpeg stream in JpegProcessor could be deleted while process new capture is ongoing, which unsafe to access a dead consumer endpoint. Bug: 9316454 Change-Id: I2950f31ea28d0ba01f08502e2e3ba452bf8bb818 --- .../api1/client2/JpegProcessor.cpp | 79 ++++++++++++---------- 1 file changed, 44 insertions(+), 35 deletions(-) (limited to 'services') diff --git a/services/camera/libcameraservice/api1/client2/JpegProcessor.cpp b/services/camera/libcameraservice/api1/client2/JpegProcessor.cpp index 77d5c8a..ec81456 100644 --- a/services/camera/libcameraservice/api1/client2/JpegProcessor.cpp +++ b/services/camera/libcameraservice/api1/client2/JpegProcessor.cpp @@ -200,50 +200,59 @@ status_t JpegProcessor::processNewCapture() { ATRACE_CALL(); status_t res; sp captureHeap; + sp captureBuffer; CpuConsumer::LockedBuffer imgBuffer; - res = mCaptureConsumer->lockNextBuffer(&imgBuffer); - if (res != OK) { - if (res != BAD_VALUE) { - ALOGE("%s: Camera %d: Error receiving still image buffer: " - "%s (%d)", __FUNCTION__, - mId, strerror(-res), res); + { + Mutex::Autolock l(mInputMutex); + if (mCaptureStreamId == NO_STREAM) { + ALOGW("%s: Camera %d: No stream is available", __FUNCTION__, mId); + return INVALID_OPERATION; } - return res; - } - ALOGV("%s: Camera %d: Still capture available", __FUNCTION__, - mId); + res = mCaptureConsumer->lockNextBuffer(&imgBuffer); + if (res != OK) { + if (res != BAD_VALUE) { + ALOGE("%s: Camera %d: Error receiving still image buffer: " + "%s (%d)", __FUNCTION__, + mId, strerror(-res), res); + } + return res; + } - if (imgBuffer.format != HAL_PIXEL_FORMAT_BLOB) { - ALOGE("%s: Camera %d: Unexpected format for still image: " - "%x, expected %x", __FUNCTION__, mId, - imgBuffer.format, - HAL_PIXEL_FORMAT_BLOB); - mCaptureConsumer->unlockBuffer(imgBuffer); - return OK; - } + ALOGV("%s: Camera %d: Still capture available", __FUNCTION__, + mId); - // Find size of JPEG image - size_t jpegSize = findJpegSize(imgBuffer.data, imgBuffer.width); - if (jpegSize == 0) { // failed to find size, default to whole buffer - jpegSize = imgBuffer.width; - } - size_t heapSize = mCaptureHeap->getSize(); - if (jpegSize > heapSize) { - ALOGW("%s: JPEG image is larger than expected, truncating " - "(got %d, expected at most %d bytes)", - __FUNCTION__, jpegSize, heapSize); - jpegSize = heapSize; - } + if (imgBuffer.format != HAL_PIXEL_FORMAT_BLOB) { + ALOGE("%s: Camera %d: Unexpected format for still image: " + "%x, expected %x", __FUNCTION__, mId, + imgBuffer.format, + HAL_PIXEL_FORMAT_BLOB); + mCaptureConsumer->unlockBuffer(imgBuffer); + return OK; + } - // TODO: Optimize this to avoid memcopy - sp captureBuffer = new MemoryBase(mCaptureHeap, 0, jpegSize); - void* captureMemory = mCaptureHeap->getBase(); - memcpy(captureMemory, imgBuffer.data, jpegSize); + // Find size of JPEG image + size_t jpegSize = findJpegSize(imgBuffer.data, imgBuffer.width); + if (jpegSize == 0) { // failed to find size, default to whole buffer + jpegSize = imgBuffer.width; + } + size_t heapSize = mCaptureHeap->getSize(); + if (jpegSize > heapSize) { + ALOGW("%s: JPEG image is larger than expected, truncating " + "(got %d, expected at most %d bytes)", + __FUNCTION__, jpegSize, heapSize); + jpegSize = heapSize; + } + + // TODO: Optimize this to avoid memcopy + captureBuffer = new MemoryBase(mCaptureHeap, 0, jpegSize); + void* captureMemory = mCaptureHeap->getBase(); + memcpy(captureMemory, imgBuffer.data, jpegSize); - mCaptureConsumer->unlockBuffer(imgBuffer); + mCaptureConsumer->unlockBuffer(imgBuffer); + } sp sequencer = mSequencer.promote(); if (sequencer != 0) { -- cgit v1.1