1c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev/* 2c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * Copyright (C) Texas Instruments - http://www.ti.com/ 3c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * 4c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * Licensed under the Apache License, Version 2.0 (the "License"); 5c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * you may not use this file except in compliance with the License. 6c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * You may obtain a copy of the License at 7c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * 8c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * http://www.apache.org/licenses/LICENSE-2.0 9c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * 10c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * Unless required by applicable law or agreed to in writing, software 11c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * distributed under the License is distributed on an "AS IS" BASIS, 12c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * See the License for the specific language governing permissions and 14c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev * limitations under the License. 15c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev */ 16c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 17c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev/** 18c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev* @file V4LCameraAdapter.cpp 19c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev* 20c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev* This file maps the Camera Hardware Interface to V4L2. 21c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev* 22c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev*/ 23c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 24c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 25c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include "V4LCameraAdapter.h" 26c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include "CameraHal.h" 27c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include "TICameraParameters.h" 28c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include <signal.h> 29c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include <stdio.h> 30c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include <stdlib.h> 31c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include <string.h> 32c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include <fcntl.h> 33c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include <unistd.h> 34c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include <errno.h> 35c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include <sys/ioctl.h> 36c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include <sys/mman.h> 37c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include <sys/select.h> 38c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include <linux/videodev.h> 39c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 40c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 41c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#include <cutils/properties.h> 42c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false )) 43c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatic int mDebugFps = 0; 44c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 45c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#define Q16_OFFSET 16 46c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 47c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#define HERE(Msg) {CAMHAL_LOGEB("--===line %d, %s===--\n", __LINE__, Msg);} 48c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 49c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevnamespace android { 50c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 51c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#undef LOG_TAG 52c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev///Maintain a separate tag for V4LCameraAdapter logs to isolate issues OMX specific 53c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#define LOG_TAG "CameraHAL" 54c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 55c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev//frames skipped before recalculating the framerate 56c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev#define FPS_PERIOD 30 57c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 58c322989ae6ff6769490828de1b5eda12b749cce9Iliyan MalchevMutex gAdapterLock; 59c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevconst char *device = DEVICE; 60c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 61c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 62c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev/*--------------------Camera Adapter Class STARTS here-----------------------------*/ 63c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 649a412956d5327ec851ff8adc3e9804640fa30c7fTyler Luustatus_t V4LCameraAdapter::initialize(CameraProperties::Properties* caps) 65c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{ 66c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev LOG_FUNCTION_NAME; 67c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 68c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev char value[PROPERTY_VALUE_MAX]; 69c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev property_get("debug.camera.showfps", value, "0"); 70c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mDebugFps = atoi(value); 71c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 72c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev int ret = NO_ERROR; 73c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 74c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev // Allocate memory for video info structure 75c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mVideoInfo = (struct VideoInfo *) calloc (1, sizeof (struct VideoInfo)); 76c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if(!mVideoInfo) 77c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev { 78c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return NO_MEMORY; 79c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 80c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 81c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if ((mCameraHandle = open(device, O_RDWR)) == -1) 82c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev { 83c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev CAMHAL_LOGEB("Error while opening handle to V4L2 Camera: %s", strerror(errno)); 84c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return -EINVAL; 85c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 86c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 87c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev ret = ioctl (mCameraHandle, VIDIOC_QUERYCAP, &mVideoInfo->cap); 88c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if (ret < 0) 89c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev { 90c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev CAMHAL_LOGEA("Error when querying the capabilities of the V4L Camera"); 91c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return -EINVAL; 92c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 93c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 94c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if ((mVideoInfo->cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) == 0) 95c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev { 96c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev CAMHAL_LOGEA("Error while adapter initialization: video capture not supported."); 97c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return -EINVAL; 98c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 99c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 100c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if (!(mVideoInfo->cap.capabilities & V4L2_CAP_STREAMING)) 101c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev { 102c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev CAMHAL_LOGEA("Error while adapter initialization: Capture device does not support streaming i/o"); 103c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return -EINVAL; 104c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 105c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 106c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev // Initialize flags 107c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mPreviewing = false; 108c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mVideoInfo->isStreaming = false; 109c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mRecording = false; 110c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 111c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev LOG_FUNCTION_NAME_EXIT; 112c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 113c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return ret; 114c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev} 115c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 116c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatus_t V4LCameraAdapter::fillThisBuffer(void* frameBuf, CameraFrame::FrameType frameType) 117c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{ 118c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 119c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev status_t ret = NO_ERROR; 120c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 121c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if ( !mVideoInfo->isStreaming ) 122c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev { 123c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return NO_ERROR; 124c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 125c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 126c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev int i = mPreviewBufs.valueFor(( unsigned int )frameBuf); 127c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if(i<0) 128c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev { 129c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return BAD_VALUE; 130c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 131c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 132c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mVideoInfo->buf.index = i; 133c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mVideoInfo->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 134c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mVideoInfo->buf.memory = V4L2_MEMORY_MMAP; 135c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 136c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev ret = ioctl(mCameraHandle, VIDIOC_QBUF, &mVideoInfo->buf); 137c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if (ret < 0) { 138c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev CAMHAL_LOGEA("Init: VIDIOC_QBUF Failed"); 139c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return -1; 140c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 141c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 142c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev nQueued++; 143c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 144c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return ret; 145c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 146c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev} 147c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 148c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatus_t V4LCameraAdapter::setParameters(const CameraParameters ¶ms) 149c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{ 150c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev LOG_FUNCTION_NAME; 151c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 152c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev status_t ret = NO_ERROR; 153c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 154c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev int width, height; 155c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 156c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev params.getPreviewSize(&width, &height); 157c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 158c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev CAMHAL_LOGDB("Width * Height %d x %d format 0x%x", width, height, DEFAULT_PIXEL_FORMAT); 159c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 160c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mVideoInfo->width = width; 161c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mVideoInfo->height = height; 162c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mVideoInfo->framesizeIn = (width * height << 1); 163c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mVideoInfo->formatIn = DEFAULT_PIXEL_FORMAT; 164c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 165c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mVideoInfo->format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 166c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mVideoInfo->format.fmt.pix.width = width; 167c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mVideoInfo->format.fmt.pix.height = height; 168c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mVideoInfo->format.fmt.pix.pixelformat = DEFAULT_PIXEL_FORMAT; 169c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 170c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev ret = ioctl(mCameraHandle, VIDIOC_S_FMT, &mVideoInfo->format); 171c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if (ret < 0) { 172c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev CAMHAL_LOGEB("Open: VIDIOC_S_FMT Failed: %s", strerror(errno)); 173c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return ret; 174c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 175c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 176c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev // Udpate the current parameter set 177c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mParams = params; 178c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 179c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev LOG_FUNCTION_NAME_EXIT; 180c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return ret; 181c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev} 182c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 183c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 184c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevvoid V4LCameraAdapter::getParameters(CameraParameters& params) 185c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{ 186c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev LOG_FUNCTION_NAME; 187c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 188c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev // Return the current parameter set 189c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev params = mParams; 190c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 191c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev LOG_FUNCTION_NAME_EXIT; 192c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev} 193c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 194c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 195c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev///API to give the buffers to Adapter 196c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatus_t V4LCameraAdapter::useBuffers(CameraMode mode, void* bufArr, int num, size_t length, unsigned int queueable) 197c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{ 198c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev status_t ret = NO_ERROR; 199c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 200c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev LOG_FUNCTION_NAME; 201c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 202c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev Mutex::Autolock lock(mLock); 203c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 204c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev switch(mode) 205c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev { 206c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev case CAMERA_PREVIEW: 207c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev ret = UseBuffersPreview(bufArr, num); 208c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev break; 209c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 210c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev //@todo Insert Image capture case here 211c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 212c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev case CAMERA_VIDEO: 213c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev //@warn Video capture is not fully supported yet 214c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev ret = UseBuffersPreview(bufArr, num); 215c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev break; 216c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 217c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 218c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 219c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev LOG_FUNCTION_NAME_EXIT; 220c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 221c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return ret; 222c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev} 223c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 224c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatus_t V4LCameraAdapter::UseBuffersPreview(void* bufArr, int num) 225c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{ 226c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev int ret = NO_ERROR; 227c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 228c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if(NULL == bufArr) 229c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev { 230c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return BAD_VALUE; 231c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 232c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 233c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev //First allocate adapter internal buffers at V4L level for USB Cam 234c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev //These are the buffers from which we will copy the data into overlay buffers 235c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev /* Check if camera can handle NB_BUFFER buffers */ 236c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mVideoInfo->rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 237c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mVideoInfo->rb.memory = V4L2_MEMORY_MMAP; 238c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mVideoInfo->rb.count = num; 239c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 240c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev ret = ioctl(mCameraHandle, VIDIOC_REQBUFS, &mVideoInfo->rb); 241c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if (ret < 0) { 242c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev CAMHAL_LOGEB("VIDIOC_REQBUFS failed: %s", strerror(errno)); 243c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return ret; 244c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 245c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 246c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev for (int i = 0; i < num; i++) { 247c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 248c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev memset (&mVideoInfo->buf, 0, sizeof (struct v4l2_buffer)); 249c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 250c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mVideoInfo->buf.index = i; 251c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mVideoInfo->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 252c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mVideoInfo->buf.memory = V4L2_MEMORY_MMAP; 253c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 254c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev ret = ioctl (mCameraHandle, VIDIOC_QUERYBUF, &mVideoInfo->buf); 255c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if (ret < 0) { 256c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev CAMHAL_LOGEB("Unable to query buffer (%s)", strerror(errno)); 257c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return ret; 258c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 259c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 260c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mVideoInfo->mem[i] = mmap (0, 261c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mVideoInfo->buf.length, 262c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev PROT_READ | PROT_WRITE, 263c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev MAP_SHARED, 264c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mCameraHandle, 265c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mVideoInfo->buf.m.offset); 266c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 267c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if (mVideoInfo->mem[i] == MAP_FAILED) { 268c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev CAMHAL_LOGEB("Unable to map buffer (%s)", strerror(errno)); 269c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return -1; 270c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 271c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 272c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev uint32_t *ptr = (uint32_t*) bufArr; 273c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 274c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev //Associate each Camera internal buffer with the one from Overlay 275c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mPreviewBufs.add((int)ptr[i], i); 276c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 277c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 278c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 279c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev // Update the preview buffer count 280c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mPreviewBufferCount = num; 281c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 282c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return ret; 283c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev} 284c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 285c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatus_t V4LCameraAdapter::startPreview() 286c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{ 287c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev status_t ret = NO_ERROR; 288c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 289c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev Mutex::Autolock lock(mPreviewBufsLock); 290c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 291c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if(mPreviewing) 292c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev { 293c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return BAD_VALUE; 294c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 295c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 296c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev for (int i = 0; i < mPreviewBufferCount; i++) { 297c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 298c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mVideoInfo->buf.index = i; 299c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mVideoInfo->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 300c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mVideoInfo->buf.memory = V4L2_MEMORY_MMAP; 301c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 302c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev ret = ioctl(mCameraHandle, VIDIOC_QBUF, &mVideoInfo->buf); 303c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if (ret < 0) { 304c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev CAMHAL_LOGEA("VIDIOC_QBUF Failed"); 305c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return -EINVAL; 306c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 307c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 308c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev nQueued++; 309c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 310c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 311c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev enum v4l2_buf_type bufType; 312c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if (!mVideoInfo->isStreaming) { 313c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev bufType = V4L2_BUF_TYPE_VIDEO_CAPTURE; 314c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 315c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev ret = ioctl (mCameraHandle, VIDIOC_STREAMON, &bufType); 316c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if (ret < 0) { 317c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev CAMHAL_LOGEB("StartStreaming: Unable to start capture: %s", strerror(errno)); 318c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return ret; 319c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 320c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 321c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mVideoInfo->isStreaming = true; 322c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 323c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 324c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev // Create and start preview thread for receiving buffers from V4L Camera 325c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mPreviewThread = new PreviewThread(this); 326c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 327c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev CAMHAL_LOGDA("Created preview thread"); 328c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 329c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 330c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev //Update the flag to indicate we are previewing 331c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mPreviewing = true; 332c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 333c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return ret; 334c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 335c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev} 336c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 337c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatus_t V4LCameraAdapter::stopPreview() 338c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{ 339c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev enum v4l2_buf_type bufType; 340c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev int ret = NO_ERROR; 341c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 342c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev Mutex::Autolock lock(mPreviewBufsLock); 343c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 344c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if(!mPreviewing) 345c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev { 346c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return NO_INIT; 347c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 348c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 349c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if (mVideoInfo->isStreaming) { 350c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev bufType = V4L2_BUF_TYPE_VIDEO_CAPTURE; 351c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 352c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev ret = ioctl (mCameraHandle, VIDIOC_STREAMOFF, &bufType); 353c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if (ret < 0) { 354c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev CAMHAL_LOGEB("StopStreaming: Unable to stop capture: %s", strerror(errno)); 355c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return ret; 356c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 357c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 358c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mVideoInfo->isStreaming = false; 359c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 360c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 361c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mVideoInfo->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 362c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mVideoInfo->buf.memory = V4L2_MEMORY_MMAP; 363c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 364c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev nQueued = 0; 365c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev nDequeued = 0; 366c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 367c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev /* Unmap buffers */ 368c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev for (int i = 0; i < mPreviewBufferCount; i++) 369c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if (munmap(mVideoInfo->mem[i], mVideoInfo->buf.length) < 0) 370c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev CAMHAL_LOGEA("Unmap failed"); 371c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 372c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mPreviewBufs.clear(); 373c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 374c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mPreviewThread->requestExitAndWait(); 375c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mPreviewThread.clear(); 376c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 377c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return ret; 378c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 379c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev} 380c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 381c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevchar * V4LCameraAdapter::GetFrame(int &index) 382c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{ 383c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev int ret; 384c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 385c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mVideoInfo->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 386c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mVideoInfo->buf.memory = V4L2_MEMORY_MMAP; 387c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 388c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev /* DQ */ 389c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev ret = ioctl(mCameraHandle, VIDIOC_DQBUF, &mVideoInfo->buf); 390c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if (ret < 0) { 391c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev CAMHAL_LOGEA("GetFrame: VIDIOC_DQBUF Failed"); 392c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return NULL; 393c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 394c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev nDequeued++; 395c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 396c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev index = mVideoInfo->buf.index; 397c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 398c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return (char *)mVideoInfo->mem[mVideoInfo->buf.index]; 399c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev} 400c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 401c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev//API to get the frame size required to be allocated. This size is used to override the size passed 402c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev//by camera service when VSTAB/VNF is turned ON for example 403c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatus_t V4LCameraAdapter::getFrameSize(size_t &width, size_t &height) 404c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{ 405c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev status_t ret = NO_ERROR; 406c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 407c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev // Just return the current preview size, nothing more to do here. 408c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mParams.getPreviewSize(( int * ) &width, 409c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev ( int * ) &height); 410c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 411c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev LOG_FUNCTION_NAME_EXIT; 412c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 413c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return ret; 414c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev} 415c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 416c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatus_t V4LCameraAdapter::getFrameDataSize(size_t &dataFrameSize, size_t bufferCount) 417c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{ 418c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev // We don't support meta data, so simply return 419c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return NO_ERROR; 420c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev} 421c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 422c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatus_t V4LCameraAdapter::getPictureBufferSize(size_t &length, size_t bufferCount) 423c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{ 424c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev // We don't support image capture yet, safely return from here without messing up 425c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return NO_ERROR; 426c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev} 427c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 428c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatic void debugShowFPS() 429c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{ 430c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev static int mFrameCount = 0; 431c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev static int mLastFrameCount = 0; 432c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev static nsecs_t mLastFpsTime = 0; 433c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev static float mFps = 0; 434c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mFrameCount++; 435c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if (!(mFrameCount & 0x1F)) { 436c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev nsecs_t now = systemTime(); 437c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev nsecs_t diff = now - mLastFpsTime; 438c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mFps = ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff; 439c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mLastFpsTime = now; 440c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mLastFrameCount = mFrameCount; 4413a7df2c042eb8c7289e24e77dd316f73bd0c456fSteve Block ALOGD("Camera %d Frames, %f FPS", mFrameCount, mFps); 442c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 443c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev // XXX: mFPS has the value we want 444c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev} 445c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 446c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevstatus_t V4LCameraAdapter::recalculateFPS() 447c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{ 448c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev float currentFPS; 449c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 450c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mFrameCount++; 451c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 452c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if ( ( mFrameCount % FPS_PERIOD ) == 0 ) 453c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev { 454c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev nsecs_t now = systemTime(); 455c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev nsecs_t diff = now - mLastFPSTime; 456c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev currentFPS = ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff; 457c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mLastFPSTime = now; 458c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mLastFrameCount = mFrameCount; 459c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 460c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if ( 1 == mIter ) 461c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev { 462c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mFPS = currentFPS; 463c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 464c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev else 465c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev { 466c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev //cumulative moving average 467c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mFPS = mLastFPS + (currentFPS - mLastFPS)/mIter; 468c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 469c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 470c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mLastFPS = mFPS; 471c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mIter++; 472c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 473c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 474c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return NO_ERROR; 475c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev} 476c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 477c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevvoid V4LCameraAdapter::onOrientationEvent(uint32_t orientation, uint32_t tilt) 478c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{ 479c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev LOG_FUNCTION_NAME; 480c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 481c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev LOG_FUNCTION_NAME_EXIT; 482c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev} 483c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 484c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 4859a412956d5327ec851ff8adc3e9804640fa30c7fTyler LuuV4LCameraAdapter::V4LCameraAdapter(size_t sensor_index) 486c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{ 487c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev LOG_FUNCTION_NAME; 488c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 489c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev // Nothing useful to do in the constructor 490c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 491c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev LOG_FUNCTION_NAME_EXIT; 492c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev} 493c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 494c322989ae6ff6769490828de1b5eda12b749cce9Iliyan MalchevV4LCameraAdapter::~V4LCameraAdapter() 495c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{ 496c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev LOG_FUNCTION_NAME; 497c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 498c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev // Close the camera handle and free the video info structure 499c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev close(mCameraHandle); 500c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 501c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if (mVideoInfo) 502c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev { 503c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev free(mVideoInfo); 504c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mVideoInfo = NULL; 505c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 506c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 507c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev LOG_FUNCTION_NAME_EXIT; 508c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev} 509c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 510c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev/* Preview Thread */ 511c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev// --------------------------------------------------------------------------- 512c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 513c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevint V4LCameraAdapter::previewThread() 514c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{ 515c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev status_t ret = NO_ERROR; 516c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev int width, height; 517c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev CameraFrame frame; 518c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 519c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if (mPreviewing) 520c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev { 521c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev int index = 0; 522c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev char *fp = this->GetFrame(index); 523c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if(!fp) 524c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev { 525c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return BAD_VALUE; 526c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 527c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 528c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev uint8_t* ptr = (uint8_t*) mPreviewBufs.keyAt(index); 529c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 530c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev int width, height; 531c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev uint16_t* dest = (uint16_t*)ptr; 532c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev uint16_t* src = (uint16_t*) fp; 533c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mParams.getPreviewSize(&width, &height); 534c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev for(int i=0;i<height;i++) 535c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev { 536c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev for(int j=0;j<width;j++) 537c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev { 538c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev //*dest = *src; 539c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev //convert from YUYV to UYVY supported in Camera service 540c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev *dest = (((*src & 0xFF000000)>>24)<<16)|(((*src & 0x00FF0000)>>16)<<24) | 541c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev (((*src & 0xFF00)>>8)<<0)|(((*src & 0x00FF)>>0)<<8); 542c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev src++; 543c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev dest++; 544c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 545c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev dest += 4096/2-width; 546c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 547c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 548c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev mParams.getPreviewSize(&width, &height); 549c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev frame.mFrameType = CameraFrame::PREVIEW_FRAME_SYNC; 550c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev frame.mBuffer = ptr; 551c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev frame.mLength = width*height*2; 552c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev frame.mAlignment = width*2; 553c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev frame.mOffset = 0; 554c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev frame.mTimestamp = systemTime(SYSTEM_TIME_MONOTONIC);; 555c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 556c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev ret = sendFrameToSubscribers(&frame); 557c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 558c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 559c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 560c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return ret; 561c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev} 562c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 563c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevextern "C" CameraAdapter* CameraAdapter_Factory() 564c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev{ 5659a412956d5327ec851ff8adc3e9804640fa30c7fTyler Luu CameraAdapter *adapter = NULL; 566c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev Mutex::Autolock lock(gAdapterLock); 567c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 568c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev LOG_FUNCTION_NAME; 569c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 5709a412956d5327ec851ff8adc3e9804640fa30c7fTyler Luu adapter = new V4LCameraAdapter(sensor_index); 5719a412956d5327ec851ff8adc3e9804640fa30c7fTyler Luu if ( adapter ) { 5729a412956d5327ec851ff8adc3e9804640fa30c7fTyler Luu CAMHAL_LOGDB("New OMX Camera adapter instance created for sensor %d",sensor_index); 5739a412956d5327ec851ff8adc3e9804640fa30c7fTyler Luu } else { 5749a412956d5327ec851ff8adc3e9804640fa30c7fTyler Luu CAMHAL_LOGEA("Camera adapter create failed!"); 5759a412956d5327ec851ff8adc3e9804640fa30c7fTyler Luu } 576c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 577c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev LOG_FUNCTION_NAME_EXIT; 578c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 5799a412956d5327ec851ff8adc3e9804640fa30c7fTyler Luu return adapter; 580c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev} 581c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 582c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchevextern "C" int CameraAdapter_Capabilities(CameraProperties::Properties* properties_array, 583c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev const unsigned int starting_camera, 584c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev const unsigned int max_camera) { 585c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev int num_cameras_supported = 0; 586c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev CameraProperties::Properties* properties = NULL; 587c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 588c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev LOG_FUNCTION_NAME; 589c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 590c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if(!properties_array) 591c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev { 592c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return -EINVAL; 593c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 594c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 595c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev // TODO: Need to tell camera properties what other cameras we can support 596c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev if (starting_camera + num_cameras_supported < max_camera) { 597c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev num_cameras_supported++; 598c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev properties = properties_array + starting_camera; 599c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev properties->set(CameraProperties::CAMERA_NAME, "USBCamera"); 600c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev } 601c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 602c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev LOG_FUNCTION_NAME_EXIT; 603c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 604c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev return num_cameras_supported; 605c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev} 606c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 607c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev}; 608c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 609c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 610c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev/*--------------------Camera Adapter Class ENDS here-----------------------------*/ 611c322989ae6ff6769490828de1b5eda12b749cce9Iliyan Malchev 612