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