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 &params)
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