summaryrefslogtreecommitdiff
path: root/V4LCameraAdapter/V4LCameraAdapter.cpp (plain)
blob: 32528e023cc7ca00a5dcbaca38fcfe2247e62153
1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/**
18* @file V4LCameraAdapter.cpp
19*
20* This file maps the Camera Hardware Interface to V4L2.
21*
22*/
23
24//#define LOG_NDEBUG 0
25#define LOG_TAG "CAMHAL_V4LCameraAdapter"
26//reinclude because of a bug with the log macros
27#include <utils/Log.h>
28#include "DebugUtils.h"
29
30#include "V4LCameraAdapter.h"
31#ifdef AMLOGIC_VIRTUAL_CAMERA_SUPPORT
32#include "V4LCamAdpt.h"
33#endif
34#include "CameraHal.h"
35#include "ExCameraParameters.h"
36#include <signal.h>
37#include <stdio.h>
38#include <stdlib.h>
39#include <string.h>
40#include <fcntl.h>
41#include <unistd.h>
42#include <errno.h>
43#include <sys/ioctl.h>
44#include <sys/mman.h>
45#include <sys/select.h>
46#include <linux/videodev2.h>
47#include <sys/time.h>
48
49#include <cutils/properties.h>
50#include <sys/types.h>
51#include <sys/stat.h>
52#include "CameraHal.h"
53extern "C"{
54 #include "usb_fmt.h"
55 #include "jutils.h"
56}
57
58//for private_handle_t TODO move out of private header
59#include <ion/ion.h>
60#include <gralloc_priv.h>
61#include <MetadataBufferType.h>
62
63static int iCamerasNum = -1;
64
65#ifdef ION_MODE_FOR_METADATA_MODE
66#define ION_IOC_MESON_PHYS_ADDR 8
67
68struct meson_phys_data{
69 int handle;
70 unsigned int phys_addr;
71 unsigned int size;
72};
73#endif
74
75#ifndef ARRAY_SIZE
76#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
77#endif
78#ifdef AMLOGIC_USB_CAMERA_SUPPORT
79
80const char *SENSOR_PATH[]={
81 "/dev/video0",
82 "/dev/video1",
83 "/dev/video2",
84 };
85#define DEVICE_PATH(_sensor_index) (SENSOR_PATH[_sensor_index])
86#else
87#define DEVICE_PATH(_sensor_index) (_sensor_index == 0 ? "/dev/video0" : "/dev/video1")
88#endif
89#define DUMP_FILE "/data/preview_dump"
90namespace android {
91
92//frames skipped before recalculating the framerate
93#define FPS_PERIOD 30
94
95Mutex gAdapterLock;
96
97extern "C" int set_night_mode(int camera_fd,const char *snm);
98extern "C" int set_effect(int camera_fd,const char *sef);
99extern "C" int SYS_set_zoom(int zoom);
100extern "C" int set_flash_mode(int camera_fd, const char *sfm);
101static bool get_flash_mode(int camera_fd, char *flash_status,
102 char *def_flash_status);
103
104static int set_hflip_mode(int camera_fd, bool mode);
105static int get_hflip_mode(int camera_fd);
106static int get_supported_zoom(int camera_fd, char * zoom_str);
107static int set_zoom_level(int camera_fd, int zoom);
108static bool is_mjpeg_supported(int camera_fd);
109static void ParserLimitedRateInfo(LimitedRate_t* rate);
110#ifdef AMLOGIC_CAMERA_NONBLOCK_SUPPORT
111extern "C" int get_framerate (int camera_fd,int *fps, int *fps_num);
112extern "C" int enumFramerate ( int camera_fd, int *fps, int *fps_num);
113#endif
114#ifndef AMLOGIC_USB_CAMERA_SUPPORT
115static int set_rotate_value(int camera_fd, int value);
116#endif
117
118#ifdef AMLOGIC_USB_CAMERA_SUPPORT
119#ifdef AMLOGIC_TWO_CH_UVC
120extern "C" bool isPreviewDevice(int camera_fd);
121extern "C" status_t getVideodevId(int &camera_id, int &main_id);
122#endif
123#endif
124/*--------------------junk STARTS here-----------------------------*/
125#ifndef AMLOGIC_USB_CAMERA_SUPPORT
126#define SYSFILE_CAMERA_SET_PARA "/sys/class/vm/attr2"
127#define SYSFILE_CAMERA_SET_MIRROR "/sys/class/vm/mirror"
128static int writefile(char* path,char* content)
129{
130 FILE* fp = fopen(path, "w+");
131
132 CAMHAL_LOGDB("Write file %s(%p) content %s", path, fp, content);
133
134 if (fp){
135 while( ((*content) != '\0') ) {
136 if (EOF == fputc(*content,fp)){
137 CAMHAL_LOGDA("write char fail");
138 }
139 content++;
140 }
141 fclose(fp);
142 }else{
143 CAMHAL_LOGDA("open file fail\n");
144 }
145 return 1;
146}
147#ifndef CAMHAL_USER_MODE
148//
149//usage
150//+ char property1[80];
151//+
152//+ readfile((char*)SYSFILE_CAMERA_SET_MIRROR, property1);
153//+ CAMHAL_LOGDB("mirror =%s\n", property1);
154//
155static int readfile(char *path,char *content)
156{
157 char *tmp=content;
158
159 FILE *fp = fopen(path,"r");
160
161 if(fp == NULL) {
162 CAMHAL_LOGDA("readfile open fail");
163 return -1;
164 }
165 int ch;
166 while ((ch=fgetc(fp)) != EOF ) {
167 *content = (char)ch;
168 content++;
169 }
170 fclose(fp);
171 *content='\0';
172
173 return 0;
174}
175#endif
176#endif
177/*--------------------Camera Adapter Class STARTS here-----------------------------*/
178status_t V4LCameraAdapter::sendCommand(CameraCommands operation, int value1, int value2, int value3) {
179 if(operation==CAMERA_APK) {
180 mPreviewOriation=value1;
181 mCaptureOriation=value2;
182 return 1;
183 }else{
184 return BaseCameraAdapter::sendCommand(operation, value1, value2, value3);
185 }
186}
187
188status_t V4LCameraAdapter::initialize(CameraProperties::Properties* caps)
189{
190 LOG_FUNCTION_NAME;
191
192 //char value[PROPERTY_VALUE_MAX];
193 //property_get("debug.camera.showfps", value, "0");
194
195 int ret = NO_ERROR;
196 int oflag = O_RDWR;
197
198#ifdef AMLOGIC_CAMERA_NONBLOCK_SUPPORT
199 oflag = O_RDWR | O_NONBLOCK;
200#endif
201
202 // Allocate memory for video info structure
203 mVideoInfo = (struct VideoInfo *) calloc (1, sizeof (struct VideoInfo));
204 if(!mVideoInfo){
205 return NO_MEMORY;
206 }
207
208 memset(mVideoInfo,0,sizeof(struct VideoInfo));
209
210#ifdef ION_MODE_FOR_METADATA_MODE
211 ion_mode = false;
212 mIonClient = -1;
213 memset(mPhyAddr, 0, sizeof(mPhyAddr));
214#endif
215
216#ifdef AMLOGIC_USB_CAMERA_SUPPORT
217#ifdef AMLOGIC_TWO_CH_UVC
218 mCamEncodeIndex = -1;
219 mCamEncodeHandle = -1;
220 ret = getVideodevId( mSensorIndex, mCamEncodeIndex);
221 if(NO_ERROR == ret){
222 if ((mCameraHandle = open(DEVICE_PATH(mSensorIndex), oflag )) != -1){
223 CAMHAL_LOGDB("open %s success to preview\n", DEVICE_PATH(mSensorIndex));
224 }
225 if ((0<= mCamEncodeIndex)&& (mCamEncodeIndex < (int)ARRAY_SIZE(SENSOR_PATH))&&
226 ((mCamEncodeHandle = open(DEVICE_PATH(mCamEncodeIndex), O_RDWR)) != -1)){
227 CAMHAL_LOGDB("open %s success to encode\n", DEVICE_PATH(mCamEncodeIndex));
228 }
229 }
230#else
231 while(mSensorIndex < (int)ARRAY_SIZE(SENSOR_PATH)){
232 if ((mCameraHandle = open(DEVICE_PATH(mSensorIndex), oflag)) != -1){
233 CAMHAL_LOGDB("open %s success!\n", DEVICE_PATH(mSensorIndex));
234 break;
235 }
236 mSensorIndex++;
237 }
238 if(mSensorIndex >= (int)ARRAY_SIZE(SENSOR_PATH)){
239 CAMHAL_LOGEB("opening %dth Camera, error: %s", mSensorIndex, strerror(errno));
240 return -EINVAL;
241 }
242#endif
243#else
244 if ((mCameraHandle = open(DEVICE_PATH(mSensorIndex), oflag)) == -1){
245 CAMHAL_LOGEB("Error while opening handle to V4L2 Camera: %s", strerror(errno));
246 return -EINVAL;
247 }
248#endif
249
250 ret = ioctl (mCameraHandle, VIDIOC_QUERYCAP, &mVideoInfo->cap);
251 if (ret < 0){
252 CAMHAL_LOGEA("Error when querying the capabilities of the V4L Camera");
253 return -EINVAL;
254 }
255
256 if ((mVideoInfo->cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) == 0){
257 CAMHAL_LOGEA("Error while adapter initialization: video capture not supported.");
258 return -EINVAL;
259 }
260
261 if (!(mVideoInfo->cap.capabilities & V4L2_CAP_STREAMING)){
262 CAMHAL_LOGEA("Error while adapter initialization: Capture device does not support streaming i/o");
263 return -EINVAL;
264 }
265
266 if (V4L2_CAP_VIDEO_M2M == (mVideoInfo->cap.capabilities & V4L2_CAP_VIDEO_M2M)){
267 m_eDeviceType = DEV_ION;
268 m_eV4l2Memory = V4L2_MEMORY_DMABUF;
269 CAMHAL_LOGIA("Capture device support streaming ION\n");
270 } else {
271 m_eDeviceType = DEV_MMAP;
272 m_eV4l2Memory = V4L2_MEMORY_MMAP;
273 }
274#ifdef AMLOGIC_USB_CAMERA_SUPPORT
275 m_eDeviceType = DEV_USB;
276 mVideoInfo->idVendor = mVideoInfo->cap.reserved[0] >> 16;
277 mVideoInfo->idProduct = mVideoInfo->cap.reserved[0] & 0xffff;
278#endif
279
280 mVideoInfo->canvas_mode = false;
281
282 char* str = strchr((const char *)mVideoInfo->cap.card,'.');
283 if(str){
284 if(!strncmp(str,".canvas",strlen(str))){
285 mVideoInfo->canvas_mode = true;
286 CAMHAL_LOGDB("Camera %d use canvas mode",mSensorIndex);
287 }
288 }
289 if (strcmp(caps->get(CameraProperties::FACING_INDEX), (const char *) android::ExCameraParameters::FACING_FRONT) == 0)
290 mbFrontCamera = true;
291 else
292 mbFrontCamera = false;
293 CAMHAL_LOGDB("mbFrontCamera=%d",mbFrontCamera);
294
295 // Initialize flags
296 mPreviewing = false;
297 mVideoInfo->isStreaming = false;
298 mRecording = false;
299 mZoomlevel = -1;
300 mEnableContiFocus = false;
301 cur_focus_mode_for_conti = CAM_FOCUS_MODE_RELEASE;
302 mFlashMode = FLASHLIGHT_OFF;
303 mPixelFormat = 0;
304 mSensorFormat = 0;
305
306 mPreviewWidth = 0 ;
307 mPreviewHeight = 0;
308 mCaptureWidth = 0;
309 mCaptureHeight = 0;
310
311#ifdef AMLOGIC_USB_CAMERA_SUPPORT
312 mIsDequeuedEIOError = false;
313#endif
314
315 IoctlStateProbe();
316
317 mSupportMJPEG = false;
318 {
319 char property[PROPERTY_VALUE_MAX];
320 int enable = 0;
321 memset(property,0,sizeof(property));
322 if(property_get("ro.camera.preview.UseMJPEG", property, NULL) > 0){
323 enable = atoi(property);
324 }
325 mUseMJPEG = (enable!=0)?true:false;
326 enable = 0;
327 if(property_get("camera.preview.DebugMJPEG", property, NULL) > 0){
328 enable = atoi(property);
329 }
330 mDebugMJPEG = (enable!=0)?true:false;
331
332 }
333 if(mUseMJPEG == true){
334 mSupportMJPEG = is_mjpeg_supported(mCameraHandle);
335 if(mSupportMJPEG == true){
336 CAMHAL_LOGDA("Current Camera's preview format set as MJPEG\n");
337 }
338 }
339
340 ParserLimitedRateInfo(&LimitedRate);
341 if(LimitedRate.num>0){
342 CAMHAL_LOGDB("Current Camera's succeed parser %d limited rate parameter(s)\n",LimitedRate.num);
343 for(int k = 0;k<LimitedRate.num;k++){
344 CAMHAL_LOGVB("limited rate parameter %d : %dx%dx%d\n",LimitedRate.num,LimitedRate.arg[k].width,LimitedRate.arg[k].height,LimitedRate.arg[k].framerate);
345 }
346 }
347
348 mLimitedFrameRate = 0; // no limited
349 mExpectedFrameInv = (unsigned) (1000000)/15;
350 mFramerate = 15;
351
352#ifndef AMLOGIC_USB_CAMERA_SUPPORT
353 writefile((char*)SYSFILE_CAMERA_SET_PARA, (char*)"1");
354#endif
355 if (DEV_ION == m_eDeviceType) {
356 ret = allocImageIONBuf(caps);
357 }
358 mResetTH = 5000000; // initial reset threshold is 5s,then set it to 3s
359 mPreviewCache = NULL;
360 mEnableDump = false;
361 mDumpCnt = 0;
362 //mirror set at here will not work.
363 LOG_FUNCTION_NAME_EXIT;
364 return ret;
365}
366
367status_t V4LCameraAdapter::allocImageIONBuf(CameraProperties::Properties* caps)
368{
369 status_t ret = NO_ERROR;
370 int max_width, max_height;
371 int bytes;
372
373 DBG_LOGB("picture size=%s\n", caps->get(CameraProperties::PICTURE_SIZE));
374 if (NULL == caps->get(CameraProperties::PICTURE_SIZE))
375 return -EINVAL;
376 ret = sscanf(caps->get(CameraProperties::PICTURE_SIZE), "%dx%d", &max_width, &max_height);
377 if ((ret < 0) || (max_width <0) || (max_height < 0))
378 return -EINVAL;
379
380 max_width = ALIGN(max_width, 32);
381 max_height = ALIGN(max_height, 32);
382
383 if(DEFAULT_IMAGE_CAPTURE_PIXEL_FORMAT == V4L2_PIX_FMT_RGB24){ // rgb24
384
385 bytes = max_width*max_height*3;
386 }else if(DEFAULT_IMAGE_CAPTURE_PIXEL_FORMAT == V4L2_PIX_FMT_YUYV){ // 422I
387
388 bytes = max_width*max_height*2;
389 }else if(DEFAULT_IMAGE_CAPTURE_PIXEL_FORMAT == V4L2_PIX_FMT_NV21){
390
391 bytes = max_width*max_height*3/2;
392 }else{
393
394 bytes = max_width*max_height*3;
395 }
396
397
398 mIonFd = ion_open();
399 if (mIonFd < 0){
400 CAMHAL_LOGVB("ion_open failed, errno=%d", errno);
401 return -EINVAL;
402 }
403 ret = ion_alloc(mIonFd, bytes, 0, ION_HEAP_CARVEOUT_MASK, 0, &mIonHnd);
404 if (ret < 0){
405 ion_close(mIonFd);
406 CAMHAL_LOGVB("ion_alloc failed, errno=%d", errno);
407 mIonFd = -1;
408 return -ENOMEM;
409 }
410 ret = ion_share(mIonFd, mIonHnd, &mImageFd);
411 if (ret < 0){
412 CAMHAL_LOGVB("ion_share failed, errno=%d", errno);
413 ion_free(mIonFd, mIonHnd);
414 ion_close(mIonFd);
415 mIonFd = -1;
416 return -EINVAL;
417 }
418
419 DBG_LOGB("allocate ion buffer for capture, ret=%d, bytes=%d, max_width=%d, max_height=%d\n",
420 ret, bytes, max_width, max_height);
421 return NO_ERROR;
422}
423
424status_t V4LCameraAdapter::IoctlStateProbe(void)
425{
426 struct v4l2_queryctrl qc;
427 int ret = 0;
428
429 LOG_FUNCTION_NAME;
430
431 mIoctlSupport = 0;
432 if(get_hflip_mode(mCameraHandle)==0){
433 mIoctlSupport |= IOCTL_MASK_HFLIP;
434 }else{
435 mIoctlSupport &= ~IOCTL_MASK_HFLIP;
436 }
437
438 memset(&qc, 0, sizeof(struct v4l2_queryctrl));
439 qc.id = V4L2_CID_ZOOM_ABSOLUTE;
440 ret = ioctl (mCameraHandle, VIDIOC_QUERYCTRL, &qc);
441 if((qc.flags == V4L2_CTRL_FLAG_DISABLED) ||( ret < 0)|| (qc.type != V4L2_CTRL_TYPE_INTEGER)){
442 mIoctlSupport &= ~IOCTL_MASK_ZOOM;
443 }else{
444 mIoctlSupport |= IOCTL_MASK_ZOOM;
445 }
446
447#ifndef AMLOGIC_USB_CAMERA_SUPPORT
448 memset(&qc, 0, sizeof(struct v4l2_queryctrl));
449 qc.id = V4L2_ROTATE_ID;
450 ret = ioctl (mCameraHandle, VIDIOC_QUERYCTRL, &qc);
451 if((qc.flags == V4L2_CTRL_FLAG_DISABLED) ||( ret < 0)|| (qc.type != V4L2_CTRL_TYPE_INTEGER)){
452 mIoctlSupport &= ~IOCTL_MASK_ROTATE;
453 }else{
454 mIoctlSupport |= IOCTL_MASK_ROTATE;
455 }
456
457 if(mIoctlSupport & IOCTL_MASK_ROTATE){
458 CAMHAL_LOGDB("camera %d support capture rotate",mSensorIndex);
459 }
460 mRotateValue = 0;
461#endif
462
463 memset(&qc, 0, sizeof(struct v4l2_queryctrl));
464#ifdef AMLOGIC_USB_CAMERA_SUPPORT
465 qc.id = V4L2_CID_EXPOSURE_ABSOLUTE;
466#else
467 qc.id = V4L2_CID_EXPOSURE;
468#endif
469 ret = ioctl (mCameraHandle, VIDIOC_QUERYCTRL, &qc);
470 if((qc.flags == V4L2_CTRL_FLAG_DISABLED) ||( ret < 0) ){
471 mIoctlSupport &= ~IOCTL_MASK_EXPOSURE;
472 mEVdef = 4;
473 mEVmin = 0;
474 mEVmax = 8;
475 }else{
476 mIoctlSupport |= IOCTL_MASK_EXPOSURE;
477 mEVdef = qc.default_value;
478 mEVmin = qc.minimum;
479 mEVmax = qc.maximum;
480 }
481 mEV = mEVdef;
482
483 memset(&qc, 0, sizeof(struct v4l2_queryctrl));
484#ifdef AMLOGIC_USB_CAMERA_SUPPORT
485 qc.id = V4L2_CID_AUTO_WHITE_BALANCE;
486#else
487 qc.id = V4L2_CID_DO_WHITE_BALANCE;
488#endif
489 ret = ioctl (mCameraHandle, VIDIOC_QUERYCTRL, &qc);
490 if((qc.flags == V4L2_CTRL_FLAG_DISABLED) ||( ret < 0)){
491 mIoctlSupport &= ~IOCTL_MASK_WB;
492 }else{
493 mIoctlSupport |= IOCTL_MASK_WB;
494 }
495
496 mWhiteBalance = qc.default_value;
497 memset(&qc, 0, sizeof(struct v4l2_queryctrl));
498 qc.id = V4L2_CID_BACKLIGHT_COMPENSATION;
499 ret = ioctl (mCameraHandle, VIDIOC_QUERYCTRL, &qc);
500 if((qc.flags == V4L2_CTRL_FLAG_DISABLED) ||( ret < 0)|| (qc.type != V4L2_CTRL_TYPE_MENU)){
501 mIoctlSupport &= ~IOCTL_MASK_FLASH;
502 }else{
503 mIoctlSupport |= IOCTL_MASK_FLASH;
504 }
505
506 memset(&qc, 0, sizeof(struct v4l2_queryctrl));
507 qc.id = V4L2_CID_COLORFX;
508 ret = ioctl (mCameraHandle, VIDIOC_QUERYCTRL, &qc);
509 if((qc.flags == V4L2_CTRL_FLAG_DISABLED) ||( ret < 0)|| (qc.type != V4L2_CTRL_TYPE_MENU)){
510 mIoctlSupport &= ~IOCTL_MASK_EFFECT;
511 }else{
512 mIoctlSupport |= IOCTL_MASK_EFFECT;
513 }
514
515 memset(&qc, 0, sizeof(struct v4l2_queryctrl));
516 qc.id = V4L2_CID_POWER_LINE_FREQUENCY;
517 ret = ioctl (mCameraHandle, VIDIOC_QUERYCTRL, &qc);
518 if((qc.flags == V4L2_CTRL_FLAG_DISABLED) ||( ret < 0)|| (qc.type != V4L2_CTRL_TYPE_MENU)){
519 mIoctlSupport &= ~IOCTL_MASK_BANDING;
520 }else{
521 mIoctlSupport |= IOCTL_MASK_BANDING;
522 }
523 mAntiBanding = qc.default_value;
524
525 memset(&qc, 0, sizeof(struct v4l2_queryctrl));
526 qc.id = V4L2_CID_FOCUS_AUTO;
527 ret = ioctl (mCameraHandle, VIDIOC_QUERYCTRL, &qc);
528 if((qc.flags == V4L2_CTRL_FLAG_DISABLED) ||( ret < 0)|| (qc.type != V4L2_CTRL_TYPE_MENU)){
529 mIoctlSupport &= ~IOCTL_MASK_FOCUS;
530 }else{
531 mIoctlSupport |= IOCTL_MASK_FOCUS;
532 }
533
534 memset(&qc, 0, sizeof(struct v4l2_queryctrl));
535 qc.id = V4L2_CID_AUTO_FOCUS_STATUS;
536 ret = ioctl (mCameraHandle, VIDIOC_QUERYCTRL, &qc);
537 if((qc.flags == V4L2_CTRL_FLAG_DISABLED) ||( ret < 0)){
538 mIoctlSupport &= ~IOCTL_MASK_FOCUS_MOVE;
539 }else{
540 mIoctlSupport |= IOCTL_MASK_FOCUS_MOVE;
541 }
542
543 LOG_FUNCTION_NAME_EXIT;
544 return ret;
545}
546
547status_t V4LCameraAdapter::fillThisBuffer(void* frameBuf, CameraFrame::FrameType frameType)
548{
549 status_t ret = NO_ERROR;
550 v4l2_buffer hbuf_query;
551 private_handle_t* gralloc_hnd;
552
553 memset(&hbuf_query,0,sizeof(v4l2_buffer));
554
555 if (CameraFrame::IMAGE_FRAME == frameType){
556 //if (NULL != mEndImageCaptureCallback)
557 //mEndImageCaptureCallback(mEndCaptureData);
558 if (NULL != mReleaseImageBuffersCallback)
559 mReleaseImageBuffersCallback(mReleaseData);
560 return NO_ERROR;
561 }
562 if ( !mVideoInfo->isStreaming || !mPreviewing){
563 return NO_ERROR;
564 }
565 {
566 Mutex::Autolock lock(mPreviewBufsLock);// add this to protect previewbufs when reset sensor
567 int i = mPreviewBufs.valueFor(( unsigned int )frameBuf);
568 if(i<0){
569 return BAD_VALUE;
570 }
571 if(nQueued>=mPreviewBufferCount){
572 CAMHAL_LOGEB("fill buffer error, reach the max preview buff:%d,max:%d",nQueued,mPreviewBufferCount);
573 return BAD_VALUE;
574 }
575
576 hbuf_query.index = i;
577 hbuf_query.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
578 hbuf_query.memory = m_eV4l2Memory;
579 if (V4L2_MEMORY_DMABUF == m_eV4l2Memory)
580 {
581 gralloc_hnd = (private_handle_t *)frameBuf;
582 hbuf_query.m.fd = gralloc_hnd->share_fd;
583 }
584
585 ret = ioctl(mCameraHandle, VIDIOC_QBUF, &hbuf_query);
586 if (ret < 0) {
587 CAMHAL_LOGEB("Init: VIDIOC_QBUF %d Failed, errno=%d\n",i, errno);
588 return -1;
589 }
590 nQueued++;
591 }
592#ifdef AMLOGIC_USB_CAMERA_SUPPORT
593 if(mIsDequeuedEIOError){
594 CAMHAL_LOGEA("DQBUF EIO error has occurred!\n");
595 this->stopPreview();
596 close(mCameraHandle);
597 mCameraHandle = -1;
598 return -1;
599 }
600#endif
601 return ret;
602}
603
604status_t V4LCameraAdapter::setParameters(const CameraParameters &params)
605{
606 LOG_FUNCTION_NAME;
607 status_t rtn = NO_ERROR;
608
609 // Update the current parameter set
610 mParams = params;
611 //check zoom value
612 int zoom = mParams.getInt(CameraParameters::KEY_ZOOM);
613 int maxzoom = mParams.getInt(CameraParameters::KEY_MAX_ZOOM);
614 char *p = (char *)mParams.get(CameraParameters::KEY_ZOOM_RATIOS);
615
616 if(zoom > maxzoom){
617 rtn = INVALID_OPERATION;
618 CAMHAL_LOGDB("Zoom Out of range, level:%d,max:%d",zoom,maxzoom);
619 zoom = maxzoom;
620 mParams.set((const char*)CameraParameters::KEY_ZOOM, maxzoom);
621 }else if(zoom <0) {
622 rtn = INVALID_OPERATION;
623 zoom = 0;
624 CAMHAL_LOGEB("Zoom Parameter Out of range2------zoom level:%d,max level:%d",zoom,maxzoom);
625 mParams.set((const char*)CameraParameters::KEY_ZOOM, zoom);
626 }
627
628 if ((p) && (zoom >= 0)&&(zoom!=mZoomlevel)) {
629 int z = (int)strtol(p, &p, 10);
630 int i = 0;
631 while (i < zoom) {
632 if (*p != ',') break;
633 z = (int)strtol(p+1, &p, 10);
634 i++;
635 }
636 CAMHAL_LOGDB("Change the zoom level---old:%d,new:%d",mZoomlevel,zoom);
637 mZoomlevel = zoom;
638#ifndef AMLOGIC_USB_CAMERA_SUPPORT
639 if(mIoctlSupport & IOCTL_MASK_ZOOM)
640 set_zoom_level(mCameraHandle,z);
641 else
642 SYS_set_zoom(z);
643#endif
644 notifyZoomSubscribers((mZoomlevel<0)?0:mZoomlevel,true);
645 }
646
647 int min_fps,max_fps;
648 const char *white_balance=NULL;
649 const char *exposure=NULL;
650 const char *effect=NULL;
651 //const char *night_mode=NULL;
652 const char *qulity=NULL;
653 const char *banding=NULL;
654 const char *flashmode=NULL;
655 const char *focusmode=NULL;
656 const char *supportfocusmode=NULL;
657 const char *focusarea = NULL;
658
659 qulity=mParams.get(CameraParameters::KEY_JPEG_QUALITY);
660
661 flashmode = mParams.get(CameraParameters::KEY_FLASH_MODE);
662 if((mIoctlSupport & IOCTL_MASK_FLASH) && flashmode){
663 if(strcasecmp(flashmode, "torch")==0){
664 set_flash_mode(mCameraHandle, flashmode);
665 mFlashMode = FLASHLIGHT_TORCH;
666 }else if(strcasecmp(flashmode, "on")==0){
667 if( FLASHLIGHT_TORCH == mFlashMode){
668 set_flash_mode(mCameraHandle, "off");
669 }
670 mFlashMode = FLASHLIGHT_ON;
671 }else if(strcasecmp(flashmode, "off")==0){
672 set_flash_mode(mCameraHandle, flashmode);
673 mFlashMode = FLASHLIGHT_OFF;
674 }
675 }
676
677 exposure=mParams.get(CameraParameters::KEY_EXPOSURE_COMPENSATION);
678 if( (mIoctlSupport & IOCTL_MASK_EXPOSURE) && exposure){
679 SetExposure(mCameraHandle,exposure);
680 }
681
682 white_balance=mParams.get(CameraParameters::KEY_WHITE_BALANCE);
683 if((mIoctlSupport & IOCTL_MASK_WB) && white_balance){
684 set_white_balance(mCameraHandle,white_balance);
685 }
686
687 effect=mParams.get(CameraParameters::KEY_EFFECT);
688 if( (mIoctlSupport & IOCTL_MASK_EFFECT) && effect){
689 set_effect(mCameraHandle,effect);
690 }
691
692 banding=mParams.get(CameraParameters::KEY_ANTIBANDING);
693 if((mIoctlSupport & IOCTL_MASK_BANDING) && banding){
694 set_banding(mCameraHandle,banding);
695 }
696
697 focusmode = mParams.get(CameraParameters::KEY_FOCUS_MODE);
698 if(focusmode) {
699 if(strcasecmp(focusmode,"fixed")==0)
700 cur_focus_mode = CAM_FOCUS_MODE_FIXED;
701 else if(strcasecmp(focusmode,"auto")==0)
702 cur_focus_mode = CAM_FOCUS_MODE_AUTO;
703 else if(strcasecmp(focusmode,"infinity")==0)
704 cur_focus_mode = CAM_FOCUS_MODE_INFINITY;
705 else if(strcasecmp(focusmode,"macro")==0)
706 cur_focus_mode = CAM_FOCUS_MODE_MACRO;
707 else if(strcasecmp(focusmode,"edof")==0)
708 cur_focus_mode = CAM_FOCUS_MODE_EDOF;
709 else if(strcasecmp(focusmode,"continuous-video")==0)
710 cur_focus_mode = CAM_FOCUS_MODE_CONTI_VID;
711 else if(strcasecmp(focusmode,"continuous-picture")==0)
712 cur_focus_mode = CAM_FOCUS_MODE_CONTI_PIC;
713 else
714 cur_focus_mode = CAM_FOCUS_MODE_FIXED;
715 }
716 supportfocusmode = mParams.get(CameraParameters::KEY_SUPPORTED_FOCUS_MODES);
717 if( NULL != strstr(supportfocusmode, "continuous")){
718 if(CAM_FOCUS_MODE_AUTO != cur_focus_mode_for_conti){
719 struct v4l2_control ctl;
720 if( (CAM_FOCUS_MODE_CONTI_VID != cur_focus_mode_for_conti ) &&
721 ( (CAM_FOCUS_MODE_AUTO == cur_focus_mode )
722 ||( CAM_FOCUS_MODE_CONTI_PIC == cur_focus_mode )
723 ||( CAM_FOCUS_MODE_CONTI_VID == cur_focus_mode ) )){
724 mEnableContiFocus = true;
725 ctl.id = V4L2_CID_FOCUS_AUTO;
726 ctl.value = CAM_FOCUS_MODE_CONTI_VID;
727 if(ioctl(mCameraHandle, VIDIOC_S_CTRL, &ctl)<0){
728 CAMHAL_LOGDA("failed to set CAM_FOCUS_MODE_CONTI_VID!\n");
729 }
730 mFocusWaitCount = FOCUS_PROCESS_FRAMES;
731 bFocusMoveState = true;
732 cur_focus_mode_for_conti = CAM_FOCUS_MODE_CONTI_VID;
733 }else if( (CAM_FOCUS_MODE_CONTI_VID != cur_focus_mode_for_conti)&&
734 (CAM_FOCUS_MODE_AUTO != cur_focus_mode) &&
735 ( CAM_FOCUS_MODE_CONTI_PIC != cur_focus_mode )&&
736 ( CAM_FOCUS_MODE_CONTI_VID != cur_focus_mode )){
737 mEnableContiFocus = false;
738 ctl.id = V4L2_CID_FOCUS_AUTO;
739 ctl.value = CAM_FOCUS_MODE_RELEASE;
740 if(ioctl(mCameraHandle, VIDIOC_S_CTRL, &ctl)<0){
741 CAMHAL_LOGDA("failed to set CAM_FOCUS_MODE_RELEASE!\n");
742 }
743 cur_focus_mode_for_conti = CAM_FOCUS_MODE_RELEASE;
744 }else if( (CAM_FOCUS_MODE_INFINITY != cur_focus_mode_for_conti)&&
745 (CAM_FOCUS_MODE_INFINITY == cur_focus_mode) ){
746 mEnableContiFocus = false;
747 ctl.id = V4L2_CID_FOCUS_AUTO;
748 ctl.value = CAM_FOCUS_MODE_INFINITY;
749 if(ioctl(mCameraHandle, VIDIOC_S_CTRL, &ctl)<0){
750 CAMHAL_LOGDA("failed to set CAM_FOCUS_MODE_INFINITY!\n");
751 }
752 cur_focus_mode_for_conti = CAM_FOCUS_MODE_INFINITY;
753 }
754 }
755 }else{
756 mEnableContiFocus = false;
757 CAMHAL_LOGDA("not support continuous mode!\n");
758 }
759
760 focusarea = mParams.get(CameraParameters::KEY_FOCUS_AREAS);
761 if(focusarea){
762 set_focus_area( mCameraHandle, focusarea);
763 }
764
765 min_fps = mParams.getPreviewFrameRate();
766 if( min_fps ){
767 mExpectedFrameInv = (unsigned) (1000000)/min_fps;
768 }else{
769 mExpectedFrameInv = (unsigned) (1000000)/15;
770 }
771 mFramerate = min_fps ? min_fps : 15;
772 mParams.getPreviewFpsRange(&min_fps, &max_fps);
773 if((min_fps<0)||(max_fps<0)||(max_fps<min_fps)){
774 rtn = INVALID_OPERATION;
775 }
776
777 LOG_FUNCTION_NAME_EXIT;
778 return rtn;
779}
780
781
782void V4LCameraAdapter::getParameters(CameraParameters& params)
783{
784 LOG_FUNCTION_NAME;
785
786 // Return the current parameter set
787 //params = mParams;
788 //that won't work. we might wipe out the existing params
789
790 LOG_FUNCTION_NAME_EXIT;
791}
792
793///API to give the buffers to Adapter
794status_t V4LCameraAdapter::useBuffers(CameraMode mode, void* bufArr, int num, size_t length, unsigned int queueable)
795{
796 status_t ret = NO_ERROR;
797
798 LOG_FUNCTION_NAME;
799 Mutex::Autolock lock(mLock);
800 mPreviewCache = NULL;
801 switch(mode){
802 case CAMERA_PREVIEW:
803 ret = UseBuffersPreview(bufArr, num);
804 //maxQueueable = queueable;
805 break;
806 case CAMERA_IMAGE_CAPTURE:
807 ret = UseBuffersCapture(bufArr, num);
808 break;
809 case CAMERA_VIDEO:
810 //@warn Video capture is not fully supported yet
811 ret = UseBuffersPreview(bufArr, num);
812 //maxQueueable = queueable;
813 break;
814 default:
815 break;
816 }
817
818 LOG_FUNCTION_NAME_EXIT;
819 return ret;
820}
821
822status_t V4LCameraAdapter::tryBuffersFormat(int width, int height, int pixelformat)
823{
824 int ret = NO_ERROR;
825 CAMHAL_LOGIB("try Width * Height %d x %d pixelformat:%.4s\n",
826 width, height, (char*)&pixelformat);
827
828 mVideoInfo->width = width;
829 mVideoInfo->height = height;
830 mVideoInfo->framesizeIn = (width * height << 1);
831 mVideoInfo->formatIn = pixelformat;
832
833 mVideoInfo->format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
834 mVideoInfo->format.fmt.pix.width = width;
835 mVideoInfo->format.fmt.pix.height = height;
836 mVideoInfo->format.fmt.pix.pixelformat = pixelformat;
837
838 ret = ioctl(mCameraHandle, VIDIOC_TRY_FMT, &mVideoInfo->format);
839 if (ret < 0) {
840 CAMHAL_LOGVB("VIDIOC_TRY_FMT Failed: %s, wxd=%dx%d, ret=%d\n", strerror(errno), width, height, ret);
841 }
842
843 if ( ((int)mVideoInfo->format.fmt.pix.width != width) ||
844 ((int)mVideoInfo->format.fmt.pix.height != height) ) {
845 CAMHAL_LOGVB("VIDIOC_TRY_FMT Failed: %s, wxd=%dx%d, ret=%d\n", strerror(errno), width, height, ret);
846 ret = -EINVAL;
847 }
848
849 return ret;
850}
851
852status_t V4LCameraAdapter::setBuffersFormat(int width, int height, int pixelformat)
853{
854 int ret = NO_ERROR;
855 CAMHAL_LOGIB("Width * Height %d x %d pixelformat:%.4s\n",
856 width, height, (char*)&pixelformat);
857
858 mVideoInfo->width = width;
859 mVideoInfo->height = height;
860 mVideoInfo->framesizeIn = (width * height << 1);
861 mVideoInfo->formatIn = pixelformat;
862
863 mVideoInfo->format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
864 mVideoInfo->format.fmt.pix.width = width;
865 mVideoInfo->format.fmt.pix.height = height;
866 mVideoInfo->format.fmt.pix.pixelformat = pixelformat;
867
868 ret = ioctl(mCameraHandle, VIDIOC_S_FMT, &mVideoInfo->format);
869 if (ret < 0) {
870 CAMHAL_LOGEB("Open: VIDIOC_S_FMT Failed: %s, ret=%d\n", strerror(errno), ret);
871 }
872 return ret;
873}
874
875status_t V4LCameraAdapter::getBuffersFormat(int &width, int &height, int &pixelformat)
876{
877 int ret = NO_ERROR;
878 struct v4l2_format format;
879
880 memset(&format, 0,sizeof(struct v4l2_format));
881
882 format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
883 ret = ioctl(mCameraHandle, VIDIOC_G_FMT, &format);
884 if (ret < 0) {
885 CAMHAL_LOGDB("Open: VIDIOC_G_FMT Failed: %s", strerror(errno));
886 return ret;
887 }
888 width = format.fmt.pix.width;
889 height = format.fmt.pix.height;
890 pixelformat = format.fmt.pix.pixelformat;
891 CAMHAL_LOGDB("VIDIOC_G_FMT, w*h: %5dx%5d, format 0x%x", width, height, pixelformat);
892 return ret;
893}
894
895status_t V4LCameraAdapter::setCrop(int width, int height)
896{
897 int ret = NO_ERROR;
898#ifndef AMLOGIC_USB_CAMERA_SUPPORT
899 struct v4l2_crop crop;
900
901 memset (&crop, 0, sizeof(crop));
902 crop.c.width = width;
903 crop.c.height = height;
904 ret = ioctl(mCameraHandle, VIDIOC_S_CROP, &crop);
905 if (ret < 0) {
906 CAMHAL_LOGVB("VIDIOC_S_CROP Failed: %s, ret=%d\n", strerror(errno), ret);
907 }
908
909#endif
910 return ret;
911}
912
913status_t V4LCameraAdapter::UseBuffersPreview(void* bufArr, int num)
914{
915 int ret = NO_ERROR;
916 private_handle_t* gralloc_hnd;
917 uint32_t limit_pixelfmt = 0;
918
919 if(NULL == bufArr)
920 return BAD_VALUE;
921
922 int width, height,k = 0;
923 mParams.getPreviewSize(&width, &height);
924
925 mPreviewWidth = width;
926 mPreviewHeight = height;
927
928 mLimitedFrameRate = 0;
929
930 for(k = 0; k<LimitedRate.num; k++){
931 if((mPreviewWidth == LimitedRate.arg[k].width)&&(mPreviewHeight == LimitedRate.arg[k].height)){
932 mLimitedFrameRate = LimitedRate.arg[k].framerate;
933 CAMHAL_LOGVB("UseBuffersPreview, Get the limited rate: %dx%dx%d", mPreviewWidth, mPreviewHeight, mLimitedFrameRate);
934 break;
935 }
936 }
937
938 const char *pixfmtchar;
939 int pixfmt = V4L2_PIX_FMT_NV21;
940
941 pixfmtchar = mParams.getPreviewFormat();
942 if(strcasecmp( pixfmtchar, "yuv420p")==0){
943 pixfmt = V4L2_PIX_FMT_YVU420;
944 mPixelFormat =CameraFrame::PIXEL_FMT_YV12;
945 }else if(strcasecmp( pixfmtchar, "yuv420sp")==0){
946 pixfmt = V4L2_PIX_FMT_NV21;
947 mPixelFormat = CameraFrame::PIXEL_FMT_NV21;
948 }else if(strcasecmp( pixfmtchar, "yuv422")==0){
949 pixfmt = V4L2_PIX_FMT_YUYV;
950 mPixelFormat = CameraFrame::PIXEL_FMT_YUYV;
951 }
952
953 mSensorFormat = pixfmt;
954#ifdef AMLOGIC_USB_CAMERA_SUPPORT
955 if((mUseMJPEG == true)&&(mSupportMJPEG == true)) {
956 mSensorFormat = V4L2_PIX_FMT_MJPEG;
957 ret = tryBuffersFormat(width, height, mSensorFormat);
958 if( ret < 0) {
959 CAMHAL_LOGVB("try format :%4s wxh=%dx%d not support\n", (char *)&mSensorFormat, width, height);
960 mSensorFormat = V4L2_PIX_FMT_YUYV;
961 mSupportMJPEG = false;
962 }
963
964 } else {
965 mSensorFormat = V4L2_PIX_FMT_YUYV;
966 }
967
968
969
970 limit_pixelfmt = query_aml_usb_pixelfmt(mVideoInfo->idVendor, mVideoInfo->idProduct, width, height);
971 if (limit_pixelfmt) {
972 mSensorFormat = limit_pixelfmt;
973 }
974 if(mDebugMJPEG) {
975 mSensorFormat = V4L2_PIX_FMT_YUYV;
976 mSupportMJPEG = false;
977 CAMHAL_LOGDA("use YUYV for debug purpose\n");
978 }
979#endif
980 ret = setBuffersFormat(width, height, mSensorFormat);
981 if( 0 > ret ){
982 CAMHAL_LOGEB("VIDIOC_S_FMT failed: %s", strerror(errno));
983 return BAD_VALUE;
984 }
985 //First allocate adapter internal buffers at V4L level for USB Cam
986 //These are the buffers from which we will copy the data into overlay buffers
987 /* Check if camera can handle NB_BUFFER buffers */
988 mVideoInfo->rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
989 mVideoInfo->rb.memory = m_eV4l2Memory;
990 mVideoInfo->rb.count = num;
991
992 ret = ioctl(mCameraHandle, VIDIOC_REQBUFS, &mVideoInfo->rb);
993 if (ret < 0) {
994 CAMHAL_LOGEB("VIDIOC_REQBUFS failed: %s", strerror(errno));
995 return ret;
996 }
997 uint32_t *ptr = (uint32_t*) bufArr;
998 mPreviewCache = (uint32_t*) bufArr;
999 {
1000 Mutex::Autolock lock(mPreviewBufsLock);
1001 for (int i = 0; i < num; i++) {
1002 memset (&mVideoInfo->buf, 0, sizeof (struct v4l2_buffer));
1003 mVideoInfo->buf.index = i;
1004 mVideoInfo->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1005 mVideoInfo->buf.memory = m_eV4l2Memory;
1006 ret = ioctl (mCameraHandle, VIDIOC_QUERYBUF, &mVideoInfo->buf);
1007 if (ret < 0) {
1008 CAMHAL_LOGEB("Unable to query buffer (%s)", strerror(errno));
1009 return ret;
1010 }
1011
1012 if (V4L2_MEMORY_DMABUF == m_eV4l2Memory)
1013 {
1014 gralloc_hnd = (private_handle_t*)ptr[i];
1015 mVideoInfo->mem[i] = mmap (0,
1016 mVideoInfo->buf.length,
1017 PROT_READ | PROT_WRITE,
1018 MAP_SHARED,
1019 gralloc_hnd->share_fd,
1020 0);
1021 } else {
1022 mVideoInfo->mem[i] = mmap (0,
1023 mVideoInfo->buf.length,
1024 PROT_READ | PROT_WRITE,
1025 MAP_SHARED,
1026 mCameraHandle,
1027 mVideoInfo->buf.m.offset);
1028 }
1029
1030 if (mVideoInfo->mem[i] == MAP_FAILED) {
1031 CAMHAL_LOGEB("Unable to map buffer (%s)", strerror(errno));
1032 return -1;
1033 }
1034
1035 if(mVideoInfo->canvas_mode){
1036 mVideoInfo->canvas[i] = mVideoInfo->buf.reserved;
1037 }
1038 //Associate each Camera internal buffer with the one from Overlay
1039 CAMHAL_LOGDB("mPreviewBufs.add %#x, %d", ptr[i], i);
1040 mPreviewBufs.add((int)ptr[i], i);
1041 }
1042
1043 for(int i = 0;i < num; i++){
1044 mPreviewIdxs.add(mPreviewBufs.valueAt(i),i);
1045 }
1046 }
1047
1048 // Update the preview buffer count
1049 mPreviewBufferCount = num;
1050 return ret;
1051}
1052
1053status_t V4LCameraAdapter::UseBuffersCapture(void* bufArr, int num)
1054{
1055 int ret = NO_ERROR;
1056 uint32_t limit_pixelfmt = 0;
1057
1058 LOG_FUNCTION_NAME;
1059
1060 if(NULL == bufArr)
1061 return BAD_VALUE;
1062
1063 if (num != 1){
1064 CAMHAL_LOGDB("num=%d\n", num);
1065 }
1066
1067 int width, height;
1068 mParams.getPictureSize(&width, &height);
1069 mCaptureWidth = width;
1070 mCaptureHeight = height;
1071#ifdef AMLOGIC_USB_CAMERA_SUPPORT
1072 if((mUseMJPEG == true)&&(mSupportMJPEG == true)) {
1073 mSensorFormat = V4L2_PIX_FMT_MJPEG;
1074 ret = tryBuffersFormat(width, height, mSensorFormat);
1075 if( ret < 0) {
1076 CAMHAL_LOGVB("try wxh=%dx%d not support mjpeg\n", width, height);
1077 mSensorFormat = V4L2_PIX_FMT_YUYV;
1078 mSupportMJPEG = false;
1079 }
1080 } else {
1081 mSensorFormat = V4L2_PIX_FMT_YUYV;
1082 }
1083
1084
1085 limit_pixelfmt = query_aml_usb_pixelfmt(mVideoInfo->idVendor, mVideoInfo->idProduct, width, height);
1086 if (limit_pixelfmt) {
1087 mSensorFormat = limit_pixelfmt;
1088 }
1089#else
1090 if(mIoctlSupport & IOCTL_MASK_ROTATE){
1091 int temp = 0;
1092 mRotateValue = mParams.getInt(CameraParameters::KEY_ROTATION);
1093 if((mRotateValue!=0)&&(mRotateValue!=90)&&(mRotateValue!=180)&&(mRotateValue!=270))
1094 mRotateValue = 0;
1095 if((mRotateValue==90)||(mRotateValue==270)){
1096 temp = width;
1097 width = height;
1098 height = temp;
1099 }
1100 }
1101 mSensorFormat = DEFAULT_IMAGE_CAPTURE_PIXEL_FORMAT;
1102#endif
1103
1104 setCrop( mCaptureWidth, mCaptureHeight);
1105 /* This will only be called right before taking a picture, so
1106 * stop preview now so that we can set buffer format here.
1107 */
1108 this->stopPreview();
1109
1110 setBuffersFormat(width, height, mSensorFormat);
1111
1112 //First allocate adapter internal buffers at V4L level for Cam
1113 //These are the buffers from which we will copy the data into display buffers
1114 /* Check if camera can handle NB_BUFFER buffers */
1115 mVideoInfo->rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1116 mVideoInfo->rb.memory = m_eV4l2Memory;
1117 mVideoInfo->rb.count = num;
1118
1119 ret = ioctl(mCameraHandle, VIDIOC_REQBUFS, &mVideoInfo->rb);
1120 if (ret < 0) {
1121 CAMHAL_LOGEB("VIDIOC_REQBUFS failed: %s", strerror(errno));
1122 return ret;
1123 }
1124
1125 for (int i = 0; i < num; i++) {
1126 memset (&mVideoInfo->buf, 0, sizeof (struct v4l2_buffer));
1127 mVideoInfo->buf.index = i;
1128 mVideoInfo->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1129 mVideoInfo->buf.memory = m_eV4l2Memory;
1130 ret = ioctl (mCameraHandle, VIDIOC_QUERYBUF, &mVideoInfo->buf);
1131 if (ret < 0) {
1132 CAMHAL_LOGEB("Unable to query buffer (%s)", strerror(errno));
1133 return ret;
1134 }
1135 if (V4L2_MEMORY_DMABUF == m_eV4l2Memory) {
1136 mVideoInfo->mem[i] = mmap (0,
1137 mVideoInfo->buf.length,
1138 PROT_READ | PROT_WRITE,
1139 MAP_SHARED,
1140 mImageFd,
1141 0);
1142 } else {
1143 mVideoInfo->mem[i] = mmap (0,
1144 mVideoInfo->buf.length,
1145 PROT_READ | PROT_WRITE,
1146 MAP_SHARED,
1147 mCameraHandle,
1148 mVideoInfo->buf.m.offset);
1149 }
1150
1151 if (mVideoInfo->mem[i] == MAP_FAILED) {
1152 CAMHAL_LOGEB("Unable to map buffer (%s)", strerror(errno));
1153 return -1;
1154 }
1155 if(mVideoInfo->canvas_mode)
1156 mVideoInfo->canvas[i] = mVideoInfo->buf.reserved;
1157
1158 uint32_t *ptr = (uint32_t*) bufArr;
1159 mCaptureBuf = (camera_memory_t*)ptr[0];
1160 CAMHAL_LOGDB("UseBuffersCapture %#x", ptr[0]);
1161 }
1162
1163 LOG_FUNCTION_NAME_EXIT;
1164 return ret;
1165}
1166
1167status_t V4LCameraAdapter::takePicture()
1168{
1169 LOG_FUNCTION_NAME;
1170 if (createThread(beginPictureThread, this) == false)
1171 return -1;
1172 LOG_FUNCTION_NAME_EXIT;
1173 return NO_ERROR;
1174}
1175
1176
1177int V4LCameraAdapter::beginAutoFocusThread(void *cookie)
1178{
1179 V4LCameraAdapter *c = (V4LCameraAdapter *)cookie;
1180 struct v4l2_control ctl;
1181 int ret = -1;
1182
1183 if( c->mIoctlSupport & IOCTL_MASK_FOCUS){
1184 ctl.id = V4L2_CID_FOCUS_AUTO;
1185 ctl.value = CAM_FOCUS_MODE_AUTO;//c->cur_focus_mode;
1186 ret = ioctl(c->mCameraHandle, VIDIOC_S_CTRL, &ctl);
1187 for(int j=0; j<70; j++){
1188 usleep(30000);//30*70ms=2.1s
1189 ret = ioctl(c->mCameraHandle, VIDIOC_G_CTRL, &ctl);
1190 if( (0==ret) || ((ret < 0)&&(EBUSY != errno)) ){
1191 break;
1192 }
1193 }
1194 }
1195
1196 c->setState(CAMERA_CANCEL_AUTOFOCUS);
1197 c->commitState();
1198
1199 if( (c->mIoctlSupport & IOCTL_MASK_FLASH)&&(FLASHLIGHT_ON == c->mFlashMode)){
1200 set_flash_mode( c->mCameraHandle, "off");
1201 }
1202 if(ret < 0) {
1203 if( c->mIoctlSupport & IOCTL_MASK_FOCUS){
1204 CAMHAL_LOGDA("AUTO FOCUS Failed");
1205 }
1206 c->notifyFocusSubscribers(false);
1207 } else {
1208 c->notifyFocusSubscribers(true);
1209 }
1210 // may need release auto focus mode at here.
1211 return ret;
1212}
1213
1214status_t V4LCameraAdapter::autoFocus()
1215{
1216 status_t ret = NO_ERROR;
1217 LOG_FUNCTION_NAME;
1218
1219 if( (mIoctlSupport & IOCTL_MASK_FLASH)&&(FLASHLIGHT_ON == mFlashMode)){
1220 set_flash_mode( mCameraHandle, "on");
1221 }
1222 cur_focus_mode_for_conti = CAM_FOCUS_MODE_AUTO;
1223
1224 if (createThread(beginAutoFocusThread, this) == false){
1225 ret = UNKNOWN_ERROR;
1226 }
1227
1228 LOG_FUNCTION_NAME_EXIT;
1229 return ret;
1230}
1231
1232status_t V4LCameraAdapter::cancelAutoFocus()
1233{
1234 status_t ret = NO_ERROR;
1235
1236 LOG_FUNCTION_NAME;
1237 struct v4l2_control ctl;
1238
1239 if( (mIoctlSupport & IOCTL_MASK_FOCUS) == 0x00 ){
1240 return 0;
1241 }
1242
1243 if ( !mEnableContiFocus){
1244 ctl.id = V4L2_CID_FOCUS_AUTO;
1245 ctl.value = CAM_FOCUS_MODE_RELEASE;
1246 ret = ioctl(mCameraHandle, VIDIOC_S_CTRL, &ctl);
1247 if(ret < 0) {
1248 CAMHAL_LOGDA("AUTO FOCUS Failed");
1249 }
1250 }else if( CAM_FOCUS_MODE_AUTO == cur_focus_mode_for_conti){
1251 if(CAM_FOCUS_MODE_INFINITY != cur_focus_mode){
1252 ctl.id = V4L2_CID_FOCUS_AUTO;
1253 ctl.value = CAM_FOCUS_MODE_CONTI_VID;
1254 if(ioctl(mCameraHandle, VIDIOC_S_CTRL, &ctl)<0){
1255 CAMHAL_LOGDA("failed to set CAM_FOCUS_MODE_CONTI_VID\n");
1256 }
1257 cur_focus_mode_for_conti = CAM_FOCUS_MODE_CONTI_VID;
1258 }else{
1259 ctl.id = V4L2_CID_FOCUS_AUTO;
1260 ctl.value = CAM_FOCUS_MODE_INFINITY;
1261 if(ioctl(mCameraHandle, VIDIOC_S_CTRL, &ctl)<0){
1262 CAMHAL_LOGDA("failed to set CAM_FOCUS_MODE_INFINITY\n");
1263 }
1264 cur_focus_mode_for_conti = CAM_FOCUS_MODE_INFINITY;
1265 }
1266 }
1267 LOG_FUNCTION_NAME_EXIT;
1268 return ret;
1269}
1270
1271status_t V4LCameraAdapter::startPreview()
1272{
1273 status_t ret = NO_ERROR;
1274 int frame_count = 0,ret_c = 0;
1275 void *frame_buf = NULL;
1276
1277
1278 if(mPreviewing){
1279 return BAD_VALUE;
1280 }
1281
1282#ifdef ION_MODE_FOR_METADATA_MODE
1283 if ((CAMHAL_GRALLOC_USAGE) & GRALLOC_USAGE_PRIVATE_1) {
1284 mIonClient = ion_open();
1285 if (mIonClient >= 0) {
1286 ion_mode = true;
1287 memset(mPhyAddr, 0, sizeof(mPhyAddr));
1288 } else {
1289 CAMHAL_LOGEA("open ion client error");
1290 }
1291 }
1292#endif
1293
1294#ifndef AMLOGIC_USB_CAMERA_SUPPORT
1295 setMirrorEffect();
1296
1297 if(mIoctlSupport & IOCTL_MASK_ROTATE){
1298 if(mPreviewOriation!=0) {
1299 set_rotate_value(mCameraHandle,mPreviewOriation);
1300 mPreviewOriation=0;
1301 }else{
1302 set_rotate_value(mCameraHandle,0);
1303 mRotateValue = 0;
1304 }
1305 }
1306#endif
1307
1308 nQueued = 0;
1309 private_handle_t* gralloc_hnd;
1310 {
1311 Mutex::Autolock lock(mPreviewBufsLock);
1312 for (int i = 0; i < mPreviewBufferCount; i++){
1313 frame_count = -1;
1314 frame_buf = (void *)mPreviewBufs.keyAt(i);
1315
1316 if((ret_c = getFrameRefCount(frame_buf,CameraFrame::PREVIEW_FRAME_SYNC))>=0)
1317 frame_count = ret_c;
1318
1319 //if((ret_c = getFrameRefCount(frame_buf,CameraFrame::VIDEO_FRAME_SYNC))>=0)
1320 // frame_count += ret_c;
1321
1322 CAMHAL_LOGDB("startPreview--buffer address:0x%x, refcount:%d",(uint32_t)frame_buf,frame_count);
1323 if(frame_count>0)
1324 continue;
1325 //mVideoInfo->buf.index = i;
1326 mVideoInfo->buf.index = mPreviewBufs.valueFor((uint32_t)frame_buf);
1327 mVideoInfo->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1328 mVideoInfo->buf.memory = m_eV4l2Memory;
1329 if (V4L2_MEMORY_DMABUF == m_eV4l2Memory) {
1330 gralloc_hnd = (private_handle_t *)frame_buf;
1331 mVideoInfo->buf.m.fd = gralloc_hnd->share_fd;
1332 }
1333
1334 ret = ioctl(mCameraHandle, VIDIOC_QBUF, &mVideoInfo->buf);
1335 if (ret < 0) {
1336 CAMHAL_LOGEA("VIDIOC_QBUF Failed");
1337 return -EINVAL;
1338 }
1339 CAMHAL_LOGDB("startPreview --length=%d, index:%d", mVideoInfo->buf.length,mVideoInfo->buf.index);
1340 nQueued++;
1341 }
1342 }
1343
1344 enum v4l2_buf_type bufType;
1345 if (!mVideoInfo->isStreaming){
1346 bufType = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1347#ifdef AMLOGIC_CAMERA_NONBLOCK_SUPPORT
1348 gettimeofday( &previewTime1, NULL);
1349#endif
1350 ret = ioctl (mCameraHandle, VIDIOC_STREAMON, &bufType);
1351 if (ret < 0) {
1352 CAMHAL_LOGEB("StartStreaming: Unable to start capture: %s", strerror(errno));
1353 return ret;
1354 }
1355 mVideoInfo->isStreaming = true;
1356 }
1357
1358 if( mEnableContiFocus &&
1359 (CAM_FOCUS_MODE_AUTO != cur_focus_mode_for_conti) &&
1360 (CAM_FOCUS_MODE_INFINITY != cur_focus_mode_for_conti)){
1361 struct v4l2_control ctl;
1362 ctl.id = V4L2_CID_FOCUS_AUTO;
1363 ctl.value = CAM_FOCUS_MODE_CONTI_VID;
1364 if(ioctl(mCameraHandle, VIDIOC_S_CTRL, &ctl)<0){
1365 CAMHAL_LOGDA("failed to set CAM_FOCUS_MODE_CONTI_VID!\n");
1366 }
1367 cur_focus_mode_for_conti = CAM_FOCUS_MODE_CONTI_VID;
1368 }
1369 // Create and start preview thread for receiving buffers from V4L Camera
1370 mFailedCnt = 0;
1371 mEagainCnt = 0;
1372 mPreviewThread = new PreviewThread(this);
1373 CAMHAL_LOGDA("Created preview thread");
1374 //Update the flag to indicate we are previewing
1375 mPreviewing = true;
1376#ifdef PREVIEW_TIME_DEBUG
1377 gettimeofday(&mTimeStart,NULL);
1378 precount = 0;
1379#endif
1380#ifdef AMLOGIC_CAMERA_NONBLOCK_SUPPORT
1381 mFirstBuff = true;
1382 mFrameInvAdjust = 0;
1383 mFrameInv = 0;
1384 mCache.bufPtr = NULL;
1385 mCache.index = -1;
1386#endif
1387 return ret;
1388}
1389
1390status_t V4LCameraAdapter::stopPreview()
1391{
1392 enum v4l2_buf_type bufType;
1393 int ret = NO_ERROR;
1394
1395 LOG_FUNCTION_NAME;
1396 Mutex::Autolock lock(mPreviewBufsLock);
1397 if(!mPreviewing){
1398 return NO_INIT;
1399 }
1400
1401 mPreviewing = false;
1402 mFocusMoveEnabled = false;
1403 mPreviewThread->requestExitAndWait();
1404 mPreviewThread.clear();
1405
1406 if (mVideoInfo->isStreaming) {
1407 bufType = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1408 ret = ioctl (mCameraHandle, VIDIOC_STREAMOFF, &bufType);
1409 if (ret < 0) {
1410 CAMHAL_LOGDB("StopStreaming: Unable to stop capture: %s", strerror(errno));
1411 }
1412 mVideoInfo->isStreaming = false;
1413 }
1414
1415 mVideoInfo->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1416 mVideoInfo->buf.memory = m_eV4l2Memory;
1417
1418 nQueued = 0;
1419 nDequeued = 0;
1420
1421 if( mEnableContiFocus &&
1422 (CAM_FOCUS_MODE_AUTO != cur_focus_mode_for_conti) &&
1423 (CAM_FOCUS_MODE_INFINITY != cur_focus_mode_for_conti)){
1424 struct v4l2_control ctl;
1425 ctl.id = V4L2_CID_FOCUS_AUTO;
1426 ctl.value = CAM_FOCUS_MODE_RELEASE;
1427 if(ioctl(mCameraHandle, VIDIOC_S_CTRL, &ctl)<0){
1428 CAMHAL_LOGDA("failed to set CAM_FOCUS_MODE_RELEASE!\n");
1429 }
1430 cur_focus_mode_for_conti = CAM_FOCUS_MODE_RELEASE;
1431 }
1432
1433 /* Unmap buffers */
1434 for (int i = 0; i < mPreviewBufferCount; i++){
1435 if (munmap(mVideoInfo->mem[i], mVideoInfo->buf.length) < 0){
1436 CAMHAL_LOGEA("Unmap failed");
1437 }
1438 mVideoInfo->canvas[i] = 0;
1439 }
1440
1441 if ((DEV_USB == m_eDeviceType) ||
1442 (DEV_ION == m_eDeviceType) ||
1443 (DEV_ION_MPLANE == m_eDeviceType))
1444 {
1445 mVideoInfo->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1446 mVideoInfo->buf.memory = m_eV4l2Memory;
1447 mVideoInfo->rb.count = 0;
1448
1449 ret = ioctl(mCameraHandle, VIDIOC_REQBUFS, &mVideoInfo->rb);
1450 if (ret < 0) {
1451 CAMHAL_LOGDB("VIDIOC_REQBUFS failed: %s", strerror(errno));
1452 }else{
1453 CAMHAL_LOGVA("VIDIOC_REQBUFS delete buffer success\n");
1454 }
1455 }
1456
1457#ifdef ION_MODE_FOR_METADATA_MODE
1458 if (mIonClient >= 0)
1459 ion_close(mIonClient);
1460 mIonClient = -1;
1461 memset(mPhyAddr, 0, sizeof(mPhyAddr));
1462#endif
1463
1464 mPreviewBufs.clear();
1465 mPreviewIdxs.clear();
1466 LOG_FUNCTION_NAME_EXIT;
1467 return ret;
1468}
1469
1470char * V4LCameraAdapter::GetFrame(int &index, unsigned int* canvas)
1471{
1472 int ret;
1473 if(nQueued<=0){
1474 CAMHAL_LOGVA("GetFrame: No buff for Dequeue");
1475 usleep(2000); // add sleep to avoid this case always in
1476 return NULL;
1477 }
1478 mVideoInfo->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1479 mVideoInfo->buf.memory = m_eV4l2Memory;
1480
1481 /* DQ */
1482#ifdef AMLOGIC_USB_CAMERA_SUPPORT
1483 if(mIsDequeuedEIOError){
1484 return NULL;
1485 }
1486 if(mEagainCnt == 0)
1487 gettimeofday(&mEagainStartTime, NULL);
1488
1489#endif
1490 ret = ioctl(mCameraHandle, VIDIOC_DQBUF, &mVideoInfo->buf);
1491 if (ret < 0) {
1492#ifdef AMLOGIC_USB_CAMERA_SUPPORT
1493 if((EIO==errno) || (ENODEV==errno)){
1494 mIsDequeuedEIOError = true;
1495 this->stopPreview();
1496 close(mCameraHandle);
1497 mCameraHandle = -1;
1498 CAMHAL_LOGEA("GetFrame: VIDIOC_DQBUF Failed--EIO\n");
1499 mErrorNotifier->errorNotify(CAMERA_ERROR_SOFT);
1500 }
1501#endif
1502 if(EAGAIN == errno){
1503 index = -1;
1504#ifdef AMLOGIC_USB_CAMERA_SUPPORT
1505 mEagainCnt++;
1506 gettimeofday(&mEagainEndTime, NULL);
1507 int intreval = (mEagainEndTime.tv_sec - mEagainStartTime.tv_sec) * 1000000 + (mEagainEndTime.tv_usec - mEagainStartTime.tv_usec);
1508 if(intreval > (int)mResetTH){
1509 ALOGD("EAGIN Too Much, Restart");
1510 force_reset_sensor();
1511 mEagainCnt = 0;
1512 mResetTH = 3000000; // for debug
1513 }
1514#endif
1515 }else{
1516 CAMHAL_LOGEB("GetFrame: VIDIOC_DQBUF Failed,errno=%d\n",errno);
1517 }
1518 return NULL;
1519 }
1520 mResetTH = 3000000;
1521 mEagainCnt = 0;
1522 nDequeued++;
1523 nQueued--;
1524 index = mVideoInfo->buf.index;
1525 if(mVideoInfo->canvas_mode)
1526 *canvas = mVideoInfo->canvas[mVideoInfo->buf.index];
1527 else
1528 *canvas = 0;
1529 return (char *)mVideoInfo->mem[mVideoInfo->buf.index];
1530}
1531
1532//API to get the frame size required to be allocated. This size is used to override the size passed
1533//by camera service when VSTAB/VNF is turned ON for example
1534status_t V4LCameraAdapter::getFrameSize(size_t &width, size_t &height)
1535{
1536 status_t ret = NO_ERROR;
1537
1538 // Just return the current preview size, nothing more to do here.
1539 mParams.getPreviewSize(( int * ) &width, ( int * ) &height);
1540
1541 return ret;
1542}
1543
1544status_t V4LCameraAdapter::getFrameDataSize(size_t &dataFrameSize, size_t bufferCount)
1545{
1546 // We don't support meta data, so simply return
1547 return NO_ERROR;
1548}
1549
1550status_t V4LCameraAdapter::getPictureBufferSize(size_t &length, size_t bufferCount)
1551{
1552 int width, height;
1553 mParams.getPictureSize(&width, &height);
1554 if(DEFAULT_IMAGE_CAPTURE_PIXEL_FORMAT == V4L2_PIX_FMT_RGB24){ // rgb24
1555 length = width * height * 3;
1556 }else if(DEFAULT_IMAGE_CAPTURE_PIXEL_FORMAT == V4L2_PIX_FMT_YUYV){ // 422I
1557 length = width * height * 2;
1558 }else if(DEFAULT_IMAGE_CAPTURE_PIXEL_FORMAT == V4L2_PIX_FMT_NV21){
1559 length = width * height * 3/2;
1560 }else{
1561 length = width * height * 3;
1562 }
1563 return NO_ERROR;
1564}
1565
1566static void debugShowFPS()
1567{
1568 static int mFrameCount = 0;
1569 static int mLastFrameCount = 0;
1570 static nsecs_t mLastFpsTime = 0;
1571 static float mFps = 0;
1572 mFrameCount++;
1573 if (!(mFrameCount & 0x1F)) {
1574 nsecs_t now = systemTime();
1575 nsecs_t diff = now - mLastFpsTime;
1576 mFps = ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
1577 mLastFpsTime = now;
1578 mLastFrameCount = mFrameCount;
1579 CAMHAL_LOGDB("Camera %d Frames, %f FPS", mFrameCount, mFps);
1580 }
1581 // XXX: mFPS has the value we want
1582}
1583
1584status_t V4LCameraAdapter::recalculateFPS()
1585{
1586 float currentFPS;
1587 mFrameCount++;
1588 if ( ( mFrameCount % FPS_PERIOD ) == 0 ){
1589 nsecs_t now = systemTime();
1590 nsecs_t diff = now - mLastFPSTime;
1591 currentFPS = ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
1592 mLastFPSTime = now;
1593 mLastFrameCount = mFrameCount;
1594
1595 if ( 1 == mIter ){
1596 mFPS = currentFPS;
1597 }else{
1598 //cumulative moving average
1599 mFPS = mLastFPS + (currentFPS - mLastFPS)/mIter;
1600 }
1601 mLastFPS = mFPS;
1602 mIter++;
1603 }
1604 return NO_ERROR;
1605}
1606
1607void V4LCameraAdapter::onOrientationEvent(uint32_t orientation, uint32_t tilt)
1608{
1609 //LOG_FUNCTION_NAME;
1610
1611 //LOG_FUNCTION_NAME_EXIT;
1612}
1613
1614
1615V4LCameraAdapter::V4LCameraAdapter(size_t sensor_index)
1616{
1617 LOG_FUNCTION_NAME;
1618 mbDisableMirror = false;
1619 mSensorIndex = sensor_index;
1620 m_eV4l2Memory = V4L2_MEMORY_MMAP;
1621 m_eDeviceType = DEV_MMAP;
1622 mImageFd = -1;
1623 //mImgPtr = NULL;
1624 mPreviewOriation=0;
1625 mCaptureOriation=0;
1626#ifdef ION_MODE_FOR_METADATA_MODE
1627 ion_mode = false;
1628 mIonClient = -1;
1629 memset(mPhyAddr, 0, sizeof(mPhyAddr));
1630#endif
1631 LOG_FUNCTION_NAME_EXIT;
1632}
1633
1634V4LCameraAdapter::~V4LCameraAdapter()
1635{
1636 LOG_FUNCTION_NAME;
1637 int ret;
1638
1639 if (mImageFd > 0){
1640 close(mImageFd);
1641 ret = ion_free( mIonFd, mIonHnd);
1642 mImageFd = -1;
1643 ion_close(mIonFd);
1644 mIonFd = -1;
1645 CAMHAL_LOGVA("success to release buffer\n");
1646 }
1647
1648 // Close the camera handle and free the video info structure
1649 if (mCameraHandle > 0) {
1650 close(mCameraHandle);
1651 mCameraHandle = -1;
1652 }
1653#ifdef AMLOGIC_TWO_CH_UVC
1654 if(mCamEncodeHandle > 0){
1655 close(mCamEncodeHandle);
1656 mCamEncodeHandle = -1;
1657 }
1658#endif
1659
1660#ifdef ION_MODE_FOR_METADATA_MODE
1661 if (mIonClient >= 0)
1662 ion_close(mIonClient);
1663 mIonClient = -1;
1664 memset(mPhyAddr, 0, sizeof(mPhyAddr));
1665#endif
1666 if (mVideoInfo){
1667 free(mVideoInfo);
1668 mVideoInfo = NULL;
1669 }
1670
1671 LOG_FUNCTION_NAME_EXIT;
1672}
1673
1674/* Preview Thread */
1675// ---------------------------------------------------------------------------
1676
1677int V4LCameraAdapter::previewThread()
1678{
1679 status_t ret = NO_ERROR;
1680 int width, height;
1681 CameraFrame frame;
1682 unsigned delay;
1683 int previewframeduration = 0;
1684 int active_duration = 0;
1685 uint8_t* ptr = NULL;
1686 bool noFrame = true;
1687 unsigned int canvas_id = 0;
1688 if (mPreviewing){
1689
1690 int index = -1;
1691
1692 previewframeduration = mExpectedFrameInv;
1693 if(mLimitedFrameRate!=0){
1694 if(mExpectedFrameInv < (unsigned)(1000000.0f / float(mLimitedFrameRate))){
1695 previewframeduration = (unsigned)(1000000.0f / float(mLimitedFrameRate));
1696 }
1697 mFramerate = mLimitedFrameRate;
1698 }
1699#ifdef AMLOGIC_CAMERA_NONBLOCK_SUPPORT
1700 delay = 5000;//previewframeduration>>2;
1701#else
1702 delay = previewframeduration;
1703#endif
1704 if((mPreviewWidth <= 0)||(mPreviewHeight <= 0)){
1705 mParams.getPreviewSize(&width, &height);
1706 }else{
1707 width = mPreviewWidth;
1708 height = mPreviewHeight;
1709 }
1710 if(mSensorFormat != V4L2_PIX_FMT_MJPEG || mFailedCnt > 0 || mEagainCnt > 0 || (width < 640 && height < 480))
1711 usleep(delay);
1712
1713 char *fp = this->GetFrame(index, &canvas_id);
1714
1715 if((-1==index)||!fp){
1716 noFrame = true;
1717 }else{
1718 noFrame = false;
1719#ifdef AMLOGIC_USB_CAMERA_SUPPORT
1720 if(mSensorFormat != V4L2_PIX_FMT_MJPEG){
1721 if(mVideoInfo->buf.length != mVideoInfo->buf.bytesused){
1722 fillThisBuffer((uint8_t*) mPreviewBufs.keyAt(mPreviewIdxs.valueFor(index)), CameraFrame::PREVIEW_FRAME_SYNC);
1723 CAMHAL_LOGDB("length=%d bytesused=%d index=%d\n", mVideoInfo->buf.length, mVideoInfo->buf.bytesused, index);
1724 noFrame = true;
1725 index = -1;
1726 }
1727 }
1728#endif
1729 }
1730
1731 if(noFrame == true){
1732 index = -1;
1733 fp = NULL;
1734#ifdef AMLOGIC_CAMERA_NONBLOCK_SUPPORT
1735 if(mFirstBuff == true) // need wait for first frame
1736 return 0;
1737#else
1738 delay = previewframeduration >> 1;
1739 CAMHAL_LOGEB("Preview thread get frame fail, need sleep:%d",delay);
1740 usleep(delay);
1741 return BAD_VALUE;
1742#endif
1743 }else{
1744 ptr = (uint8_t*) mPreviewBufs.keyAt(mPreviewIdxs.valueFor(index));
1745 if (!ptr){
1746 CAMHAL_LOGEA("Preview thread mPreviewBufs error!");
1747 return BAD_VALUE;
1748 }
1749 }
1750
1751#ifdef AMLOGIC_CAMERA_NONBLOCK_SUPPORT
1752 if(mFirstBuff == true){
1753 mFrameInvAdjust = 0;
1754 mFrameInv = 0;
1755 mFirstBuff = false;
1756 mCache.index = -1;
1757 mCache.bufPtr == NULL;
1758 mCache.canvas = 0;
1759 ptr = (uint8_t*) mPreviewBufs.keyAt(mPreviewIdxs.valueFor(index));
1760 gettimeofday(&previewTime1, NULL);
1761 CAMHAL_LOGDA("Get first preview buff");
1762 }else{
1763 gettimeofday( &previewTime2, NULL);
1764 int bwFrames_tmp = previewTime2.tv_sec - previewTime1.tv_sec;
1765 bwFrames_tmp = bwFrames_tmp*1000000 + previewTime2.tv_usec -previewTime1.tv_usec;
1766 mFrameInv += bwFrames_tmp;
1767 memcpy( &previewTime1, &previewTime2, sizeof( struct timeval));
1768
1769 active_duration = mFrameInv - mFrameInvAdjust;
1770 if((mFrameInv + 20000 > (int)mExpectedFrameInv) //kTestSlopMargin = 20ms from CameraGLTest
1771 &&((active_duration>previewframeduration)||((active_duration + 5000)>previewframeduration))){ // more preview duration -5000 us
1772 if(noFrame == false){ //current catch a picture,use it and release tmp buf;
1773 if( mCache.index != -1){
1774 fillThisBuffer((uint8_t*) mPreviewBufs.keyAt(mPreviewIdxs.valueFor(mCache.index)), CameraFrame::PREVIEW_FRAME_SYNC);
1775 }
1776 mCache.index = -1;
1777 mCache.canvas = 0;
1778 }else if(mCache.index != -1){ //current catch no picture,but have a tmp buf;
1779 fp = mCache.bufPtr;
1780 ptr = (uint8_t*) mPreviewBufs.keyAt(mPreviewIdxs.valueFor(mCache.index));
1781 index = mCache.index;
1782 canvas_id = mCache.canvas;
1783 mCache.index = -1;
1784 mCache.canvas = 0;
1785 }else{
1786 return 0;
1787 }
1788 } else{ // during this period,should not show any picture,so we cache the current picture,and release the old one firstly;
1789 if(noFrame == false){
1790 mCache.bufPtr = fp;
1791 if(mCache.index != -1){
1792 fillThisBuffer((uint8_t*) mPreviewBufs.keyAt(mPreviewIdxs.valueFor(mCache.index)), CameraFrame::PREVIEW_FRAME_SYNC);
1793 }
1794 mCache.index = index;
1795 mCache.canvas = canvas_id;
1796 }
1797 return 0;
1798 }
1799 }
1800
1801 while(active_duration>=(int) previewframeduration){ // skip one or more than one frame
1802 active_duration -= previewframeduration;
1803 }
1804
1805 if((active_duration+10000)>previewframeduration)
1806 mFrameInvAdjust = previewframeduration - active_duration;
1807 else
1808 mFrameInvAdjust = -active_duration;
1809 mFrameInv = 0;
1810#endif
1811
1812 frame.mTimestamp = systemTime(SYSTEM_TIME_MONOTONIC);
1813 uint8_t* dest = NULL;
1814#ifdef AMLOGIC_CAMERA_OVERLAY_SUPPORT
1815 camera_memory_t* VideoCameraBufferMemoryBase = (camera_memory_t*)ptr;
1816 dest = (uint8_t*)VideoCameraBufferMemoryBase->data; //ptr;
1817#else
1818 private_handle_t* gralloc_hnd = (private_handle_t*)ptr;
1819 dest = (uint8_t*)gralloc_hnd->base; //ptr;
1820#endif
1821 uint8_t* src = (uint8_t*) fp;
1822
1823#ifdef AMLOGIC_USB_CAMERA_SUPPORT
1824 if(mFailedCnt == 0)
1825 gettimeofday(&mStartTime, NULL);
1826#endif
1827 if(mSensorFormat == V4L2_PIX_FMT_MJPEG){ //enable mjpeg
1828 if(jpeg_decode(&dest,src,width,height, ( CameraFrame::PIXEL_FMT_NV21 == mPixelFormat)?V4L2_PIX_FMT_NV21:V4L2_PIX_FMT_YVU420) != 0){ // output format is nv21
1829 fillThisBuffer((uint8_t*) mPreviewBufs.keyAt(mPreviewIdxs.valueFor(index)), CameraFrame::PREVIEW_FRAME_SYNC);
1830 CAMHAL_LOGEB("jpeg decode failed,src:%02x %02x %02x %02x",src[0], src[1], src[2], src[3]);
1831#ifdef AMLOGIC_USB_CAMERA_SUPPORT
1832 mFailedCnt++;
1833 gettimeofday(&mEndTime, NULL);
1834 int intreval = (mEndTime.tv_sec - mStartTime.tv_sec) * 1000000 + (mEndTime.tv_usec - mStartTime.tv_usec);
1835 if(intreval > (int)mResetTH){
1836 CAMHAL_LOGIA("MJPEG Stream error ! Restart Preview");
1837 force_reset_sensor();
1838 mFailedCnt = 0;
1839 mFirstBuff = true;
1840 }
1841#endif
1842 return -1;
1843 }
1844 mFailedCnt = 0;
1845 frame.mLength = width*height*3/2;
1846 }else{
1847 if(DEFAULT_PREVIEW_PIXEL_FORMAT == V4L2_PIX_FMT_YUYV){ // 422I
1848 frame.mLength = width*height*2;
1849 memcpy(dest,src,frame.mLength);
1850 }else if(DEFAULT_PREVIEW_PIXEL_FORMAT == V4L2_PIX_FMT_NV21){ //420sp
1851 frame.mLength = width*height*3/2;
1852#ifdef AMLOGIC_USB_CAMERA_SUPPORT
1853 if ( CameraFrame::PIXEL_FMT_NV21 == mPixelFormat){
1854 //convert yuyv to nv21
1855 yuyv422_to_nv21(src,dest,width,height);
1856 }else{
1857 yuyv_to_yv12( src, dest, width, height);
1858 }
1859#else
1860 if (DEV_ION != m_eDeviceType) {
1861 if ( CameraFrame::PIXEL_FMT_NV21 == mPixelFormat){
1862 if (frame.mLength == mVideoInfo->buf.length) {
1863 memcpy(dest,src,frame.mLength);
1864 }else if((mVideoInfo->canvas_mode == true)&&(width == 1920)&&(height == 1080)){
1865 nv21_memcpy_canvas1080 (dest, src, width, height);
1866 }else{
1867 nv21_memcpy_align32 (dest, src, width, height);
1868 }
1869 }else{
1870 if (frame.mLength == mVideoInfo->buf.length) {
1871 yv12_adjust_memcpy(dest,src,width,height);
1872 }else if((mVideoInfo->canvas_mode == true)&&(width == 1920)&&(height == 1080)){
1873 yv12_memcpy_canvas1080 (dest, src, width, height);
1874 }else{
1875 yv12_memcpy_align32 (dest, src, width, height);
1876 }
1877 }
1878 } else {
1879
1880 if ( CameraFrame::PIXEL_FMT_NV21 == mPixelFormat){
1881 //if (frame.mLength != mVideoInfo->buf.length) {
1882 if (width%32) {
1883 CAMHAL_LOGDB("frame.mLength =%d, mVideoInfo->buf.length=%d\n",
1884 frame.mLength, mVideoInfo->buf.length);
1885 nv21_memcpy_align32 (dest, src, width, height);
1886 }
1887 }else{
1888 //if (frame.mLength != mVideoInfo->buf.length) {
1889 if (width%64) {
1890 CAMHAL_LOGDB("frame.mLength =%d, mVideoInfo->buf.length=%d\n",
1891 frame.mLength, mVideoInfo->buf.length);
1892 yv12_memcpy_align32 (dest, src, width, height);
1893 }
1894 }
1895 }
1896#endif
1897 }else{ //default case
1898 frame.mLength = width*height*3/2;
1899 memcpy(dest,src,frame.mLength);
1900 }
1901 }
1902
1903#ifdef AMLOGIC_USB_CAMERA_SUPPORT
1904 char property[PROPERTY_VALUE_MAX];
1905 int enable = 0;
1906 memset(property,0,sizeof(property));
1907 if(property_get("camera.preview.EnableDump", property, NULL) > 0){
1908 enable = atoi(property);
1909 }
1910 mEnableDump = enable > 0 ? true : false;
1911 CAMHAL_LOGDB("mEnableDump:%d",mEnableDump);
1912 if(mEnableDump){
1913 char filename[50];
1914 memset(filename, 0 , 50);
1915 sprintf(filename,"%s%d%s",DUMP_FILE,mDumpCnt,".yuv");
1916 FILE *fdump;
1917 if((fdump = fopen(filename,"w")) != NULL){
1918 fwrite(dest, frame.mLength, 1, fdump);
1919 CAMHAL_LOGDB("previewthread dump frame:%d,length:%d",mDumpCnt,frame.mLength);
1920 fclose(fdump);
1921 }else
1922 CAMHAL_LOGDB("open failed :%s",strerror(errno));
1923 mDumpCnt++;
1924 }
1925#endif
1926 frame.mFrameMask |= CameraFrame::PREVIEW_FRAME_SYNC;
1927
1928 if(mRecording){
1929 frame.mFrameMask |= CameraFrame::VIDEO_FRAME_SYNC;
1930 }
1931 frame.mBuffer = ptr; //dest
1932 frame.mAlignment = width;
1933 frame.mOffset = 0;
1934 frame.mYuv[0] = 0;
1935 frame.mYuv[1] = 0;
1936#ifdef ION_MODE_FOR_METADATA_MODE
1937 if (ion_mode) {
1938 int iret;
1939 struct meson_phys_data phy_data = {
1940 .handle = ((private_handle_t *)ptr)->share_fd,
1941 .phys_addr = 0,
1942 .size = 0,
1943 };
1944 struct ion_custom_data custom_data = {
1945 .cmd = ION_IOC_MESON_PHYS_ADDR,
1946 .arg = (unsigned long)&phy_data,
1947 };
1948 if (mPhyAddr[index] == 0) {
1949 iret = ioctl(mIonClient, ION_IOC_CUSTOM, (unsigned long)&custom_data);
1950 if (iret < 0) {
1951 CAMHAL_LOGEB("ion custom ioctl %x failed with code %d: %s\n",
1952 ION_IOC_MESON_PHYS_ADDR,
1953 iret, strerror(errno));
1954 frame.metadataBufferType = kMetadataBufferTypeGrallocSource;
1955 frame.mCanvas = 0;
1956 } else {
1957 frame.mCanvas = phy_data.phys_addr;
1958 mPhyAddr[index] = phy_data.phys_addr;
1959 frame.metadataBufferType = kMetadataBufferTypeGrallocSource;
1960 }
1961 } else {
1962 frame.mCanvas = mPhyAddr[index];
1963 frame.metadataBufferType = kMetadataBufferTypeGrallocSource;
1964 }
1965 } else {
1966 frame.mCanvas = canvas_id;
1967 frame.metadataBufferType = (canvas_id != 0) ? kMetadataBufferTypeCanvasSource : kMetadataBufferTypeGrallocSource;
1968 }
1969#else
1970 frame.mCanvas = canvas_id;
1971 frame.metadataBufferType = kMetadataBufferTypeGrallocSource;
1972#endif
1973 if (canvas_id != 0) {
1974 frame.mCanvas = canvas_id;
1975 frame.metadataBufferType = kMetadataBufferTypeCanvasSource;
1976 }
1977 frame.mWidth = width;
1978 frame.mHeight = height;
1979 frame.mPixelFmt = mPixelFormat;
1980 frame.mColorFormat = ((private_handle_t *)ptr)->format;
1981 ret = setInitFrameRefCount(frame.mBuffer, frame.mFrameMask);
1982 if (ret){
1983 CAMHAL_LOGEB("setInitFrameRefCount err=%d", ret);
1984 }else{
1985 ret = sendFrameToSubscribers(&frame);
1986 }
1987 }
1988 if( (mIoctlSupport & IOCTL_MASK_FOCUS_MOVE) && mFocusMoveEnabled ){
1989 getFocusMoveStatus();
1990 }
1991 return ret;
1992}
1993
1994/* Image Capture Thread */
1995// ---------------------------------------------------------------------------
1996int V4LCameraAdapter::GenExif(ExifElementsTable* exiftable)
1997{
1998 char exifcontent[256];
1999
2000 //Make
2001 exiftable->insertElement("Make",(const char*)mParams.get(ExCameraParameters::KEY_EXIF_MAKE));
2002
2003 //Model
2004 exiftable->insertElement("Model",(const char*)mParams.get(ExCameraParameters::KEY_EXIF_MODEL));
2005
2006 //Image orientation
2007 int orientation = mParams.getInt(CameraParameters::KEY_ROTATION);
2008 //covert 0 90 180 270 to 0 1 2 3
2009 CAMHAL_LOGDB("get orientaion %d",orientation);
2010 if(orientation == 0)
2011 orientation = 1;
2012 else if(orientation == 90)
2013 orientation = 6;
2014 else if(orientation == 180)
2015 orientation = 3;
2016 else if(orientation == 270)
2017 orientation = 8;
2018
2019 //Image width,height
2020 int width,height;
2021 if((mCaptureWidth <= 0)||(mCaptureHeight <= 0)){
2022 mParams.getPictureSize(&width, &height);
2023 }else{
2024 width = mCaptureWidth;
2025 height = mCaptureHeight;
2026 }
2027
2028#ifndef AMLOGIC_USB_CAMERA_SUPPORT
2029 if(mIoctlSupport & IOCTL_MASK_ROTATE){
2030 orientation = 1;
2031 if((mRotateValue==90)||(mRotateValue==270)){
2032 int temp = width;
2033 width = height;
2034 height = temp;
2035 }
2036 }
2037#endif
2038
2039 sprintf(exifcontent,"%d",orientation);
2040 //LOGD("exifcontent %s",exifcontent);
2041 exiftable->insertElement("Orientation",(const char*)exifcontent);
2042
2043 sprintf(exifcontent,"%d",width);
2044 exiftable->insertElement("ImageWidth",(const char*)exifcontent);
2045 sprintf(exifcontent,"%d",height);
2046 exiftable->insertElement("ImageLength",(const char*)exifcontent);
2047
2048 //focal length RATIONAL
2049 float focallen = mParams.getFloat(CameraParameters::KEY_FOCAL_LENGTH);
2050 if(focallen >= 0){
2051 int focalNum = focallen*1000;
2052 int focalDen = 1000;
2053 sprintf(exifcontent,"%d/%d",focalNum,focalDen);
2054 exiftable->insertElement("FocalLength",(const char*)exifcontent);
2055 }
2056
2057 //datetime of photo
2058 time_t times;
2059 {
2060 time(&times);
2061 struct tm tmstruct;
2062 tmstruct = *(localtime(&times)); //convert to local time
2063
2064 //date&time
2065 strftime(exifcontent, 30, "%Y:%m:%d %H:%M:%S", &tmstruct);
2066 exiftable->insertElement("DateTime",(const char*)exifcontent);
2067 }
2068
2069 //gps date stamp & time stamp
2070 times = mParams.getInt(CameraParameters::KEY_GPS_TIMESTAMP);
2071 if(times != -1){
2072 struct tm tmstruct;
2073 tmstruct = *(gmtime(&times));//convert to standard time
2074 //date
2075 strftime(exifcontent, 20, "%Y:%m:%d", &tmstruct);
2076 exiftable->insertElement("GPSDateStamp",(const char*)exifcontent);
2077 //time
2078 sprintf(exifcontent,"%d/%d,%d/%d,%d/%d",tmstruct.tm_hour,1,tmstruct.tm_min,1,tmstruct.tm_sec,1);
2079 exiftable->insertElement("GPSTimeStamp",(const char*)exifcontent);
2080 }
2081
2082 //gps latitude info
2083 char* latitudestr = (char*)mParams.get(CameraParameters::KEY_GPS_LATITUDE);
2084 if(latitudestr!=NULL){
2085 int offset = 0;
2086 float latitude = mParams.getFloat(CameraParameters::KEY_GPS_LATITUDE);
2087 if(latitude < 0.0){
2088 offset = 1;
2089 latitude*= (float)(-1);
2090 }
2091
2092 int latitudedegree = latitude;
2093 float latitudeminuts = (latitude-(float)latitudedegree)*60;
2094 int latitudeminuts_int = latitudeminuts;
2095 float latituseconds = (latitudeminuts-(float)latitudeminuts_int)*60+0.5;
2096 int latituseconds_int = latituseconds;
2097 sprintf(exifcontent,"%d/%d,%d/%d,%d/%d",latitudedegree,1,latitudeminuts_int,1,latituseconds_int,1);
2098 exiftable->insertElement("GPSLatitude",(const char*)exifcontent);
2099 exiftable->insertElement("GPSLatitudeRef",(offset==1)?"S":"N");
2100 }
2101
2102 //gps Longitude info
2103 char* longitudestr = (char*)mParams.get(CameraParameters::KEY_GPS_LONGITUDE);
2104 if(longitudestr!=NULL){
2105 int offset = 0;
2106 float longitude = mParams.getFloat(CameraParameters::KEY_GPS_LONGITUDE);
2107 if(longitude < 0.0){
2108 offset = 1;
2109 longitude*= (float)(-1);
2110 }
2111
2112 int longitudedegree = longitude;
2113 float longitudeminuts = (longitude-(float)longitudedegree)*60;
2114 int longitudeminuts_int = longitudeminuts;
2115 float longitudeseconds = (longitudeminuts-(float)longitudeminuts_int)*60+0.5;
2116 int longitudeseconds_int = longitudeseconds;
2117 sprintf(exifcontent,"%d/%d,%d/%d,%d/%d",longitudedegree,1,longitudeminuts_int,1,longitudeseconds_int,1);
2118 exiftable->insertElement("GPSLongitude",(const char*)exifcontent);
2119 exiftable->insertElement("GPSLongitudeRef",(offset==1)?"S":"N");
2120 }
2121
2122 //gps Altitude info
2123 char* altitudestr = (char*)mParams.get(CameraParameters::KEY_GPS_ALTITUDE);
2124 if(altitudestr!=NULL){
2125 int offset = 0;
2126 float altitude = mParams.getFloat(CameraParameters::KEY_GPS_ALTITUDE);
2127 if(altitude < 0.0){
2128 offset = 1;
2129 altitude*= (float)(-1);
2130 }
2131
2132 int altitudenum = altitude*1000;
2133 int altitudedec= 1000;
2134 sprintf(exifcontent,"%d/%d",altitudenum,altitudedec);
2135 exiftable->insertElement("GPSAltitude",(const char*)exifcontent);
2136 sprintf(exifcontent,"%d",offset);
2137 exiftable->insertElement("GPSAltitudeRef",(const char*)exifcontent);
2138 }
2139
2140 //gps processing method
2141 char* processmethod = (char*)mParams.get(CameraParameters::KEY_GPS_PROCESSING_METHOD);
2142 if(processmethod!=NULL){
2143 memset(exifcontent,0,sizeof(exifcontent));
2144 char ExifAsciiPrefix[] = { 0x41, 0x53, 0x43, 0x49, 0x49, 0x0, 0x0, 0x0 };//asicii
2145 memcpy(exifcontent,ExifAsciiPrefix,8);
2146 memcpy(exifcontent+8,processmethod,strlen(processmethod));
2147 exiftable->insertElement("GPSProcessingMethod",(const char*)exifcontent);
2148 }
2149 return 1;
2150}
2151
2152/*static*/ int V4LCameraAdapter::beginPictureThread(void *cookie)
2153{
2154 V4LCameraAdapter *c = (V4LCameraAdapter *)cookie;
2155 return c->pictureThread();
2156}
2157
2158int V4LCameraAdapter::pictureThread()
2159{
2160 status_t ret = NO_ERROR;
2161 int width, height;
2162 CameraFrame frame;
2163 int dqTryNum = 3;
2164
2165#ifndef AMLOGIC_USB_CAMERA_SUPPORT
2166 setMirrorEffect();
2167#endif
2168
2169 if( (mIoctlSupport & IOCTL_MASK_FLASH)&&(FLASHLIGHT_ON == mFlashMode)){
2170 set_flash_mode( mCameraHandle, "on");
2171 }
2172 //if (true){
2173 mVideoInfo->buf.index = 0;
2174 mVideoInfo->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2175 mVideoInfo->buf.memory = m_eV4l2Memory;
2176 if (V4L2_MEMORY_DMABUF == m_eV4l2Memory) {
2177 mVideoInfo->buf.m.fd = mImageFd;
2178 }
2179
2180#ifdef AMLOGIC_USB_CAMERA_SUPPORT
2181 if(mIsDequeuedEIOError){
2182 CAMHAL_LOGEA("DQBUF EIO has occured!\n");
2183 return -EINVAL;
2184 }
2185#endif
2186 ret = ioctl(mCameraHandle, VIDIOC_QBUF, &mVideoInfo->buf);
2187 if (ret < 0){
2188 CAMHAL_LOGDB("VIDIOC_QBUF Failed, errno=%s\n", strerror(errno));
2189 return -EINVAL;
2190 }
2191 nQueued ++;
2192
2193#ifndef AMLOGIC_USB_CAMERA_SUPPORT
2194 if(mIoctlSupport & IOCTL_MASK_ROTATE){
2195 if(mCaptureOriation!=0){
2196 set_rotate_value(mCameraHandle,mCaptureOriation);
2197 mCaptureOriation=0;
2198 }else{
2199 set_rotate_value(mCameraHandle,mRotateValue);
2200 }
2201 }
2202#endif
2203
2204 enum v4l2_buf_type bufType;
2205 if (!mVideoInfo->isStreaming){
2206 bufType = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2207 ret = ioctl (mCameraHandle, VIDIOC_STREAMON, &bufType);
2208 if (ret < 0) {
2209 CAMHAL_LOGEB("StartStreaming: Unable to start capture: %s", strerror(errno));
2210 return ret;
2211 }
2212 mVideoInfo->isStreaming = true;
2213 }
2214
2215 int index = 0;
2216 unsigned int canvas_id = 0;
2217 char *fp = this->GetFrame(index,&canvas_id);
2218#ifdef AMLOGIC_USB_CAMERA_SUPPORT
2219 while( (mSensorFormat == V4L2_PIX_FMT_YUYV) &&
2220 (mVideoInfo->buf.length != mVideoInfo->buf.bytesused) && (dqTryNum>0)) {
2221 if(NULL != fp){
2222 mVideoInfo->buf.index = 0;
2223 mVideoInfo->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2224 mVideoInfo->buf.memory = m_eV4l2Memory;
2225
2226 if(mIsDequeuedEIOError){
2227 CAMHAL_LOGEA("DQBUF EIO has occured!\n");
2228 break;
2229 }
2230
2231 ret = ioctl(mCameraHandle, VIDIOC_QBUF, &mVideoInfo->buf);
2232 if (ret < 0){
2233 CAMHAL_LOGEB("VIDIOC_QBUF Failed errno=%d\n", errno);
2234 break;
2235 }
2236 nQueued ++;
2237 dqTryNum --;
2238 }
2239
2240#ifdef AMLOGIC_CAMERA_NONBLOCK_SUPPORT
2241 usleep( 10000 );
2242#endif
2243 fp = this->GetFrame(index,&canvas_id);
2244 }
2245#endif
2246
2247#ifdef AMLOGIC_CAMERA_NONBLOCK_SUPPORT
2248 while(!fp && (-1 == index)){
2249 usleep( 10000 );
2250 fp = this->GetFrame(index,&canvas_id);
2251 }
2252#else
2253 if(!fp){
2254 CAMHAL_LOGDA("GetFrame fail, this may stop preview\n");
2255 return 0; //BAD_VALUE;
2256 }
2257#endif
2258 if (!mCaptureBuf || !mCaptureBuf->data){
2259 return 0; //BAD_VALUE;
2260 }
2261
2262 uint8_t* dest = (uint8_t*)mCaptureBuf->data;
2263 uint8_t* src = (uint8_t*) fp;
2264 if((mCaptureWidth <= 0)||(mCaptureHeight <= 0)){
2265 mParams.getPictureSize(&width, &height);
2266 }else{
2267 width = mCaptureWidth;
2268 height = mCaptureHeight;
2269 }
2270
2271#ifndef AMLOGIC_USB_CAMERA_SUPPORT
2272 if((mRotateValue==90)||(mRotateValue==270)){
2273 int temp = 0;
2274 temp = width;
2275 width = height;
2276 height = temp;
2277 }
2278#endif
2279
2280 CAMHAL_LOGDB("mCaptureBuf=%p,dest=%p,fp=%p,index=%d\n"
2281 "w=%d h=%d,len=%d,bytesused=%d\n",
2282 mCaptureBuf, dest, fp,index, width, height,
2283 mVideoInfo->buf.length, mVideoInfo->buf.bytesused);
2284
2285 if(mSensorFormat == V4L2_PIX_FMT_MJPEG){
2286 if(jpeg_decode(&dest,src,width,height,V4L2_PIX_FMT_NV21) != 0){ // output format is nv21
2287 //fillThisBuffer(mCaptureBuf, CameraFrame::IMAGE_FRAME);
2288 CAMHAL_LOGEA("jpeg decode failed");
2289 }
2290 frame.mLength = width*height*3/2;
2291 frame.mQuirks = CameraFrame::ENCODE_RAW_YUV420SP_TO_JPEG | CameraFrame::HAS_EXIF_DATA;
2292
2293 }else if(DEFAULT_IMAGE_CAPTURE_PIXEL_FORMAT == V4L2_PIX_FMT_RGB24){ // rgb24
2294 frame.mLength = width*height*3;
2295 frame.mQuirks = CameraFrame::ENCODE_RAW_RGB24_TO_JPEG | CameraFrame::HAS_EXIF_DATA;
2296#ifdef AMLOGIC_USB_CAMERA_SUPPORT
2297 //convert yuyv to rgb24
2298 yuyv422_to_rgb24(src,dest,width,height);
2299#else
2300 DBG_LOGB("frame.mLength =%d, mVideoInfo->buf.length=%d\n",frame.mLength, mVideoInfo->buf.length);
2301 if (frame.mLength == mVideoInfo->buf.length) {
2302 memcpy (dest, src, frame.mLength);
2303 }else{
2304 rgb24_memcpy( dest, src, width, height);
2305 CAMHAL_LOGVB("w*h*3=%d, mLength=%d\n", width*height*3, mVideoInfo->buf.length);
2306 }
2307#endif
2308 }else if(DEFAULT_IMAGE_CAPTURE_PIXEL_FORMAT == V4L2_PIX_FMT_YUYV){ // 422I
2309 frame.mLength = width*height*2;
2310 frame.mQuirks = CameraFrame::ENCODE_RAW_YUV422I_TO_JPEG | CameraFrame::HAS_EXIF_DATA;
2311 memcpy(dest, src, mVideoInfo->buf.length);
2312 }else if(DEFAULT_IMAGE_CAPTURE_PIXEL_FORMAT == V4L2_PIX_FMT_NV21){ // 420sp
2313 frame.mLength = width*height*3/2;
2314 frame.mQuirks = CameraFrame::ENCODE_RAW_YUV420SP_TO_JPEG | CameraFrame::HAS_EXIF_DATA;
2315#ifdef AMLOGIC_USB_CAMERA_SUPPORT
2316 //convert yuyv to nv21
2317 yuyv422_to_nv21(src,dest,width,height);
2318#else
2319 memcpy(dest,src,mVideoInfo->buf.length);
2320#endif
2321 }else{ //default case
2322 frame.mLength = width*height*3;
2323 frame.mQuirks = CameraFrame::ENCODE_RAW_RGB24_TO_JPEG | CameraFrame::HAS_EXIF_DATA;
2324 memcpy(dest, src, mVideoInfo->buf.length);
2325 }
2326
2327 notifyShutterSubscribers();
2328 //TODO correct time to call this?
2329 if (NULL != mEndImageCaptureCallback)
2330 mEndImageCaptureCallback(mEndCaptureData);
2331
2332 //gen exif message
2333 ExifElementsTable* exiftable = new ExifElementsTable();
2334 GenExif(exiftable);
2335
2336 frame.mFrameMask = CameraFrame::IMAGE_FRAME;
2337 frame.mFrameType = CameraFrame::IMAGE_FRAME;
2338 frame.mBuffer = mCaptureBuf->data;
2339 frame.mCookie2 = (void*)exiftable;
2340 frame.mAlignment = width;
2341 frame.mOffset = 0;
2342 frame.mYuv[0] = 0;
2343 frame.mYuv[1] = 0;
2344 frame.mCanvas = canvas_id;
2345 frame.mWidth = width;
2346 frame.mHeight = height;
2347 frame.mTimestamp = systemTime(SYSTEM_TIME_MONOTONIC);
2348
2349 if (mVideoInfo->isStreaming){
2350 bufType = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2351 ret = ioctl (mCameraHandle, VIDIOC_STREAMOFF, &bufType);
2352 if (ret < 0){
2353 CAMHAL_LOGEB("StopStreaming: Unable to stop capture: %s", strerror(errno));
2354 return ret;
2355 }
2356 mVideoInfo->isStreaming = false;
2357 }
2358
2359 mVideoInfo->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2360 mVideoInfo->buf.memory = m_eV4l2Memory;
2361
2362 nQueued = 0;
2363 nDequeued = 0;
2364
2365 /* Unmap buffers */
2366 if (munmap(mVideoInfo->mem[0], mVideoInfo->buf.length) < 0){
2367 CAMHAL_LOGEA("Unmap failed");
2368 }
2369 mVideoInfo->canvas[0] = 0;
2370
2371 if ((DEV_USB == m_eDeviceType) ||
2372 (DEV_ION == m_eDeviceType) ||
2373 (DEV_ION_MPLANE == m_eDeviceType))
2374 {
2375 mVideoInfo->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2376 mVideoInfo->buf.memory = m_eV4l2Memory;
2377 mVideoInfo->rb.count = 0;
2378
2379 ret = ioctl(mCameraHandle, VIDIOC_REQBUFS, &mVideoInfo->rb);
2380 if (ret < 0) {
2381 CAMHAL_LOGEB("VIDIOC_REQBUFS failed: %s", strerror(errno));
2382 return ret;
2383 }else{
2384 CAMHAL_LOGVA("VIDIOC_REQBUFS delete buffer success\n");
2385 }
2386 }
2387
2388 if( (mIoctlSupport & IOCTL_MASK_FLASH)&&(FLASHLIGHT_ON == mFlashMode)){
2389 set_flash_mode( mCameraHandle, "off");
2390 }
2391#ifndef AMLOGIC_USB_CAMERA_SUPPORT
2392 if(mIoctlSupport & IOCTL_MASK_ROTATE){
2393 set_rotate_value(mCameraHandle,0);
2394 mRotateValue = 0;
2395 }
2396#endif
2397
2398 // start preview thread again after stopping it in UseBuffersCapture
2399 {
2400 Mutex::Autolock lock(mPreviewBufferLock);
2401 UseBuffersPreview(mPreviewBuffers, mPreviewBufferCount);
2402 }
2403 startPreview();
2404 setCrop( 0, 0); //set to zero and then go preview
2405
2406 ret = setInitFrameRefCount(frame.mBuffer, frame.mFrameMask);
2407 if (ret){
2408 CAMHAL_LOGEB("setInitFrameRefCount err=%d", ret);
2409 }else{
2410 ret = sendFrameToSubscribers(&frame);
2411 }
2412 return ret;
2413}
2414
2415status_t V4LCameraAdapter::disableMirror(bool bDisable)
2416{
2417 CAMHAL_LOGDB("disableMirror %d\n",bDisable);
2418 mbDisableMirror = bDisable;
2419 setMirrorEffect();
2420 return NO_ERROR;
2421}
2422
2423status_t V4LCameraAdapter::setMirrorEffect() {
2424#ifndef AMLOGIC_USB_CAMERA_SUPPORT
2425 bool bEnable = mbFrontCamera&&(!mbDisableMirror);
2426 CAMHAL_LOGDB("setmirror effect %d",bEnable);
2427
2428 if(mIoctlSupport & IOCTL_MASK_HFLIP){
2429 if(set_hflip_mode(mCameraHandle,bEnable))
2430 writefile((char *)SYSFILE_CAMERA_SET_MIRROR,(char*)(bEnable?"1":"0"));
2431 }else{
2432 writefile((char *)SYSFILE_CAMERA_SET_MIRROR,(char*)(bEnable?"1":"0"));
2433 }
2434#endif
2435 return NO_ERROR;
2436}
2437
2438// ---------------------------------------------------------------------------
2439extern "C" CameraAdapter* CameraAdapter_Factory(size_t sensor_index)
2440{
2441 CameraAdapter *adapter = NULL;
2442 Mutex::Autolock lock(gAdapterLock);
2443
2444 LOG_FUNCTION_NAME;
2445
2446#ifdef AMLOGIC_VIRTUAL_CAMERA_SUPPORT
2447 if( sensor_index == (size_t)(iCamerasNum)){
2448 //MAX_CAM_NUM_ADD_VCAM-1) ){
2449 adapter = new V4LCamAdpt(sensor_index);
2450 }else{
2451#endif
2452 adapter = new V4LCameraAdapter(sensor_index);
2453#ifdef AMLOGIC_VIRTUAL_CAMERA_SUPPORT
2454 }
2455#endif
2456
2457 if ( adapter ) {
2458 CAMHAL_LOGDB("New V4L Camera adapter instance created for sensor %d", sensor_index);
2459 } else {
2460 CAMHAL_LOGEA("Camera adapter create failed!");
2461 }
2462
2463 LOG_FUNCTION_NAME_EXIT;
2464 return adapter;
2465}
2466
2467extern "C" int CameraAdapter_Capabilities(CameraProperties::Properties* properties_array,
2468 const unsigned int starting_camera,
2469 const unsigned int camera_num) {
2470 int num_cameras_supported = 0;
2471 CameraProperties::Properties* properties = NULL;
2472
2473 LOG_FUNCTION_NAME;
2474
2475 if(!properties_array)
2476 return -EINVAL;
2477
2478 while (starting_camera + num_cameras_supported < camera_num){
2479 properties = properties_array + starting_camera + num_cameras_supported;
2480 properties->set(CameraProperties::CAMERA_NAME, "Camera");
2481 extern void loadCaps(int camera_id, CameraProperties::Properties* params);
2482 loadCaps(starting_camera + num_cameras_supported, properties);
2483 num_cameras_supported++;
2484 }
2485
2486 LOG_FUNCTION_NAME_EXIT;
2487 return num_cameras_supported;
2488}
2489
2490extern "C" int CameraAdapter_CameraNum()
2491{
2492#if defined(AMLOGIC_FRONT_CAMERA_SUPPORT) || defined(AMLOGIC_BACK_CAMERA_SUPPORT)
2493 CAMHAL_LOGDB("CameraAdapter_CameraNum %d",MAX_CAMERAS_SUPPORTED);
2494#ifdef AMLOGIC_VIRTUAL_CAMERA_SUPPORT
2495 return MAX_CAM_NUM_ADD_VCAM;
2496#else
2497 return MAX_CAMERAS_SUPPORTED;
2498#endif
2499#elif defined ( AMLOGIC_VIRTUAL_CAMERA_SUPPORT)
2500 iCamerasNum = 0;
2501 for( int i = 0; i < (int)ARRAY_SIZE(SENSOR_PATH); i++ ){
2502 if( access(DEVICE_PATH(i), 0) == 0 )
2503 iCamerasNum++;
2504 }
2505
2506 CAMHAL_LOGDB("GetCameraNums %d\n", iCamerasNum+1);
2507 return iCamerasNum+1;
2508#elif defined (AMLOGIC_USB_CAMERA_SUPPORT)
2509 iCamerasNum = 0;
2510 for( int i = 0; i < (int)ARRAY_SIZE(SENSOR_PATH); i++ ){
2511 if( access(DEVICE_PATH(i), 0) == 0 ){
2512 int camera_fd;
2513 if((camera_fd = open(DEVICE_PATH(i), O_RDWR)) != -1){
2514 CAMHAL_LOGIB("try open %s\n", DEVICE_PATH(i));
2515 close(camera_fd);
2516 iCamerasNum++;
2517 }
2518 }
2519
2520 }
2521 iCamerasNum = iCamerasNum > MAX_CAMERAS_SUPPORTED?MAX_CAMERAS_SUPPORTED :iCamerasNum;
2522 return iCamerasNum;
2523#else
2524 CAMHAL_LOGDB("CameraAdapter_CameraNum %d",iCamerasNum);
2525 if(iCamerasNum == -1){
2526 iCamerasNum = 0;
2527 for(int i = 0;i < MAX_CAMERAS_SUPPORTED;i++){
2528 if( access(DEVICE_PATH(i), 0) == 0 )
2529 iCamerasNum++;
2530 }
2531 CAMHAL_LOGDB("GetCameraNums %d",iCamerasNum);
2532 }
2533 return iCamerasNum;
2534#endif
2535}
2536
2537#ifdef AMLOGIC_TWO_CH_UVC
2538extern "C" bool isPreviewDevice(int camera_fd)
2539{
2540 int ret;
2541 int index;
2542 struct v4l2_fmtdesc fmtdesc;
2543
2544 for(index=0;;index++){
2545 memset(&fmtdesc, 0, sizeof(struct v4l2_fmtdesc));
2546 fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2547 fmtdesc.index = index;
2548 ret = ioctl( camera_fd, VIDIOC_ENUM_FMT, &fmtdesc);
2549 if(V4L2_PIX_FMT_YUYV==fmtdesc.pixelformat){
2550 return true;
2551 }
2552 if(ret < 0)
2553 break;
2554 }
2555 return false;
2556}
2557
2558extern "C" status_t getVideodevId(int &camera_id, int &main_id)
2559{
2560 int tmp_id = camera_id;
2561 int tmp_fd = -1;
2562 int suc_id = -1;
2563 int camera_fd = -1;
2564 int ret = NO_ERROR;
2565 char cardname[32]="";
2566 char cardname2[32]="";
2567 struct v4l2_capability cap;
2568 bool needPreviewCh=false;
2569 while(1){
2570 if ((tmp_fd = open(DEVICE_PATH(tmp_id), O_RDWR)) != -1){
2571 if(isPreviewDevice(tmp_fd)){
2572 if(needPreviewCh){
2573 memset(&cap, 0, sizeof(struct v4l2_capability));
2574 ret = ioctl(tmp_fd,VIDIOC_QUERYCAP,&cap);
2575 if(ret < 0){
2576 CAMHAL_LOGDB("failed to query %s !\n", DEVICE_PATH(tmp_id));
2577 }
2578 strncpy(cardname2,(char *)cap.card, sizeof(cardname2));
2579 if(strcmp(cardname, cardname2)==0){
2580 close(tmp_fd);
2581 camera_id = tmp_id;
2582 return NO_ERROR;
2583 }
2584 suc_id = tmp_id;
2585 close(tmp_fd);
2586 }else{
2587 close(tmp_fd);
2588 camera_id = tmp_id;
2589 return NO_ERROR;
2590 }
2591 }else{
2592 main_id = tmp_id;
2593 needPreviewCh = true;
2594 memset(&cap, 0, sizeof(struct v4l2_capability));
2595 ret = ioctl(tmp_fd,VIDIOC_QUERYCAP,&cap);
2596 if(ret < 0){
2597 CAMHAL_LOGDB("failed to query %s !\n", DEVICE_PATH(tmp_id));
2598 }
2599 strncpy(cardname,(char *)cap.card, sizeof(cardname));
2600 CAMHAL_LOGDB("%s for main channel!\n", DEVICE_PATH(tmp_id));
2601 close(tmp_fd);
2602 }
2603 }
2604 tmp_id++;
2605 tmp_id%= ARRAY_SIZE(SENSOR_PATH);
2606 if(tmp_id ==camera_id){
2607 needPreviewCh = false;
2608 camera_id = suc_id;
2609 return NO_ERROR;
2610 }
2611 }
2612 return NO_ERROR;
2613}
2614#endif
2615int enumFrameFormats(int camera_fd, enum camera_mode_e c)
2616{
2617 int ret=0;
2618 struct v4l2_fmtdesc fmt;
2619 int i;
2620 int size = 0;
2621
2622 struct camera_fmt cam_fmt_preview[] = {
2623 {
2624 .pixelfmt = V4L2_PIX_FMT_NV21,
2625 .support = 0,
2626 },{
2627 .pixelfmt = V4L2_PIX_FMT_MJPEG,
2628 .support = 0,
2629 },{
2630 .pixelfmt = V4L2_PIX_FMT_YUYV,
2631 .support = 0,
2632 },
2633 };
2634
2635 struct camera_fmt cam_fmt_capture[] = {
2636 {
2637 .pixelfmt = V4L2_PIX_FMT_RGB24,
2638 .support = 0,
2639 },{
2640 .pixelfmt = V4L2_PIX_FMT_MJPEG,
2641 .support = 0,
2642 },{
2643 .pixelfmt = V4L2_PIX_FMT_YUYV,
2644 .support = 0,
2645 },
2646 };
2647
2648 struct camera_fmt *cam_fmt = cam_fmt_preview;
2649 size = ARRAY_SIZE(cam_fmt_preview);
2650 if (CAM_PREVIEW == c){
2651 cam_fmt = cam_fmt_preview;
2652 size = ARRAY_SIZE(cam_fmt_preview);
2653 } else if (CAM_CAPTURE == c){
2654 cam_fmt = cam_fmt_capture;
2655 size = ARRAY_SIZE(cam_fmt_capture);
2656 }if (CAM_RECORD == c){
2657 cam_fmt = cam_fmt_preview;
2658 size = ARRAY_SIZE(cam_fmt_preview);
2659 }
2660
2661 memset(&fmt, 0, sizeof(fmt));
2662 fmt.index = 0;
2663 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2664
2665 while ((ret = ioctl(camera_fd, VIDIOC_ENUM_FMT, &fmt)) == 0)
2666 {
2667 fmt.index++;
2668
2669 CAMHAL_LOGVB("{ pixelformat = '%.4s', description = '%s' }\n",
2670 (char *)&fmt.pixelformat,
2671 fmt.description);
2672 for (i = 0; i<size; i++) {
2673 if (fmt.pixelformat == cam_fmt[i].pixelfmt) {
2674 cam_fmt[i].support = 1;
2675 break;
2676 }
2677 }
2678
2679 }
2680 if (errno != EINVAL) {
2681 CAMHAL_LOGDA("VIDIOC_ENUM_FMT - Error enumerating frame formats");
2682 }
2683
2684 for (i = 0; i<size; i++) {
2685 if (1 == cam_fmt[i].support) {
2686 return cam_fmt[i].pixelfmt;
2687 }
2688 }
2689
2690 CAMHAL_LOGDA("no camera format found\n");
2691
2692 return CAM_CAPTURE==c ? V4L2_PIX_FMT_RGB24:V4L2_PIX_FMT_NV21;
2693}
2694
2695extern "C" int getValidFrameSize(int camera_fd, int pixel_format, char *framesize, bool preview)
2696{
2697 struct v4l2_frmsizeenum frmsize;
2698 int i=0;
2699 char tempsize[12];
2700 framesize[0] = '\0';
2701 unsigned int support_w,support_h;
2702 if(preview == true){
2703 char property[PROPERTY_VALUE_MAX];
2704 support_w = 10000;
2705 support_h = 10000;
2706 memset(property,0,sizeof(property));
2707 if(property_get("ro.camera.preview.MaxSize", property, NULL) > 0){
2708 CAMHAL_LOGDB("support Max Preview Size :%s",property);
2709 if(sscanf(property,"%dx%d",&support_w,&support_h)!=2){
2710 support_w = 10000;
2711 support_h = 10000;
2712 }
2713 }
2714 }
2715 if (camera_fd >= 0) {
2716 memset(&frmsize,0,sizeof(v4l2_frmsizeenum));
2717 for(i=0;;i++){
2718 frmsize.index = i;
2719 frmsize.pixel_format = pixel_format;
2720 if(ioctl(camera_fd, VIDIOC_ENUM_FRAMESIZES, &frmsize) == 0){
2721 if(frmsize.type == V4L2_FRMSIZE_TYPE_DISCRETE){ //only support this type
2722 if( preview && (frmsize.discrete.width > support_w) && (frmsize.discrete.height >support_h))
2723 continue;
2724 if( preview && (0 != (frmsize.discrete.width%16)))
2725 continue;
2726 snprintf(tempsize, sizeof(tempsize), "%dx%d,", frmsize.discrete.width, frmsize.discrete.height);
2727 DBG_LOGB("tmpsize=%s", tempsize);
2728 strcat(framesize, tempsize);
2729 }else{
2730 break;
2731 }
2732 }else{
2733 break;
2734 }
2735 }
2736 }
2737 if(framesize[0] == '\0')
2738 return -1;
2739 else
2740 return 0;
2741}
2742
2743static int getCameraOrientation(bool frontcamera, char* p)
2744{
2745 int degree = -1;
2746 char property[PROPERTY_VALUE_MAX];
2747 if(frontcamera){
2748 if (property_get("ro.camera.orientation.front", property, NULL) > 0){
2749 degree = atoi(property);
2750 }
2751 }else{
2752 if (property_get("ro.camera.orientation.back", property, NULL) > 0){
2753 degree = atoi(property);
2754 }
2755 }
2756 if((degree != 0)&&(degree != 90)
2757 &&(degree != 180)&&(degree != 270))
2758 degree = -1;
2759
2760 memcpy( p, property, sizeof(property));
2761 return degree;
2762}
2763
2764static bool is_mjpeg_supported(int camera_fd)
2765{
2766 struct v4l2_fmtdesc fmt;
2767 int ret;
2768 memset(&fmt,0,sizeof(fmt));
2769 fmt.index = 0;
2770 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2771
2772 while((ret = ioctl(camera_fd,VIDIOC_ENUM_FMT,&fmt)) == 0){
2773 if(fmt.pixelformat == V4L2_PIX_FMT_MJPEG){
2774 return true;
2775 }
2776 fmt.index++;
2777 }
2778 return false;
2779}
2780
2781static void ParserLimitedRateInfo(LimitedRate_t* rate)
2782{
2783 char property[PROPERTY_VALUE_MAX];
2784 int w,h,r;
2785 char* pos = NULL;
2786 memset(property,0,sizeof(property));
2787 rate->num = 0;
2788 if(property_get("ro.camera.preview.LimitedRate", property, NULL) > 0){
2789 pos = &property[0];
2790 while((pos != NULL)&&(rate->num<MAX_LIMITED_RATE_NUM)){
2791 if(sscanf(pos,"%dx%dx%d",&w,&h,&r)!=3){
2792 break;
2793 }
2794 rate->arg[rate->num].width = w;
2795 rate->arg[rate->num].height = h;
2796 rate->arg[rate->num].framerate = r;
2797 rate->num++;
2798 pos = strchr(pos, ',');
2799 if(pos)
2800 pos++;
2801 }
2802 }
2803}
2804
2805static int enumCtrlMenu(int camera_fd, struct v4l2_queryctrl *qi, char* menu_items, char*def_menu_item)
2806{
2807 struct v4l2_queryctrl qc;
2808 struct v4l2_querymenu qm;
2809 int ret;
2810 int mode_count = -1;
2811
2812 memset(&qc, 0, sizeof(struct v4l2_queryctrl));
2813 qc.id = qi->id;
2814 ret = ioctl (camera_fd, VIDIOC_QUERYCTRL, &qc);
2815 if( (ret<0) || (qc.flags == V4L2_CTRL_FLAG_DISABLED)){
2816 CAMHAL_LOGDB("camera handle %d can't support this ctrl",camera_fd);
2817 return mode_count;
2818 }else if( qc.type != V4L2_CTRL_TYPE_MENU){
2819 CAMHAL_LOGDB("this ctrl of camera handle %d can't support menu type",camera_fd);
2820 return 0;
2821 }else{
2822 memset(&qm, 0, sizeof(qm));
2823 qm.id = qi->id;
2824 qm.index = qc.default_value;
2825 if(ioctl (camera_fd, VIDIOC_QUERYMENU, &qm) < 0){
2826 return 0;
2827 } else {
2828 strcpy(def_menu_item, (char*)qm.name);
2829 }
2830 int index = 0;
2831 mode_count = 0;
2832
2833 for (index = qc.minimum; index <= qc.maximum; index+= qc.step) {
2834 memset(&qm, 0, sizeof(struct v4l2_querymenu));
2835 qm.id = qi->id;
2836 qm.index = index;
2837 if(ioctl (camera_fd, VIDIOC_QUERYMENU, &qm) < 0){
2838 continue;
2839 } else {
2840 if(mode_count>0)
2841 strcat(menu_items, ",");
2842 strcat( menu_items, (char*)qm.name);
2843 mode_count++;
2844 }
2845 }
2846 }
2847 return mode_count;
2848}
2849
2850static bool getCameraWhiteBalance(int camera_fd, char* wb_modes, char*def_wb_mode)
2851{
2852 struct v4l2_queryctrl qc;
2853 int item_count=0;
2854
2855 memset( &qc, 0, sizeof(qc));
2856#ifdef AMLOGIC_USB_CAMERA_SUPPORT
2857 qc.id = V4L2_CID_AUTO_WHITE_BALANCE;
2858#else
2859 qc.id = V4L2_CID_DO_WHITE_BALANCE;
2860#endif
2861 item_count = enumCtrlMenu( camera_fd, &qc, wb_modes, def_wb_mode);
2862 if(0 >= item_count){
2863 strcpy( wb_modes, "auto,daylight,incandescent,fluorescent");
2864 strcpy(def_wb_mode, "auto");
2865 }
2866 return true;
2867}
2868
2869static bool getCameraBanding(int camera_fd, char* banding_modes, char*def_banding_mode)
2870{
2871 struct v4l2_queryctrl qc;
2872 int item_count=0;
2873 char *tmpbuf=NULL;
2874
2875 memset( &qc, 0, sizeof(qc));
2876 qc.id = V4L2_CID_POWER_LINE_FREQUENCY;
2877 item_count = enumCtrlMenu( camera_fd, &qc, banding_modes, def_banding_mode);
2878
2879#ifdef AMLOGIC_USB_CAMERA_SUPPORT
2880 char *b;
2881 tmpbuf = (char *) calloc (1, 256);
2882 memset( tmpbuf, 0, 256);
2883 if( (0 < item_count)&&( NULL!= tmpbuf)){
2884 char *tmp =NULL;
2885 item_count =0;
2886 tmp = strstr( banding_modes, "auto");
2887 if(tmp){
2888 item_count ++;
2889 strcat( tmpbuf, "auto,");
2890 }
2891 tmp = strstr( banding_modes, "isable");//Disabled
2892 if(tmp){
2893 item_count ++;
2894 strcat( tmpbuf, "off,");
2895 }
2896 tmp = strstr( banding_modes, "50");
2897 if(tmp){
2898 item_count ++;
2899 strcat( tmpbuf, "50hz,");
2900 }
2901 tmp = strstr( banding_modes, "60");
2902 if(tmp){
2903 item_count ++;
2904 strcat( tmpbuf, "60hz,");
2905 }
2906
2907 b = strrchr(tmpbuf, ',');
2908 if(NULL != b){
2909 b[0] = '\0';
2910 }
2911 strcpy( banding_modes, tmpbuf);
2912 memset(tmpbuf, 0, 256);
2913 if( NULL != (tmp = strstr(def_banding_mode, "50")) ){
2914 strcat(tmpbuf, "50hz");
2915 }else if( NULL != (tmp = strstr(def_banding_mode, "60")) ){
2916 strcat(tmpbuf, "60hz");
2917 }else if( NULL != (tmp = strstr(def_banding_mode, "isable")) ){
2918 strcat(tmpbuf, "off");
2919 }else if( NULL != (tmp = strstr(def_banding_mode, "auto")) ){
2920 strcat(tmpbuf, "auto");
2921 }
2922 strcpy( def_banding_mode, tmpbuf);
2923 }
2924
2925 if(tmpbuf){
2926 free(tmpbuf);
2927 tmpbuf = NULL;
2928 }
2929#endif
2930
2931 if(0 >= item_count){
2932 strcpy( banding_modes, "50hz,60hz");
2933 strcpy( def_banding_mode, "50hz");
2934 }
2935 if (NULL == strstr(banding_modes, "auto")) {
2936 strcat( banding_modes, ",auto");
2937 }
2938
2939 return true;
2940}
2941
2942#define MAX_LEVEL_FOR_EXPOSURE 16
2943#define MIN_LEVEL_FOR_EXPOSURE 3
2944
2945static bool getCameraExposureValue(int camera_fd, int &min, int &max, int &step, int &def)
2946{
2947 struct v4l2_queryctrl qc;
2948 int ret=0;
2949 int level = 0;
2950 int middle = 0;
2951
2952 memset( &qc, 0, sizeof(qc));
2953
2954#ifdef AMLOGIC_USB_CAMERA_SUPPORT
2955 qc.id = V4L2_CID_EXPOSURE_ABSOLUTE;
2956#else
2957 qc.id = V4L2_CID_EXPOSURE;
2958#endif
2959 ret = ioctl( camera_fd, VIDIOC_QUERYCTRL, &qc);
2960 if(ret<0){
2961 CAMHAL_LOGDB("QUERYCTRL failed, errno=%d\n", errno);
2962#ifdef AMLOGIC_USB_CAMERA_SUPPORT
2963 min = 0;
2964 max = 0;
2965 def = 0;
2966 step = 0;
2967#else
2968 min = -4;
2969 max = 4;
2970 def = 0;
2971 step = 1;
2972#endif
2973 return true;
2974 }
2975
2976 if(0 < qc.step)
2977 level = ( qc.maximum - qc.minimum + 1 )/qc.step;
2978
2979 if((level > MAX_LEVEL_FOR_EXPOSURE)
2980 || (level < MIN_LEVEL_FOR_EXPOSURE)){
2981 min = -4;
2982 max = 4;
2983 def = 0;
2984 step = 1;
2985 CAMHAL_LOGDB("not in[min,max], min=%d, max=%d, def=%d, step=%d\n", min, max, def, step);
2986 return true;
2987 }
2988
2989 middle = (qc.minimum+qc.maximum)/2;
2990 min = qc.minimum - middle;
2991 max = qc.maximum - middle;
2992 def = qc.default_value - middle;
2993 step = qc.step;
2994 return true;
2995}
2996
2997static bool getCameraAutoFocus(int camera_fd, char* focus_mode_str, char*def_focus_mode)
2998{
2999 struct v4l2_queryctrl qc;
3000 struct v4l2_querymenu qm;
3001 bool auto_focus_enable = false;
3002 int menu_num = 0;
3003 int mode_count = 0;
3004
3005 memset(&qc, 0, sizeof(struct v4l2_queryctrl));
3006 qc.id = V4L2_CID_FOCUS_AUTO;
3007 menu_num = ioctl (camera_fd, VIDIOC_QUERYCTRL, &qc);
3008 if((qc.flags == V4L2_CTRL_FLAG_DISABLED) ||( menu_num < 0) || (qc.type != V4L2_CTRL_TYPE_MENU)){
3009 auto_focus_enable = false;
3010 CAMHAL_LOGDB("can't support auto focus,%sret=%d%s\n",
3011 qc.flags == V4L2_CTRL_FLAG_DISABLED?"disable,":"",
3012 menu_num,
3013 qc.type == V4L2_CTRL_TYPE_MENU? "":",type not right");
3014
3015 }else {
3016 memset(&qm, 0, sizeof(qm));
3017 qm.id = V4L2_CID_FOCUS_AUTO;
3018 qm.index = qc.default_value;
3019 strcpy(def_focus_mode, "auto");
3020
3021 for (int index = qc.minimum; index <= qc.maximum; index+= qc.step) {
3022 memset(&qm, 0, sizeof(struct v4l2_querymenu));
3023 qm.id = V4L2_CID_FOCUS_AUTO;
3024 qm.index = index;
3025 if(ioctl (camera_fd, VIDIOC_QUERYMENU, &qm) < 0){
3026 continue;
3027 } else {
3028 if(mode_count>0)
3029 strcat(focus_mode_str, ",");
3030 strcat(focus_mode_str, (char*)qm.name);
3031 mode_count++;
3032 }
3033 }
3034 if(mode_count>0)
3035 auto_focus_enable = true;
3036 }
3037 return auto_focus_enable;
3038}
3039
3040static bool getCameraFocusArea(int camera_fd, char* max_num_focus_area, char*focus_area)
3041{
3042 struct v4l2_queryctrl qc;
3043 int ret = 0;
3044 int x0 = 0;
3045 int y0 = 0;
3046 int x1 = 0;
3047 int y1 = 0;
3048
3049 memset(&qc, 0, sizeof(struct v4l2_queryctrl));
3050 qc.id = V4L2_CID_FOCUS_ABSOLUTE;
3051 ret = ioctl (camera_fd, VIDIOC_QUERYCTRL, &qc);
3052 if((qc.flags == V4L2_CTRL_FLAG_DISABLED) ||( ret < 0) || (qc.type != V4L2_CTRL_TYPE_INTEGER)){
3053 CAMHAL_LOGDB("can't support touch focus,%sret=%d%s\n",
3054 qc.flags == V4L2_CTRL_FLAG_DISABLED? "disble,":"",
3055 ret,
3056 qc.type == V4L2_CTRL_TYPE_INTEGER?"":", type not right");
3057 return false;
3058 }
3059
3060 x0 = qc.minimum & 0xFFFF;
3061 y0 = (qc.minimum >> 16) & 0xFFFF;
3062 x1 = qc.maximum & 0xFFFF;
3063 y1 = (qc.maximum >> 16) & 0xFFFF;
3064 strcpy(max_num_focus_area, "1");
3065 sprintf(focus_area, "(%d,%d,%d,%d, 1)", x0, y0, x1, y1);
3066 return true;
3067}
3068
3069struct v4l2_frmsize_discrete VIDEO_PREFER_SIZES[]={
3070 {176, 144},
3071 {320, 240},
3072 {352, 288},
3073 {640, 480},
3074 {1280,720},
3075 {1920,1080},
3076};
3077
3078#ifdef AMLOGIC_VIRTUAL_CAMERA_SUPPORT
3079extern "C" void newloadCaps(int camera_id, CameraProperties::Properties* params);
3080#endif
3081//TODO move
3082extern "C" void loadCaps(int camera_id, CameraProperties::Properties* params) {
3083 const char DEFAULT_BRIGHTNESS[] = "50";
3084 const char DEFAULT_CONTRAST[] = "100";
3085 const char DEFAULT_IPP[] = "ldc-nsf";
3086 const char DEFAULT_GBCE[] = "disable";
3087 const char DEFAULT_ISO_MODE[] = "auto";
3088 const char DEFAULT_PICTURE_FORMAT[] = "jpeg";
3089 const char DEFAULT_PICTURE_SIZE[] = "640x480";
3090 const char PREVIEW_FORMAT_420SP[] = "yuv420sp";
3091 const char PREVIEW_FORMAT_420P[] = "yuv420p";
3092 const char PREVIEW_FORMAT_422I[] = "yuv422i-yuyv";
3093 const char DEFAULT_PREVIEW_SIZE[] = "640x480";
3094 const char DEFAULT_NUM_PREV_BUFS[] = "6";
3095 const char DEFAULT_NUM_PIC_BUFS[] = "1";
3096 const char DEFAULT_MAX_FOCUS_AREAS[] = "1";
3097 const char DEFAULT_SATURATION[] = "100";
3098 const char DEFAULT_SCENE_MODE[] = "auto";
3099 const char DEFAULT_SHARPNESS[] = "100";
3100 const char DEFAULT_VSTAB[] = "false";
3101 const char DEFAULT_VSTAB_SUPPORTED[] = "true";
3102 const char DEFAULT_MAX_FD_HW_FACES[] = "0";
3103 const char DEFAULT_MAX_FD_SW_FACES[] = "0";
3104 const char DEFAULT_FOCAL_LENGTH_PRIMARY[] = "4.31";
3105 const char DEFAULT_FOCAL_LENGTH_SECONDARY[] = "1.95";
3106 const char DEFAULT_HOR_ANGLE[] = "54.8";
3107 const char DEFAULT_VER_ANGLE[] = "42.5";
3108 const char DEFAULT_AE_LOCK[] = "false";
3109 const char DEFAULT_AWB_LOCK[] = "false";
3110 const char DEFAULT_MAX_NUM_METERING_AREAS[] = "0";
3111 const char DEFAULT_LOCK_SUPPORTED[] = "true";
3112 const char DEFAULT_LOCK_UNSUPPORTED[] = "false";
3113 const char DEFAULT_VIDEO_SIZE[] = "640x480";
3114 const char DEFAULT_PREFERRED_PREVIEW_SIZE_FOR_VIDEO[] = "640x480";
3115
3116#ifdef AMLOGIC_VIRTUAL_CAMERA_SUPPORT
3117 if( camera_id == iCamerasNum){
3118 //(MAX_CAM_NUM_ADD_VCAM-1)){
3119 newloadCaps(camera_id, params);
3120 CAMHAL_LOGDA("return from newloadCaps\n");
3121 return ;
3122 }
3123#endif
3124 bool bFrontCam = false;
3125 int camera_fd = -1;
3126
3127 if (camera_id == 0) {
3128#ifdef AMLOGIC_BACK_CAMERA_SUPPORT
3129 bFrontCam = false;
3130#elif defined(AMLOGIC_FRONT_CAMERA_SUPPORT)
3131 bFrontCam = true;
3132#elif defined(AMLOGIC_USB_CAMERA_SUPPORT)
3133 bFrontCam = true;
3134#else//defined nothing, we try by ourself.we assume, the 0 is front camera, 1 is back camera
3135 bFrontCam = true;
3136#endif
3137 } else if (camera_id == 1) {
3138#if defined(AMLOGIC_BACK_CAMERA_SUPPORT) && defined(AMLOGIC_FRONT_CAMERA_SUPPORT)
3139 bFrontCam = true;
3140#else//defined nothing, we try to by ourself
3141 bFrontCam = false;
3142#endif
3143 }
3144
3145 //should changed while the screen orientation changed.
3146 int degree = -1;
3147 char property[PROPERTY_VALUE_MAX];
3148 memset(property,0,sizeof(property));
3149 if(bFrontCam == true) {
3150 params->set(CameraProperties::FACING_INDEX, ExCameraParameters::FACING_FRONT);
3151 if(getCameraOrientation(bFrontCam,property)>=0){
3152 params->set(CameraProperties::ORIENTATION_INDEX,property);
3153 }else{
3154#ifdef AMLOGIC_USB_CAMERA_SUPPORT
3155 params->set(CameraProperties::ORIENTATION_INDEX,"0");
3156#else
3157 params->set(CameraProperties::ORIENTATION_INDEX,"270");
3158#endif
3159 }
3160 } else {
3161 params->set(CameraProperties::FACING_INDEX, ExCameraParameters::FACING_BACK);
3162 if(getCameraOrientation(bFrontCam,property)>=0){
3163 params->set(CameraProperties::ORIENTATION_INDEX,property);
3164 }else{
3165#ifdef AMLOGIC_USB_CAMERA_SUPPORT
3166 params->set(CameraProperties::ORIENTATION_INDEX,"180");
3167#else
3168 params->set(CameraProperties::ORIENTATION_INDEX,"90");
3169#endif
3170 }
3171 }
3172
3173#ifdef AMLOGIC_USB_CAMERA_SUPPORT
3174 params->set(CameraProperties::RELOAD_WHEN_OPEN, "1");
3175#else
3176 params->set(CameraProperties::RELOAD_WHEN_OPEN, "0");
3177#endif
3178 params->set(CameraProperties::SUPPORTED_PREVIEW_FORMATS,"yuv420sp,yuv420p"); //yuv420p for cts
3179 if(DEFAULT_PREVIEW_PIXEL_FORMAT == V4L2_PIX_FMT_YUYV){ // 422I
3180 //params->set(CameraProperties::SUPPORTED_PREVIEW_FORMATS,PREVIEW_FORMAT_422I);
3181 params->set(CameraProperties::PREVIEW_FORMAT,PREVIEW_FORMAT_422I);
3182 }else if(DEFAULT_PREVIEW_PIXEL_FORMAT == V4L2_PIX_FMT_NV21){ //420sp
3183 //params->set(CameraProperties::SUPPORTED_PREVIEW_FORMATS,PREVIEW_FORMAT_420SP);
3184 params->set(CameraProperties::PREVIEW_FORMAT,PREVIEW_FORMAT_420SP);
3185 }else{ //default case
3186 //params->set(CameraProperties::SUPPORTED_PREVIEW_FORMATS,PREVIEW_FORMAT_420SP);
3187 params->set(CameraProperties::PREVIEW_FORMAT,PREVIEW_FORMAT_420P);
3188 }
3189
3190#ifdef AMLOGIC_USB_CAMERA_SUPPORT
3191#ifdef AMLOGIC_TWO_CH_UVC
3192 int main_id = -1;
3193 if(NO_ERROR == getVideodevId( camera_id,main_id )){
3194 if ((camera_fd = open(DEVICE_PATH(camera_id), O_RDWR)) != -1){
3195 CAMHAL_LOGDB("open %s success to loadCaps\n", DEVICE_PATH(camera_id));
3196 }
3197 }
3198#else
3199 while( camera_id < (int)ARRAY_SIZE(SENSOR_PATH)){
3200 if ((camera_fd = open(DEVICE_PATH(camera_id), O_RDWR)) != -1){
3201 CAMHAL_LOGDB("open %s success when loadCaps!\n", DEVICE_PATH(camera_id));
3202 break;
3203 }
3204 camera_id++;
3205 }
3206 if(camera_id >= (int)ARRAY_SIZE(SENSOR_PATH)){
3207 CAMHAL_LOGDB("failed to opening Camera when loadCaps: %s", strerror(errno));
3208 }
3209#endif
3210#else
3211 camera_fd = open(DEVICE_PATH(camera_id), O_RDWR);
3212#endif
3213 if(camera_fd<0){
3214 CAMHAL_LOGDB("open camera %d error when loadcaps",camera_id);
3215 }
3216
3217#ifdef AMLOGIC_CAMERA_NONBLOCK_SUPPORT
3218 int fps=0, fps_num=0;
3219 int ret;
3220 char fpsrange[64];
3221 memset(fpsrange,0,sizeof(fpsrange));
3222
3223 ret = enumFramerate(camera_fd, &fps, &fps_num);
3224 if((NO_ERROR == ret) && ( 0 !=fps )){
3225 CAMHAL_LOGDA("O_NONBLOCK operation to do previewThread\n");
3226 int tmp_fps = fps/fps_num/5;
3227 int iter = 0;
3228 int shift = 0;
3229 for(iter = 0;iter < tmp_fps;){
3230 iter++;
3231 if(iter == tmp_fps)
3232 sprintf(fpsrange+shift,"%d",iter*5);
3233 else
3234 sprintf(fpsrange+shift,"%d,",iter*5);
3235 if(iter == 1)
3236 shift += 2;
3237 else
3238 shift += 3;
3239 }
3240 if((fps/fps_num)%5 != 0)
3241 sprintf(fpsrange+shift-1,",%d",fps/fps_num);
3242 params->set(CameraProperties::SUPPORTED_PREVIEW_FRAME_RATES, fpsrange);
3243 params->set(CameraProperties::PREVIEW_FRAME_RATE, fps/fps_num);
3244
3245 memset(fpsrange, 0, sizeof(fpsrange));
3246 sprintf(fpsrange,"%s%d","5000,",fps*1000/fps_num);
3247 params->set(CameraProperties::FRAMERATE_RANGE_IMAGE, fpsrange);
3248 params->set(CameraProperties::FRAMERATE_RANGE_VIDEO, fpsrange);
3249
3250 memset(fpsrange, 0, sizeof(fpsrange));;
3251 sprintf(fpsrange,"(%s%d)","5000,15000),(5000,",fps*1000/fps_num);
3252 params->set(CameraProperties::FRAMERATE_RANGE_SUPPORTED, fpsrange);
3253 memset(fpsrange, 0, sizeof(fpsrange));
3254 sprintf(fpsrange,"%s%d","5000,",fps*1000/fps_num);
3255 params->set(CameraProperties::FRAMERATE_RANGE, fpsrange);
3256 }else{
3257 if(NO_ERROR != ret){
3258 CAMHAL_LOGDA("sensor driver need to implement enum framerate func!!!\n");
3259 }
3260 params->set(CameraProperties::SUPPORTED_PREVIEW_FRAME_RATES, "5,15");
3261 params->set(CameraProperties::PREVIEW_FRAME_RATE, "15");
3262
3263 params->set(CameraProperties::FRAMERATE_RANGE_SUPPORTED, "(5000,15000),(5000,30000)");
3264 params->set(CameraProperties::FRAMERATE_RANGE, "5000,30000");
3265 params->set(CameraProperties::FRAMERATE_RANGE_IMAGE, "5000,15000");
3266 params->set(CameraProperties::FRAMERATE_RANGE_VIDEO, "5000,15000");
3267 }
3268#else
3269 params->set(CameraProperties::SUPPORTED_PREVIEW_FRAME_RATES, "5,15");
3270 params->set(CameraProperties::PREVIEW_FRAME_RATE, "15");
3271
3272 params->set(CameraProperties::FRAMERATE_RANGE_SUPPORTED, "(5000,15000),(5000,30000)");
3273 params->set(CameraProperties::FRAMERATE_RANGE, "5000,30000");
3274 params->set(CameraProperties::FRAMERATE_RANGE_IMAGE, "5000,15000");
3275 params->set(CameraProperties::FRAMERATE_RANGE_VIDEO, "5000,15000");
3276#endif
3277 //get preview size & set
3278 char *sizes = (char *) calloc (1, 1024);
3279 char *video_sizes = (char *) calloc (1, 1024);
3280 char vsize_tmp[15];
3281 if(!sizes || !video_sizes){
3282 if(sizes){
3283 free(sizes);
3284 sizes = NULL;
3285 }
3286 if(video_sizes){
3287 free(video_sizes);
3288 video_sizes = NULL;
3289 }
3290 CAMHAL_LOGDA("Alloc string buff error!");
3291 return;
3292 }
3293
3294 memset(sizes,0,1024);
3295 uint32_t preview_format = DEFAULT_PREVIEW_PIXEL_FORMAT;
3296 int useMJPEG = 0;
3297 preview_format = enumFrameFormats(camera_fd, CAM_PREVIEW);
3298 memset(property,0,sizeof(property));
3299 if(property_get("ro.camera.preview.UseMJPEG", property, NULL) > 0){
3300 useMJPEG = atoi(property);
3301 }
3302#ifdef AMLOGIC_USB_CAMERA_SUPPORT
3303 if (0 == useMJPEG) {
3304 preview_format = V4L2_PIX_FMT_YUYV;
3305 }
3306#endif
3307
3308 if (!getValidFrameSize(camera_fd, preview_format, sizes,true)) {
3309 int len = strlen(sizes);
3310 unsigned int supported_w = 0, supported_h = 0,w = 0,h = 0;
3311 if(len>1){
3312 if(sizes[len-1] == ',')
3313 sizes[len-1] = '\0';
3314 }
3315#ifndef AMLOGIC_USB_CAMERA_SUPPORT
3316 char small_size[8] = "176x144"; //for cts
3317 if(strstr(sizes,small_size)==NULL){
3318 if((len+sizeof(small_size))<(1024-1)){
3319 strcat(sizes,",");
3320 strcat(sizes,small_size);
3321 }
3322 }
3323#endif
3324 params->set(CameraProperties::SUPPORTED_PREVIEW_SIZES, sizes);
3325
3326 char * b = (char *)sizes;
3327 int index = 0;
3328
3329 while(b != NULL){
3330 if (sscanf(b, "%dx%d", &supported_w, &supported_h) != 2){
3331 break;
3332 }
3333 for(index =0; index< (int)ARRAY_SIZE(VIDEO_PREFER_SIZES);index++){
3334 if((VIDEO_PREFER_SIZES[index].width == supported_w) && (VIDEO_PREFER_SIZES[index].height == supported_h)){
3335 sprintf(vsize_tmp,"%dx%d,", supported_w, supported_h);
3336 strncat(video_sizes, vsize_tmp, sizeof(vsize_tmp));
3337 break;
3338 }
3339 }
3340 if((supported_w*supported_h)>(w*h)){
3341 w = supported_w;
3342 h = supported_h;
3343 }
3344 b = strchr(b, ',');
3345 if(b)
3346 b++;
3347 }
3348 b = strrchr(video_sizes, ',');
3349 if(NULL != b){
3350 b[0] = '\0';
3351 }
3352 if((w>0)&&(h>0)){
3353 memset(sizes, 0, 1024);
3354 sprintf(sizes,"%dx%d",w,h);
3355 }
3356 params->set(CameraProperties::PREVIEW_SIZE, sizes);
3357 params->set(CameraProperties::SUPPORTED_VIDEO_SIZES, video_sizes);
3358 }else {
3359#ifdef AMLOGIC_USB_CAMERA_SUPPORT
3360 params->set(CameraProperties::SUPPORTED_PREVIEW_SIZES, "320x240,176x144,160x120");
3361 params->set(CameraProperties::SUPPORTED_VIDEO_SIZES, "320x240,176x144,160x120");
3362 params->set(CameraProperties::PREVIEW_SIZE,"320x240");
3363#else
3364 params->set(CameraProperties::SUPPORTED_PREVIEW_SIZES, "640x480,352x288,176x144");
3365 params->set(CameraProperties::SUPPORTED_VIDEO_SIZES, "640x480,352x288,176x144");
3366 params->set(CameraProperties::PREVIEW_SIZE,"640x480");
3367#endif
3368 }
3369
3370 params->set(CameraProperties::SUPPORTED_PICTURE_FORMATS, DEFAULT_PICTURE_FORMAT);
3371 params->set(CameraProperties::PICTURE_FORMAT,DEFAULT_PICTURE_FORMAT);
3372 params->set(CameraProperties::JPEG_QUALITY, 90);
3373
3374 //must have >2 sizes and contain "0x0"
3375 params->set(CameraProperties::SUPPORTED_THUMBNAIL_SIZES, "160x120,0x0");
3376 params->set(CameraProperties::JPEG_THUMBNAIL_SIZE, "160x120");
3377 params->set(CameraProperties::JPEG_THUMBNAIL_QUALITY, 90);
3378
3379 //get & set picture size
3380 memset(sizes,0,1024);
3381 uint32_t picture_format = DEFAULT_IMAGE_CAPTURE_PIXEL_FORMAT;
3382 picture_format = enumFrameFormats(camera_fd, CAM_CAPTURE);
3383#ifdef AMLOGIC_USB_CAMERA_SUPPORT
3384 if (0 == useMJPEG) {
3385 preview_format = V4L2_PIX_FMT_YUYV;
3386 }
3387#endif
3388 if (!getValidFrameSize(camera_fd, picture_format, sizes,false)) {
3389 int len = strlen(sizes);
3390 unsigned int supported_w = 0, supported_h = 0,w = 0,h = 0;
3391 if(len>1){
3392 if(sizes[len-1] == ',')
3393 sizes[len-1] = '\0';
3394 }
3395
3396 params->set(CameraProperties::SUPPORTED_PICTURE_SIZES, sizes);
3397
3398 char * b = (char *)sizes;
3399 while(b != NULL){
3400 if (sscanf(b, "%dx%d", &supported_w, &supported_h) != 2){
3401 break;
3402 }
3403 if((supported_w*supported_h)>(w*h)){
3404 w = supported_w;
3405 h = supported_h;
3406 }
3407 b = strchr(b, ',');
3408 if(b)
3409 b++;
3410 }
3411 if((w>0)&&(h>0)){
3412 memset(sizes, 0, 1024);
3413 sprintf(sizes,"%dx%d",w,h);
3414 }
3415 params->set(CameraProperties::PICTURE_SIZE, sizes);
3416 }else{
3417#ifdef AMLOGIC_USB_CAMERA_SUPPORT
3418 params->set(CameraProperties::SUPPORTED_PICTURE_SIZES, "320x240");
3419 params->set(CameraProperties::PICTURE_SIZE,"320x240");
3420#else
3421 params->set(CameraProperties::SUPPORTED_PICTURE_SIZES, "640x480");
3422 params->set(CameraProperties::PICTURE_SIZE,"640x480");
3423#endif
3424 }
3425 if(sizes){
3426 free(sizes);
3427 sizes = NULL;
3428 }
3429 if(video_sizes){
3430 free(video_sizes);
3431 video_sizes = NULL;
3432 }
3433
3434 char *focus_mode = (char *) calloc (1, 256);
3435 char * def_focus_mode = (char *) calloc (1, 64);
3436 if((focus_mode)&&(def_focus_mode)){
3437 memset(focus_mode,0,256);
3438 memset(def_focus_mode,0,64);
3439 if(getCameraAutoFocus(camera_fd, focus_mode,def_focus_mode)) {
3440 params->set(CameraProperties::SUPPORTED_FOCUS_MODES, focus_mode);
3441 params->set(CameraProperties::FOCUS_MODE, def_focus_mode);
3442 memset(focus_mode,0,256);
3443 memset(def_focus_mode,0,64);
3444 if (getCameraFocusArea( camera_fd, def_focus_mode, focus_mode)){
3445 params->set(CameraProperties::MAX_FOCUS_AREAS, def_focus_mode);
3446 CAMHAL_LOGDB("focus_area=%s, max_num_focus_area=%s\n", focus_mode, def_focus_mode);
3447 }
3448 }else {
3449 params->set(CameraProperties::SUPPORTED_FOCUS_MODES, "fixed");
3450 params->set(CameraProperties::FOCUS_MODE, "fixed");
3451 }
3452 }else{
3453 params->set(CameraProperties::SUPPORTED_FOCUS_MODES, "fixed");
3454 params->set(CameraProperties::FOCUS_MODE, "fixed");
3455 }
3456 if(focus_mode){
3457 free(focus_mode);
3458 focus_mode = NULL;
3459 }
3460 if(def_focus_mode){
3461 free(def_focus_mode);
3462 def_focus_mode = NULL;
3463 }
3464
3465 char *banding_mode = (char *) calloc (1, 256);
3466 char *def_banding_mode = (char *) calloc (1, 64);
3467 if((banding_mode)&&(def_banding_mode)){
3468 memset(banding_mode,0,256);
3469 memset(def_banding_mode,0,64);
3470 getCameraBanding(camera_fd, banding_mode, def_banding_mode);
3471 params->set(CameraProperties::SUPPORTED_ANTIBANDING, banding_mode);
3472 params->set(CameraProperties::ANTIBANDING, def_banding_mode);
3473 }else{
3474 params->set(CameraProperties::SUPPORTED_ANTIBANDING, "50hz,60hz,auto");
3475 params->set(CameraProperties::ANTIBANDING, "50hz");
3476 }
3477 if(banding_mode){
3478 free(banding_mode);
3479 banding_mode = NULL;
3480 }
3481 if(def_banding_mode){
3482 free(def_banding_mode);
3483 def_banding_mode = NULL;
3484 }
3485
3486 params->set(CameraProperties::FOCAL_LENGTH, "4.31");
3487
3488 params->set(CameraProperties::HOR_ANGLE,"54.8");
3489 params->set(CameraProperties::VER_ANGLE,"42.5");
3490
3491#ifdef AMLOGIC_USB_CAMERA_SUPPORT
3492 params->set(CameraProperties::SUPPORTED_WHITE_BALANCE, "auto");
3493 params->set(CameraProperties::WHITEBALANCE, "auto");
3494#else
3495 char *wb_mode = (char *) calloc (1, 256);
3496 char *def_wb_mode = (char *) calloc (1, 64);
3497
3498 if( wb_mode && def_wb_mode){
3499 memset(wb_mode, 0, 256);
3500 memset(def_wb_mode, 0, 64);
3501 getCameraWhiteBalance(camera_fd, wb_mode, def_wb_mode);
3502 params->set(CameraProperties::SUPPORTED_WHITE_BALANCE, wb_mode);
3503 params->set(CameraProperties::WHITEBALANCE, def_wb_mode);
3504 }else{
3505 params->set(CameraProperties::SUPPORTED_WHITE_BALANCE, "auto,daylight,incandescent,fluorescent");
3506 params->set(CameraProperties::WHITEBALANCE, "auto");
3507 }
3508
3509 if(wb_mode){
3510 free(wb_mode);
3511 wb_mode = NULL;
3512 }
3513 if(def_wb_mode){
3514 free(def_wb_mode);
3515 def_wb_mode = NULL;
3516 }
3517#endif
3518
3519 params->set(CameraProperties::AUTO_WHITEBALANCE_LOCK, DEFAULT_AWB_LOCK);
3520
3521 params->set(CameraProperties::SUPPORTED_EFFECTS, "none,negative,sepia");
3522 params->set(CameraProperties::EFFECT, "none");
3523
3524 char *flash_mode = (char *) calloc (1, 256);
3525 char *def_flash_mode = (char *) calloc (1, 64);
3526 if((flash_mode)&&(def_flash_mode)){
3527 memset(flash_mode,0,256);
3528 memset(def_flash_mode,0,64);
3529 if (get_flash_mode(camera_fd, flash_mode,def_flash_mode)) {
3530 params->set(CameraProperties::SUPPORTED_FLASH_MODES, flash_mode);
3531 params->set(CameraProperties::FLASH_MODE, def_flash_mode);
3532 CAMHAL_LOGDB("def_flash_mode=%s, flash_mode=%s\n", def_flash_mode, flash_mode);
3533 }
3534 }
3535 if (flash_mode) {
3536 free(flash_mode);
3537 flash_mode = NULL;
3538 }
3539 if (def_flash_mode) {
3540 free(def_flash_mode);
3541 def_flash_mode = NULL;
3542 }
3543
3544 //params->set(CameraParameters::KEY_SUPPORTED_SCENE_MODES,"auto,night,snow");
3545 //params->set(CameraParameters::KEY_SCENE_MODE,"auto");
3546
3547 params->set(CameraProperties::EXPOSURE_MODE, "auto");
3548 params->set(CameraProperties::SUPPORTED_EXPOSURE_MODES, "auto");
3549 params->set(CameraProperties::AUTO_EXPOSURE_LOCK, DEFAULT_AE_LOCK);
3550
3551 int min=0, max =0, def=0, step =0;
3552 getCameraExposureValue( camera_fd, min, max, step, def);
3553 params->set(CameraProperties::SUPPORTED_EV_MAX, max > 3 ? 3 : max);
3554 params->set(CameraProperties::SUPPORTED_EV_MIN, min < -3 ? -3 : min);
3555 params->set(CameraProperties::EV_COMPENSATION, def);
3556 params->set(CameraProperties::SUPPORTED_EV_STEP, step);
3557
3558 //don't support digital zoom now
3559#ifndef AMLOGIC_USB_CAMERA_SUPPORT
3560 int zoom_level = -1;
3561 char *zoom_str = (char *) calloc (1, 256);
3562 if(zoom_str)
3563 memset(zoom_str,0,256);
3564 zoom_level = get_supported_zoom(camera_fd,zoom_str);
3565 if(zoom_level>0){ //new interface by v4l ioctl
3566 params->set(CameraProperties::ZOOM_SUPPORTED,"true");
3567 params->set(CameraProperties::SMOOTH_ZOOM_SUPPORTED,"false");
3568 params->set(CameraProperties::SUPPORTED_ZOOM_RATIOS,zoom_str);
3569 params->set(CameraProperties::SUPPORTED_ZOOM_STAGES,zoom_level); //think the zoom ratios as a array, the max zoom is the max index
3570 params->set(CameraProperties::ZOOM, 0);//default should be 0
3571 }else{ // by set video layer zoom sys
3572 params->set(CameraProperties::ZOOM_SUPPORTED,"true");
3573 params->set(CameraProperties::SMOOTH_ZOOM_SUPPORTED,"false");
3574 params->set(CameraProperties::SUPPORTED_ZOOM_RATIOS,"100,120,140,160,180,200,220,280,300");
3575 params->set(CameraProperties::SUPPORTED_ZOOM_STAGES,8); //think the zoom ratios as a array, the max zoom is the max index
3576 params->set(CameraProperties::ZOOM, 0);//default should be 0
3577 }
3578 if(zoom_str)
3579 free(zoom_str);
3580#else
3581 params->set(CameraProperties::ZOOM_SUPPORTED,"false");
3582 params->set(CameraProperties::SMOOTH_ZOOM_SUPPORTED,"false");
3583 params->set(CameraProperties::SUPPORTED_ZOOM_RATIOS,"100");
3584 params->set(CameraProperties::SUPPORTED_ZOOM_STAGES,0); //think the zoom ratios as a array, the max zoom is the max index
3585 params->set(CameraProperties::ZOOM, 0);//default should be 0
3586#endif
3587
3588 params->set(CameraProperties::SUPPORTED_ISO_VALUES, "auto");
3589 params->set(CameraProperties::ISO_MODE, DEFAULT_ISO_MODE);
3590
3591 params->set(CameraProperties::SUPPORTED_IPP_MODES, DEFAULT_IPP);
3592 params->set(CameraProperties::IPP, DEFAULT_IPP);
3593
3594 params->set(CameraProperties::SUPPORTED_SCENE_MODES, "auto");
3595 params->set(CameraProperties::SCENE_MODE, DEFAULT_SCENE_MODE);
3596
3597 params->set(CameraProperties::BRIGHTNESS, DEFAULT_BRIGHTNESS);
3598 params->set(CameraProperties::CONTRAST, DEFAULT_CONTRAST);
3599 params->set(CameraProperties::GBCE, DEFAULT_GBCE);
3600 params->set(CameraProperties::SATURATION, DEFAULT_SATURATION);
3601 params->set(CameraProperties::SHARPNESS, DEFAULT_SHARPNESS);
3602 params->set(CameraProperties::VSTAB, DEFAULT_VSTAB);
3603 params->set(CameraProperties::VSTAB_SUPPORTED, DEFAULT_VSTAB_SUPPORTED);
3604 params->set(CameraProperties::MAX_FD_HW_FACES, DEFAULT_MAX_FD_HW_FACES);
3605 params->set(CameraProperties::MAX_FD_SW_FACES, DEFAULT_MAX_FD_SW_FACES);
3606 params->set(CameraProperties::REQUIRED_PREVIEW_BUFS, DEFAULT_NUM_PREV_BUFS);
3607 params->set(CameraProperties::REQUIRED_IMAGE_BUFS, DEFAULT_NUM_PIC_BUFS);
3608#ifdef AMLOGIC_ENABLE_VIDEO_SNAPSHOT
3609 params->set(CameraProperties::VIDEO_SNAPSHOT_SUPPORTED, "true");
3610#else
3611 params->set(CameraProperties::VIDEO_SNAPSHOT_SUPPORTED, "false");
3612#endif
3613#ifdef AMLOGIC_USB_CAMERA_SUPPORT
3614 params->set(CameraProperties::VIDEO_SIZE,params->get(CameraProperties::PREVIEW_SIZE));
3615 params->set(CameraProperties::PREFERRED_PREVIEW_SIZE_FOR_VIDEO,params->get(CameraProperties::PREVIEW_SIZE));
3616#else
3617 params->set(CameraProperties::VIDEO_SIZE, DEFAULT_VIDEO_SIZE);
3618 params->set(CameraProperties::PREFERRED_PREVIEW_SIZE_FOR_VIDEO, DEFAULT_PREFERRED_PREVIEW_SIZE_FOR_VIDEO);
3619#endif
3620
3621 if(camera_fd>=0)
3622 close(camera_fd);
3623}
3624
3625#ifdef AMLOGIC_CAMERA_NONBLOCK_SUPPORT
3626/* gets video device defined frame rate (not real - consider it a maximum value)
3627 * args:
3628 *
3629 * returns: VIDIOC_G_PARM ioctl result value
3630*/
3631extern "C" int get_framerate ( int camera_fd, int *fps, int *fps_num)
3632{
3633#ifdef AMLOGIC_USB_CAMERA_SUPPORT
3634 *fps = 15;
3635 *fps_num = 1;
3636 return 0;
3637#else
3638 int ret=0;
3639
3640 struct v4l2_streamparm streamparm;
3641
3642 streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
3643 ret = ioctl( camera_fd,VIDIOC_G_PARM,&streamparm);
3644 if (ret < 0){
3645 CAMHAL_LOGDA("VIDIOC_G_PARM - Unable to get timeperframe");
3646 }else{
3647 if (streamparm.parm.capture.capability & V4L2_CAP_TIMEPERFRAME) {
3648 // it seems numerator is allways 1 but we don't do assumptions here :-)
3649 *fps = streamparm.parm.capture.timeperframe.denominator;
3650 *fps_num = streamparm.parm.capture.timeperframe.numerator;
3651 }
3652 }
3653 return ret;
3654#endif
3655}
3656
3657int enumFramerate (int camera_fd, int *fps, int *fps_num)
3658{
3659 int ret=0;
3660 int framerate=0;
3661 int temp_rate=0;
3662 struct v4l2_frmivalenum fival;
3663 int i,j;
3664
3665 int pixelfmt_tbl[]={
3666#ifdef AMLOGIC_USB_CAMERA_SUPPORT
3667 V4L2_PIX_FMT_MJPEG,
3668 V4L2_PIX_FMT_YUYV,
3669#else
3670 V4L2_PIX_FMT_NV21,
3671#endif
3672 V4L2_PIX_FMT_YVU420,
3673 };
3674 struct v4l2_frmsize_discrete resolution_tbl[]={
3675#ifdef AMLOGIC_USB_CAMERA_SUPPORT
3676 {960, 720},
3677#endif
3678 {640, 480},
3679 {320, 240},
3680 };
3681
3682 for( i = 0; i < (int) ARRAY_SIZE(pixelfmt_tbl); i++){
3683 for( j = 0; j < (int) ARRAY_SIZE(resolution_tbl); j++){
3684 memset(&fival, 0, sizeof(fival));
3685 fival.index = 0;
3686 fival.pixel_format = pixelfmt_tbl[i];
3687 fival.width = resolution_tbl[j].width;
3688 fival.height = resolution_tbl[j].height;
3689
3690 while ((ret = ioctl(camera_fd, VIDIOC_ENUM_FRAMEINTERVALS, &fival)) == 0){
3691 if (fival.type == V4L2_FRMIVAL_TYPE_DISCRETE){
3692 temp_rate = fival.discrete.denominator/fival.discrete.numerator;
3693 if(framerate < temp_rate)
3694 framerate = temp_rate;
3695 }else if (fival.type == V4L2_FRMIVAL_TYPE_CONTINUOUS){
3696 framerate = fival.stepwise.max.denominator/fival.stepwise.max.numerator;
3697 CAMHAL_LOGDB("pixelfmt=%d,resolution:%dx%d,"
3698 "FRAME TYPE is continuous,step=%d/%d s\n",
3699 pixelfmt_tbl[i],
3700 resolution_tbl[j].width,
3701 resolution_tbl[j].height,
3702 fival.stepwise.max.numerator,
3703 fival.stepwise.max.denominator);
3704 break;
3705 }else if (fival.type == V4L2_FRMIVAL_TYPE_STEPWISE) {
3706 CAMHAL_LOGDB("pixelfmt=%d,resolution:%dx%d,"
3707 "FRAME TYPE is step wise,step=%d/%d s\n",
3708 pixelfmt_tbl[i],
3709 resolution_tbl[j].width,
3710 resolution_tbl[j].height,
3711 fival.stepwise.step.numerator,
3712 fival.stepwise.step.denominator);
3713 framerate = fival.stepwise.max.denominator/fival.stepwise.max.numerator;
3714 break;
3715 }
3716 fival.index++;
3717 }
3718 }
3719 }
3720
3721 *fps = framerate;
3722 *fps_num = 1;
3723 CAMHAL_LOGDB("enum framerate=%d\n", framerate);
3724 return 0;
3725}
3726#endif
3727
3728extern "C" int V4LCameraAdapter::set_white_balance(int camera_fd,const char *swb)
3729{
3730 int ret = 0;
3731 struct v4l2_control ctl;
3732 if(camera_fd<0)
3733 return -1;
3734
3735#ifdef AMLOGIC_USB_CAMERA_SUPPORT
3736 memset(&ctl, 0, sizeof(ctl));
3737 ctl.id = V4L2_CID_AUTO_WHITE_BALANCE;
3738 ctl.value= true;
3739#else
3740 ctl.id = V4L2_CID_DO_WHITE_BALANCE;
3741
3742 if(strcasecmp(swb,"auto")==0)
3743 ctl.value=CAM_WB_AUTO;
3744 else if(strcasecmp(swb,"daylight")==0)
3745 ctl.value=CAM_WB_DAYLIGHT;
3746 else if(strcasecmp(swb,"incandescent")==0)
3747 ctl.value=CAM_WB_INCANDESCENCE;
3748 else if(strcasecmp(swb,"fluorescent")==0)
3749 ctl.value=CAM_WB_FLUORESCENT;
3750 else if(strcasecmp(swb,"cloudy-daylight")==0)
3751 ctl.value=CAM_WB_CLOUD;
3752 else if(strcasecmp(swb,"shade")==0)
3753 ctl.value=CAM_WB_SHADE;
3754 else if(strcasecmp(swb,"twilight")==0)
3755 ctl.value=CAM_WB_TWILIGHT;
3756 else if(strcasecmp(swb,"warm-fluorescent")==0)
3757 ctl.value=CAM_WB_WARM_FLUORESCENT;
3758#endif
3759
3760 if(mWhiteBalance == ctl.value){
3761 return 0;
3762 }else{
3763 mWhiteBalance = ctl.value;
3764 }
3765 ret = ioctl(camera_fd, VIDIOC_S_CTRL, &ctl);
3766 if(ret<0){
3767 CAMHAL_LOGDB("AMLOGIC CAMERA Set white balance fail: %s. ret=%d", strerror(errno),ret);
3768 }
3769 return ret ;
3770}
3771
3772status_t V4LCameraAdapter::getFocusMoveStatus()
3773{
3774 struct v4l2_control ctl;
3775 int ret;
3776 if( (cur_focus_mode != CAM_FOCUS_MODE_CONTI_VID) &&
3777 (cur_focus_mode != CAM_FOCUS_MODE_CONTI_PIC) &&
3778 (cur_focus_mode != CAM_FOCUS_MODE_AUTO)){
3779 mFocusMoveEnabled = false;
3780 return 0;
3781 }
3782
3783 mFocusWaitCount --;
3784 if(mFocusWaitCount >= 0){
3785 return 0;
3786 }
3787 mFocusWaitCount = 0;
3788
3789 memset( &ctl, 0, sizeof(ctl));
3790 ctl.id =V4L2_CID_AUTO_FOCUS_STATUS;
3791 ret = ioctl(mCameraHandle, VIDIOC_G_CTRL, &ctl);
3792 if (0 > ret ){
3793 CAMHAL_LOGDA("V4L2_CID_AUTO_FOCUS_STATUS failed\n");
3794 return -EINVAL;
3795 }
3796
3797 if( ctl.value == V4L2_AUTO_FOCUS_STATUS_BUSY ){
3798 if(!bFocusMoveState){
3799 bFocusMoveState = true;
3800 notifyFocusMoveSubscribers(FOCUS_MOVE_START);
3801 }
3802 }else {
3803 mFocusWaitCount = FOCUS_PROCESS_FRAMES;
3804 if(bFocusMoveState){
3805 bFocusMoveState = false;
3806 notifyFocusMoveSubscribers(FOCUS_MOVE_STOP);
3807 }
3808 }
3809 return ctl.value;
3810}
3811
3812extern "C" int V4LCameraAdapter::set_focus_area( int camera_fd, const char *focusarea)
3813{
3814 struct v4l2_control ctl;
3815 int ret;
3816 int x0 = 0;
3817 int y0 = 0;
3818 int x1 = 0;
3819 int y1 = 0;
3820 int weight = 0;
3821 int tempvalue = 0;
3822
3823 sscanf(focusarea,"(%d,%d,%d,%d,%d)",&x0,&y0,&x1,&y1,&weight);
3824 if( (x0==x1)&&(y0==y1) ){
3825 CAMHAL_LOGDA("Invalid position for tap focus!\n");
3826 return 0;
3827 }
3828 memset( &ctl, 0, sizeof(ctl));
3829 ctl.id = V4L2_CID_FOCUS_ABSOLUTE;
3830 tempvalue = ((x0+x1)/2 + 1000);
3831 tempvalue <<= 16;
3832 ctl.value = tempvalue;
3833 tempvalue = ((y0+y1)/2 + 1000) & 0xffff;
3834 ctl.value |= tempvalue;
3835 ret = ioctl(mCameraHandle, VIDIOC_S_CTRL, &ctl);
3836 if ( 0 > ret ){
3837 CAMHAL_LOGDA("focus tap failed\n");
3838 return -EINVAL;
3839 }
3840 return 0;
3841}
3842
3843/*
3844 * use id V4L2_CID_EXPOSURE_AUTO to set exposure mode
3845 * 0: Auto Mode, commit failure @20120504
3846 * 1: Manual Mode
3847 * 2: Shutter Priority Mode, commit failure @20120504
3848 * 3: Aperture Priority Mode
3849 */
3850#ifdef AMLOGIC_USB_CAMERA_SUPPORT
3851extern "C" int V4LCameraAdapter::SetExposureMode(int camera_fd, unsigned int mode)
3852{
3853 int ret = 0;
3854 struct v4l2_control ctl;
3855
3856 memset(&ctl, 0, sizeof(ctl));
3857
3858 ctl.id = V4L2_CID_EXPOSURE_AUTO;
3859 ctl.value = mode;
3860 ret = ioctl(camera_fd, VIDIOC_S_CTRL, &ctl);
3861 if(ret<0){
3862 CAMHAL_LOGDB("fail: %s. ret=%d", strerror(errno),ret);
3863 return ret;
3864 }
3865 if( (V4L2_EXPOSURE_APERTURE_PRIORITY ==ctl.value)||(V4L2_EXPOSURE_AUTO ==ctl.value)){
3866 memset( &ctl, 0, sizeof(ctl));
3867 ctl.id = V4L2_CID_EXPOSURE_AUTO_PRIORITY;
3868 ctl.value = false;
3869 ret = ioctl(camera_fd, VIDIOC_S_CTRL, &ctl);
3870 if(ret<0){
3871 CAMHAL_LOGDB("Exposure auto priority Set manual fail: %s. ret=%d", strerror(errno),ret);
3872 return ret;
3873 }
3874 }
3875 return 0;
3876}
3877#endif
3878
3879extern "C" int V4LCameraAdapter::SetExposure(int camera_fd,const char *sbn)
3880{
3881 int ret = 0;
3882 struct v4l2_control ctl;
3883 int level;
3884
3885 if(camera_fd<0)
3886 return -1;
3887 level = atoi(sbn);
3888 if(mEV == level){
3889 return 0;
3890 }else{
3891 mEV = level;
3892 }
3893 memset(&ctl, 0, sizeof(ctl));
3894
3895#ifdef AMLOGIC_USB_CAMERA_SUPPORT
3896 level ++;
3897 if(level !=1){
3898 ret = SetExposureMode( camera_fd, V4L2_EXPOSURE_MANUAL);
3899 if(ret<0){
3900 CAMHAL_LOGDA("Exposure Mode change to manual mode failure\n");
3901 return ret;
3902 }
3903 }else{
3904 ret = SetExposureMode( camera_fd, V4L2_EXPOSURE_APERTURE_PRIORITY);// 3);
3905 if(ret<0){
3906 CAMHAL_LOGDA("Exposure Mode change to Aperture mode failure\n");
3907 }
3908 return ret;//APERTURE mode cann't set followed control
3909 }
3910 ctl.id = V4L2_CID_EXPOSURE_ABSOLUTE;
3911 if(level>=0){
3912 ctl.value= mEVdef << level;
3913 }else{
3914 ctl.value= mEVdef >> (-level);
3915 }
3916 ctl.value= ctl.value>mEVmax? mEVmax:ctl.value;
3917 ctl.value= ctl.value<mEVmin? mEVmin:ctl.value;
3918
3919 level --;
3920#else
3921 ctl.id = V4L2_CID_EXPOSURE;
3922 ctl.value = level + (mEVmax - mEVmin)/2;
3923#endif
3924
3925 ret = ioctl(camera_fd, VIDIOC_S_CTRL, &ctl);
3926 if(ret<0){
3927 CAMHAL_LOGDB("AMLOGIC CAMERA Set Exposure fail: %s. ret=%d", strerror(errno),ret);
3928 }
3929 return ret ;
3930}
3931
3932extern "C" int set_effect(int camera_fd,const char *sef)
3933{
3934 int ret = 0;
3935 struct v4l2_control ctl;
3936 if(camera_fd<0)
3937 return -1;
3938
3939 memset(&ctl, 0, sizeof(ctl));
3940 ctl.id = V4L2_CID_COLORFX;
3941 if(strcasecmp(sef,"none")==0)
3942 ctl.value=CAM_EFFECT_ENC_NORMAL;
3943 else if(strcasecmp(sef,"negative")==0)
3944 ctl.value=CAM_EFFECT_ENC_COLORINV;
3945 else if(strcasecmp(sef,"sepia")==0)
3946 ctl.value=CAM_EFFECT_ENC_SEPIA;
3947 ret = ioctl(camera_fd, VIDIOC_S_CTRL, &ctl);
3948 if(ret<0){
3949 CAMHAL_LOGDB("Set effect fail: %s. ret=%d", strerror(errno),ret);
3950 }
3951 return ret ;
3952}
3953
3954extern "C" int set_night_mode(int camera_fd,const char *snm)
3955{
3956 int ret = 0;
3957 struct v4l2_control ctl;
3958 if(camera_fd<0)
3959 return -1;
3960
3961 memset( &ctl, 0, sizeof(ctl));
3962 if(strcasecmp(snm,"auto")==0)
3963 ctl.value=CAM_NM_AUTO;
3964 else if(strcasecmp(snm,"night")==0)
3965 ctl.value=CAM_NM_ENABLE;
3966 ctl.id = V4L2_CID_DO_WHITE_BALANCE;
3967 ret = ioctl(camera_fd, VIDIOC_S_CTRL, &ctl);
3968 if(ret<0){
3969 CAMHAL_LOGDB("Set night mode fail: %s. ret=%d", strerror(errno),ret);
3970 }
3971 return ret ;
3972}
3973
3974extern "C" int V4LCameraAdapter::set_banding(int camera_fd,const char *snm)
3975{
3976 int ret = 0;
3977 struct v4l2_control ctl;
3978
3979 if(camera_fd<0)
3980 return -1;
3981
3982 memset( &ctl, 0, sizeof(ctl));
3983 if(strcasecmp(snm,"50hz")==0)
3984 ctl.value= CAM_ANTIBANDING_50HZ;
3985 else if(strcasecmp(snm,"60hz")==0)
3986 ctl.value= CAM_ANTIBANDING_60HZ;
3987 else if(strcasecmp(snm,"auto")==0)
3988 ctl.value= CAM_ANTIBANDING_AUTO;
3989 else if(strcasecmp(snm,"off")==0)
3990 ctl.value= CAM_ANTIBANDING_OFF;
3991
3992 ctl.id = V4L2_CID_POWER_LINE_FREQUENCY;
3993 if(mAntiBanding == ctl.value){
3994 return 0;
3995 }else{
3996 mAntiBanding = ctl.value;
3997 }
3998 ret = ioctl(camera_fd, VIDIOC_S_CTRL, &ctl);
3999 if(ret<0){
4000 CAMHAL_LOGDB("Set banding fail: %s. ret=%d", strerror(errno),ret);
4001 }
4002 return ret ;
4003}
4004
4005static bool get_flash_mode(int camera_fd, char *flash_status,
4006 char *def_flash_status)
4007{
4008 struct v4l2_queryctrl qc;
4009 struct v4l2_querymenu qm;
4010 bool flash_enable = false;
4011 int ret = NO_ERROR;
4012 int status_count = 0;
4013
4014 memset(&qc, 0, sizeof(qc));
4015 qc.id = V4L2_CID_BACKLIGHT_COMPENSATION;
4016 ret = ioctl (camera_fd, VIDIOC_QUERYCTRL, &qc);
4017 if((qc.flags == V4L2_CTRL_FLAG_DISABLED) ||( ret < 0) || (qc.type != V4L2_CTRL_TYPE_MENU)){
4018 flash_enable = false;
4019 CAMHAL_LOGDB("can't support flash, %sret=%d%s\n",
4020 (qc.flags == V4L2_CTRL_FLAG_DISABLED)?"disable,":"",
4021 ret, (qc.type != V4L2_CTRL_TYPE_MENU)?"":",type not right");
4022 }else {
4023 memset(&qm, 0, sizeof(qm));
4024 qm.id = V4L2_CID_BACKLIGHT_COMPENSATION;
4025 qm.index = qc.default_value;
4026 if(ioctl (camera_fd, VIDIOC_QUERYMENU, &qm) < 0){
4027 strcpy(def_flash_status, "off");
4028 } else {
4029 strcpy(def_flash_status, (char*)qm.name);
4030 }
4031 int index = 0;
4032 for (index = qc.minimum; index <= qc.maximum; index+= qc.step) {
4033 memset(&qm, 0, sizeof(struct v4l2_querymenu));
4034 qm.id = V4L2_CID_BACKLIGHT_COMPENSATION;
4035 qm.index = index;
4036 if(ioctl (camera_fd, VIDIOC_QUERYMENU, &qm) < 0){
4037 continue;
4038 } else {
4039 if(status_count>0)
4040 strcat(flash_status, ",");
4041 strcat(flash_status, (char*)qm.name);
4042 status_count++;
4043 }
4044 }
4045 if(status_count>0)
4046 flash_enable = true;
4047 }
4048 return flash_enable;
4049}
4050
4051extern "C" int set_flash_mode(int camera_fd, const char *sfm)
4052{
4053 int ret = NO_ERROR;
4054 struct v4l2_control ctl;
4055
4056 memset(&ctl, 0, sizeof(ctl));
4057 if(strcasecmp(sfm,"auto")==0)
4058 ctl.value=FLASHLIGHT_AUTO;
4059 else if(strcasecmp(sfm,"on")==0)
4060 ctl.value=FLASHLIGHT_ON;
4061 else if(strcasecmp(sfm,"off")==0)
4062 ctl.value=FLASHLIGHT_OFF;
4063 else if(strcasecmp(sfm,"torch")==0)
4064 ctl.value=FLASHLIGHT_TORCH;
4065 else if(strcasecmp(sfm,"red-eye")==0)
4066 ctl.value=FLASHLIGHT_RED_EYE;
4067
4068 ctl.id = V4L2_CID_BACKLIGHT_COMPENSATION;
4069 ret = ioctl( camera_fd, VIDIOC_S_CTRL, &ctl);
4070 if( ret < 0 ){
4071 CAMHAL_LOGDB("BACKLIGHT_COMPENSATION failed, errno=%d\n", errno);
4072 }
4073 return ret;
4074}
4075
4076static int get_hflip_mode(int camera_fd)
4077{
4078 struct v4l2_queryctrl qc;
4079 int ret = 0;
4080
4081 if(camera_fd<0){
4082 CAMHAL_LOGDA("Get_hflip_mode --camera handle is invalid\n");
4083 return -1;
4084 }
4085
4086 memset(&qc, 0, sizeof(qc));
4087 qc.id = V4L2_CID_HFLIP;
4088 ret = ioctl (camera_fd, VIDIOC_QUERYCTRL, &qc);
4089 if((qc.flags == V4L2_CTRL_FLAG_DISABLED) ||( ret < 0) || (qc.type != V4L2_CTRL_TYPE_INTEGER)){
4090 ret = -1;
4091 CAMHAL_LOGDB("can't support HFlip! %s ret=%d %s\n",
4092 (qc.flags == V4L2_CTRL_FLAG_DISABLED)?"disable,":"",
4093 ret, (qc.type != V4L2_CTRL_TYPE_INTEGER)?"":",type not right");
4094 }else{
4095 CAMHAL_LOGDB("camera handle %d supports HFlip!\n",camera_fd);
4096 }
4097 return ret;
4098}
4099
4100static int set_hflip_mode(int camera_fd, bool mode)
4101{
4102 int ret = 0;
4103 struct v4l2_control ctl;
4104 if(camera_fd<0)
4105 return -1;
4106
4107 memset(&ctl, 0,sizeof(ctl));
4108 ctl.value=mode?1:0;
4109 ctl.id = V4L2_CID_HFLIP;
4110 ret = ioctl(camera_fd, VIDIOC_S_CTRL, &ctl);
4111 if(ret<0){
4112 CAMHAL_LOGDB("Set hflip mode fail: %s. ret=%d", strerror(errno),ret);
4113 }
4114 return ret ;
4115}
4116
4117static int get_supported_zoom(int camera_fd, char * zoom_str)
4118{
4119 int ret = 0;
4120 struct v4l2_queryctrl qc;
4121 char str_zoom_element[10];
4122 if((camera_fd<0)||(!zoom_str))
4123 return -1;
4124
4125 memset(&qc, 0, sizeof(qc));
4126 qc.id = V4L2_CID_ZOOM_ABSOLUTE;
4127 ret = ioctl (camera_fd, VIDIOC_QUERYCTRL, &qc);
4128 if((qc.flags == V4L2_CTRL_FLAG_DISABLED) ||( ret < 0) || (qc.type != V4L2_CTRL_TYPE_INTEGER)){
4129 ret = -1;
4130 CAMHAL_LOGDB("camera handle %d can't get zoom level!\n",camera_fd);
4131 }else{
4132 int i = 0;
4133 ret = (qc.maximum - qc.minimum)/qc.step;
4134 for (i=qc.minimum; i<=qc.maximum; i+=qc.step) {
4135 memset(str_zoom_element,0,sizeof(str_zoom_element));
4136 sprintf(str_zoom_element,"%d,", i);
4137 strcat(zoom_str,str_zoom_element);
4138 }
4139 }
4140 return ret ;
4141}
4142
4143static int set_zoom_level(int camera_fd, int zoom)
4144{
4145 int ret = 0;
4146 struct v4l2_control ctl;
4147 if((camera_fd<0)||(zoom<0))
4148 return -1;
4149
4150 memset( &ctl, 0, sizeof(ctl));
4151 ctl.value=zoom;
4152 ctl.id = V4L2_CID_ZOOM_ABSOLUTE;
4153 ret = ioctl(camera_fd, VIDIOC_S_CTRL, &ctl);
4154 if(ret<0){
4155 CAMHAL_LOGDB("Set zoom level fail: %s. ret=%d", strerror(errno),ret);
4156 }
4157 return ret ;
4158}
4159
4160#ifndef AMLOGIC_USB_CAMERA_SUPPORT
4161static int set_rotate_value(int camera_fd, int value)
4162{
4163 int ret = 0;
4164 struct v4l2_control ctl;
4165 if(camera_fd<0)
4166 return -1;
4167
4168 if((value!=0)&&(value!=90)&&(value!=180)&&(value!=270)){
4169 CAMHAL_LOGDB("Set rotate value invalid: %d.", value);
4170 return -1;
4171 }
4172 memset( &ctl, 0, sizeof(ctl));
4173 ctl.value=value;
4174 ctl.id = V4L2_ROTATE_ID;
4175 ret = ioctl(camera_fd, VIDIOC_S_CTRL, &ctl);
4176 if(ret<0){
4177 CAMHAL_LOGDB("Set rotate value fail: %s. ret=%d", strerror(errno),ret);
4178 }
4179 return ret ;
4180}
4181#endif
4182
4183status_t V4LCameraAdapter::force_reset_sensor(){
4184 CAMHAL_LOGIA("Restart Preview");
4185 status_t ret = NO_ERROR;
4186 int frame_count = 0;
4187 int ret_c = 0;
4188 void *frame_buf = NULL;
4189
4190 Mutex::Autolock lock(mPreviewBufsLock);
4191 enum v4l2_buf_type bufType;
4192 bufType = V4L2_BUF_TYPE_VIDEO_CAPTURE;
4193 ret = ioctl (mCameraHandle, VIDIOC_STREAMOFF, &bufType);
4194 if (ret < 0) {
4195 CAMHAL_LOGEB("Stop preview: Unable to stop Preview: %s", strerror(errno));
4196 return ret;
4197 }
4198 /* Unmap buffers */
4199 for (int i = 0; i < mPreviewBufferCount; i++){
4200 if (munmap(mVideoInfo->mem[i], mVideoInfo->buf.length) < 0){
4201 CAMHAL_LOGEA("Unmap failed");
4202 }
4203 mVideoInfo->canvas[i] = 0;
4204 }
4205
4206 if ((DEV_USB == m_eDeviceType) ||
4207 (DEV_ION == m_eDeviceType) ||
4208 (DEV_ION_MPLANE == m_eDeviceType))
4209 {
4210 mVideoInfo->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
4211 mVideoInfo->buf.memory = m_eV4l2Memory;
4212 mVideoInfo->rb.count = 0;
4213
4214 ret = ioctl(mCameraHandle, VIDIOC_REQBUFS, &mVideoInfo->rb);
4215 if (ret < 0) {
4216 CAMHAL_LOGDB("VIDIOC_REQBUFS failed: %s", strerror(errno));
4217 }else{
4218 CAMHAL_LOGVA("VIDIOC_REQBUFS delete buffer success\n");
4219 }
4220 }
4221 mPreviewBufs.clear();
4222 mPreviewIdxs.clear();
4223
4224 CAMHAL_LOGDA("clera preview buffer");
4225 ret = setBuffersFormat(mPreviewWidth, mPreviewHeight, mSensorFormat);
4226 if( 0 > ret ){
4227 CAMHAL_LOGEB("VIDIOC_S_FMT failed: %s", strerror(errno));
4228 return ret;
4229 }
4230 mVideoInfo->rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
4231 mVideoInfo->rb.memory = m_eV4l2Memory;
4232 mVideoInfo->rb.count = mPreviewBufferCount;
4233
4234 ret = ioctl(mCameraHandle, VIDIOC_REQBUFS, &mVideoInfo->rb);
4235 if (ret < 0) {
4236 CAMHAL_LOGEB("VIDIOC_REQBUFS failed: %s", strerror(errno));
4237 return ret;
4238 }
4239 usleep(10000);
4240 uint32_t *ptr = (uint32_t*) mPreviewCache;
4241
4242 for (int i = 0; i < mPreviewBufferCount; i++) {
4243 memset (&mVideoInfo->buf, 0, sizeof (struct v4l2_buffer));
4244 mVideoInfo->buf.index = i;
4245 mVideoInfo->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
4246 mVideoInfo->buf.memory = m_eV4l2Memory;
4247 ret = ioctl (mCameraHandle, VIDIOC_QUERYBUF, &mVideoInfo->buf);
4248 if (ret < 0) {
4249 CAMHAL_LOGEB("Unable to query buffer (%s)", strerror(errno));
4250 return ret;
4251 }
4252 private_handle_t* gralloc_hnd;
4253 if (V4L2_MEMORY_DMABUF == m_eV4l2Memory)
4254 {
4255 gralloc_hnd = (private_handle_t*)ptr[i];
4256 mVideoInfo->mem[i] = mmap (0,
4257 mVideoInfo->buf.length,
4258 PROT_READ | PROT_WRITE,
4259 MAP_SHARED,
4260 gralloc_hnd->share_fd,
4261 0);
4262 } else {
4263 mVideoInfo->mem[i] = mmap (0,
4264 mVideoInfo->buf.length,
4265 PROT_READ | PROT_WRITE,
4266 MAP_SHARED,
4267 mCameraHandle,
4268 mVideoInfo->buf.m.offset);
4269 }
4270
4271 if (mVideoInfo->mem[i] == MAP_FAILED) {
4272 CAMHAL_LOGEB("Unable to map buffer (%s)", strerror(errno));
4273 return ret;
4274 }
4275
4276 if(mVideoInfo->canvas_mode){
4277 mVideoInfo->canvas[i] = mVideoInfo->buf.reserved;
4278 }
4279 //Associate each Camera internal buffer with the one from Overlay
4280 CAMHAL_LOGDB("mPreviewBufs.add %#x, %d", ptr[i], i);
4281 mPreviewBufs.add((int)ptr[i], i);
4282 }
4283
4284 for(int i = 0;i < mPreviewBufferCount; i++){
4285 mPreviewIdxs.add(mPreviewBufs.valueAt(i),i);
4286 }
4287 CAMHAL_LOGDA("reset sensor add preview buffer ok");
4288
4289 nQueued = 0;
4290 private_handle_t* gralloc_hnd;
4291 for (int i = 0; i < mPreviewBufferCount; i++){
4292 frame_count = -1;
4293 frame_buf = (void *)mPreviewBufs.keyAt(i);
4294
4295 if((ret_c = getFrameRefCount(frame_buf,CameraFrame::PREVIEW_FRAME_SYNC))>=0)
4296 frame_count = ret_c;
4297
4298 CAMHAL_LOGDB("startPreview--buffer address:0x%x, refcount:%d",(uint32_t)frame_buf,frame_count);
4299 if(frame_count>0)
4300 continue;
4301 mVideoInfo->buf.index = mPreviewBufs.valueFor((uint32_t)frame_buf);
4302 mVideoInfo->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
4303 mVideoInfo->buf.memory = m_eV4l2Memory;
4304 if (V4L2_MEMORY_DMABUF == m_eV4l2Memory) {
4305 gralloc_hnd = (private_handle_t *)frame_buf;
4306 mVideoInfo->buf.m.fd = gralloc_hnd->share_fd;
4307 }
4308
4309 ret = ioctl(mCameraHandle, VIDIOC_QBUF, &mVideoInfo->buf);
4310 if (ret < 0) {
4311 CAMHAL_LOGEA("VIDIOC_QBUF Failed");
4312 return ret;
4313 }
4314 CAMHAL_LOGDB("startPreview --length=%d, index:%d", mVideoInfo->buf.length,mVideoInfo->buf.index);
4315 nQueued++;
4316 }
4317 ret = ioctl (mCameraHandle, VIDIOC_STREAMON, &bufType);
4318 if (ret < 0) {
4319 CAMHAL_LOGEB("Start preview: Unable to start Preview: %s", strerror(errno));
4320 return ret;
4321 }
4322 CAMHAL_LOGDA("reset sensor finish");
4323 return NO_ERROR;
4324}
4325
4326};
4327
4328
4329/*--------------------Camera Adapter Class ENDS here-----------------------------*/
4330
4331