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