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