summaryrefslogtreecommitdiffstats
path: root/camera/V4LCameraAdapter
diff options
context:
space:
mode:
authorSaravanan Solaiyappan <saravanan.s@ti.com>2012-02-15 18:22:51 -0600
committerDaniel Levin <dendy@ti.com>2012-07-25 08:55:43 -0500
commit5d2300c6ca28086860bb4c667c44887e2b528648 (patch)
tree82e0e97d5b79ce058e50a2d0f100b3118803d1b3 /camera/V4LCameraAdapter
parentd1331730a10d1343dac39940277b17321a1db7f8 (diff)
downloadhardware_ti_omap4-5d2300c6ca28086860bb4c667c44887e2b528648.zip
hardware_ti_omap4-5d2300c6ca28086860bb4c667c44887e2b528648.tar.gz
hardware_ti_omap4-5d2300c6ca28086860bb4c667c44887e2b528648.tar.bz2
CameraHAL: V4LCameraAdapter: Enables USB camera basic preview.
[Comment] This pach enables the usb camera preview via V4L camera adapter in ICS. The following change needs to be done in camera/Android.mk file to build the V4L camera adapter. OMAP4_CAMERA_HAL_USES:= USB [DR] - Change-Id: I314649e0bbe52978a28296e1f9da20f176171d7d Signed-off-by: Solaiyappan Saravanan <saravanan.s@ti.com>
Diffstat (limited to 'camera/V4LCameraAdapter')
-rw-r--r--camera/V4LCameraAdapter/V4LCameraAdapter.cpp203
1 files changed, 151 insertions, 52 deletions
diff --git a/camera/V4LCameraAdapter/V4LCameraAdapter.cpp b/camera/V4LCameraAdapter/V4LCameraAdapter.cpp
index 44904f3..8affa2c 100644
--- a/camera/V4LCameraAdapter/V4LCameraAdapter.cpp
+++ b/camera/V4LCameraAdapter/V4LCameraAdapter.cpp
@@ -25,6 +25,7 @@
#include "V4LCameraAdapter.h"
#include "CameraHal.h"
#include "TICameraParameters.h"
+#include "DebugUtils.h"
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
@@ -37,6 +38,8 @@
#include <sys/select.h>
#include <linux/videodev.h>
+#include <ui/GraphicBuffer.h>
+#include <ui/GraphicBufferMapper.h>
#include <cutils/properties.h>
#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
@@ -51,6 +54,10 @@ namespace android {
//frames skipped before recalculating the framerate
#define FPS_PERIOD 30
+//define this macro to save first few raw frames when starting the preview.
+//#define SAVE_RAW_FRAMES 1
+
+#define FPS_PERIOD 30
Mutex gAdapterLock;
const char *device = DEVICE;
@@ -220,11 +227,11 @@ status_t V4LCameraAdapter::useBuffers(CameraMode mode, void* bufArr, int num, si
status_t V4LCameraAdapter::UseBuffersPreview(void* bufArr, int num)
{
int ret = NO_ERROR;
+ uint32_t *ptr = (uint32_t*) bufArr;
- if(NULL == bufArr)
- {
+ if(NULL == bufArr) {
return BAD_VALUE;
- }
+ }
//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
@@ -265,11 +272,8 @@ status_t V4LCameraAdapter::UseBuffersPreview(void* bufArr, int num)
return -1;
}
- uint32_t *ptr = (uint32_t*) bufArr;
-
//Associate each Camera internal buffer with the one from Overlay
mPreviewBufs.add((int)ptr[i], i);
-
}
// Update the preview buffer count
@@ -280,14 +284,13 @@ status_t V4LCameraAdapter::UseBuffersPreview(void* bufArr, int num)
status_t V4LCameraAdapter::startPreview()
{
- status_t ret = NO_ERROR;
+ status_t ret = NO_ERROR;
Mutex::Autolock lock(mPreviewBufsLock);
- if(mPreviewing)
- {
+ if(mPreviewing) {
return BAD_VALUE;
- }
+ }
for (int i = 0; i < mPreviewBufferCount; i++) {
@@ -304,7 +307,7 @@ status_t V4LCameraAdapter::startPreview()
nQueued++;
}
- enum v4l2_buf_type bufType;
+ enum v4l2_buf_type bufType;
if (!mVideoInfo->isStreaming) {
bufType = V4L2_BUF_TYPE_VIDEO_CAPTURE;
@@ -322,12 +325,10 @@ status_t V4LCameraAdapter::startPreview()
CAMHAL_LOGDA("Created preview thread");
-
//Update the flag to indicate we are previewing
mPreviewing = true;
return ret;
-
}
status_t V4LCameraAdapter::stopPreview()
@@ -371,7 +372,6 @@ status_t V4LCameraAdapter::stopPreview()
mPreviewThread.clear();
return ret;
-
}
char * V4LCameraAdapter::GetFrame(int &index)
@@ -399,6 +399,7 @@ char * V4LCameraAdapter::GetFrame(int &index)
status_t V4LCameraAdapter::getFrameSize(size_t &width, size_t &height)
{
status_t ret = NO_ERROR;
+ LOG_FUNCTION_NAME;
// Just return the current preview size, nothing more to do here.
mParams.getPreviewSize(( int * ) &width,
@@ -503,6 +504,64 @@ V4LCameraAdapter::~V4LCameraAdapter()
LOG_FUNCTION_NAME_EXIT;
}
+void convertYUV422ToNV12(unsigned char *src, unsigned char *dest, int width, int height ) {
+ //convert YUV422I to YUV420 NV12 format.
+ size_t nv12_buf_size = (width * height)*3/2;
+ unsigned char *bf = src;
+ unsigned char *dst = dest;
+
+ for(int i = 0; i < height; i++)
+ {
+ for(int j = 0; j < width; j++)
+ {
+ *dst = *bf;
+ dst++;
+ bf = bf + 2;
+ }
+ }
+
+ bf = src;
+ bf++; //U sample
+ for(int i = 0; i < height/2; i++)
+ {
+ for(int j=0; j<width; j++)
+ {
+ *dst = *bf;
+ dst++;
+ bf = bf + 2;
+ }
+ bf = bf + width*2;
+ }
+}
+
+#ifdef SAVE_RAW_FRAMES
+void saveFile(unsigned char* buff, int buff_size) {
+ static int counter = 1;
+ int fd = -1;
+ char fn[256];
+
+ LOG_FUNCTION_NAME;
+ if (counter > 3) {
+ return;
+ }
+ //dump nv12 buffer
+ sprintf(fn, "/data/misc/camera/raw/nv12_dump_%03d.yuv", counter);
+ CAMHAL_LOGEB("Dumping nv12 frame to a file : %s.", fn);
+
+ fd = open(fn, O_CREAT | O_WRONLY | O_SYNC | O_TRUNC, 0777);
+ if(fd < 0) {
+ LOGE("Unable to open file %s: %s", fn, strerror(fd));
+ return;
+ }
+
+ counter++;
+ write(fd, buff, buff_size );
+ close(fd);
+
+ LOG_FUNCTION_NAME_EXIT;
+}
+#endif
+
/* Preview Thread */
// ---------------------------------------------------------------------------
@@ -511,52 +570,74 @@ int V4LCameraAdapter::previewThread()
status_t ret = NO_ERROR;
int width, height;
CameraFrame frame;
+ unsigned char *nv12_buff = NULL;
+ void *y_uv[2];
- if (mPreviewing)
- {
+ mParams.getPreviewSize(&width, &height);
+ nv12_buff = (unsigned char*) malloc(width*height*3/2);
+
+ if (mPreviewing) {
int index = 0;
char *fp = this->GetFrame(index);
- if(!fp)
- {
+ if(!fp) {
return BAD_VALUE;
- }
+ }
uint8_t* ptr = (uint8_t*) mPreviewBufs.keyAt(index);
+ int stride = 4096;
+
+ //Convert yuv422i ti yuv420sp(NV12) & dump the frame to a file
+ convertYUV422ToNV12 ( (unsigned char*)fp, nv12_buff, width, height);
+#ifdef SAVE_RAW_FRAMES
+ saveFile( nv12_buff, ((width*height)*3/2) );
+#endif
+
+ CameraFrame *lframe = (CameraFrame *)mFrameQueue.valueFor(ptr);
+ y_uv[0] = (void*) lframe->mYuv[0];
+ //y_uv[1] = (void*) lframe->mYuv[1];
+ y_uv[1] = (void*) lframe->mYuv[0] + height*stride;
+
+ CAMHAL_LOGVB("##...index= %d.;ptr= 0x%x; y= 0x%x; UV= 0x%x.",index, ptr, y_uv[0], y_uv[1] );
+
+ unsigned char *bufferDst = ( unsigned char * ) y_uv[0];
+ unsigned char *bufferSrc = nv12_buff;
+ int rowBytes = width;
+
+ //Copy the Y plane to Gralloc buffer
+ for(int i = 0; i < height; i++) {
+ memcpy(bufferDst, bufferSrc, rowBytes);
+ bufferDst += stride;
+ bufferSrc += rowBytes;
+ }
+ //Copy UV plane, now Y & UV are contiguous.
+ //bufferDst = ( unsigned char * ) y_uv[1];
+ for(int j = 0; j < height/2; j++) {
+ memcpy(bufferDst, bufferSrc, rowBytes);
+ bufferDst += stride;
+ bufferSrc += rowBytes;
+ }
- int width, height;
- uint16_t* dest = (uint16_t*)ptr;
- uint16_t* src = (uint16_t*) fp;
- mParams.getPreviewSize(&width, &height);
- for(int i=0;i<height;i++)
- {
- for(int j=0;j<width;j++)
- {
- //*dest = *src;
- //convert from YUYV to UYVY supported in Camera service
- *dest = (((*src & 0xFF000000)>>24)<<16)|(((*src & 0x00FF0000)>>16)<<24) |
- (((*src & 0xFF00)>>8)<<0)|(((*src & 0x00FF)>>0)<<8);
- src++;
- dest++;
- }
- dest += 4096/2-width;
- }
-
- mParams.getPreviewSize(&width, &height);
frame.mFrameType = CameraFrame::PREVIEW_FRAME_SYNC;
frame.mBuffer = ptr;
- frame.mLength = width*height*2;
- frame.mAlignment = width*2;
+ frame.mLength = width*height*3/2;
+ frame.mAlignment = stride;
frame.mOffset = 0;
frame.mTimestamp = systemTime(SYSTEM_TIME_MONOTONIC);;
+ frame.mFrameMask = (unsigned int)CameraFrame::PREVIEW_FRAME_SYNC;
- ret = sendFrameToSubscribers(&frame);
-
+ ret = setInitFrameRefCount(frame.mBuffer, frame.mFrameMask);
+ if (ret != NO_ERROR) {
+ CAMHAL_LOGDB("Error in setInitFrameRefCount %d", ret);
+ } else {
+ ret = sendFrameToSubscribers(&frame);
}
+ }
+ free (nv12_buff);
return ret;
}
-extern "C" CameraAdapter* CameraAdapter_Factory()
+extern "C" CameraAdapter* CameraAdapter_Factory(size_t sensor_index)
{
CameraAdapter *adapter = NULL;
Mutex::Autolock lock(gAdapterLock);
@@ -575,17 +656,21 @@ extern "C" CameraAdapter* CameraAdapter_Factory()
return adapter;
}
-extern "C" int CameraAdapter_Capabilities(CameraProperties::Properties* properties_array,
- const unsigned int starting_camera,
- const unsigned int max_camera) {
+extern "C" status_t CameraAdapter_Capabilities(
+ CameraProperties::Properties * const properties_array,
+ const int starting_camera, const int max_camera, int & supportedCameras)
+{
+ LOG_FUNCTION_NAME;
+
+ supportedCameras = 0;
int num_cameras_supported = 0;
CameraProperties::Properties* properties = NULL;
+ CAMHAL_LOGEB("starting_camera+%d, max_camera=%d, supportedCameras=%d", starting_camera,max_camera,supportedCameras);
- LOG_FUNCTION_NAME;
-
- if(!properties_array)
- {
- return -EINVAL;
+ if (!properties_array) {
+ CAMHAL_LOGEB("invalid param: properties = 0x%p", properties_array);
+ LOG_FUNCTION_NAME_EXIT;
+ return BAD_VALUE;
}
// TODO: Need to tell camera properties what other cameras we can support
@@ -593,11 +678,25 @@ extern "C" int CameraAdapter_Capabilities(CameraProperties::Properties* properti
num_cameras_supported++;
properties = properties_array + starting_camera;
properties->set(CameraProperties::CAMERA_NAME, "USBCamera");
+ properties->set(CameraProperties::PREVIEW_SIZE, "640x480");
+ properties->set(CameraProperties::PREVIEW_FORMAT, "yuv420sp");
+ properties->set(CameraProperties::SUPPORTED_PREVIEW_FORMATS, "yuv420sp");
+ properties->set(CameraProperties::PICTURE_SIZE, "640x480");
+ properties->set(CameraProperties::JPEG_THUMBNAIL_SIZE, "320x240");
+ properties->set(CameraProperties::SUPPORTED_PREVIEW_SIZES, "640x480");
+ properties->set(CameraProperties::SUPPORTED_PICTURE_SIZES, "640x480");
+ properties->set(CameraProperties::REQUIRED_PREVIEW_BUFS, "6");
+ properties->set(CameraProperties::FRAMERATE_RANGE_SUPPORTED, "30000,30000");
+ properties->set(CameraProperties::SUPPORTED_PREVIEW_FRAME_RATES, "30000,30000");
+ properties->set(CameraProperties::FRAMERATE_RANGE, "30000,30000");
+ properties->set(CameraProperties::PREVIEW_FRAME_RATE, "30000");
+
}
+ supportedCameras = num_cameras_supported;
LOG_FUNCTION_NAME_EXIT;
- return num_cameras_supported;
+ return NO_ERROR;
}
};