summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndriy Chepurnyy <x0155536@ti.com>2012-11-15 16:59:36 +0200
committerHashcode <hashcode0f@gmail.com>2015-02-03 13:38:56 -0800
commita603d727088717a2e442d71a6f09439e3bc09d0e (patch)
treea5d9f754ef4cb1fed8a582f6a97cb2cc60b922da
parent8736cdb17c995e83399ba0604d52f007439afcee (diff)
downloadhardware_ti_omap4-a603d727088717a2e442d71a6f09439e3bc09d0e.zip
hardware_ti_omap4-a603d727088717a2e442d71a6f09439e3bc09d0e.tar.gz
hardware_ti_omap4-a603d727088717a2e442d71a6f09439e3bc09d0e.tar.bz2
CameraHAL: Fixed Image capture when using V4L camera
- Added correct stop of the preview thread when doing image capture - Added WA that propose ability to skip some frames count if case of use buggy camera driver that do distortions of first frames after stream on Change-Id: I49b7708f4596499142bface731fbccd43cac6ec7 Signed-off-by: Andriy Chepurnyy <x0155536@ti.com>
-rwxr-xr-xcamera/V4LCameraAdapter/V4LCameraAdapter.cpp99
-rwxr-xr-xcamera/inc/V4LCameraAdapter/V4LCameraAdapter.h3
2 files changed, 79 insertions, 23 deletions
diff --git a/camera/V4LCameraAdapter/V4LCameraAdapter.cpp b/camera/V4LCameraAdapter/V4LCameraAdapter.cpp
index 10a1574..e2cc5f3 100755
--- a/camera/V4LCameraAdapter/V4LCameraAdapter.cpp
+++ b/camera/V4LCameraAdapter/V4LCameraAdapter.cpp
@@ -38,7 +38,6 @@
#include <sys/select.h>
#include <linux/videodev.h>
#include <cutils/properties.h>
-
#include "DecoderFactory.h"
#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
@@ -103,14 +102,11 @@ status_t V4LCameraAdapter::v4lIoctl (int fd, int req, void* argp) {
return ret;
}
-status_t V4LCameraAdapter::v4lInitMmap(int& count) {
+status_t V4LCameraAdapter::v4lInitMmap(int& count, int width, int height) {
status_t ret = NO_ERROR;
LOG_FUNCTION_NAME;
- int width, height;
- mParams.getPreviewSize(&width, &height);
-
//First allocate adapter internal buffers at V4L level for USB Cam
//These are the buffers from which we will copy the data into overlay buffers
/* Check if camera can handle NB_BUFFER buffers */
@@ -215,6 +211,18 @@ status_t V4LCameraAdapter::v4lStartStreaming () {
mVideoInfo->isStreaming = true;
}
+ // This is WA for some cameras with incorrect driver behavior
+ // there is possibility that fist frame after VIDIOC_STREAMON
+ // will remain from previous resolution/will be distorted
+ // for such cameras can be dynamically set frame count that will be
+ // skipped after frame on.
+ for (int i = 0; i < mSkipFramesCount; i++) {
+ int id = 0, length = 0;
+ if (GetFrame(id, length) != NULL) {
+ returnBufferToV4L(id);
+ }
+ }
+
LOG_FUNCTION_NAME_EXIT;
return ret;
}
@@ -229,9 +237,9 @@ status_t V4LCameraAdapter::v4lStopStreaming (int nBufferCount) {
bufType = V4L2_BUF_TYPE_VIDEO_CAPTURE;
ret = v4lIoctl (mCameraHandle, VIDIOC_STREAMOFF, &bufType);
- if (ret < 0) {
+ if (ret != 0) {
CAMHAL_LOGEB("StopStreaming: Unable to stop capture: %s", strerror(errno));
- goto EXIT;
+ return ret;
}
mVideoInfo->isStreaming = false;
@@ -242,6 +250,7 @@ status_t V4LCameraAdapter::v4lStopStreaming (int nBufferCount) {
if (munmap(mVideoInfo->mem[i], mVideoInfo->buf.length) < 0) {
CAMHAL_LOGEA("munmap() failed");
}
+ mVideoInfo->mem[i] = 0;
}
//free the memory allocated during REQBUFS, by setting the count=0
@@ -312,7 +321,7 @@ status_t V4LCameraAdapter::restartPreview ()
goto EXIT;
}
- ret = v4lInitMmap(mPreviewBufferCount);
+ ret = v4lInitMmap(mPreviewBufferCount, width, height);
if (ret < 0) {
CAMHAL_LOGEB("v4lInitMmap Failed: %s", strerror(errno));
goto EXIT;
@@ -333,6 +342,14 @@ status_t V4LCameraAdapter::restartPreview ()
nQueued++;
}
+ if (isNeedToUseDecoder()) {
+ for (int i = 0; i < mPreviewBufferCountQueueable; i++) {
+ mDecoder->queueOutputBuffer(i);
+ CAMHAL_LOGV("Queued output buffer with id=%d ", i);
+ }
+ mDecoder->start();
+ }
+
ret = v4lStartStreaming();
CAMHAL_LOGDA("Ready for preview....");
EXIT:
@@ -615,6 +632,8 @@ EXIT:
status_t V4LCameraAdapter::UseBuffersPreview(CameraBuffer *bufArr, int num)
{
int ret = NO_ERROR;
+ int width = 0, height = 0;
+
LOG_FUNCTION_NAME;
if(NULL == bufArr) {
@@ -622,7 +641,8 @@ status_t V4LCameraAdapter::UseBuffersPreview(CameraBuffer *bufArr, int num)
goto EXIT;
}
- ret = v4lInitMmap(num);
+ mParams.getPreviewSize(&width, &height);
+ ret = v4lInitMmap(num, width, height);
mOutBuffers.clear();
@@ -659,12 +679,28 @@ status_t V4LCameraAdapter::takePicture() {
android::AutoMutex lock(mLock);
- if(mCapturing) {
+ if (mCapturing) {
CAMHAL_LOGEA("Already Capture in Progress...");
- ret = BAD_VALUE;
- goto EXIT;
+ return BAD_VALUE;
+ }
+
+ mPreviewing = false;
+ mLock.unlock();
+
+ {
+ android::AutoMutex stopLock(mStopLock);
+ CAMHAL_LOGW("Wait till preview stops");
+ ret = mStopCondition.waitRelative(mStopLock, 100000000);
+ if (ret != NO_ERROR) {
+ CAMHAL_LOGW("Timeout waiting for preview stop");
+ }
}
+ if (isNeedToUseDecoder()) {
+ mDecoder->stop();
+ mDecoder->flush();
+ }
+ mLock.lock();
mCapturing = true;
mPreviewing = false;
@@ -686,7 +722,7 @@ status_t V4LCameraAdapter::takePicture() {
goto EXIT;
}
- ret = v4lInitMmap(mCaptureBufferCount);
+ ret = v4lInitMmap(mCaptureBufferCount, width, height);
if (ret < 0) {
CAMHAL_LOGEB("v4lInitMmap Failed: %s", strerror(errno));
goto EXIT;
@@ -702,8 +738,7 @@ status_t V4LCameraAdapter::takePicture() {
ret = v4lIoctl(mCameraHandle, VIDIOC_QBUF, &buf);
if (ret < 0) {
CAMHAL_LOGEA("VIDIOC_QBUF Failed");
- ret = BAD_VALUE;
- goto EXIT;
+ return BAD_VALUE;
}
nQueued++;
}
@@ -719,19 +754,21 @@ status_t V4LCameraAdapter::takePicture() {
//get the frame and send to encode as JPG
int filledLen;
CAMHAL_LOGD("*********Will dequeue frame for Image Capture***********");
+
fp = this->GetFrame(index, filledLen);
- if(!fp) {
+ if (!fp) {
CAMHAL_LOGEA("!!! Captured frame is NULL !!!!");
- ret = BAD_VALUE;
- goto EXIT;
+ return BAD_VALUE;
}
+
+
CAMHAL_LOGDA("::Capture Frame received from V4L::");
buffer = mCaptureBufs.keyAt(index);
CAMHAL_LOGVB("## captureBuf[%d] = 0x%x, yuv422i_buff_size=%d fill_length=%d", index, buffer->opaque, yuv422i_buff_size, filledLen);
//copy the yuv422i data to the image buffer.
- memcpy(buffer->opaque, fp, yuv422i_buff_size);
+ memcpy(buffer->opaque, fp, filledLen);
#ifdef DUMP_CAPTURE_FRAME
//dump the YUV422 buffer in to a file
@@ -776,7 +813,6 @@ status_t V4LCameraAdapter::takePicture() {
CAMHAL_LOGEB("v4lStopStreaming Failed: %s", strerror(errno));
goto EXIT;
}
-
ret = restartPreview();
EXIT:
LOG_FUNCTION_NAME_EXIT;
@@ -826,8 +862,20 @@ status_t V4LCameraAdapter::startPreview()
}
for (int i = 0; i < mPreviewBufferCountQueueable; i++) {
-
v4l2_buffer buf;
+
+ memset (&mVideoInfo->buf, 0, sizeof (struct v4l2_buffer));
+
+ mVideoInfo->buf.index = i;
+ mVideoInfo->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ mVideoInfo->buf.memory = V4L2_MEMORY_MMAP;
+
+ ret = v4lIoctl (mCameraHandle, VIDIOC_QUERYBUF, &mVideoInfo->buf);
+ if (ret < 0) {
+ CAMHAL_LOGEB("Unable to query buffer (%s)", strerror(errno));
+ return ret;
+ }
+
buf.index = i;
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
@@ -839,6 +887,7 @@ status_t V4LCameraAdapter::startPreview()
}
nQueued++;
}
+
if (isNeedToUseDecoder()) {
for (int i = 0; i < mPreviewBufferCountQueueable; i++) {
mDecoder->queueOutputBuffer(i);
@@ -1113,10 +1162,13 @@ void V4LCameraAdapter::setupWorkingMode() {
}
V4LCameraAdapter::V4LCameraAdapter(size_t sensor_index, CameraHal* hal)
- :mPixelFormat(DEFAULT_PIXEL_FORMAT), mFrameRate(0), mCameraHal(hal)
+ :mPixelFormat(DEFAULT_PIXEL_FORMAT), mFrameRate(0), mCameraHal(hal),
+ mSkipFramesCount(0)
{
LOG_FUNCTION_NAME;
+ char value[PROPERTY_VALUE_MAX];
+
// Nothing useful to do in the constructor
mFramesWithEncoder = 0;
mDecoder = 0;
@@ -1125,6 +1177,9 @@ V4LCameraAdapter::V4LCameraAdapter(size_t sensor_index, CameraHal* hal)
setupWorkingMode();
+ property_get("camera.v4l.skipframes", value, "1");
+ mSkipFramesCount = atoi(value);
+
LOG_FUNCTION_NAME_EXIT;
}
diff --git a/camera/inc/V4LCameraAdapter/V4LCameraAdapter.h b/camera/inc/V4LCameraAdapter/V4LCameraAdapter.h
index 2189727..e1e7cad 100755
--- a/camera/inc/V4LCameraAdapter/V4LCameraAdapter.h
+++ b/camera/inc/V4LCameraAdapter/V4LCameraAdapter.h
@@ -196,7 +196,7 @@ private:
static status_t sortAscend(V4L_TI_CAPTYPE&, uint16_t ) ;
status_t v4lIoctl(int, int, void*);
- status_t v4lInitMmap(int&);
+ status_t v4lInitMmap(int& count, int width, int height);
status_t v4lInitUsrPtr(int&);
status_t v4lStartStreaming();
status_t v4lStopStreaming(int nBufferCount);
@@ -253,6 +253,7 @@ private:
android::Condition mStopCondition;
CameraHal* mCameraHal;
+ int mSkipFramesCount;
};
} // namespace Camera