diff options
Diffstat (limited to 'camera/V4LCameraAdapter/V4LCameraAdapter.cpp')
-rw-r--r-- | camera/V4LCameraAdapter/V4LCameraAdapter.cpp | 1318 |
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 ¶ms) -{ - 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-----------------------------*/ - |