summaryrefslogtreecommitdiffstats
path: root/camera/V4LCameraAdapter/V4LCameraAdapter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'camera/V4LCameraAdapter/V4LCameraAdapter.cpp')
-rw-r--r--camera/V4LCameraAdapter/V4LCameraAdapter.cpp1318
1 files changed, 0 insertions, 1318 deletions
diff --git a/camera/V4LCameraAdapter/V4LCameraAdapter.cpp b/camera/V4LCameraAdapter/V4LCameraAdapter.cpp
deleted file mode 100644
index 29c71c7..0000000
--- a/camera/V4LCameraAdapter/V4LCameraAdapter.cpp
+++ /dev/null
@@ -1,1318 +0,0 @@
-/*
- * Copyright (C) Texas Instruments - http://www.ti.com/
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
-* @file V4LCameraAdapter.cpp
-*
-* This file maps the Camera Hardware Interface to V4L2.
-*
-*/
-
-
-#include "V4LCameraAdapter.h"
-#include "CameraHal.h"
-#include "TICameraParameters.h"
-#include "DebugUtils.h"
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <errno.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#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 ))
-static int mDebugFps = 0;
-
-#define Q16_OFFSET 16
-
-#define HERE(Msg) {CAMHAL_LOGEB("--=== %s===--\n", Msg);}
-
-namespace Ti {
-namespace Camera {
-
-//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 DUMP_CAPTURE_FRAME 1
-//#define PPM_PER_FRAME_CONVERSION 1
-
-//Proto Types
-static void convertYUV422i_yuyvTouyvy(uint8_t *src, uint8_t *dest, size_t size );
-static void convertYUV422ToNV12Tiler(unsigned char *src, unsigned char *dest, int width, int height );
-static void convertYUV422ToNV12(unsigned char *src, unsigned char *dest, int width, int height );
-
-android::Mutex gV4LAdapterLock;
-char device[15];
-
-
-/*--------------------Camera Adapter Class STARTS here-----------------------------*/
-
-/*--------------------V4L wrapper functions -------------------------------*/
-status_t V4LCameraAdapter::v4lIoctl (int fd, int req, void* argp) {
- status_t ret = NO_ERROR;
- errno = 0;
-
- do {
- ret = ioctl (fd, req, argp);
- }while (-1 == ret && EINTR == errno);
-
- return ret;
-}
-
-status_t V4LCameraAdapter::v4lInitMmap(int& count) {
- status_t ret = NO_ERROR;
-
- //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 */
- mVideoInfo->rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- mVideoInfo->rb.memory = V4L2_MEMORY_MMAP;
- mVideoInfo->rb.count = count;
-
- ret = v4lIoctl(mCameraHandle, VIDIOC_REQBUFS, &mVideoInfo->rb);
- if (ret < 0) {
- CAMHAL_LOGEB("VIDIOC_REQBUFS failed: %s", strerror(errno));
- return ret;
- }
-
- count = mVideoInfo->rb.count;
- for (int i = 0; i < count; i++) {
-
- 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;
- }
-
- mVideoInfo->mem[i] = mmap (NULL,
- mVideoInfo->buf.length,
- PROT_READ | PROT_WRITE,
- MAP_SHARED,
- mCameraHandle,
- mVideoInfo->buf.m.offset);
-
- CAMHAL_LOGVB(" mVideoInfo->mem[%d]=%p ; mVideoInfo->buf.length = %d", i, mVideoInfo->mem[i], mVideoInfo->buf.length);
- if (mVideoInfo->mem[i] == MAP_FAILED) {
- CAMHAL_LOGEB("Unable to map buffer [%d]. (%s)", i, strerror(errno));
- return -1;
- }
- }
- return ret;
-}
-
-status_t V4LCameraAdapter::v4lInitUsrPtr(int& count) {
- status_t ret = NO_ERROR;
-
- mVideoInfo->rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- mVideoInfo->rb.memory = V4L2_MEMORY_USERPTR;
- mVideoInfo->rb.count = count;
-
- ret = v4lIoctl(mCameraHandle, VIDIOC_REQBUFS, &mVideoInfo->rb);
- if (ret < 0) {
- CAMHAL_LOGEB("VIDIOC_REQBUFS failed for USERPTR: %s", strerror(errno));
- return ret;
- }
-
- count = mVideoInfo->rb.count;
- return ret;
-}
-
-status_t V4LCameraAdapter::v4lStartStreaming () {
- status_t ret = NO_ERROR;
- enum v4l2_buf_type bufType;
-
- if (!mVideoInfo->isStreaming) {
- bufType = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
- ret = v4lIoctl (mCameraHandle, VIDIOC_STREAMON, &bufType);
- if (ret < 0) {
- CAMHAL_LOGEB("StartStreaming: Unable to start capture: %s", strerror(errno));
- return ret;
- }
- mVideoInfo->isStreaming = true;
- }
- return ret;
-}
-
-status_t V4LCameraAdapter::v4lStopStreaming (int nBufferCount) {
- status_t ret = NO_ERROR;
- enum v4l2_buf_type bufType;
-
- if (mVideoInfo->isStreaming) {
- bufType = V4L2_BUF_TYPE_VIDEO_CAPTURE;
-
- ret = v4lIoctl (mCameraHandle, VIDIOC_STREAMOFF, &bufType);
- if (ret < 0) {
- CAMHAL_LOGEB("StopStreaming: Unable to stop capture: %s", strerror(errno));
- goto EXIT;
- }
- mVideoInfo->isStreaming = false;
-
- /* Unmap buffers */
- mVideoInfo->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- mVideoInfo->buf.memory = V4L2_MEMORY_MMAP;
- for (int i = 0; i < nBufferCount; i++) {
- if (munmap(mVideoInfo->mem[i], mVideoInfo->buf.length) < 0) {
- CAMHAL_LOGEA("munmap() failed");
- }
- }
-
- //free the memory allocated during REQBUFS, by setting the count=0
- mVideoInfo->rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- mVideoInfo->rb.memory = V4L2_MEMORY_MMAP;
- mVideoInfo->rb.count = 0;
-
- ret = v4lIoctl(mCameraHandle, VIDIOC_REQBUFS, &mVideoInfo->rb);
- if (ret < 0) {
- CAMHAL_LOGEB("VIDIOC_REQBUFS failed: %s", strerror(errno));
- goto EXIT;
- }
- }
-EXIT:
- return ret;
-}
-
-status_t V4LCameraAdapter::v4lSetFormat (int width, int height, uint32_t pix_format) {
- status_t ret = NO_ERROR;
-
- mVideoInfo->format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- ret = v4lIoctl(mCameraHandle, VIDIOC_G_FMT, &mVideoInfo->format);
- if (ret < 0) {
- CAMHAL_LOGEB("VIDIOC_G_FMT Failed: %s", strerror(errno));
- }
-
- mVideoInfo->width = width;
- mVideoInfo->height = height;
- mVideoInfo->framesizeIn = (width * height << 1);
- mVideoInfo->formatIn = DEFAULT_PIXEL_FORMAT;
-
- mVideoInfo->format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- mVideoInfo->format.fmt.pix.width = width;
- mVideoInfo->format.fmt.pix.height = height;
- mVideoInfo->format.fmt.pix.pixelformat = pix_format;
-
- ret = v4lIoctl(mCameraHandle, VIDIOC_S_FMT, &mVideoInfo->format);
- if (ret < 0) {
- CAMHAL_LOGEB("VIDIOC_S_FMT Failed: %s", strerror(errno));
- return ret;
- }
- v4lIoctl(mCameraHandle, VIDIOC_G_FMT, &mVideoInfo->format);
- CAMHAL_LOGDB("VIDIOC_G_FMT : WxH = %dx%d", mVideoInfo->format.fmt.pix.width, mVideoInfo->format.fmt.pix.height);
- return ret;
-}
-
-status_t V4LCameraAdapter::restartPreview ()
-{
- status_t ret = NO_ERROR;
- int width = 0;
- int height = 0;
- struct v4l2_streamparm streamParams;
-
- //configure for preview size and pixel format.
- mParams.getPreviewSize(&width, &height);
-
- ret = v4lSetFormat (width, height, DEFAULT_PIXEL_FORMAT);
- if (ret < 0) {
- CAMHAL_LOGEB("v4lSetFormat Failed: %s", strerror(errno));
- goto EXIT;
- }
-
- ret = v4lInitMmap(mPreviewBufferCount);
- if (ret < 0) {
- CAMHAL_LOGEB("v4lInitMmap Failed: %s", strerror(errno));
- goto EXIT;
- }
-
- //set frame rate
- streamParams.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- streamParams.parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
- streamParams.parm.capture.capturemode = V4L2_MODE_HIGHQUALITY;
- streamParams.parm.capture.timeperframe.denominator = FPS_PERIOD;
- streamParams.parm.capture.timeperframe.numerator= 1;
- ret = v4lIoctl(mCameraHandle, VIDIOC_S_PARM, &streamParams);
- if (ret < 0) {
- CAMHAL_LOGEB("VIDIOC_S_PARM Failed: %s", strerror(errno));
- goto EXIT;
- }
-
- for (int i = 0; i < mPreviewBufferCountQueueable; i++) {
-
- mVideoInfo->buf.index = i;
- mVideoInfo->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- mVideoInfo->buf.memory = V4L2_MEMORY_MMAP;
-
- ret = v4lIoctl(mCameraHandle, VIDIOC_QBUF, &mVideoInfo->buf);
- if (ret < 0) {
- CAMHAL_LOGEA("VIDIOC_QBUF Failed");
- goto EXIT;
- }
- nQueued++;
- }
-
- ret = v4lStartStreaming();
- CAMHAL_LOGDA("Ready for preview....");
-EXIT:
- return ret;
-}
-
-/*--------------------Camera Adapter Functions-----------------------------*/
-status_t V4LCameraAdapter::initialize(CameraProperties::Properties* caps)
-{
- char value[PROPERTY_VALUE_MAX];
-
- LOG_FUNCTION_NAME;
- property_get("debug.camera.showfps", value, "0");
- mDebugFps = atoi(value);
-
- int ret = NO_ERROR;
-
- // Allocate memory for video info structure
- mVideoInfo = (struct VideoInfo *) calloc (1, sizeof (struct VideoInfo));
- if(!mVideoInfo) {
- ret = NO_MEMORY;
- goto EXIT;
- }
-
- if ((mCameraHandle = open(device, O_RDWR) ) == -1) {
- CAMHAL_LOGEB("Error while opening handle to V4L2 Camera: %s", strerror(errno));
- ret = BAD_VALUE;
- goto EXIT;
- }
-
- ret = v4lIoctl (mCameraHandle, VIDIOC_QUERYCAP, &mVideoInfo->cap);
- if (ret < 0) {
- CAMHAL_LOGEA("Error when querying the capabilities of the V4L Camera");
- ret = BAD_VALUE;
- goto EXIT;
- }
-
- if ((mVideoInfo->cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) == 0) {
- CAMHAL_LOGEA("Error while adapter initialization: video capture not supported.");
- ret = BAD_VALUE;
- goto EXIT;
- }
-
- if (!(mVideoInfo->cap.capabilities & V4L2_CAP_STREAMING)) {
- CAMHAL_LOGEA("Error while adapter initialization: Capture device does not support streaming i/o");
- ret = BAD_VALUE;
- goto EXIT;
- }
-
- // Initialize flags
- mPreviewing = false;
- mVideoInfo->isStreaming = false;
- mRecording = false;
- mCapturing = false;
-EXIT:
- LOG_FUNCTION_NAME_EXIT;
- return ret;
-}
-
-status_t V4LCameraAdapter::fillThisBuffer(CameraBuffer *frameBuf, CameraFrame::FrameType frameType)
-{
- status_t ret = NO_ERROR;
- int idx = 0;
- LOG_FUNCTION_NAME;
-
- if ( frameType == CameraFrame::IMAGE_FRAME) { //(1 > mCapturedFrames)
- // Signal end of image capture
- if ( NULL != mEndImageCaptureCallback) {
- CAMHAL_LOGDB("===========Signal End Image Capture==========");
- mEndImageCaptureCallback(mEndCaptureData);
- }
- goto EXIT;
- }
- if ( !mVideoInfo->isStreaming ) {
- goto EXIT;
- }
-
- idx = mPreviewBufs.valueFor(frameBuf);
- if(idx < 0) {
- CAMHAL_LOGEB("Wrong index = %d",idx);
- goto EXIT;
- }
-
- mVideoInfo->buf.index = idx;
- mVideoInfo->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- mVideoInfo->buf.memory = V4L2_MEMORY_MMAP;
-
- ret = v4lIoctl(mCameraHandle, VIDIOC_QBUF, &mVideoInfo->buf);
- if (ret < 0) {
- CAMHAL_LOGEA("VIDIOC_QBUF Failed");
- goto EXIT;
- }
- nQueued++;
-EXIT:
- LOG_FUNCTION_NAME_EXIT;
- return ret;
-
-}
-
-status_t V4LCameraAdapter::setParameters(const android::CameraParameters &params)
-{
- status_t ret = NO_ERROR;
- int width, height;
- struct v4l2_streamparm streamParams;
-
- LOG_FUNCTION_NAME;
-
- if(!mPreviewing && !mCapturing) {
- params.getPreviewSize(&width, &height);
- CAMHAL_LOGDB("Width * Height %d x %d format 0x%x", width, height, DEFAULT_PIXEL_FORMAT);
-
- ret = v4lSetFormat( width, height, DEFAULT_PIXEL_FORMAT);
- if (ret < 0) {
- CAMHAL_LOGEB(" VIDIOC_S_FMT Failed: %s", strerror(errno));
- goto EXIT;
- }
- //set frame rate
- // Now its fixed to 30 FPS
- streamParams.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- streamParams.parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
- streamParams.parm.capture.capturemode = V4L2_MODE_HIGHQUALITY;
- streamParams.parm.capture.timeperframe.denominator = FPS_PERIOD;
- streamParams.parm.capture.timeperframe.numerator= 1;
- ret = v4lIoctl(mCameraHandle, VIDIOC_S_PARM, &streamParams);
- if (ret < 0) {
- CAMHAL_LOGEB(" VIDIOC_S_PARM Failed: %s", strerror(errno));
- goto EXIT;
- }
- int actualFps = streamParams.parm.capture.timeperframe.denominator / streamParams.parm.capture.timeperframe.numerator;
- CAMHAL_LOGDB("Actual FPS set is : %d.", actualFps);
- }
-
- // Udpate the current parameter set
- mParams = params;
-
-EXIT:
- LOG_FUNCTION_NAME_EXIT;
- return ret;
-}
-
-
-void V4LCameraAdapter::getParameters(android::CameraParameters& params)
-{
- LOG_FUNCTION_NAME;
-
- // Return the current parameter set
- params = mParams;
-
- LOG_FUNCTION_NAME_EXIT;
-}
-
-
-///API to give the buffers to Adapter
-status_t V4LCameraAdapter::useBuffers(CameraMode mode, CameraBuffer *bufArr, int num, size_t length, unsigned int queueable)
-{
- status_t ret = NO_ERROR;
-
- LOG_FUNCTION_NAME;
-
- android::AutoMutex lock(mLock);
-
- switch(mode)
- {
- case CAMERA_PREVIEW:
- mPreviewBufferCountQueueable = queueable;
- ret = UseBuffersPreview(bufArr, num);
- break;
-
- case CAMERA_IMAGE_CAPTURE:
- mCaptureBufferCountQueueable = queueable;
- ret = UseBuffersCapture(bufArr, num);
- break;
-
- case CAMERA_VIDEO:
- //@warn Video capture is not fully supported yet
- mPreviewBufferCountQueueable = queueable;
- ret = UseBuffersPreview(bufArr, num);
- break;
-
- case CAMERA_MEASUREMENT:
- break;
-
- default:
- break;
- }
-
- LOG_FUNCTION_NAME_EXIT;
-
- return ret;
-}
-
-status_t V4LCameraAdapter::UseBuffersCapture(CameraBuffer *bufArr, int num) {
- int ret = NO_ERROR;
-
- LOG_FUNCTION_NAME;
- if(NULL == bufArr) {
- ret = BAD_VALUE;
- goto EXIT;
- }
-
- for (int i = 0; i < num; i++) {
- //Associate each Camera internal buffer with the one from Overlay
- mCaptureBufs.add(&bufArr[i], i);
- CAMHAL_LOGDB("capture- buff [%d] = 0x%x ",i, mCaptureBufs.keyAt(i));
- }
-
- // Update the preview buffer count
- mCaptureBufferCount = num;
-EXIT:
- LOG_FUNCTION_NAME_EXIT;
- return ret;
-
-}
-
-status_t V4LCameraAdapter::UseBuffersPreview(CameraBuffer *bufArr, int num)
-{
- int ret = NO_ERROR;
- LOG_FUNCTION_NAME;
-
- if(NULL == bufArr) {
- ret = BAD_VALUE;
- goto EXIT;
- }
-
- ret = v4lInitMmap(num);
- if (ret == NO_ERROR) {
- for (int i = 0; i < num; i++) {
- //Associate each Camera internal buffer with the one from Overlay
- mPreviewBufs.add(&bufArr[i], i);
- CAMHAL_LOGDB("Preview- buff [%d] = 0x%x ",i, mPreviewBufs.keyAt(i));
- }
-
- // Update the preview buffer count
- mPreviewBufferCount = num;
- }
-EXIT:
- LOG_FUNCTION_NAME_EXIT;
- return ret;
-}
-
-status_t V4LCameraAdapter::takePicture() {
- status_t ret = NO_ERROR;
- int width = 0;
- int height = 0;
- size_t yuv422i_buff_size = 0;
- int index = 0;
- char *fp = NULL;
- CameraBuffer *buffer = NULL;
- CameraFrame frame;
-
- LOG_FUNCTION_NAME;
-
- android::AutoMutex lock(mCaptureBufsLock);
-
- if(mCapturing) {
- CAMHAL_LOGEA("Already Capture in Progress...");
- ret = BAD_VALUE;
- goto EXIT;
- }
-
- mCapturing = true;
- mPreviewing = false;
-
- // Stop preview streaming
- ret = v4lStopStreaming(mPreviewBufferCount);
- if (ret < 0 ) {
- CAMHAL_LOGEB("v4lStopStreaming Failed: %s", strerror(errno));
- goto EXIT;
- }
-
- //configure for capture image size and pixel format.
- mParams.getPictureSize(&width, &height);
- CAMHAL_LOGDB("Image Capture Size WxH = %dx%d",width,height);
- yuv422i_buff_size = width * height * 2;
-
- ret = v4lSetFormat (width, height, DEFAULT_PIXEL_FORMAT);
- if (ret < 0) {
- CAMHAL_LOGEB("v4lSetFormat Failed: %s", strerror(errno));
- goto EXIT;
- }
-
- ret = v4lInitMmap(mCaptureBufferCount);
- if (ret < 0) {
- CAMHAL_LOGEB("v4lInitMmap Failed: %s", strerror(errno));
- goto EXIT;
- }
-
- for (int i = 0; i < mCaptureBufferCountQueueable; i++) {
-
- mVideoInfo->buf.index = i;
- mVideoInfo->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- mVideoInfo->buf.memory = V4L2_MEMORY_MMAP;
-
- ret = v4lIoctl(mCameraHandle, VIDIOC_QBUF, &mVideoInfo->buf);
- if (ret < 0) {
- CAMHAL_LOGEA("VIDIOC_QBUF Failed");
- ret = BAD_VALUE;
- goto EXIT;
- }
- nQueued++;
- }
-
- ret = v4lStartStreaming();
- if (ret < 0) {
- CAMHAL_LOGEB("v4lStartStreaming Failed: %s", strerror(errno));
- goto EXIT;
- }
-
- CAMHAL_LOGDA("Streaming started for Image Capture");
-
- //get the frame and send to encode as JPG
- fp = this->GetFrame(index);
- if(!fp) {
- CAMHAL_LOGEA("!!! Captured frame is NULL !!!!");
- ret = BAD_VALUE;
- goto EXIT;
- }
-
- CAMHAL_LOGDA("::Capture Frame received from V4L::");
- buffer = mCaptureBufs.keyAt(index);
- CAMHAL_LOGVB("## captureBuf[%d] = 0x%x, yuv422i_buff_size=%d", index, buffer->opaque, yuv422i_buff_size);
-
- //copy the yuv422i data to the image buffer.
- memcpy(buffer->opaque, fp, yuv422i_buff_size);
-
-#ifdef DUMP_CAPTURE_FRAME
- //dump the YUV422 buffer in to a file
- //a folder should have been created at /data/misc/camera/raw/
- {
- int fd =-1;
- fd = open("/data/misc/camera/raw/captured_yuv422i_dump.yuv", O_CREAT | O_WRONLY | O_SYNC | O_TRUNC, 0777);
- if(fd < 0) {
- CAMHAL_LOGEB("Unable to open file: %s", strerror(fd));
- }
- else {
- write(fd, fp, yuv422i_buff_size );
- close(fd);
- CAMHAL_LOGDB("::Captured Frame dumped at /data/misc/camera/raw/captured_yuv422i_dump.yuv::");
- }
- }
-#endif
-
- CAMHAL_LOGDA("::sending capture frame to encoder::");
- frame.mFrameType = CameraFrame::IMAGE_FRAME;
- frame.mBuffer = buffer;
- frame.mLength = yuv422i_buff_size;
- frame.mWidth = width;
- frame.mHeight = height;
- frame.mAlignment = width*2;
- frame.mOffset = 0;
- frame.mTimestamp = systemTime(SYSTEM_TIME_MONOTONIC);
- frame.mFrameMask = (unsigned int)CameraFrame::IMAGE_FRAME;
- frame.mQuirks |= CameraFrame::ENCODE_RAW_YUV422I_TO_JPEG;
- frame.mQuirks |= CameraFrame::FORMAT_YUV422I_YUYV;
-
- ret = setInitFrameRefCount(frame.mBuffer, frame.mFrameMask);
- if (ret != NO_ERROR) {
- CAMHAL_LOGDB("Error in setInitFrameRefCount %d", ret);
- } else {
- ret = sendFrameToSubscribers(&frame);
- }
-
- // Stop streaming after image capture
- ret = v4lStopStreaming(mCaptureBufferCount);
- if (ret < 0 ) {
- CAMHAL_LOGEB("v4lStopStreaming Failed: %s", strerror(errno));
- goto EXIT;
- }
-
- ret = restartPreview();
-EXIT:
- LOG_FUNCTION_NAME_EXIT;
- return ret;
-}
-
-status_t V4LCameraAdapter::stopImageCapture()
-{
- status_t ret = NO_ERROR;
- LOG_FUNCTION_NAME;
-
- //Release image buffers
- if ( NULL != mReleaseImageBuffersCallback ) {
- mReleaseImageBuffersCallback(mReleaseData);
- }
- mCaptureBufs.clear();
-
- mCapturing = false;
- mPreviewing = true;
- LOG_FUNCTION_NAME_EXIT;
- return ret;
-}
-
-status_t V4LCameraAdapter::autoFocus()
-{
- status_t ret = NO_ERROR;
- LOG_FUNCTION_NAME;
-
- //autoFocus is not implemented. Just return.
- LOG_FUNCTION_NAME_EXIT;
- return ret;
-}
-
-status_t V4LCameraAdapter::startPreview()
-{
- status_t ret = NO_ERROR;
-
- LOG_FUNCTION_NAME;
- android::AutoMutex lock(mPreviewBufsLock);
-
- if(mPreviewing) {
- ret = BAD_VALUE;
- goto EXIT;
- }
-
- for (int i = 0; i < mPreviewBufferCountQueueable; i++) {
-
- mVideoInfo->buf.index = i;
- mVideoInfo->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- mVideoInfo->buf.memory = V4L2_MEMORY_MMAP;
-
- ret = v4lIoctl(mCameraHandle, VIDIOC_QBUF, &mVideoInfo->buf);
- if (ret < 0) {
- CAMHAL_LOGEA("VIDIOC_QBUF Failed");
- goto EXIT;
- }
- nQueued++;
- }
-
- ret = v4lStartStreaming();
-
- // Create and start preview thread for receiving buffers from V4L Camera
- if(!mCapturing) {
- mPreviewThread = new PreviewThread(this);
- CAMHAL_LOGDA("Created preview thread");
- }
-
- //Update the flag to indicate we are previewing
- mPreviewing = true;
- mCapturing = false;
-
-EXIT:
- LOG_FUNCTION_NAME_EXIT;
- return ret;
-}
-
-status_t V4LCameraAdapter::stopPreview()
-{
- enum v4l2_buf_type bufType;
- int ret = NO_ERROR;
-
- LOG_FUNCTION_NAME;
- android::AutoMutex lock(mStopPreviewLock);
-
- if(!mPreviewing) {
- return NO_INIT;
- }
- mPreviewing = false;
-
- ret = v4lStopStreaming(mPreviewBufferCount);
- if (ret < 0) {
- CAMHAL_LOGEB("StopStreaming: FAILED: %s", strerror(errno));
- }
-
- nQueued = 0;
- nDequeued = 0;
- mFramesWithEncoder = 0;
-
- mPreviewBufs.clear();
-
- mPreviewThread->requestExitAndWait();
- mPreviewThread.clear();
-
- LOG_FUNCTION_NAME_EXIT;
- return ret;
-}
-
-char * V4LCameraAdapter::GetFrame(int &index)
-{
- int ret = NO_ERROR;
- LOG_FUNCTION_NAME;
-
- mVideoInfo->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
- mVideoInfo->buf.memory = V4L2_MEMORY_MMAP;
-
- /* DQ */
- ret = v4lIoctl(mCameraHandle, VIDIOC_DQBUF, &mVideoInfo->buf);
- if (ret < 0) {
- CAMHAL_LOGEA("GetFrame: VIDIOC_DQBUF Failed");
- return NULL;
- }
- nDequeued++;
-
- index = mVideoInfo->buf.index;
-
- LOG_FUNCTION_NAME_EXIT;
- return (char *)mVideoInfo->mem[mVideoInfo->buf.index];
-}
-
-//API to get the frame size required to be allocated. This size is used to override the size passed
-//by camera service when VSTAB/VNF is turned ON for example
-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,
- ( int * ) &height);
-
- LOG_FUNCTION_NAME_EXIT;
-
- return ret;
-}
-
-status_t V4LCameraAdapter::getFrameDataSize(size_t &dataFrameSize, size_t bufferCount)
-{
- // We don't support meta data, so simply return
- return NO_ERROR;
-}
-
-status_t V4LCameraAdapter::getPictureBufferSize(CameraFrame *frame, size_t bufferCount)
-{
- int width = 0;
- int height = 0;
- int bytesPerPixel = 2; // for YUV422i; default pixel format
-
- LOG_FUNCTION_NAME;
-
- if (frame == NULL) {
- return BAD_VALUE;
- }
-
- mParams.getPictureSize( &width, &height );
- frame->mLength = width * height * bytesPerPixel;
- frame->mWidth = width;
- frame->mHeight = height;
- frame->mAlignment = width * bytesPerPixel;
-
- CAMHAL_LOGDB("Picture size: W x H = %u x %u (size=%u bytes, alignment=%u bytes)",
- frame->mWidth, frame->mHeight, frame->mLength, frame->mAlignment);
- LOG_FUNCTION_NAME_EXIT;
- return NO_ERROR;
-}
-
-static void debugShowFPS()
-{
- static int mFrameCount = 0;
- static int mLastFrameCount = 0;
- static nsecs_t mLastFpsTime = 0;
- static float mFps = 0;
- if(mDebugFps) {
- mFrameCount++;
- if (!(mFrameCount & 0x1F)) {
- nsecs_t now = systemTime();
- nsecs_t diff = now - mLastFpsTime;
- mFps = ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
- mLastFpsTime = now;
- mLastFrameCount = mFrameCount;
- CAMHAL_LOGD("Camera %d Frames, %f FPS", mFrameCount, mFps);
- }
- }
-}
-
-status_t V4LCameraAdapter::recalculateFPS()
-{
- float currentFPS;
-
- mFrameCount++;
-
- if ( ( mFrameCount % FPS_PERIOD ) == 0 )
- {
- nsecs_t now = systemTime();
- nsecs_t diff = now - mLastFPSTime;
- currentFPS = ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
- mLastFPSTime = now;
- mLastFrameCount = mFrameCount;
-
- if ( 1 == mIter )
- {
- mFPS = currentFPS;
- }
- else
- {
- //cumulative moving average
- mFPS = mLastFPS + (currentFPS - mLastFPS)/mIter;
- }
-
- mLastFPS = mFPS;
- mIter++;
- }
-
- return NO_ERROR;
-}
-
-void V4LCameraAdapter::onOrientationEvent(uint32_t orientation, uint32_t tilt)
-{
- LOG_FUNCTION_NAME;
-
- LOG_FUNCTION_NAME_EXIT;
-}
-
-
-V4LCameraAdapter::V4LCameraAdapter(size_t sensor_index)
-{
- LOG_FUNCTION_NAME;
-
- // Nothing useful to do in the constructor
- mFramesWithEncoder = 0;
-
- LOG_FUNCTION_NAME_EXIT;
-}
-
-V4LCameraAdapter::~V4LCameraAdapter()
-{
- LOG_FUNCTION_NAME;
-
- // Close the camera handle and free the video info structure
- close(mCameraHandle);
-
- if (mVideoInfo)
- {
- free(mVideoInfo);
- mVideoInfo = NULL;
- }
-
- LOG_FUNCTION_NAME_EXIT;
-}
-
-static void convertYUV422i_yuyvTouyvy(uint8_t *src, uint8_t *dest, size_t size ) {
- //convert YUV422I yuyv to uyvy format.
- uint32_t *bf = (uint32_t*)src;
- uint32_t *dst = (uint32_t*)dest;
-
- LOG_FUNCTION_NAME;
-
- if (!src || !dest) {
- return;
- }
-
- for(size_t i = 0; i < size; i = i+4)
- {
- dst[0] = ((bf[0] & 0x00FF00FF) << 8) | ((bf[0] & 0xFF00FF00) >> 8);
- bf++;
- dst++;
- }
-
- LOG_FUNCTION_NAME_EXIT;
-}
-
-static void convertYUV422ToNV12Tiler(unsigned char *src, unsigned char *dest, int width, int height ) {
- //convert YUV422I to YUV420 NV12 format and copies directly to preview buffers (Tiler memory).
- int stride = 4096;
- unsigned char *bf = src;
- unsigned char *dst_y = dest;
- unsigned char *dst_uv = dest + ( height * stride);
-#ifdef PPM_PER_FRAME_CONVERSION
- static int frameCount = 0;
- static nsecs_t ppm_diff = 0;
- nsecs_t ppm_start = systemTime();
-#endif
-
- LOG_FUNCTION_NAME;
-
- if (width % 16 ) {
- for(int i = 0; i < height; i++) {
- for(int j = 0; j < width; j++) {
- *dst_y = *bf;
- dst_y++;
- bf = bf + 2;
- }
- dst_y += (stride - width);
- }
-
- bf = src;
- bf++; //UV sample
- for(int i = 0; i < height/2; i++) {
- for(int j=0; j<width; j++) {
- *dst_uv = *bf;
- dst_uv++;
- bf = bf + 2;
- }
- bf = bf + width*2;
- dst_uv = dst_uv + (stride - width);
- }
- } else {
- //neon conversion
- for(int i = 0; i < height; i++) {
- int n = width;
- int skip = i & 0x1; // skip uv elements for the odd rows
- asm volatile (
- " pld [%[src], %[src_stride], lsl #2] \n\t"
- " cmp %[n], #16 \n\t"
- " blt 5f \n\t"
- "0: @ 16 pixel copy \n\t"
- " vld2.8 {q0, q1} , [%[src]]! @ q0 = yyyy.. q1 = uvuv.. \n\t"
- " @ now q0 = y q1 = uv \n\t"
- " vst1.32 {d0,d1}, [%[dst_y]]! \n\t"
- " cmp %[skip], #0 \n\t"
- " bne 1f \n\t"
- " vst1.32 {d2,d3},[%[dst_uv]]! \n\t"
- "1: @ skip odd rows for UV \n\t"
- " sub %[n], %[n], #16 \n\t"
- " cmp %[n], #16 \n\t"
- " bge 0b \n\t"
- "5: @ end \n\t"
-#ifdef NEEDS_ARM_ERRATA_754319_754320
- " vmov s0,s0 @ add noop for errata item \n\t"
-#endif
- : [dst_y] "+r" (dst_y), [dst_uv] "+r" (dst_uv), [src] "+r" (src), [n] "+r" (n)
- : [src_stride] "r" (width), [skip] "r" (skip)
- : "cc", "memory", "q0", "q1", "q2", "d0", "d1", "d2", "d3"
- );
- dst_y = dst_y + (stride - width);
- if (skip == 0) {
- dst_uv = dst_uv + (stride - width);
- }
- } //end of for()
- }
-
-#ifdef PPM_PER_FRAME_CONVERSION
- ppm_diff += (systemTime() - ppm_start);
- frameCount++;
-
- if (frameCount >= 30) {
- ppm_diff = ppm_diff / frameCount;
- LOGD("PPM: YUV422i to NV12 Conversion(%d x %d): %llu us ( %llu ms )", width, height,
- ns2us(ppm_diff), ns2ms(ppm_diff) );
- ppm_diff = 0;
- frameCount = 0;
- }
-#endif
-
- LOG_FUNCTION_NAME_EXIT;
-}
-
-static void convertYUV422ToNV12(unsigned char *src, unsigned char *dest, int width, int height ) {
- //convert YUV422I to YUV420 NV12 format.
- unsigned char *bf = src;
- unsigned char *dst_y = dest;
- unsigned char *dst_uv = dest + (width * height);
-
- LOG_FUNCTION_NAME;
-
- if (width % 16 ) {
- for(int i = 0; i < height; i++) {
- for(int j = 0; j < width; j++) {
- *dst_y = *bf;
- dst_y++;
- bf = bf + 2;
- }
- }
-
- bf = src;
- bf++; //UV sample
- for(int i = 0; i < height/2; i++) {
- for(int j=0; j<width; j++) {
- *dst_uv = *bf;
- dst_uv++;
- bf = bf + 2;
- }
- bf = bf + width*2;
- }
- } else {
- //neon conversion
- for(int i = 0; i < height; i++) {
- int n = width;
- int skip = i & 0x1; // skip uv elements for the odd rows
- asm volatile (
- " pld [%[src], %[src_stride], lsl #2] \n\t"
- " cmp %[n], #16 \n\t"
- " blt 5f \n\t"
- "0: @ 16 pixel copy \n\t"
- " vld2.8 {q0, q1} , [%[src]]! @ q0 = yyyy.. q1 = uvuv.. \n\t"
- " @ now q0 = y q1 = uv \n\t"
- " vst1.32 {d0,d1}, [%[dst_y]]! \n\t"
- " cmp %[skip], #0 \n\t"
- " bne 1f \n\t"
- " vst1.32 {d2,d3},[%[dst_uv]]! \n\t"
- "1: @ skip odd rows for UV \n\t"
- " sub %[n], %[n], #16 \n\t"
- " cmp %[n], #16 \n\t"
- " bge 0b \n\t"
- "5: @ end \n\t"
-#ifdef NEEDS_ARM_ERRATA_754319_754320
- " vmov s0,s0 @ add noop for errata item \n\t"
-#endif
- : [dst_y] "+r" (dst_y), [dst_uv] "+r" (dst_uv), [src] "+r" (src), [n] "+r" (n)
- : [src_stride] "r" (width), [skip] "r" (skip)
- : "cc", "memory", "q0", "q1", "q2", "d0", "d1", "d2", "d3"
- );
- }
- }
-
- LOG_FUNCTION_NAME_EXIT;
-}
-
-#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
- counter++;
- 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) {
- CAMHAL_LOGE("Unable to open file %s: %s", fn, strerror(fd));
- return;
- }
-
- write(fd, buff, buff_size );
- close(fd);
-
- LOG_FUNCTION_NAME_EXIT;
-}
-#endif
-
-/* Preview Thread */
-// ---------------------------------------------------------------------------
-
-int V4LCameraAdapter::previewThread()
-{
- status_t ret = NO_ERROR;
- int width, height;
- CameraFrame frame;
- void *y_uv[2];
- int index = 0;
- int stride = 4096;
- char *fp = NULL;
-
- mParams.getPreviewSize(&width, &height);
-
- if (mPreviewing) {
-
- fp = this->GetFrame(index);
- if(!fp) {
- ret = BAD_VALUE;
- goto EXIT;
- }
- CameraBuffer *buffer = mPreviewBufs.keyAt(index);
- CameraFrame *lframe = (CameraFrame *)mFrameQueue.valueFor(buffer);
- if (!lframe) {
- ret = BAD_VALUE;
- goto EXIT;
- }
-
- debugShowFPS();
-
- if ( mFrameSubscribers.size() == 0 ) {
- ret = BAD_VALUE;
- goto EXIT;
- }
- y_uv[0] = (void*) lframe->mYuv[0];
- //y_uv[1] = (void*) lframe->mYuv[1];
- //y_uv[1] = (void*) (lframe->mYuv[0] + height*stride);
- convertYUV422ToNV12Tiler ( (unsigned char*)fp, (unsigned char*)y_uv[0], width, height);
- CAMHAL_LOGVB("##...index= %d.;camera buffer= 0x%x; y= 0x%x; UV= 0x%x.",index, buffer, y_uv[0], y_uv[1] );
-
-#ifdef SAVE_RAW_FRAMES
- unsigned char* nv12_buff = (unsigned char*) malloc(width*height*3/2);
- //Convert yuv422i to yuv420sp(NV12) & dump the frame to a file
- convertYUV422ToNV12 ( (unsigned char*)fp, nv12_buff, width, height);
- saveFile( nv12_buff, ((width*height)*3/2) );
- free (nv12_buff);
-#endif
-
- frame.mFrameType = CameraFrame::PREVIEW_FRAME_SYNC;
- frame.mBuffer = buffer;
- 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;
-
- if (mRecording)
- {
- frame.mFrameMask |= (unsigned int)CameraFrame::VIDEO_FRAME_SYNC;
- mFramesWithEncoder++;
- }
-
- ret = setInitFrameRefCount(frame.mBuffer, frame.mFrameMask);
- if (ret != NO_ERROR) {
- CAMHAL_LOGDB("Error in setInitFrameRefCount %d", ret);
- } else {
- ret = sendFrameToSubscribers(&frame);
- }
- }
-EXIT:
-
- return ret;
-}
-
-//scan for video devices
-void detectVideoDevice(char** video_device_list, int& num_device) {
- char dir_path[20];
- char* filename;
- char** dev_list = video_device_list;
- DIR *d;
- struct dirent *dir;
- int index = 0;
-
- strcpy(dir_path, DEVICE_PATH);
- d = opendir(dir_path);
- if(d) {
- //read each entry in the /dev/ and find if there is videox entry.
- while ((dir = readdir(d)) != NULL) {
- filename = dir->d_name;
- if (strncmp(filename, DEVICE_NAME, 5) == 0) {
- strcpy(dev_list[index],DEVICE_PATH);
- strncat(dev_list[index],filename,sizeof(DEVICE_NAME));
- index++;
- }
- } //end of while()
- closedir(d);
- num_device = index;
-
- for(int i=0; i<index; i++){
- CAMHAL_LOGDB("Video device list::dev_list[%d]= %s",i,dev_list[i]);
- }
- }
-}
-
-extern "C" CameraAdapter* V4LCameraAdapter_Factory(size_t sensor_index)
-{
- CameraAdapter *adapter = NULL;
- android::AutoMutex lock(gV4LAdapterLock);
-
- LOG_FUNCTION_NAME;
-
- adapter = new V4LCameraAdapter(sensor_index);
- if ( adapter ) {
- CAMHAL_LOGDB("New V4L Camera adapter instance created for sensor %d",sensor_index);
- } else {
- CAMHAL_LOGEA("V4L Camera adapter create failed for sensor index = %d!",sensor_index);
- }
-
- LOG_FUNCTION_NAME_EXIT;
-
- return adapter;
-}
-
-extern "C" status_t V4LCameraAdapter_Capabilities(
- CameraProperties::Properties * const properties_array,
- const int starting_camera, const int max_camera, int & supportedCameras)
-{
- status_t ret = NO_ERROR;
- struct v4l2_capability cap;
- int tempHandle = NULL;
- int num_cameras_supported = 0;
- char device_list[5][15];
- char* video_device_list[5];
- int num_v4l_devices = 0;
- int sensorId = 0;
- CameraProperties::Properties* properties = NULL;
-
- LOG_FUNCTION_NAME;
-
- supportedCameras = 0;
- memset((void*)&cap, 0, sizeof(v4l2_capability));
-
- if (!properties_array) {
- CAMHAL_LOGEB("invalid param: properties = 0x%p", properties_array);
- LOG_FUNCTION_NAME_EXIT;
- return BAD_VALUE;
- }
-
- for (int i = 0; i < 5; i++) {
- video_device_list[i] = device_list[i];
- }
- //look for the connected video devices
- detectVideoDevice(video_device_list, num_v4l_devices);
-
- for (int i = 0; i < num_v4l_devices; i++) {
- if ( (starting_camera + num_cameras_supported) < max_camera) {
- sensorId = starting_camera + num_cameras_supported;
-
- CAMHAL_LOGDB("Opening device[%d] = %s..",i, video_device_list[i]);
- if ((tempHandle = open(video_device_list[i], O_RDWR)) == -1) {
- CAMHAL_LOGEB("Error while opening handle to V4L2 Camera(%s): %s",video_device_list[i], strerror(errno));
- continue;
- }
-
- ret = ioctl (tempHandle, VIDIOC_QUERYCAP, &cap);
- if (ret < 0) {
- CAMHAL_LOGEA("Error when querying the capabilities of the V4L Camera");
- close(tempHandle);
- continue;
- }
-
- //check for video capture devices
- if ((cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) == 0) {
- CAMHAL_LOGEA("Error while adapter initialization: video capture not supported.");
- close(tempHandle);
- continue;
- }
-
- strcpy(device, video_device_list[i]);
- properties = properties_array + starting_camera + num_cameras_supported;
-
- //fetch capabilities for this camera
- ret = V4LCameraAdapter::getCaps( sensorId, properties, tempHandle );
- if (ret < 0) {
- CAMHAL_LOGEA("Error while getting capabilities.");
- close(tempHandle);
- continue;
- }
-
- num_cameras_supported++;
-
- }
- //For now exit this loop once a valid video capture device is found.
- //TODO: find all V4L capture devices and it capabilities
- break;
- }//end of for() loop
-
- supportedCameras = num_cameras_supported;
- CAMHAL_LOGDB("Number of V4L cameras detected =%d", num_cameras_supported);
-
-EXIT:
- LOG_FUNCTION_NAME_EXIT;
- close(tempHandle);
- return NO_ERROR;
-}
-
-} // namespace Camera
-} // namespace Ti
-
-
-/*--------------------Camera Adapter Class ENDS here-----------------------------*/
-