summaryrefslogtreecommitdiff
path: root/vircam/V4LCamAdpt.cpp (plain)
blob: c2b08f4fb03ce76ca44c10432cc6f187714208b6
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 V4LCamAdpt.cpp
19*
20* This file maps the Camera Hardware Interface to V4L2.
21*
22*/
23
24#define LOG_TAG "V4LCamAdpt "
25//reinclude because of a bug with the log macros
26#include <utils/Log.h>
27#include "DebugUtils.h"
28
29#include "V4LCamAdpt.h"
30#include "CameraHal.h"
31#include "ExCameraParameters.h"
32#include <signal.h>
33#include <stdio.h>
34#include <stdlib.h>
35#include <string.h>
36#include <fcntl.h>
37#include <unistd.h>
38#include <errno.h>
39#include <sys/ioctl.h>
40#include <sys/mman.h>
41#include <sys/select.h>
42#include <linux/videodev.h>
43#include <sys/time.h>
44
45#include <cutils/properties.h>
46#include <sys/types.h>
47#include <sys/stat.h>
48#include "CameraHal.h"
49
50
51//for private_handle_t TODO move out of private header
52#include <gralloc_priv.h>
53
54static int mDebugFps = 0;
55
56#ifndef ARRAY_SIZE
57#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
58#endif
59
60#define VIRTUAL_DEVICE_PATH(_sensor_index) \
61 (_sensor_index == (MAX_CAM_NUM_ADD_VCAM-1) ? "/dev/video11" : "/dev/video11")
62
63namespace android {
64
65//frames skipped before recalculating the framerate
66#define FPS_PERIOD 30
67
68/*--------------------junk STARTS here-----------------------------*/
69#define SYSFILE_CAMERA_SET_PARA "/sys/class/vm/attr2"
70#define SYSFILE_CAMERA_SET_MIRROR "/sys/class/vm/mirror"
71static int writefile(char* path,char* content)
72{
73 FILE* fp = fopen(path, "w+");
74
75 CAMHAL_LOGDB("Write file %s(%p) content %s", path, fp, content);
76
77 if (fp) {
78 while( ((*content) != '\0') ) {
79 if (EOF == fputc(*content,fp)){
80 CAMHAL_LOGDA("write char fail");
81 }
82 content++;
83 }
84
85 fclose(fp);
86 }
87 else
88 CAMHAL_LOGDA("open file fail\n");
89 return 1;
90}
91/*--------------------Camera Adapter Class STARTS here-----------------------------*/
92
93status_t V4LCamAdpt::initialize(CameraProperties::Properties* caps)
94{
95 LOG_FUNCTION_NAME;
96
97 char value[PROPERTY_VALUE_MAX];
98 char const*filename = NULL;
99 property_get("debug.camera.showfps", value, "0");
100 mDebugFps = atoi(value);
101
102 int ret = NO_ERROR;
103
104 // Allocate memory for video info structure
105 mVideoInfo = (struct VideoInfo *) calloc (1, sizeof (struct VideoInfo));
106 if(!mVideoInfo)
107 {
108 return NO_MEMORY;
109 }
110
111
112 filename = caps->get(CameraProperties::DEVICE_NAME);
113 if(filename == NULL){
114 CAMHAL_LOGEB("can't get index=%d's name ", mSensorIndex);
115 return -EINVAL;
116 }
117 if ((mCameraHandle = open( filename, O_RDWR)) == -1)
118 {
119 CAMHAL_LOGEB("Error while opening handle to V4L2 Camera: %s", strerror(errno));
120 return -EINVAL;
121 }
122
123
124 ret = ioctl (mCameraHandle, VIDIOC_QUERYCAP, &mVideoInfo->cap);
125 if (ret < 0)
126 {
127 CAMHAL_LOGEA("Error when querying the capabilities of the V4L Camera");
128 return -EINVAL;
129 }
130
131 if ((mVideoInfo->cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) == 0)
132 {
133 CAMHAL_LOGEA("Error while adapter initialization: video capture not supported.");
134 return -EINVAL;
135 }
136
137 if (!(mVideoInfo->cap.capabilities & V4L2_CAP_STREAMING))
138 {
139 CAMHAL_LOGEA("Error while adapter initialization: Capture device does not support streaming i/o");
140 return -EINVAL;
141 }
142
143 if (strcmp(caps->get(CameraProperties::FACING_INDEX), (const char *) android::ExCameraParameters::FACING_FRONT) == 0)
144 mbFrontCamera = true;
145 else
146 mbFrontCamera = false;
147 CAMHAL_LOGDB("mbFrontCamera=%d",mbFrontCamera);
148
149 // Initialize flags
150 mPreviewing = false;
151 mVideoInfo->isStreaming = false;
152 mRecording = false;
153 mZoomlevel = -1;
154 mEnableContiFocus = false;
155 cur_focus_mode_for_conti = CAM_FOCUS_MODE_RELEASE;
156 mFlashMode = FLASHLIGHT_OFF;
157 mPixelFormat = 0;
158
159 mPreviewWidth = 0 ;
160 mPreviewHeight = 0;
161 mCaptureWidth = 0;
162 mCaptureHeight = 0;
163
164 IoctlStateProbe();
165
166#ifdef AMLOGIC_VCAM_NONBLOCK_SUPPORT
167 int fps=0, fps_num=0;
168 char *fpsrange=(char *)calloc(32,sizeof(char));
169
170 ret = get_framerate(mCameraHandle, &fps, &fps_num);
171 if((fpsrange != NULL)&&(NO_ERROR == ret) && ( 0 !=fps_num )){
172 mPreviewFrameRate = fps/fps_num;
173 sprintf(fpsrange,"%s%d","10,",fps/fps_num);
174 CAMHAL_LOGDB("supported preview rates is %s\n", fpsrange);
175
176 mParams.set(CameraParameters::KEY_PREVIEW_FRAME_RATE,fps/fps_num);
177 mParams.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,fpsrange);
178
179 mParams.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE,fpsrange);
180 mParams.set(CameraParameters::KEY_PREVIEW_FPS_RANGE,fpsrange);
181 }else{
182 mPreviewFrameRate = 15;
183 sprintf(fpsrange,"%s%d","10,",mPreviewFrameRate);
184 CAMHAL_LOGDB("default preview rates is %s\n", fpsrange);
185
186 mParams.set(CameraParameters::KEY_PREVIEW_FRAME_RATE, mPreviewFrameRate);
187 mParams.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,fpsrange);
188
189 mParams.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE,fpsrange);
190 mParams.set(CameraParameters::KEY_PREVIEW_FPS_RANGE,fpsrange);
191 }
192#endif
193
194 writefile((char*)SYSFILE_CAMERA_SET_PARA, (char*)"1");
195 //mirror set at here will not work.
196 LOG_FUNCTION_NAME_EXIT;
197
198 return ret;
199}
200
201status_t V4LCamAdpt::IoctlStateProbe(void)
202{
203 struct v4l2_queryctrl qc;
204 int ret = 0;
205
206 LOG_FUNCTION_NAME;
207
208 mIoctlSupport = 0;
209
210 if(get_hflip_mode(mCameraHandle)==0){
211 mIoctlSupport |= IOCTL_MASK_HFLIP;
212 }else{
213 mIoctlSupport &= ~IOCTL_MASK_HFLIP;
214 }
215
216 memset(&qc, 0, sizeof(struct v4l2_queryctrl));
217 qc.id = V4L2_CID_ZOOM_ABSOLUTE;
218 ret = ioctl (mCameraHandle, VIDIOC_QUERYCTRL, &qc);
219 if((qc.flags == V4L2_CTRL_FLAG_DISABLED) ||( ret < 0)
220 || (qc.type != V4L2_CTRL_TYPE_INTEGER)){
221 mIoctlSupport &= ~IOCTL_MASK_ZOOM;
222 }else{
223 mIoctlSupport |= IOCTL_MASK_ZOOM;
224 }
225
226 memset(&qc, 0, sizeof(struct v4l2_queryctrl));
227 qc.id = V4L2_ROTATE_ID;
228 ret = ioctl (mCameraHandle, VIDIOC_QUERYCTRL, &qc);
229 if((qc.flags == V4L2_CTRL_FLAG_DISABLED) ||( ret < 0)
230 || (qc.type != V4L2_CTRL_TYPE_INTEGER)){
231 mIoctlSupport &= ~IOCTL_MASK_ROTATE;
232 }else{
233 mIoctlSupport |= IOCTL_MASK_ROTATE;
234 }
235
236 if(mIoctlSupport & IOCTL_MASK_ROTATE){
237 CAMHAL_LOGDB("camera %d support capture rotate",mSensorIndex);
238 }
239 mRotateValue = 0;
240
241 memset(&qc, 0, sizeof(struct v4l2_queryctrl));
242 qc.id = V4L2_CID_EXPOSURE;
243
244 ret = ioctl (mCameraHandle, VIDIOC_QUERYCTRL, &qc);
245 if((qc.flags == V4L2_CTRL_FLAG_DISABLED) ||( ret < 0) ){
246 mIoctlSupport &= ~IOCTL_MASK_EXPOSURE;
247 mEVdef = 4;
248 mEVmin = 0;
249 mEVmax = 8;
250 }else{
251 mIoctlSupport |= IOCTL_MASK_EXPOSURE;
252 mEVdef = qc.default_value;
253 mEVmin = qc.minimum;
254 mEVmax = qc.maximum;
255 }
256 mEV = mEVdef;
257
258 memset(&qc, 0, sizeof(struct v4l2_queryctrl));
259 qc.id = V4L2_CID_DO_WHITE_BALANCE;
260
261 ret = ioctl (mCameraHandle, VIDIOC_QUERYCTRL, &qc);
262 if((qc.flags == V4L2_CTRL_FLAG_DISABLED) ||( ret < 0) ){
263 mIoctlSupport &= ~IOCTL_MASK_WB;
264 }else{
265 mIoctlSupport |= IOCTL_MASK_WB;
266 }
267
268 mWhiteBalance = qc.default_value;
269
270 memset(&qc, 0, sizeof(struct v4l2_queryctrl));
271 qc.id = V4L2_CID_BACKLIGHT_COMPENSATION;
272 ret = ioctl (mCameraHandle, VIDIOC_QUERYCTRL, &qc);
273 if((qc.flags == V4L2_CTRL_FLAG_DISABLED) ||( ret < 0)
274 || (qc.type != V4L2_CTRL_TYPE_MENU)){
275 mIoctlSupport &= ~IOCTL_MASK_FLASH;
276 }else{
277 mIoctlSupport |= IOCTL_MASK_FLASH;
278 }
279
280 memset(&qc, 0, sizeof(struct v4l2_queryctrl));
281 qc.id = V4L2_CID_COLORFX;
282 ret = ioctl (mCameraHandle, VIDIOC_QUERYCTRL, &qc);
283 if((qc.flags == V4L2_CTRL_FLAG_DISABLED) ||( ret < 0)
284 || (qc.type != V4L2_CTRL_TYPE_MENU)){
285 mIoctlSupport &= ~IOCTL_MASK_EFFECT;
286 }else{
287 mIoctlSupport |= IOCTL_MASK_EFFECT;
288 }
289
290 memset(&qc, 0, sizeof(struct v4l2_queryctrl));
291 qc.id = V4L2_CID_POWER_LINE_FREQUENCY;
292 ret = ioctl (mCameraHandle, VIDIOC_QUERYCTRL, &qc);
293 if((qc.flags == V4L2_CTRL_FLAG_DISABLED) ||( ret < 0)
294 || (qc.type != V4L2_CTRL_TYPE_MENU)){
295 mIoctlSupport &= ~IOCTL_MASK_BANDING;
296 }else{
297 mIoctlSupport |= IOCTL_MASK_BANDING;
298 }
299 mAntiBanding = qc.default_value;
300
301 memset(&qc, 0, sizeof(struct v4l2_queryctrl));
302 qc.id = V4L2_CID_FOCUS_AUTO;
303 ret = ioctl (mCameraHandle, VIDIOC_QUERYCTRL, &qc);
304 if((qc.flags == V4L2_CTRL_FLAG_DISABLED) ||( ret < 0)
305 || (qc.type != V4L2_CTRL_TYPE_MENU)){
306 mIoctlSupport &= ~IOCTL_MASK_FOCUS;
307 }else{
308 mIoctlSupport |= IOCTL_MASK_FOCUS;
309 }
310
311 memset(&qc, 0, sizeof(struct v4l2_queryctrl));
312 qc.id = V4L2_CID_AUTO_FOCUS_STATUS;
313 ret = ioctl (mCameraHandle, VIDIOC_QUERYCTRL, &qc);
314 if((qc.flags == V4L2_CTRL_FLAG_DISABLED) ||( ret < 0)){
315 mIoctlSupport &= ~IOCTL_MASK_FOCUS_MOVE;
316 }else{
317 mIoctlSupport |= IOCTL_MASK_FOCUS_MOVE;
318 }
319
320 LOG_FUNCTION_NAME_EXIT;
321
322 return ret;
323}
324
325status_t V4LCamAdpt::fillThisBuffer(void* frameBuf, CameraFrame::FrameType frameType)
326{
327
328 status_t ret = NO_ERROR;
329 v4l2_buffer hbuf_query;
330 memset(&hbuf_query,0,sizeof(v4l2_buffer));
331
332 //LOGD("fillThisBuffer frameType=%d", frameType);
333 if (CameraFrame::IMAGE_FRAME == frameType)
334 {
335 //if (NULL != mEndImageCaptureCallback)
336 //mEndImageCaptureCallback(mEndCaptureData);
337 if (NULL != mReleaseImageBuffersCallback)
338 mReleaseImageBuffersCallback(mReleaseData);
339 return NO_ERROR;
340 }
341 if ( !mVideoInfo->isStreaming || !mPreviewing)
342 {
343 return NO_ERROR;
344 }
345
346 int i = mPreviewBufs.valueFor(( unsigned int )frameBuf);
347 if(i<0)
348 {
349 return BAD_VALUE;
350 }
351 if(nQueued>=mPreviewBufferCount)
352 {
353 CAMHAL_LOGEB("fill buffer error, reach the max preview buff:%d,max:%d",
354 nQueued,mPreviewBufferCount);
355 return BAD_VALUE;
356 }
357
358 hbuf_query.index = i;
359 hbuf_query.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
360 hbuf_query.memory = V4L2_MEMORY_MMAP;
361
362 ret = ioctl(mCameraHandle, VIDIOC_QBUF, &hbuf_query);
363 if (ret < 0) {
364 CAMHAL_LOGEB("Init: VIDIOC_QBUF %d Failed, errno=%d\n",i, errno);
365 return -1;
366 }
367 //CAMHAL_LOGEB("fillThis Buffer %d",i);
368 nQueued++;
369 return ret;
370
371}
372
373status_t V4LCamAdpt::setParameters(const CameraParameters &params)
374{
375 LOG_FUNCTION_NAME;
376
377 status_t rtn = NO_ERROR;
378
379 // Update the current parameter set
380 mParams = params;
381
382 //check zoom value
383 int zoom = mParams.getInt(CameraParameters::KEY_ZOOM);
384 int maxzoom = mParams.getInt(CameraParameters::KEY_MAX_ZOOM);
385 char *p = (char *)mParams.get(CameraParameters::KEY_ZOOM_RATIOS);
386
387 if(zoom > maxzoom){
388 rtn = INVALID_OPERATION;
389 CAMHAL_LOGEB("Zoom Parameter Out of range1------zoom level:%d,max level:%d",zoom,maxzoom);
390 zoom = maxzoom;
391 mParams.set((const char*)CameraParameters::KEY_ZOOM, maxzoom);
392 }else if(zoom <0) {
393 rtn = INVALID_OPERATION;
394 zoom = 0;
395 CAMHAL_LOGEB("Zoom Parameter Out of range2------zoom level:%d,max level:%d",zoom,maxzoom);
396 mParams.set((const char*)CameraParameters::KEY_ZOOM, zoom);
397 }
398
399 if ((p) && (zoom >= 0)&&(zoom!=mZoomlevel)) {
400 int z = (int)strtol(p, &p, 10);
401 int i = 0;
402 while (i < zoom) {
403 if (*p != ',') break;
404 z = (int)strtol(p+1, &p, 10);
405 i++;
406 }
407 CAMHAL_LOGDB("Change the zoom level---old:%d,new:%d",mZoomlevel,zoom);
408 mZoomlevel = zoom;
409 if(mIoctlSupport & IOCTL_MASK_ZOOM)
410 set_zoom_level(mCameraHandle,z);
411 notifyZoomSubscribers((mZoomlevel<0)?0:mZoomlevel,true);
412 }
413
414 int min_fps,max_fps;
415 const char *white_balance=NULL;
416 const char *exposure=NULL;
417 const char *effect=NULL;
418 //const char *night_mode=NULL;
419 const char *qulity=NULL;
420 const char *banding=NULL;
421 const char *flashmode=NULL;
422 const char *focusmode=NULL;
423 const char *supportfocusmode=NULL;
424
425 qulity=mParams.get(CameraParameters::KEY_JPEG_QUALITY);
426
427 flashmode = mParams.get(CameraParameters::KEY_FLASH_MODE);
428 if((mIoctlSupport & IOCTL_MASK_FLASH) && flashmode){
429 if(strcasecmp(flashmode, "torch")==0){
430 set_flash_mode(mCameraHandle, flashmode);
431 mFlashMode = FLASHLIGHT_TORCH;
432 }else if(strcasecmp(flashmode, "on")==0){
433 if( FLASHLIGHT_TORCH == mFlashMode){
434 set_flash_mode(mCameraHandle, "off");
435 }
436 mFlashMode = FLASHLIGHT_ON;
437 }else if(strcasecmp(flashmode, "off")==0){
438 set_flash_mode(mCameraHandle, flashmode);
439 mFlashMode = FLASHLIGHT_OFF;
440 }
441 }
442
443 exposure=mParams.get(CameraParameters::KEY_EXPOSURE_COMPENSATION);
444 if( (mIoctlSupport & IOCTL_MASK_EXPOSURE) && exposure){
445 SetExposure(mCameraHandle,exposure);
446 }
447
448 white_balance=mParams.get(CameraParameters::KEY_WHITE_BALANCE);
449 if((mIoctlSupport & IOCTL_MASK_WB) && white_balance){
450 set_white_balance(mCameraHandle,white_balance);
451 }
452
453 effect=mParams.get(CameraParameters::KEY_EFFECT);
454 if( (mIoctlSupport & IOCTL_MASK_EFFECT) && effect){
455 set_effect(mCameraHandle,effect);
456 }
457
458 banding=mParams.get(CameraParameters::KEY_ANTIBANDING);
459 if((mIoctlSupport & IOCTL_MASK_BANDING) && banding){
460 set_banding(mCameraHandle,banding);
461 }
462
463 focusmode = mParams.get(CameraParameters::KEY_FOCUS_MODE);
464 if(focusmode) {
465 if(strcasecmp(focusmode,"fixed")==0)
466 cur_focus_mode = CAM_FOCUS_MODE_FIXED;
467 else if(strcasecmp(focusmode,"auto")==0)
468 cur_focus_mode = CAM_FOCUS_MODE_AUTO;
469 else if(strcasecmp(focusmode,"infinity")==0)
470 cur_focus_mode = CAM_FOCUS_MODE_INFINITY;
471 else if(strcasecmp(focusmode,"macro")==0)
472 cur_focus_mode = CAM_FOCUS_MODE_MACRO;
473 else if(strcasecmp(focusmode,"edof")==0)
474 cur_focus_mode = CAM_FOCUS_MODE_EDOF;
475 else if(strcasecmp(focusmode,"continuous-video")==0)
476 cur_focus_mode = CAM_FOCUS_MODE_CONTI_VID;
477 else if(strcasecmp(focusmode,"continuous-picture")==0)
478 cur_focus_mode = CAM_FOCUS_MODE_CONTI_PIC;
479 else
480 cur_focus_mode = CAM_FOCUS_MODE_FIXED;
481 }
482 supportfocusmode = mParams.get(CameraParameters::KEY_SUPPORTED_FOCUS_MODES);
483 if( NULL != strstr(supportfocusmode, "continuous")){
484 if(CAM_FOCUS_MODE_AUTO != cur_focus_mode_for_conti){
485 struct v4l2_control ctl;
486 if( (CAM_FOCUS_MODE_CONTI_VID != cur_focus_mode_for_conti ) &&
487 ( (CAM_FOCUS_MODE_AUTO == cur_focus_mode )
488 ||( CAM_FOCUS_MODE_CONTI_PIC == cur_focus_mode )
489 ||( CAM_FOCUS_MODE_CONTI_VID == cur_focus_mode ) )){
490 mEnableContiFocus = true;
491 ctl.id = V4L2_CID_FOCUS_AUTO;
492 ctl.value = CAM_FOCUS_MODE_CONTI_VID;
493 if(ioctl(mCameraHandle, VIDIOC_S_CTRL, &ctl)<0){
494 CAMHAL_LOGDA("failed to set CAM_FOCUS_MODE_CONTI_VID!\n");
495 }
496 mFocusWaitCount = FOCUS_PROCESS_FRAMES;
497 bFocusMoveState = true;
498 cur_focus_mode_for_conti = CAM_FOCUS_MODE_CONTI_VID;
499 }else if( (CAM_FOCUS_MODE_CONTI_VID != cur_focus_mode_for_conti)&&
500 (CAM_FOCUS_MODE_AUTO != cur_focus_mode) &&
501 ( CAM_FOCUS_MODE_CONTI_PIC != cur_focus_mode )&&
502 ( CAM_FOCUS_MODE_CONTI_VID != cur_focus_mode )){
503 mEnableContiFocus = false;
504 ctl.id = V4L2_CID_FOCUS_AUTO;
505 ctl.value = CAM_FOCUS_MODE_RELEASE;
506 if(ioctl(mCameraHandle, VIDIOC_S_CTRL, &ctl)<0){
507 CAMHAL_LOGDA("failed to set CAM_FOCUS_MODE_RELEASE!\n");
508 }
509 cur_focus_mode_for_conti = CAM_FOCUS_MODE_RELEASE;
510 }else if( (CAM_FOCUS_MODE_INFINITY != cur_focus_mode_for_conti)&&
511 (CAM_FOCUS_MODE_INFINITY == cur_focus_mode) ){
512 mEnableContiFocus = false;
513 ctl.id = V4L2_CID_FOCUS_AUTO;
514 ctl.value = CAM_FOCUS_MODE_INFINITY;
515 if(ioctl(mCameraHandle, VIDIOC_S_CTRL, &ctl)<0){
516 CAMHAL_LOGDA("failed to set CAM_FOCUS_MODE_INFINITY!\n");
517 }
518 cur_focus_mode_for_conti = CAM_FOCUS_MODE_INFINITY;
519 }
520 }
521 }else{
522 mEnableContiFocus = false;
523 CAMHAL_LOGDA("not support continuous mode!\n");
524 }
525
526 mParams.getPreviewFpsRange(&min_fps, &max_fps);
527 if((min_fps<0)||(max_fps<0)||(max_fps<min_fps))
528 {
529 rtn = INVALID_OPERATION;
530 }
531
532 LOG_FUNCTION_NAME_EXIT;
533 return rtn;
534}
535
536
537void V4LCamAdpt::getParameters(CameraParameters& params)
538{
539 LOG_FUNCTION_NAME;
540
541 // Return the current parameter set
542 //params = mParams;
543 //that won't work. we might wipe out the existing params
544
545 LOG_FUNCTION_NAME_EXIT;
546}
547
548
549///API to give the buffers to Adapter
550status_t V4LCamAdpt::useBuffers(CameraMode mode, void* bufArr, int num, size_t length, unsigned int queueable)
551{
552 status_t ret = NO_ERROR;
553
554 LOG_FUNCTION_NAME;
555
556 Mutex::Autolock lock(mLock);
557
558 switch(mode)
559 {
560 case CAMERA_PREVIEW:
561 ret = UseBuffersPreview(bufArr, num);
562 //maxQueueable = queueable;
563 break;
564 case CAMERA_IMAGE_CAPTURE:
565 ret = UseBuffersCapture(bufArr, num);
566 break;
567 case CAMERA_VIDEO:
568 //@warn Video capture is not fully supported yet
569 ret = UseBuffersPreview(bufArr, num);
570 //maxQueueable = queueable;
571 break;
572 default:
573 break;
574 }
575
576 LOG_FUNCTION_NAME_EXIT;
577
578 return ret;
579}
580
581status_t V4LCamAdpt::setBuffersFormat(int width, int height, int pixelformat)
582{
583 int ret = NO_ERROR;
584 CAMHAL_LOGDB("Width * Height %d x %d format 0x%x", width, height, pixelformat);
585
586 mVideoInfo->width = width;
587 mVideoInfo->height = height;
588 mVideoInfo->framesizeIn = (width * height << 1);
589 mVideoInfo->formatIn = pixelformat;
590
591 mVideoInfo->format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
592 mVideoInfo->format.fmt.pix.width = width;
593 mVideoInfo->format.fmt.pix.height = height;
594 mVideoInfo->format.fmt.pix.pixelformat = pixelformat;
595
596 ret = ioctl(mCameraHandle, VIDIOC_S_FMT, &mVideoInfo->format);
597 if (ret < 0) {
598 CAMHAL_LOGEB("Open: VIDIOC_S_FMT Failed: %s", strerror(errno));
599 return ret;
600 }
601
602 return ret;
603}
604
605status_t V4LCamAdpt::getBuffersFormat(int &width, int &height, int &pixelformat)
606{
607 int ret = NO_ERROR;
608 struct v4l2_format format;
609
610 memset(&format, 0,sizeof(struct v4l2_format));
611
612 format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
613 ret = ioctl(mCameraHandle, VIDIOC_G_FMT, &format);
614 if (ret < 0) {
615 CAMHAL_LOGDB("Open: VIDIOC_G_FMT Failed: %s", strerror(errno));
616 return ret;
617 }
618 width = format.fmt.pix.width;
619 height = format.fmt.pix.height;
620 pixelformat = format.fmt.pix.pixelformat;
621 CAMHAL_LOGDB("VIDIOC_G_FMT,W*H: %5d x %5d format 0x%x",
622 width, height, pixelformat);
623 return ret;
624}
625
626status_t V4LCamAdpt::UseBuffersPreview(void* bufArr, int num)
627{
628 int ret = NO_ERROR;
629
630 if(NULL == bufArr)
631 {
632 return BAD_VALUE;
633 }
634
635 int width, height;
636 mParams.getPreviewSize(&width, &height);
637
638 mPreviewWidth = width;
639 mPreviewHeight = height;
640
641 const char *pixfmtchar;
642 int pixfmt = V4L2_PIX_FMT_NV21;
643
644 pixfmtchar = mParams.getPreviewFormat();
645 if(strcasecmp( pixfmtchar, "yuv420p")==0){
646 pixfmt = V4L2_PIX_FMT_YVU420;
647 mPixelFormat =CameraFrame::PIXEL_FMT_YV12;
648 }else if(strcasecmp( pixfmtchar, "yuv420sp")==0){
649 pixfmt = V4L2_PIX_FMT_NV21;
650 mPixelFormat = CameraFrame::PIXEL_FMT_NV21;
651 }else if(strcasecmp( pixfmtchar, "yuv422")==0){
652 pixfmt = V4L2_PIX_FMT_YUYV;
653 mPixelFormat = CameraFrame::PIXEL_FMT_YUYV;
654 }
655
656 setBuffersFormat(width, height, pixfmt);
657 //First allocate adapter internal buffers at V4L level for USB Cam
658 //These are the buffers from which we will copy the data into overlay buffers
659 /* Check if camera can handle NB_BUFFER buffers */
660 mVideoInfo->rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
661 mVideoInfo->rb.memory = V4L2_MEMORY_MMAP;
662 mVideoInfo->rb.count = num;
663
664 ret = ioctl(mCameraHandle, VIDIOC_REQBUFS, &mVideoInfo->rb);
665 if (ret < 0) {
666 CAMHAL_LOGEB("VIDIOC_REQBUFS failed: %s", strerror(errno));
667 return ret;
668 }
669
670 for (int i = 0; i < num; i++) {
671
672 memset (&mVideoInfo->buf, 0, sizeof (struct v4l2_buffer));
673
674 mVideoInfo->buf.index = i;
675 mVideoInfo->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
676 mVideoInfo->buf.memory = V4L2_MEMORY_MMAP;
677
678 ret = ioctl (mCameraHandle, VIDIOC_QUERYBUF, &mVideoInfo->buf);
679 if (ret < 0) {
680 CAMHAL_LOGEB("Unable to query buffer (%s)", strerror(errno));
681 return ret;
682 }
683
684 mVideoInfo->mem[i] = mmap (0,
685 mVideoInfo->buf.length,
686 PROT_READ | PROT_WRITE,
687 MAP_SHARED,
688 mCameraHandle,
689 mVideoInfo->buf.m.offset);
690
691 if (mVideoInfo->mem[i] == MAP_FAILED) {
692 CAMHAL_LOGEB("Unable to map buffer (%s)", strerror(errno));
693 return -1;
694 }
695
696 uint32_t *ptr = (uint32_t*) bufArr;
697
698 //Associate each Camera internal buffer with the one from Overlay
699 CAMHAL_LOGDB("mPreviewBufs.add %#x, %d", ptr[i], i);
700 mPreviewBufs.add((int)ptr[i], i);
701
702 }
703
704 for(int i = 0;i < num; i++)
705 {
706 mPreviewIdxs.add(mPreviewBufs.valueAt(i),i);
707 }
708
709 // Update the preview buffer count
710 mPreviewBufferCount = num;
711
712 return ret;
713}
714
715status_t V4LCamAdpt::UseBuffersCapture(void* bufArr, int num)
716{
717 int ret = NO_ERROR;
718
719 if(NULL == bufArr)
720 {
721 return BAD_VALUE;
722 }
723
724 if (num != 1)
725 {
726 CAMHAL_LOGDB("num=%d", num);
727 }
728
729 /* This will only be called right before taking a picture, so
730 * stop preview now so that we can set buffer format here.
731 */
732 this->stopPreview();
733
734 int width, height;
735 mParams.getPictureSize(&width, &height);
736 mCaptureWidth = width;
737 mCaptureHeight = height;
738
739 if(mIoctlSupport & IOCTL_MASK_ROTATE){
740 int temp = 0;
741 mRotateValue = mParams.getInt(CameraParameters::KEY_ROTATION);
742 if((mRotateValue!=0)&&(mRotateValue!=90)&&(mRotateValue!=180)&&(mRotateValue!=270))
743 mRotateValue = 0;
744 if((mRotateValue==90)||(mRotateValue==270)){
745 temp = width;
746 width = height;
747 height = temp;
748 }
749 }
750 setBuffersFormat(width, height, DEFAULT_IMAGE_CAPTURE_PIXEL_FORMAT);
751
752 //First allocate adapter internal buffers at V4L level for Cam
753 //These are the buffers from which we will copy the data into display buffers
754 /* Check if camera can handle NB_BUFFER buffers */
755 mVideoInfo->rb.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
756 mVideoInfo->rb.memory = V4L2_MEMORY_MMAP;
757 mVideoInfo->rb.count = num;
758
759 ret = ioctl(mCameraHandle, VIDIOC_REQBUFS, &mVideoInfo->rb);
760 if (ret < 0) {
761 CAMHAL_LOGEB("VIDIOC_REQBUFS failed: %s", strerror(errno));
762 return ret;
763 }
764
765 for (int i = 0; i < num; i++) {
766
767 memset (&mVideoInfo->buf, 0, sizeof (struct v4l2_buffer));
768
769 mVideoInfo->buf.index = i;
770 mVideoInfo->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
771 mVideoInfo->buf.memory = V4L2_MEMORY_MMAP;
772
773 ret = ioctl (mCameraHandle, VIDIOC_QUERYBUF, &mVideoInfo->buf);
774 if (ret < 0) {
775 CAMHAL_LOGEB("Unable to query buffer (%s)", strerror(errno));
776 return ret;
777 }
778
779 mVideoInfo->mem[i] = mmap (0,
780 mVideoInfo->buf.length,
781 PROT_READ | PROT_WRITE,
782 MAP_SHARED,
783 mCameraHandle,
784 mVideoInfo->buf.m.offset);
785
786 if (mVideoInfo->mem[i] == MAP_FAILED) {
787 CAMHAL_LOGEB("Unable to map buffer (%s)", strerror(errno));
788 return -1;
789 }
790
791 uint32_t *ptr = (uint32_t*) bufArr;
792 CAMHAL_LOGDB("UseBuffersCapture %#x", ptr[0]);
793 mCaptureBuf = (camera_memory_t*)ptr[0];
794 }
795
796 return ret;
797}
798
799status_t V4LCamAdpt::takePicture()
800{
801 LOG_FUNCTION_NAME;
802 if (createThread(beginPictureThread, this) == false)
803 return -1;
804 LOG_FUNCTION_NAME_EXIT;
805 return NO_ERROR;
806}
807
808
809int V4LCamAdpt::beginAutoFocusThread(void *cookie)
810{
811 V4LCamAdpt *c = (V4LCamAdpt *)cookie;
812 struct v4l2_control ctl;
813 int ret = -1;
814
815 if( c->mIoctlSupport & IOCTL_MASK_FOCUS){
816 ctl.id = V4L2_CID_FOCUS_AUTO;
817 ctl.value = CAM_FOCUS_MODE_AUTO;//c->cur_focus_mode;
818 ret = ioctl(c->mCameraHandle, VIDIOC_S_CTRL, &ctl);
819 for(int j=0; j<50; j++){
820 usleep(30000);//30*50ms=1.5s
821 ret = ioctl(c->mCameraHandle, VIDIOC_G_CTRL, &ctl);
822 if( (0==ret) ||
823 ((ret < 0)&&(EBUSY != errno)) ){
824 break;
825 }
826 }
827 }
828
829 c->setState(CAMERA_CANCEL_AUTOFOCUS);
830 c->commitState();
831
832 if( (c->mIoctlSupport & IOCTL_MASK_FLASH)
833 &&(FLASHLIGHT_ON == c->mFlashMode)){
834 c->set_flash_mode( c->mCameraHandle, "off");
835 }
836 if(ret < 0) {
837 if( c->mIoctlSupport & IOCTL_MASK_FOCUS){
838 CAMHAL_LOGDA("AUTO FOCUS Failed");
839 }
840 c->notifyFocusSubscribers(false);
841 } else {
842 c->notifyFocusSubscribers(true);
843 }
844 // may need release auto focus mode at here.
845 return ret;
846}
847
848status_t V4LCamAdpt::autoFocus()
849{
850 status_t ret = NO_ERROR;
851
852 LOG_FUNCTION_NAME;
853
854 if( (mIoctlSupport & IOCTL_MASK_FLASH)
855 &&(FLASHLIGHT_ON == mFlashMode)){
856 set_flash_mode( mCameraHandle, "on");
857 }
858 cur_focus_mode_for_conti = CAM_FOCUS_MODE_AUTO;
859 if (createThread(beginAutoFocusThread, this) == false)
860 {
861 ret = UNKNOWN_ERROR;
862 }
863
864 LOG_FUNCTION_NAME_EXIT;
865
866 return ret;
867}
868
869
870status_t V4LCamAdpt::cancelAutoFocus()
871{
872 status_t ret = NO_ERROR;
873
874 LOG_FUNCTION_NAME;
875 struct v4l2_control ctl;
876
877 if( (mIoctlSupport & IOCTL_MASK_FOCUS) == 0x00 ){
878 return 0;
879 }
880
881 if ( !mEnableContiFocus){
882 ctl.id = V4L2_CID_FOCUS_AUTO;
883 ctl.value = CAM_FOCUS_MODE_RELEASE;
884 ret = ioctl(mCameraHandle, VIDIOC_S_CTRL, &ctl);
885 if(ret < 0) {
886 CAMHAL_LOGDA("AUTO FOCUS Failed");
887 }
888 }else if( CAM_FOCUS_MODE_AUTO == cur_focus_mode_for_conti){
889 if(CAM_FOCUS_MODE_INFINITY != cur_focus_mode){
890 ctl.id = V4L2_CID_FOCUS_AUTO;
891 ctl.value = CAM_FOCUS_MODE_CONTI_VID;
892 if(ioctl(mCameraHandle, VIDIOC_S_CTRL, &ctl)<0){
893 CAMHAL_LOGDA("failed to set CAM_FOCUS_MODE_CONTI_VID\n");
894 }
895 cur_focus_mode_for_conti = CAM_FOCUS_MODE_CONTI_VID;
896 }else{
897 ctl.id = V4L2_CID_FOCUS_AUTO;
898 ctl.value = CAM_FOCUS_MODE_INFINITY;
899 if(ioctl(mCameraHandle, VIDIOC_S_CTRL, &ctl)<0){
900 CAMHAL_LOGDA("failed to set CAM_FOCUS_MODE_INFINITY\n");
901 }
902 cur_focus_mode_for_conti = CAM_FOCUS_MODE_INFINITY;
903 }
904 }
905 LOG_FUNCTION_NAME_EXIT;
906
907 return ret;
908}
909
910status_t V4LCamAdpt::startPreview()
911{
912 status_t ret = NO_ERROR;
913 int frame_count = 0,ret_c = 0;
914 void *frame_buf = NULL;
915 Mutex::Autolock lock(mPreviewBufsLock);
916
917 if(mPreviewing)
918 {
919 return BAD_VALUE;
920 }
921
922 setMirrorEffect();
923
924 if(mIoctlSupport & IOCTL_MASK_ROTATE){
925 set_rotate_value(mCameraHandle,0);
926 mRotateValue = 0;
927 }
928
929 nQueued = 0;
930 for (int i = 0; i < mPreviewBufferCount; i++)
931 {
932 frame_count = -1;
933 frame_buf = (void *)mPreviewBufs.keyAt(i);
934
935 if((ret_c = getFrameRefCount(frame_buf,CameraFrame::PREVIEW_FRAME_SYNC))>=0)
936 frame_count = ret_c;
937
938 //if((ret_c = getFrameRefCount(frame_buf,CameraFrame::VIDEO_FRAME_SYNC))>=0)
939 // frame_count += ret_c;
940
941 CAMHAL_LOGDB("startPreview--buffer address:0x%x, refcount:%d",
942 (uint32_t)frame_buf,frame_count);
943 if(frame_count>0)
944 continue;
945 //mVideoInfo->buf.index = i;
946 mVideoInfo->buf.index = mPreviewBufs.valueFor((uint32_t)frame_buf);
947 mVideoInfo->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
948 mVideoInfo->buf.memory = V4L2_MEMORY_MMAP;
949
950 ret = ioctl(mCameraHandle, VIDIOC_QBUF, &mVideoInfo->buf);
951 if (ret < 0) {
952 CAMHAL_LOGEA("VIDIOC_QBUF Failed");
953 return -EINVAL;
954 }
955 CAMHAL_LOGDB("startPreview --length=%d, index:%d",
956 mVideoInfo->buf.length,mVideoInfo->buf.index);
957 nQueued++;
958 }
959
960 enum v4l2_buf_type bufType;
961 if (!mVideoInfo->isStreaming)
962 {
963 bufType = V4L2_BUF_TYPE_VIDEO_CAPTURE;
964#ifdef AMLOGIC_VCAM_NONBLOCK_SUPPORT
965 gettimeofday( &previewTime1, NULL);
966#endif
967 ret = ioctl (mCameraHandle, VIDIOC_STREAMON, &bufType);
968 if (ret < 0) {
969 CAMHAL_LOGEB("StartStreaming: Unable to start capture: %s", strerror(errno));
970 return ret;
971 }
972
973 mVideoInfo->isStreaming = true;
974 }
975
976 if( mEnableContiFocus &&
977 (CAM_FOCUS_MODE_AUTO != cur_focus_mode_for_conti) &&
978 (CAM_FOCUS_MODE_INFINITY != cur_focus_mode_for_conti)){
979 struct v4l2_control ctl;
980 ctl.id = V4L2_CID_FOCUS_AUTO;
981 ctl.value = CAM_FOCUS_MODE_CONTI_VID;
982 if(ioctl(mCameraHandle, VIDIOC_S_CTRL, &ctl)<0){
983 CAMHAL_LOGDA("failed to set CAM_FOCUS_MODE_CONTI_VID!\n");
984 }
985 cur_focus_mode_for_conti = CAM_FOCUS_MODE_CONTI_VID;
986 }
987 // Create and start preview thread for receiving buffers from V4L Camera
988 mPreviewThread = new PreviewThread(this);
989 CAMHAL_LOGDA("Created preview thread");
990 //Update the flag to indicate we are previewing
991 mPreviewing = true;
992 return ret;
993}
994
995status_t V4LCamAdpt::stopPreview()
996{
997 enum v4l2_buf_type bufType;
998 int ret = NO_ERROR;
999
1000 Mutex::Autolock lock(mPreviewBufsLock);
1001 if(!mPreviewing)
1002 {
1003 return NO_INIT;
1004 }
1005
1006 mPreviewing = false;
1007 mFocusMoveEnabled = false;
1008 mPreviewThread->requestExitAndWait();
1009 mPreviewThread.clear();
1010
1011
1012 CAMHAL_LOGDA("stopPreview streamoff..\n");
1013 if (mVideoInfo->isStreaming) {
1014 bufType = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1015
1016 ret = ioctl (mCameraHandle, VIDIOC_STREAMOFF, &bufType);
1017 if (ret < 0) {
1018 CAMHAL_LOGEB("StopStreaming: Unable to stop capture: %s", strerror(errno));
1019 return ret;
1020 }
1021
1022 mVideoInfo->isStreaming = false;
1023 }
1024
1025 mVideoInfo->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1026 mVideoInfo->buf.memory = V4L2_MEMORY_MMAP;
1027
1028 nQueued = 0;
1029 nDequeued = 0;
1030
1031 if( mEnableContiFocus &&
1032 (CAM_FOCUS_MODE_AUTO != cur_focus_mode_for_conti) &&
1033 (CAM_FOCUS_MODE_INFINITY != cur_focus_mode_for_conti)){
1034 struct v4l2_control ctl;
1035 ctl.id = V4L2_CID_FOCUS_AUTO;
1036 ctl.value = CAM_FOCUS_MODE_RELEASE;
1037 if(ioctl(mCameraHandle, VIDIOC_S_CTRL, &ctl)<0){
1038 CAMHAL_LOGDA("failed to set CAM_FOCUS_MODE_RELEASE!\n");
1039 }
1040 cur_focus_mode_for_conti = CAM_FOCUS_MODE_RELEASE;
1041 }
1042
1043 /* Unmap buffers */
1044 for (int i = 0; i < mPreviewBufferCount; i++){
1045 if (munmap(mVideoInfo->mem[i], mVideoInfo->buf.length) < 0){
1046 CAMHAL_LOGEA("Unmap failed");
1047 }
1048
1049 }
1050
1051 mPreviewBufs.clear();
1052 mPreviewIdxs.clear();
1053 return ret;
1054
1055}
1056
1057char * V4LCamAdpt::GetFrame(int &index)
1058{
1059 int ret;
1060
1061 if(nQueued<=0){
1062 CAMHAL_LOGEA("GetFrame: No buff for Dequeue");
1063 return NULL;
1064 }
1065 mVideoInfo->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1066 mVideoInfo->buf.memory = V4L2_MEMORY_MMAP;
1067
1068 /* DQ */
1069 ret = ioctl(mCameraHandle, VIDIOC_DQBUF, &mVideoInfo->buf);
1070 if (ret < 0) {
1071 if(EAGAIN == errno){
1072 index = -1;
1073 }else{
1074 CAMHAL_LOGEB("GetFrame: VIDIOC_DQBUF Failed,errno=%d\n",errno);
1075 }
1076 return NULL;
1077 }
1078 nDequeued++;
1079 nQueued--;
1080 index = mVideoInfo->buf.index;
1081
1082 return (char *)mVideoInfo->mem[mVideoInfo->buf.index];
1083}
1084
1085//API to get the frame size required to be allocated. This size is used to override the size passed
1086//by camera service when VSTAB/VNF is turned ON for example
1087status_t V4LCamAdpt::getFrameSize(size_t &width, size_t &height)
1088{
1089 status_t ret = NO_ERROR;
1090
1091 // Just return the current preview size, nothing more to do here.
1092 mParams.getPreviewSize(( int * ) &width,
1093 ( int * ) &height);
1094
1095 LOG_FUNCTION_NAME_EXIT;
1096
1097 return ret;
1098}
1099
1100status_t V4LCamAdpt::getFrameDataSize(size_t &dataFrameSize, size_t bufferCount)
1101{
1102 // We don't support meta data, so simply return
1103 return NO_ERROR;
1104}
1105
1106status_t V4LCamAdpt::getPictureBufferSize(size_t &length, size_t bufferCount)
1107{
1108 int width, height;
1109 mParams.getPictureSize(&width, &height);
1110 if(DEFAULT_IMAGE_CAPTURE_PIXEL_FORMAT == V4L2_PIX_FMT_RGB24){ // rgb24
1111 length = width * height * 3;
1112 }else if(DEFAULT_IMAGE_CAPTURE_PIXEL_FORMAT == V4L2_PIX_FMT_YUYV){ // 422I
1113 length = width * height * 2;
1114 }else if(DEFAULT_IMAGE_CAPTURE_PIXEL_FORMAT == V4L2_PIX_FMT_NV21){
1115 length = width * height * 3/2;
1116 }else{
1117 length = width * height * 3;
1118 }
1119 return NO_ERROR;
1120}
1121
1122static void debugShowFPS()
1123{
1124 static int mFrameCount = 0;
1125 static int mLastFrameCount = 0;
1126 static nsecs_t mLastFpsTime = 0;
1127 static float mFps = 0;
1128 mFrameCount++;
1129 if (!(mFrameCount & 0x1F)) {
1130 nsecs_t now = systemTime();
1131 nsecs_t diff = now - mLastFpsTime;
1132 mFps = ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
1133 mLastFpsTime = now;
1134 mLastFrameCount = mFrameCount;
1135 CAMHAL_LOGDB("Camera %d Frames, %f FPS", mFrameCount, mFps);
1136 }
1137 // XXX: mFPS has the value we want
1138}
1139
1140status_t V4LCamAdpt::recalculateFPS()
1141{
1142 float currentFPS;
1143
1144 mFrameCount++;
1145
1146 if ( ( mFrameCount % FPS_PERIOD ) == 0 )
1147 {
1148 nsecs_t now = systemTime();
1149 nsecs_t diff = now - mLastFPSTime;
1150 currentFPS = ((mFrameCount - mLastFrameCount) * float(s2ns(1))) / diff;
1151 mLastFPSTime = now;
1152 mLastFrameCount = mFrameCount;
1153
1154 if ( 1 == mIter )
1155 {
1156 mFPS = currentFPS;
1157 }
1158 else
1159 {
1160 //cumulative moving average
1161 mFPS = mLastFPS + (currentFPS - mLastFPS)/mIter;
1162 }
1163
1164 mLastFPS = mFPS;
1165 mIter++;
1166 }
1167
1168 return NO_ERROR;
1169}
1170
1171void V4LCamAdpt::onOrientationEvent(uint32_t orientation, uint32_t tilt)
1172{
1173 //LOG_FUNCTION_NAME;
1174
1175 //LOG_FUNCTION_NAME_EXIT;
1176}
1177
1178
1179V4LCamAdpt::V4LCamAdpt(size_t sensor_index)
1180{
1181 LOG_FUNCTION_NAME;
1182
1183 mbDisableMirror = false;
1184 mSensorIndex = sensor_index;
1185 mCameraHandle = -1;
1186
1187#ifdef AMLOGIC_TWO_CH_UVC
1188 mCamEncodeHandle = -1;
1189#endif
1190 CAMHAL_LOGDB("mVideoInfo=%p\n", mVideoInfo);
1191 mVideoInfo = NULL;
1192
1193 LOG_FUNCTION_NAME_EXIT;
1194}
1195
1196V4LCamAdpt::~V4LCamAdpt()
1197{
1198 LOG_FUNCTION_NAME;
1199
1200 // Close the camera handle and free the video info structure
1201 close(mCameraHandle);
1202#ifdef AMLOGIC_TWO_CH_UVC
1203 if(mCamEncodeHandle > 0){
1204 close(mCamEncodeHandle);
1205 }
1206#endif
1207
1208 if (mVideoInfo)
1209 {
1210 free(mVideoInfo);
1211 mVideoInfo = NULL;
1212 }
1213
1214 LOG_FUNCTION_NAME_EXIT;
1215}
1216
1217/* Preview Thread */
1218// ---------------------------------------------------------------------------
1219
1220int V4LCamAdpt::previewThread()
1221{
1222 status_t ret = NO_ERROR;
1223 int width, height;
1224 CameraFrame frame;
1225 unsigned delay;
1226 unsigned uFrameInvals;
1227
1228 if (mPreviewing)
1229 {
1230 int index = 0;
1231
1232#ifdef AMLOGIC_VCAM_NONBLOCK_SUPPORT
1233 uFrameInvals = (unsigned)(1000000.0f / float(mPreviewFrameRate));
1234 delay = uFrameInvals >>2;
1235#else
1236 int previewFrameRate = mParams.getPreviewFrameRate();
1237 delay = (unsigned)(1000000.0f / float(previewFrameRate));
1238#endif
1239
1240#ifdef AMLOGIC_USB_CAMERA_DECREASE_FRAMES
1241 usleep(delay*5);
1242#else
1243 usleep(delay);
1244#endif
1245
1246 char *fp = this->GetFrame(index);
1247#ifdef AMLOGIC_VCAM_NONBLOCK_SUPPORT
1248 if((-1==index)||!fp)
1249 {
1250 return 0;
1251 }
1252#else
1253 if(!fp){
1254 int previewFrameRate = mParams.getPreviewFrameRate();
1255 delay = (unsigned)(1000000.0f / float(previewFrameRate)) >> 1;
1256 CAMHAL_LOGEB("Preview thread get frame fail, need sleep:%d",delay);
1257 usleep(delay);
1258 return BAD_VALUE;
1259 }
1260#endif
1261
1262 uint8_t* ptr = (uint8_t*) mPreviewBufs.keyAt(mPreviewIdxs.valueFor(index));
1263
1264 if (!ptr)
1265 {
1266 CAMHAL_LOGEA("Preview thread mPreviewBufs error!");
1267 return BAD_VALUE;
1268 }
1269
1270#ifdef AMLOGIC_VCAM_NONBLOCK_SUPPORT
1271 gettimeofday( &previewTime2, NULL);
1272 unsigned bwFrames = previewTime2.tv_sec - previewTime1.tv_sec;
1273 bwFrames = bwFrames*1000000 + previewTime2.tv_usec -previewTime1.tv_usec;
1274 if( bwFrames + 10000 < uFrameInvals ) {
1275 //cts left 20ms(Android 4.1), we left 10ms, Android may cut this 20ms;
1276 CAMHAL_LOGDB("bwFrames=%d, uFrameInvals=%d\n", bwFrames, uFrameInvals);
1277 fillThisBuffer( ptr, CameraFrame::PREVIEW_FRAME_SYNC);
1278 return 0;
1279 }else{
1280 memcpy( &previewTime1, &previewTime2, sizeof( struct timeval));
1281 }
1282#endif
1283
1284 uint8_t* dest = NULL;
1285#ifdef AMLOGIC_CAMERA_OVERLAY_SUPPORT
1286 camera_memory_t* VideoCameraBufferMemoryBase = (camera_memory_t*)ptr;
1287 dest = (uint8_t*)VideoCameraBufferMemoryBase->data; //ptr;
1288#else
1289 private_handle_t* gralloc_hnd = (private_handle_t*)ptr;
1290 dest = (uint8_t*)gralloc_hnd->base; //ptr;
1291#endif
1292 int width, height;
1293 uint8_t* src = (uint8_t*) fp;
1294 if((mPreviewWidth <= 0)||(mPreviewHeight <= 0)){
1295 mParams.getPreviewSize(&width, &height);
1296 }else{
1297 width = mPreviewWidth;
1298 height = mPreviewHeight;
1299 }
1300
1301 if(DEFAULT_PREVIEW_PIXEL_FORMAT == V4L2_PIX_FMT_YUYV){ // 422I
1302 frame.mLength = width*height*2;
1303 memcpy(dest,src,frame.mLength);
1304 }else if(DEFAULT_PREVIEW_PIXEL_FORMAT == V4L2_PIX_FMT_NV21){ //420sp
1305 frame.mLength = width*height*3/2;
1306 if ( CameraFrame::PIXEL_FMT_NV21 == mPixelFormat){
1307 memcpy(dest,src,frame.mLength);
1308 }else{
1309 yv12_adjust_memcpy(dest,src,width,height);
1310 }
1311
1312 }else{ //default case
1313 frame.mLength = width*height*3/2;
1314 memcpy(dest,src,frame.mLength);
1315 }
1316
1317 frame.mFrameMask |= CameraFrame::PREVIEW_FRAME_SYNC;
1318
1319 if(mRecording){
1320 frame.mFrameMask |= CameraFrame::VIDEO_FRAME_SYNC;
1321 }
1322 frame.mBuffer = ptr; //dest
1323 frame.mAlignment = width;
1324 frame.mOffset = 0;
1325 frame.mYuv[0] = 0;
1326 frame.mYuv[1] = 0;
1327 frame.mWidth = width;
1328 frame.mHeight = height;
1329 frame.mTimestamp = systemTime(SYSTEM_TIME_MONOTONIC);
1330 frame.mPixelFmt = mPixelFormat;
1331 ret = setInitFrameRefCount(frame.mBuffer, frame.mFrameMask);
1332 if (ret){
1333 CAMHAL_LOGEB("setInitFrameRefCount err=%d", ret);
1334 }else
1335 ret = sendFrameToSubscribers(&frame);
1336 //LOGD("previewThread /sendFrameToSubscribers ret=%d", ret);
1337 }
1338 if( (mIoctlSupport & IOCTL_MASK_FOCUS_MOVE) && mFocusMoveEnabled ){
1339 getFocusMoveStatus();
1340 }
1341
1342 return ret;
1343}
1344
1345/* Image Capture Thread */
1346// ---------------------------------------------------------------------------
1347int V4LCamAdpt::GenExif(ExifElementsTable* exiftable)
1348{
1349 char exifcontent[256];
1350
1351 //Make
1352 exiftable->insertElement("Make",
1353 (const char*)mParams.get(ExCameraParameters::KEY_EXIF_MAKE));
1354
1355 //Model
1356 exiftable->insertElement("Model",
1357 (const char*)mParams.get(ExCameraParameters::KEY_EXIF_MODEL));
1358
1359 //Image orientation
1360 int orientation = mParams.getInt(CameraParameters::KEY_ROTATION);
1361 //covert 0 90 180 270 to 0 1 2 3
1362 CAMHAL_LOGDB("get orientaion %d",orientation);
1363 if(orientation == 0)
1364 orientation = 1;
1365 else if(orientation == 90)
1366 orientation = 6;
1367 else if(orientation == 180)
1368 orientation = 3;
1369 else if(orientation == 270)
1370 orientation = 8;
1371
1372
1373 //Image width,height
1374 int width,height;
1375 if((mCaptureWidth <= 0)||(mCaptureHeight <= 0)){
1376 mParams.getPictureSize(&width, &height);
1377 }else{
1378 width = mCaptureWidth;
1379 height = mCaptureHeight;
1380 }
1381
1382 if(mIoctlSupport & IOCTL_MASK_ROTATE){
1383 orientation = 1;
1384 if((mRotateValue==90)||(mRotateValue==270)){
1385 int temp = width;
1386 width = height;
1387 height = temp;
1388 }
1389 }
1390
1391 sprintf(exifcontent,"%d",orientation);
1392 exiftable->insertElement("Orientation",(const char*)exifcontent);
1393
1394 sprintf(exifcontent,"%d",width);
1395 exiftable->insertElement("ImageWidth",(const char*)exifcontent);
1396 sprintf(exifcontent,"%d",height);
1397 exiftable->insertElement("ImageLength",(const char*)exifcontent);
1398
1399 //focal length RATIONAL
1400 float focallen = mParams.getFloat(CameraParameters::KEY_FOCAL_LENGTH);
1401 if(focallen >= 0)
1402 {
1403 int focalNum = focallen*1000;
1404 int focalDen = 1000;
1405 sprintf(exifcontent,"%d/%d",focalNum,focalDen);
1406 exiftable->insertElement("FocalLength",(const char*)exifcontent);
1407 }
1408
1409 //datetime of photo
1410 time_t times;
1411 {
1412 time(&times);
1413 struct tm tmstruct;
1414 tmstruct = *(localtime(&times)); //convert to local time
1415
1416 //date&time
1417 strftime(exifcontent, 30, "%Y:%m:%d %H:%M:%S", &tmstruct);
1418 exiftable->insertElement("DateTime",(const char*)exifcontent);
1419 }
1420
1421 //gps date stamp & time stamp
1422 times = mParams.getInt(CameraParameters::KEY_GPS_TIMESTAMP);
1423 if(times != -1)
1424 {
1425 struct tm tmstruct;
1426 tmstruct = *(gmtime(&times));//convert to standard time
1427 //date
1428 strftime(exifcontent, 20, "%Y:%m:%d", &tmstruct);
1429 exiftable->insertElement("GPSDateStamp",(const char*)exifcontent);
1430 //time
1431 sprintf(exifcontent,"%d/%d,%d/%d,%d/%d",
1432 tmstruct.tm_hour,1,tmstruct.tm_min,1,tmstruct.tm_sec,1);
1433 exiftable->insertElement("GPSTimeStamp",(const char*)exifcontent);
1434 }
1435
1436 //gps latitude info
1437 char* latitudestr = (char*)mParams.get(CameraParameters::KEY_GPS_LATITUDE);
1438 if(latitudestr!=NULL)
1439 {
1440 int offset = 0;
1441 float latitude = mParams.getFloat(CameraParameters::KEY_GPS_LATITUDE);
1442 if(latitude < 0.0)
1443 {
1444 offset = 1;
1445 latitude*= (float)(-1);
1446 }
1447
1448 int latitudedegree = latitude;
1449 float latitudeminuts = (latitude-(float)latitudedegree)*60;
1450 int latitudeminuts_int = latitudeminuts;
1451 float latituseconds = (latitudeminuts-(float)latitudeminuts_int)*60+0.5;
1452 int latituseconds_int = latituseconds;
1453 sprintf(exifcontent,"%d/%d,%d/%d,%d/%d",
1454 latitudedegree,1,latitudeminuts_int,1,latituseconds_int,1);
1455 exiftable->insertElement("GPSLatitude",(const char*)exifcontent);
1456
1457 exiftable->insertElement("GPSLatitudeRef",(offset==1)?"S":"N");
1458 }
1459
1460 //gps Longitude info
1461 char* longitudestr = (char*)mParams.get(CameraParameters::KEY_GPS_LONGITUDE);
1462 if(longitudestr!=NULL)
1463 {
1464 int offset = 0;
1465 float longitude = mParams.getFloat(CameraParameters::KEY_GPS_LONGITUDE);
1466 if(longitude < 0.0)
1467 {
1468 offset = 1;
1469 longitude*= (float)(-1);
1470 }
1471
1472 int longitudedegree = longitude;
1473 float longitudeminuts = (longitude-(float)longitudedegree)*60;
1474 int longitudeminuts_int = longitudeminuts;
1475 float longitudeseconds = (longitudeminuts-(float)longitudeminuts_int)*60+0.5;
1476 int longitudeseconds_int = longitudeseconds;
1477 sprintf(exifcontent,"%d/%d,%d/%d,%d/%d",
1478 longitudedegree,1,longitudeminuts_int,1,longitudeseconds_int,1);
1479 exiftable->insertElement("GPSLongitude",(const char*)exifcontent);
1480
1481 exiftable->insertElement("GPSLongitudeRef",(offset==1)?"S":"N");
1482 }
1483
1484 //gps Altitude info
1485 char* altitudestr = (char*)mParams.get(CameraParameters::KEY_GPS_ALTITUDE);
1486 if(altitudestr!=NULL)
1487 {
1488 int offset = 0;
1489 float altitude = mParams.getFloat(CameraParameters::KEY_GPS_ALTITUDE);
1490 if(altitude < 0.0)
1491 {
1492 offset = 1;
1493 altitude*= (float)(-1);
1494 }
1495
1496 int altitudenum = altitude*1000;
1497 int altitudedec= 1000;
1498 sprintf(exifcontent,"%d/%d",altitudenum,altitudedec);
1499 exiftable->insertElement("GPSAltitude",(const char*)exifcontent);
1500
1501 sprintf(exifcontent,"%d",offset);
1502 exiftable->insertElement("GPSAltitudeRef",(const char*)exifcontent);
1503 }
1504
1505 //gps processing method
1506 char* processmethod =
1507 (char*)mParams.get(CameraParameters::KEY_GPS_PROCESSING_METHOD);
1508 if(processmethod!=NULL)
1509 {
1510 memset(exifcontent,0,sizeof(exifcontent));
1511 char ExifAsciiPrefix[] = { 0x41, 0x53, 0x43, 0x49, 0x49, 0x0, 0x0, 0x0 };//asicii
1512 memcpy(exifcontent,ExifAsciiPrefix,8);
1513 memcpy(exifcontent+8,processmethod,strlen(processmethod));
1514 exiftable->insertElement("GPSProcessingMethod",(const char*)exifcontent);
1515 }
1516 return 1;
1517}
1518
1519/*static*/ int V4LCamAdpt::beginPictureThread(void *cookie)
1520{
1521 V4LCamAdpt *c = (V4LCamAdpt *)cookie;
1522 return c->pictureThread();
1523}
1524
1525int V4LCamAdpt::pictureThread()
1526{
1527 status_t ret = NO_ERROR;
1528 int width, height;
1529 CameraFrame frame;
1530 int dqTryNum = 3;
1531
1532 setMirrorEffect();
1533
1534 if( (mIoctlSupport & IOCTL_MASK_FLASH)
1535 &&(FLASHLIGHT_ON == mFlashMode)){
1536 set_flash_mode( mCameraHandle, "on");
1537 }
1538 if (true)
1539 {
1540 mVideoInfo->buf.index = 0;
1541 mVideoInfo->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1542 mVideoInfo->buf.memory = V4L2_MEMORY_MMAP;
1543
1544 ret = ioctl(mCameraHandle, VIDIOC_QBUF, &mVideoInfo->buf);
1545 if (ret < 0)
1546 {
1547 CAMHAL_LOGEA("VIDIOC_QBUF Failed");
1548 return -EINVAL;
1549 }
1550 nQueued ++;
1551
1552 if(mIoctlSupport & IOCTL_MASK_ROTATE){
1553 set_rotate_value(mCameraHandle,mRotateValue);
1554 }
1555
1556 enum v4l2_buf_type bufType;
1557 if (!mVideoInfo->isStreaming)
1558 {
1559 bufType = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1560
1561 ret = ioctl (mCameraHandle, VIDIOC_STREAMON, &bufType);
1562 if (ret < 0) {
1563 CAMHAL_LOGEB("StartStreaming: Unable to start capture: %s",
1564 strerror(errno));
1565 return ret;
1566 }
1567
1568 mVideoInfo->isStreaming = true;
1569 }
1570
1571 int index = 0;
1572 char *fp = this->GetFrame(index);
1573
1574#ifdef AMLOGIC_VCAM_NONBLOCK_SUPPORT
1575 while(!fp && (-1 == index) ){
1576 usleep( 10000 );
1577 fp = this->GetFrame(index);
1578 }
1579#else
1580 if(!fp)
1581 {
1582 CAMHAL_LOGDA("GetFrame fail, this may stop preview\n");
1583 return 0; //BAD_VALUE;
1584 }
1585#endif
1586 if (!mCaptureBuf || !mCaptureBuf->data)
1587 {
1588 return 0; //BAD_VALUE;
1589 }
1590
1591 int width, height;
1592 uint8_t* dest = (uint8_t*)mCaptureBuf->data;
1593 uint8_t* src = (uint8_t*) fp;
1594 if((mCaptureWidth <= 0)||(mCaptureHeight <= 0)){
1595 mParams.getPictureSize(&width, &height);
1596 }else{
1597 width = mCaptureWidth;
1598 height = mCaptureHeight;
1599 }
1600
1601 if((mRotateValue==90)||(mRotateValue==270)){
1602 int temp = 0;
1603 temp = width;
1604 width = height;
1605 height = temp;
1606 }
1607
1608 CAMHAL_LOGDB("mCaptureBuf=%p,dest=%p,fp=%p,index=%d\n"
1609 "w=%d h=%d,len=%d,bytesused=%d\n",
1610 mCaptureBuf, dest, fp,index, width, height,
1611 mVideoInfo->buf.length, mVideoInfo->buf.bytesused);
1612
1613 if(DEFAULT_IMAGE_CAPTURE_PIXEL_FORMAT == V4L2_PIX_FMT_RGB24){ // rgb24
1614 frame.mLength = width*height*3;
1615 frame.mQuirks = CameraFrame::ENCODE_RAW_RGB24_TO_JPEG
1616 | CameraFrame::HAS_EXIF_DATA;
1617 memcpy(dest,src,mVideoInfo->buf.length);
1618 }else if(DEFAULT_IMAGE_CAPTURE_PIXEL_FORMAT == V4L2_PIX_FMT_YUYV){ // 422I
1619 frame.mLength = width*height*2;
1620 frame.mQuirks = CameraFrame::ENCODE_RAW_YUV422I_TO_JPEG
1621 | CameraFrame::HAS_EXIF_DATA;
1622 memcpy(dest, src, mVideoInfo->buf.length);
1623 }else if(DEFAULT_IMAGE_CAPTURE_PIXEL_FORMAT == V4L2_PIX_FMT_NV21){ // 420sp
1624 frame.mLength = width*height*3/2;
1625 frame.mQuirks = CameraFrame::ENCODE_RAW_YUV420SP_TO_JPEG
1626 | CameraFrame::HAS_EXIF_DATA;
1627 memcpy(dest,src,mVideoInfo->buf.length);
1628 }else{ //default case
1629 frame.mLength = width*height*3;
1630 frame.mQuirks = CameraFrame::ENCODE_RAW_RGB24_TO_JPEG
1631 | CameraFrame::HAS_EXIF_DATA;
1632 memcpy(dest, src, mVideoInfo->buf.length);
1633 }
1634
1635 notifyShutterSubscribers();
1636 //TODO correct time to call this?
1637 if (NULL != mEndImageCaptureCallback)
1638 mEndImageCaptureCallback(mEndCaptureData);
1639
1640 //gen exif message
1641 ExifElementsTable* exiftable = new ExifElementsTable();
1642 GenExif(exiftable);
1643
1644 frame.mFrameMask = CameraFrame::IMAGE_FRAME;
1645 frame.mFrameType = CameraFrame::IMAGE_FRAME;
1646 frame.mBuffer = mCaptureBuf->data;
1647 frame.mCookie2 = (void*)exiftable;
1648 frame.mAlignment = width;
1649 frame.mOffset = 0;
1650 frame.mYuv[0] = 0;
1651 frame.mYuv[1] = 0;
1652 frame.mWidth = width;
1653 frame.mHeight = height;
1654 frame.mTimestamp = systemTime(SYSTEM_TIME_MONOTONIC);
1655
1656 if (mVideoInfo->isStreaming)
1657 {
1658 bufType = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1659 ret = ioctl (mCameraHandle, VIDIOC_STREAMOFF, &bufType);
1660 if (ret < 0)
1661 {
1662 CAMHAL_LOGEB("StopStreaming: Unable to stop capture: %s",
1663 strerror(errno));
1664 return ret;
1665 }
1666
1667 mVideoInfo->isStreaming = false;
1668 }
1669
1670 mVideoInfo->buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1671 mVideoInfo->buf.memory = V4L2_MEMORY_MMAP;
1672
1673 nQueued = 0;
1674 nDequeued = 0;
1675
1676 /* Unmap buffers */
1677 if (munmap(mVideoInfo->mem[0], mVideoInfo->buf.length) < 0){
1678 CAMHAL_LOGEA("Unmap failed");
1679 }
1680
1681
1682 }
1683
1684 if( (mIoctlSupport & IOCTL_MASK_FLASH)
1685 &&(FLASHLIGHT_ON == mFlashMode)){
1686 set_flash_mode( mCameraHandle, "off");
1687 }
1688 if(mIoctlSupport & IOCTL_MASK_ROTATE){
1689 set_rotate_value(mCameraHandle,0);
1690 mRotateValue = 0;
1691 }
1692
1693 // start preview thread again after stopping it in UseBuffersCapture
1694 {
1695 Mutex::Autolock lock(mPreviewBufferLock);
1696 UseBuffersPreview(mPreviewBuffers, mPreviewBufferCount);
1697 }
1698 startPreview();
1699
1700 ret = setInitFrameRefCount(frame.mBuffer, frame.mFrameMask);
1701 if (ret){
1702 CAMHAL_LOGEB("setInitFrameRefCount err=%d", ret);
1703 }else{
1704 ret = sendFrameToSubscribers(&frame);
1705 }
1706
1707 return ret;
1708}
1709
1710
1711status_t V4LCamAdpt::disableMirror(bool bDisable) {
1712 CAMHAL_LOGDB("disableMirror %d",bDisable);
1713 mbDisableMirror = bDisable;
1714 setMirrorEffect();
1715 return NO_ERROR;
1716}
1717
1718status_t V4LCamAdpt::setMirrorEffect() {
1719
1720 bool bEnable = mbFrontCamera&&(!mbDisableMirror);
1721 CAMHAL_LOGDB("setmirror effect %d",bEnable);
1722
1723 if(mIoctlSupport & IOCTL_MASK_HFLIP){
1724 if(set_hflip_mode(mCameraHandle,bEnable))
1725 writefile((char *)SYSFILE_CAMERA_SET_MIRROR,(char*)(bEnable?"1":"0"));
1726 }else{
1727 writefile((char *)SYSFILE_CAMERA_SET_MIRROR,(char*)(bEnable?"1":"0"));
1728 }
1729 return NO_ERROR;
1730}
1731
1732
1733
1734// ---------------------------------------------------------------------------
1735
1736
1737bool V4LCamAdpt::isPreviewDevice(int camera_fd)
1738{
1739 int ret;
1740 int index;
1741 struct v4l2_fmtdesc fmtdesc;
1742
1743 for(index=0;;index++){
1744 memset(&fmtdesc, 0, sizeof(struct v4l2_fmtdesc));
1745 fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1746 fmtdesc.index = index;
1747 ret = ioctl( camera_fd, VIDIOC_ENUM_FMT, &fmtdesc);
1748 if((V4L2_PIX_FMT_YUYV==fmtdesc.pixelformat) ||
1749 (V4L2_PIX_FMT_NV21==fmtdesc.pixelformat)){
1750 return true;
1751 }
1752 if(ret < 0)
1753 break;
1754 }
1755
1756 return false;
1757}
1758
1759int V4LCamAdpt::getValidFrameSize( int pixel_format, char *framesize)
1760{
1761 struct v4l2_frmsizeenum frmsize;
1762 int i=0;
1763 char tempsize[12];
1764 framesize[0] = '\0';
1765
1766 memset(&frmsize,0,sizeof(v4l2_frmsizeenum));
1767 for(i=0;;i++){
1768 frmsize.index = i;
1769 frmsize.pixel_format = pixel_format;
1770 if(ioctl(mCameraHandle, VIDIOC_ENUM_FRAMESIZES, &frmsize) == 0){
1771 if(frmsize.type == V4L2_FRMSIZE_TYPE_DISCRETE){ //only support this type
1772
1773 snprintf(tempsize, sizeof(tempsize), "%dx%d,",
1774 frmsize.discrete.width, frmsize.discrete.height);
1775 strcat(framesize, tempsize);
1776
1777 }
1778 else
1779 break;
1780 }
1781 else
1782 break;
1783 }
1784
1785 if(framesize[0] == '\0')
1786 return -1;
1787 else
1788 return 0;
1789}
1790
1791int V4LCamAdpt::getCameraOrientation(bool frontcamera, char* property)
1792{
1793 int degree = -1;
1794 if(frontcamera){
1795 if (property_get("ro.camera.orientation.front", property, NULL) > 0){
1796 degree = atoi(property);
1797 }
1798 }else{
1799 if (property_get("ro.camera.orientation.back", property, NULL) > 0){
1800 degree = atoi(property);
1801 }
1802 }
1803 if((degree != 0)&&(degree != 90)
1804 &&(degree != 180)&&(degree != 270))
1805 degree = -1;
1806 return degree;
1807}
1808
1809static int enumCtrlMenu(int camera_fd, struct v4l2_queryctrl *qi,
1810 char* menu_items, char*def_menu_item)
1811{
1812 struct v4l2_queryctrl qc;
1813 struct v4l2_querymenu qm;
1814 int ret;
1815 int mode_count = -1;
1816
1817 memset(&qc, 0, sizeof(struct v4l2_queryctrl));
1818 qc.id = qi->id;
1819 ret = ioctl (camera_fd, VIDIOC_QUERYCTRL, &qc);
1820 if( (ret<0) || (qc.flags == V4L2_CTRL_FLAG_DISABLED) ){
1821 CAMHAL_LOGDB("camera handle %d can't support this ctrl",camera_fd);
1822 return mode_count;
1823 }else if( qc.type != V4L2_CTRL_TYPE_MENU){
1824 CAMHAL_LOGDB("this ctrl of camera handle %d can't support menu type",camera_fd);
1825 return 0;
1826 }else{
1827 memset(&qm, 0, sizeof(qm));
1828 qm.id = qi->id;
1829 qm.index = qc.default_value;
1830 if(ioctl (camera_fd, VIDIOC_QUERYMENU, &qm) < 0){
1831 return 0;
1832 } else {
1833 strcpy(def_menu_item, (char*)qm.name);
1834 }
1835 int index = 0;
1836 mode_count = 0;
1837
1838 for (index = qc.minimum; index <= qc.maximum; index+= qc.step) {
1839 memset(&qm, 0, sizeof(struct v4l2_querymenu));
1840 qm.id = qi->id;
1841 qm.index = index;
1842 if(ioctl (camera_fd, VIDIOC_QUERYMENU, &qm) < 0){
1843 continue;
1844 } else {
1845 if(mode_count>0)
1846 strcat(menu_items, ",");
1847 strcat( menu_items, (char*)qm.name);
1848 mode_count++;
1849 }
1850 }
1851 }
1852 return mode_count;
1853}
1854
1855bool V4LCamAdpt::getCameraWhiteBalance( char* wb_modes, char*def_wb_mode)
1856{
1857 struct v4l2_queryctrl qc;
1858 int item_count=0;
1859
1860 memset( &qc, 0, sizeof(qc));
1861
1862 qc.id = V4L2_CID_DO_WHITE_BALANCE;
1863 item_count = enumCtrlMenu( mCameraHandle, &qc, wb_modes, def_wb_mode);
1864
1865 if(0 >= item_count){
1866 strcpy( wb_modes, "auto,daylight,incandescent,fluorescent");
1867 strcpy(def_wb_mode, "auto");
1868 }
1869 return true;
1870}
1871
1872bool V4LCamAdpt::getCameraBanding(char* banding_modes, char*def_banding_mode)
1873{
1874 struct v4l2_queryctrl qc;
1875 int item_count=0;
1876 char *tmpbuf=NULL;
1877
1878 memset( &qc, 0, sizeof(qc));
1879 qc.id = V4L2_CID_POWER_LINE_FREQUENCY;
1880
1881 item_count = enumCtrlMenu( mCameraHandle, &qc, banding_modes, def_banding_mode);
1882
1883 if(0 >= item_count){
1884 strcpy( banding_modes, "50hz,60hz");
1885 strcpy( def_banding_mode, "50hz");
1886 }
1887 return true;
1888}
1889
1890#define MAX_LEVEL_FOR_EXPOSURE 16
1891#define MIN_LEVEL_FOR_EXPOSURE 3
1892
1893bool V4LCamAdpt::getCameraExposureValue(int &min, int &max,
1894 int &step, int &def)
1895{
1896 struct v4l2_queryctrl qc;
1897 int ret=0;
1898 int level = 0;
1899 int middle = 0;
1900
1901 memset( &qc, 0, sizeof(qc));
1902
1903 qc.id = V4L2_CID_EXPOSURE;
1904 ret = ioctl( mCameraHandle, VIDIOC_QUERYCTRL, &qc);
1905 if(ret<0){
1906 CAMHAL_LOGDB("QUERYCTRL failed, errno=%d\n", errno);
1907 min = -4;
1908 max = 4;
1909 def = 0;
1910 step = 1;
1911 return true;
1912 }
1913
1914 if(0 < qc.step)
1915 level = ( qc.maximum - qc.minimum + 1 )/qc.step;
1916
1917 if((level > MAX_LEVEL_FOR_EXPOSURE)
1918 || (level < MIN_LEVEL_FOR_EXPOSURE)){
1919 min = -4;
1920 max = 4;
1921 def = 0;
1922 step = 1;
1923 CAMHAL_LOGDB("not in[min,max], min=%d, max=%d, def=%d, step=%d\n",
1924 min, max, def, step);
1925 return true;
1926 }
1927
1928 middle = (qc.minimum+qc.maximum)/2;
1929 min = qc.minimum - middle;
1930 max = qc.maximum - middle;
1931 def = qc.default_value - middle;
1932 step = qc.step;
1933
1934 return true;
1935}
1936
1937bool V4LCamAdpt::getCameraAutoFocus( char* focus_mode_str, char*def_focus_mode)
1938{
1939 struct v4l2_queryctrl qc;
1940 struct v4l2_querymenu qm;
1941 bool auto_focus_enable = false;
1942 int menu_num = 0;
1943 int mode_count = 0;
1944
1945 memset(&qc, 0, sizeof(struct v4l2_queryctrl));
1946 qc.id = V4L2_CID_FOCUS_AUTO;
1947 menu_num = ioctl (mCameraHandle, VIDIOC_QUERYCTRL, &qc);
1948 if((qc.flags == V4L2_CTRL_FLAG_DISABLED)
1949 ||( menu_num < 0) || (qc.type != V4L2_CTRL_TYPE_MENU)){
1950 auto_focus_enable = false;
1951 CAMHAL_LOGDB("camera handle %d can't support auto focus",mCameraHandle);
1952 }else {
1953 memset(&qm, 0, sizeof(qm));
1954 qm.id = V4L2_CID_FOCUS_AUTO;
1955 qm.index = qc.default_value;
1956 strcpy(def_focus_mode, "auto");
1957
1958 for (int index = qc.minimum; index <= qc.maximum; index+= qc.step) {
1959 memset(&qm, 0, sizeof(struct v4l2_querymenu));
1960 qm.id = V4L2_CID_FOCUS_AUTO;
1961 qm.index = index;
1962 if(ioctl (mCameraHandle, VIDIOC_QUERYMENU, &qm) < 0){
1963 continue;
1964 } else {
1965 if(mode_count>0)
1966 strcat(focus_mode_str, ",");
1967 strcat(focus_mode_str, (char*)qm.name);
1968 mode_count++;
1969 }
1970 }
1971 if(mode_count>0)
1972 auto_focus_enable = true;
1973 }
1974 return auto_focus_enable;
1975}
1976
1977bool V4LCamAdpt::getCameraHandle()
1978{
1979 return mCameraHandle;
1980}
1981
1982bool V4LCamAdpt::isVolatileCam()
1983{
1984
1985 char *bus_info;
1986 bool ret = true;
1987 int size = 0;
1988
1989 size = sizeof(mVideoInfo->cap.bus_info);
1990 bus_info = (char *)calloc( 1, size);
1991 memset( bus_info, 0, size);
1992
1993 strncpy( bus_info, (char *)&mVideoInfo->cap.bus_info, size);
1994 if( strstr( bus_info, "usb")){
1995 ret = true;
1996 CAMHAL_LOGDA("usb device\n")
1997 }else{
1998 ret = false;
1999 CAMHAL_LOGDA("not usb device\n")
2000 }
2001 CAMHAL_LOGDB("bus_info=%s\n", bus_info);
2002
2003 if(bus_info){
2004 free(bus_info);
2005 bus_info = NULL;
2006 }
2007
2008 return ret;
2009
2010}
2011bool V4LCamAdpt::isFrontCam( int camera_id )
2012{
2013 int bFrontCam = false;
2014
2015 if (camera_id == 0) {
2016#ifdef AMLOGIC_BACK_CAMERA_SUPPORT
2017 bFrontCam = false;
2018#elif defined(AMLOGIC_FRONT_CAMERA_SUPPORT)
2019 bFrontCam = true;
2020#elif defined(AMLOGIC_USB_CAMERA_SUPPORT)
2021 bFrontCam = true;
2022#else//defined nothing, we try by ourself.we assume, the 0 is front camera, 1 is back camera
2023 bFrontCam = true;
2024#endif
2025 } else if (camera_id == 1) {
2026#if defined(AMLOGIC_BACK_CAMERA_SUPPORT) && defined(AMLOGIC_FRONT_CAMERA_SUPPORT)
2027 bFrontCam = true;
2028#else//defined nothing, we try to by ourself
2029 bFrontCam = false;
2030#endif
2031 }
2032 return bFrontCam;
2033 //return true;// virtual camera is a front camera.
2034}
2035
2036extern "C" void newloadCaps(int camera_id, CameraProperties::Properties* params) {
2037 const char DEFAULT_BRIGHTNESS[] = "50";
2038 const char DEFAULT_CONTRAST[] = "100";
2039 const char DEFAULT_IPP[] = "ldc-nsf";
2040 const char DEFAULT_GBCE[] = "disable";
2041 const char DEFAULT_ISO_MODE[] = "auto";
2042 const char DEFAULT_PICTURE_FORMAT[] = "jpeg";
2043 const char DEFAULT_PICTURE_SIZE[] = "640x480";
2044 const char PREVIEW_FORMAT_420SP[] = "yuv420sp";
2045 const char PREVIEW_FORMAT_422I[] = "yuv422i-yuyv";
2046 const char DEFAULT_PREVIEW_SIZE[] = "640x480";
2047 const char DEFAULT_NUM_PREV_BUFS[] = "6";
2048 const char DEFAULT_NUM_PIC_BUFS[] = "1";
2049 const char DEFAULT_MAX_FOCUS_AREAS[] = "1";
2050 const char DEFAULT_SATURATION[] = "100";
2051 const char DEFAULT_SCENE_MODE[] = "auto";
2052 const char DEFAULT_SHARPNESS[] = "100";
2053 const char DEFAULT_VSTAB[] = "false";
2054 const char DEFAULT_VSTAB_SUPPORTED[] = "true";
2055 const char DEFAULT_MAX_FD_HW_FACES[] = "0";
2056 const char DEFAULT_MAX_FD_SW_FACES[] = "0";
2057 const char DEFAULT_FOCAL_LENGTH_PRIMARY[] = "4.31";
2058 const char DEFAULT_FOCAL_LENGTH_SECONDARY[] = "1.95";
2059 const char DEFAULT_HOR_ANGLE[] = "54.8";
2060 const char DEFAULT_VER_ANGLE[] = "42.5";
2061 const char DEFAULT_AE_LOCK[] = "false";
2062 const char DEFAULT_AWB_LOCK[] = "false";
2063 const char DEFAULT_MAX_NUM_METERING_AREAS[] = "0";
2064 const char DEFAULT_LOCK_SUPPORTED[] = "true";
2065 const char DEFAULT_LOCK_UNSUPPORTED[] = "false";
2066 const char DEFAULT_VIDEO_SIZE[] = "640x480";
2067 const char DEFAULT_PREFERRED_PREVIEW_SIZE_FOR_VIDEO[] = "640x480";
2068
2069 bool bFrontCam = false;
2070 int tempid = camera_id;
2071 int camera_fd = -1;
2072 V4LCamAdpt v(camera_id);
2073
2074 const char *device_name = VIRTUAL_DEVICE_PATH(camera_id);
2075 if(device_name){
2076 params->set(CameraProperties::DEVICE_NAME, device_name);
2077 }else{
2078 CAMHAL_LOGDA("no virtual camera device node\n");
2079 params->set(CameraProperties::DEVICE_NAME, "/dev/video11");
2080 }
2081
2082 int iret = 0;
2083 if(v.initialize( params ) != NO_ERROR){
2084 CAMHAL_LOGEA("Unable to create or initialize V4LCamAdpt!!");
2085 }
2086
2087#ifdef AMLOGIC_USB_CAMERA_SUPPORT
2088 params->set(CameraProperties::RELOAD_WHEN_OPEN, "1");
2089#else
2090 params->set(CameraProperties::RELOAD_WHEN_OPEN, "0");
2091#endif
2092
2093 bFrontCam = v.isFrontCam( camera_id );
2094 CAMHAL_LOGVB("%s\n", bFrontCam?"front cam":"back cam");
2095 //should changed while the screen orientation changed.
2096 int degree = -1;
2097 char property[64];
2098 memset(property,0,sizeof(property));
2099 if(bFrontCam == true) {
2100 params->set(CameraProperties::FACING_INDEX, ExCameraParameters::FACING_FRONT);
2101 if(v.getCameraOrientation(bFrontCam,property)>=0){
2102 params->set(CameraProperties::ORIENTATION_INDEX,property);
2103 }else{
2104#ifdef AMLOGIC_USB_CAMERA_SUPPORT
2105 params->set(CameraProperties::ORIENTATION_INDEX,"0");
2106#else
2107 params->set(CameraProperties::ORIENTATION_INDEX,"270");
2108#endif
2109 }
2110 } else {
2111 params->set(CameraProperties::FACING_INDEX, ExCameraParameters::FACING_BACK);
2112 if( v.getCameraOrientation(bFrontCam,property)>=0){
2113 params->set(CameraProperties::ORIENTATION_INDEX,property);
2114 }else{
2115#ifdef AMLOGIC_USB_CAMERA_SUPPORT
2116 params->set(CameraProperties::ORIENTATION_INDEX,"180");
2117#else
2118 params->set(CameraProperties::ORIENTATION_INDEX,"90");
2119#endif
2120 }
2121 }
2122
2123 params->set(CameraProperties::SUPPORTED_PREVIEW_FORMATS,"yuv420sp,yuv420p"); //yuv420p for cts
2124 if(DEFAULT_PREVIEW_PIXEL_FORMAT == V4L2_PIX_FMT_YUYV){ // 422I
2125 //params->set(CameraProperties::SUPPORTED_PREVIEW_FORMATS,PREVIEW_FORMAT_422I);
2126 params->set(CameraProperties::PREVIEW_FORMAT,PREVIEW_FORMAT_422I);
2127 }else if(DEFAULT_PREVIEW_PIXEL_FORMAT == V4L2_PIX_FMT_NV21){ //420sp
2128 //params->set(CameraProperties::SUPPORTED_PREVIEW_FORMATS,PREVIEW_FORMAT_420SP);
2129 params->set(CameraProperties::PREVIEW_FORMAT,PREVIEW_FORMAT_420SP);
2130 }else{ //default case
2131 //params->set(CameraProperties::SUPPORTED_PREVIEW_FORMATS,PREVIEW_FORMAT_420SP);
2132 params->set(CameraProperties::PREVIEW_FORMAT,PREVIEW_FORMAT_420SP);
2133 }
2134
2135#ifdef AMLOGIC_VCAM_NONBLOCK_SUPPORT
2136 int fps=0, fps_num=0;
2137 int ret;
2138 char *fpsrange=(char *)calloc(32,sizeof(char));
2139
2140 ret = v.enumFramerate(&fps, &fps_num);
2141 if((fpsrange != NULL)&&(NO_ERROR == ret) && ( 0 !=fps_num )){
2142 sprintf(fpsrange,"%s%d","10,",fps/fps_num);
2143 CAMHAL_LOGDA("O_NONBLOCK operation to do previewThread\n");
2144
2145 params->set(CameraProperties::SUPPORTED_PREVIEW_FRAME_RATES, fpsrange);
2146 params->set(CameraProperties::PREVIEW_FRAME_RATE, fps/fps_num);
2147
2148 memset( fpsrange, 0, 32*sizeof(char));
2149 sprintf(fpsrange,"%s%d","10000,",fps*1000/fps_num);
2150 params->set(CameraProperties::FRAMERATE_RANGE_IMAGE, fpsrange);
2151 params->set(CameraProperties::FRAMERATE_RANGE_VIDEO, fpsrange);
2152
2153 memset( fpsrange, 0, 32*sizeof(char));
2154 sprintf(fpsrange,"(%s%d)","5000,",fps*1000/fps_num);
2155 params->set(CameraProperties::FRAMERATE_RANGE_SUPPORTED, fpsrange);
2156 memset( fpsrange, 0, 32*sizeof(char));
2157 sprintf(fpsrange,"%s%d","5000,",fps*1000/fps_num);
2158 params->set(CameraProperties::FRAMERATE_RANGE, fpsrange);
2159 }else{
2160 if(NO_ERROR != ret){
2161 CAMHAL_LOGDA("sensor driver need to implement enum framerate!!!\n");
2162 }
2163 params->set(CameraProperties::SUPPORTED_PREVIEW_FRAME_RATES, "10,15");
2164 params->set(CameraProperties::PREVIEW_FRAME_RATE, "15");
2165
2166 params->set(CameraProperties::FRAMERATE_RANGE_SUPPORTED, "(5000,26623)");
2167 params->set(CameraProperties::FRAMERATE_RANGE, "5000,26623");
2168 params->set(CameraProperties::FRAMERATE_RANGE_IMAGE, "10000,15000");
2169 params->set(CameraProperties::FRAMERATE_RANGE_VIDEO, "10000,15000");
2170 }
2171#else
2172 params->set(CameraProperties::SUPPORTED_PREVIEW_FRAME_RATES, "10,15");
2173 params->set(CameraProperties::PREVIEW_FRAME_RATE, "15");
2174
2175 params->set(CameraProperties::FRAMERATE_RANGE_SUPPORTED, "(5000,26623)");
2176 params->set(CameraProperties::FRAMERATE_RANGE, "5000,26623");
2177 params->set(CameraProperties::FRAMERATE_RANGE_IMAGE, "10000,15000");
2178 params->set(CameraProperties::FRAMERATE_RANGE_VIDEO, "10000,15000");
2179#endif
2180
2181 //get preview size & set
2182 char *sizes = (char *) calloc (1, 1024);
2183 if(!sizes){
2184 CAMHAL_LOGDA("Alloc string buff error!");
2185 return;
2186 }
2187
2188 memset(sizes,0,1024);
2189 uint32_t preview_format = DEFAULT_PREVIEW_PIXEL_FORMAT;
2190 if (!v.getValidFrameSize( preview_format, sizes)) {
2191 int len = strlen(sizes);
2192 unsigned int supported_w = 0, supported_h = 0,w = 0,h = 0;
2193 if(len>1){
2194 if(sizes[len-1] == ',')
2195 sizes[len-1] = '\0';
2196 }
2197
2198 char small_size[8] = "176x144"; //for cts
2199 if(strstr(sizes,small_size)==NULL){
2200 if((len+sizeof(small_size))<(1024-1)){
2201 strcat(sizes,",");
2202 strcat(sizes,small_size);
2203 }
2204 }
2205
2206 params->set(CameraProperties::SUPPORTED_PREVIEW_SIZES, sizes);
2207
2208 char * b = (char *)sizes;
2209 while(b != NULL){
2210 if (sscanf(b, "%dx%d", &supported_w, &supported_h) != 2){
2211 break;
2212 }
2213 if((supported_w*supported_h)>(w*h)){
2214 w = supported_w;
2215 h = supported_h;
2216 }
2217 b = strchr(b, ',');
2218 if(b)
2219 b++;
2220 }
2221 if((w>0)&&(h>0)){
2222 memset(sizes, 0, 1024);
2223 sprintf(sizes,"%dx%d",w,h);
2224 }
2225 //char * b = strrchr(sizes, ',');
2226 //if (b)
2227 // b++;
2228 //else
2229 // b = sizes;
2230 params->set(CameraProperties::PREVIEW_SIZE, sizes);
2231 }
2232 else
2233 {
2234 params->set(CameraProperties::SUPPORTED_PREVIEW_SIZES,
2235 "640x480,352x288,176x144");
2236 params->set(CameraProperties::PREVIEW_SIZE,"640x480");
2237 }
2238
2239 params->set(CameraProperties::SUPPORTED_PICTURE_FORMATS, DEFAULT_PICTURE_FORMAT);
2240 params->set(CameraProperties::PICTURE_FORMAT,DEFAULT_PICTURE_FORMAT);
2241 params->set(CameraProperties::JPEG_QUALITY, 90);
2242
2243 //must have >2 sizes and contain "0x0"
2244 params->set(CameraProperties::SUPPORTED_THUMBNAIL_SIZES, "180x160,0x0");
2245 params->set(CameraProperties::JPEG_THUMBNAIL_SIZE, "180x160");
2246 params->set(CameraProperties::JPEG_THUMBNAIL_QUALITY, 90);
2247
2248 //get & set picture size
2249 memset(sizes,0,1024);
2250 uint32_t picture_format = DEFAULT_IMAGE_CAPTURE_PIXEL_FORMAT;
2251 CAMHAL_LOGDB("default-picture-format=%d", DEFAULT_IMAGE_CAPTURE_PIXEL_FORMAT);
2252 if (!v.getValidFrameSize( picture_format, sizes)) {
2253 int len = strlen(sizes);
2254 unsigned int supported_w = 0, supported_h = 0,w = 0,h = 0;
2255 if(len>1){
2256 if(sizes[len-1] == ',')
2257 sizes[len-1] = '\0';
2258 }
2259
2260 params->set(CameraProperties::SUPPORTED_PICTURE_SIZES, sizes);
2261
2262 char * b = (char *)sizes;
2263 while(b != NULL){
2264 if (sscanf(b, "%dx%d", &supported_w, &supported_h) != 2){
2265 break;
2266 }
2267 if((supported_w*supported_h)>(w*h)){
2268 w = supported_w;
2269 h = supported_h;
2270 }
2271 b = strchr(b, ',');
2272 if(b)
2273 b++;
2274 }
2275 if((w>0)&&(h>0)){
2276 memset(sizes, 0, 1024);
2277 sprintf(sizes,"%dx%d",w,h);
2278 }
2279 //char * b = strrchr(sizes, ',');
2280 //if (b)
2281 // b++;
2282 //else
2283 // b = sizes;
2284 params->set(CameraProperties::PICTURE_SIZE, sizes);
2285 }
2286 else
2287 {
2288 params->set(CameraProperties::SUPPORTED_PICTURE_SIZES, "640x480");
2289 params->set(CameraProperties::PICTURE_SIZE,"640x480");
2290 }
2291 if(sizes){
2292 free(sizes);
2293 sizes = NULL;
2294 }
2295
2296 char *focus_mode = (char *) calloc (1, 256);
2297 char * def_focus_mode = (char *) calloc (1, 64);
2298 if((focus_mode)&&(def_focus_mode)){
2299 memset(focus_mode,0,256);
2300 memset(def_focus_mode,0,64);
2301 if(v.getCameraAutoFocus( focus_mode,def_focus_mode)) {
2302 params->set(CameraProperties::SUPPORTED_FOCUS_MODES, focus_mode);
2303 params->set(CameraProperties::FOCUS_MODE, def_focus_mode);
2304 }else {
2305 params->set(CameraProperties::SUPPORTED_FOCUS_MODES, "fixed");
2306 params->set(CameraProperties::FOCUS_MODE, "fixed");
2307 }
2308 }else{
2309 params->set(CameraProperties::SUPPORTED_FOCUS_MODES, "fixed");
2310 params->set(CameraProperties::FOCUS_MODE, "fixed");
2311 }
2312 if(focus_mode){
2313 free(focus_mode);
2314 focus_mode = NULL;
2315 }
2316 if(def_focus_mode){
2317 free(def_focus_mode);
2318 def_focus_mode = NULL;
2319 }
2320
2321 char *banding_mode = (char *) calloc (1, 256);
2322 char *def_banding_mode = (char *) calloc (1, 64);
2323 if((banding_mode)&&(def_banding_mode)){
2324 memset(banding_mode,0,256);
2325 memset(def_banding_mode,0,64);
2326
2327 v.getCameraBanding(banding_mode, def_banding_mode);
2328 params->set(CameraProperties::SUPPORTED_ANTIBANDING, banding_mode);
2329 params->set(CameraProperties::ANTIBANDING, def_banding_mode);
2330 CAMHAL_LOGDB("def_banding=%s, banding=%s\n", def_banding_mode, banding_mode);
2331 }else{
2332 params->set(CameraProperties::SUPPORTED_ANTIBANDING, "50hz,60hz");
2333 params->set(CameraProperties::ANTIBANDING, "50hz");
2334 CAMHAL_LOGDA("banding default value\n");
2335 }
2336 if(banding_mode){
2337 free(banding_mode);
2338 banding_mode = NULL;
2339 }
2340 if(def_banding_mode){
2341 free(def_banding_mode);
2342 def_banding_mode = NULL;
2343 }
2344
2345 params->set(CameraProperties::FOCAL_LENGTH, "4.31");
2346
2347 params->set(CameraProperties::HOR_ANGLE,"54.8");
2348 params->set(CameraProperties::VER_ANGLE,"42.5");
2349
2350 char *wb_mode = (char *) calloc (1, 256);
2351 char *def_wb_mode = (char *) calloc (1, 64);
2352
2353
2354 if( wb_mode && def_wb_mode){
2355 memset(wb_mode, 0, 256);
2356 memset(def_wb_mode, 0, 64);
2357 v.getCameraWhiteBalance( wb_mode, def_wb_mode);
2358 params->set(CameraProperties::SUPPORTED_WHITE_BALANCE, wb_mode);
2359 params->set(CameraProperties::WHITEBALANCE, def_wb_mode);
2360 }else{
2361
2362
2363 params->set(CameraProperties::SUPPORTED_WHITE_BALANCE, "auto");
2364 params->set(CameraProperties::WHITEBALANCE, "auto");
2365 }
2366
2367 if(wb_mode){
2368 free(wb_mode);
2369 wb_mode = NULL;
2370 }
2371 if(def_wb_mode){
2372 free(def_wb_mode);
2373 def_wb_mode = NULL;
2374 }
2375
2376 params->set(CameraProperties::AUTO_WHITEBALANCE_LOCK, DEFAULT_AWB_LOCK);
2377
2378 params->set(CameraProperties::SUPPORTED_EFFECTS, "none,negative,sepia");
2379 params->set(CameraProperties::EFFECT, "none");
2380
2381 char *flash_mode = (char *) calloc (1, 256);
2382 char *def_flash_mode = (char *) calloc (1, 64);
2383 if((flash_mode)&&(def_flash_mode)){
2384 memset(flash_mode,0,256);
2385 memset(def_flash_mode,0,64);
2386 if (v.get_flash_mode( flash_mode,def_flash_mode)) {
2387 params->set(CameraProperties::SUPPORTED_FLASH_MODES, flash_mode);
2388 params->set(CameraProperties::FLASH_MODE, def_flash_mode);
2389 CAMHAL_LOGDB("def_flash_mode=%s, flash_mode=%s\n",
2390 def_flash_mode, flash_mode);
2391 }
2392 }
2393 if (flash_mode) {
2394 free(flash_mode);
2395 flash_mode = NULL;
2396 }
2397 if (def_flash_mode) {
2398 free(def_flash_mode);
2399 def_flash_mode = NULL;
2400 }
2401
2402 //params->set(CameraParameters::KEY_SUPPORTED_SCENE_MODES,"auto,night,snow");
2403 //params->set(CameraParameters::KEY_SCENE_MODE,"auto");
2404
2405 params->set(CameraProperties::EXPOSURE_MODE, "auto");
2406 params->set(CameraProperties::SUPPORTED_EXPOSURE_MODES, "auto");
2407 params->set(CameraProperties::AUTO_EXPOSURE_LOCK, DEFAULT_AE_LOCK);
2408
2409 int min=0, max =0, def=0, step =0;
2410 v.getCameraExposureValue( min, max, step, def);
2411 params->set(CameraProperties::SUPPORTED_EV_MAX, max);
2412 params->set(CameraProperties::SUPPORTED_EV_MIN, min);
2413 params->set(CameraProperties::EV_COMPENSATION, def);
2414 params->set(CameraProperties::SUPPORTED_EV_STEP, step);
2415
2416 //don't support digital zoom now
2417
2418 params->set(CameraProperties::ZOOM_SUPPORTED,"false");
2419 params->set(CameraProperties::SMOOTH_ZOOM_SUPPORTED,"false");
2420 params->set(CameraProperties::SUPPORTED_ZOOM_RATIOS,"100");
2421 params->set(CameraProperties::SUPPORTED_ZOOM_STAGES,0); //think the zoom ratios as a array, the max zoom is the max index
2422 params->set(CameraProperties::ZOOM, 0);//default should be 0
2423
2424 params->set(CameraProperties::SUPPORTED_ISO_VALUES, "auto");
2425 params->set(CameraProperties::ISO_MODE, DEFAULT_ISO_MODE);
2426
2427 params->set(CameraProperties::SUPPORTED_IPP_MODES, DEFAULT_IPP);
2428 params->set(CameraProperties::IPP, DEFAULT_IPP);
2429
2430 params->set(CameraProperties::SUPPORTED_SCENE_MODES, "auto");
2431 params->set(CameraProperties::SCENE_MODE, DEFAULT_SCENE_MODE);
2432
2433 params->set(CameraProperties::BRIGHTNESS, DEFAULT_BRIGHTNESS);
2434 params->set(CameraProperties::CONTRAST, DEFAULT_CONTRAST);
2435 params->set(CameraProperties::GBCE, DEFAULT_GBCE);
2436 params->set(CameraProperties::SATURATION, DEFAULT_SATURATION);
2437 params->set(CameraProperties::SHARPNESS, DEFAULT_SHARPNESS);
2438 params->set(CameraProperties::VSTAB, DEFAULT_VSTAB);
2439 params->set(CameraProperties::VSTAB_SUPPORTED, DEFAULT_VSTAB_SUPPORTED);
2440 params->set(CameraProperties::MAX_FD_HW_FACES, DEFAULT_MAX_FD_HW_FACES);
2441 params->set(CameraProperties::MAX_FD_SW_FACES, DEFAULT_MAX_FD_SW_FACES);
2442 params->set(CameraProperties::REQUIRED_PREVIEW_BUFS, DEFAULT_NUM_PREV_BUFS);
2443 params->set(CameraProperties::REQUIRED_IMAGE_BUFS, DEFAULT_NUM_PIC_BUFS);
2444#ifdef AMLOGIC_ENABLE_VIDEO_SNAPSHOT
2445 params->set(CameraProperties::VIDEO_SNAPSHOT_SUPPORTED, "true");
2446#else
2447 params->set(CameraProperties::VIDEO_SNAPSHOT_SUPPORTED, "false");
2448#endif
2449
2450 params->set(CameraProperties::VIDEO_SIZE, DEFAULT_VIDEO_SIZE);
2451 params->set(CameraProperties::PREFERRED_PREVIEW_SIZE_FOR_VIDEO, DEFAULT_PREFERRED_PREVIEW_SIZE_FOR_VIDEO);
2452
2453
2454 CAMHAL_LOGDA("newloadCaps end!\n");
2455}
2456
2457#ifdef AMLOGIC_VCAM_NONBLOCK_SUPPORT
2458/* gets video device defined frame rate (not real - consider it a maximum value)
2459 * args:
2460 *
2461 * returns: VIDIOC_G_PARM ioctl result value
2462*/
2463int V4LCamAdpt::get_framerate ( int camera_fd, int *fps, int *fps_num)
2464{
2465 int ret=0;
2466
2467 struct v4l2_streamparm streamparm;
2468
2469 streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2470 ret = ioctl( camera_fd,VIDIOC_G_PARM,&streamparm);
2471 if (ret < 0)
2472 {
2473 CAMHAL_LOGDA("VIDIOC_G_PARM - Unable to get timeperframe");
2474 }
2475 else
2476 {
2477 if (streamparm.parm.capture.capability & V4L2_CAP_TIMEPERFRAME) {
2478 // it seems numerator is allways 1 but we don't do assumptions here :-)
2479 *fps = streamparm.parm.capture.timeperframe.denominator;
2480 *fps_num = streamparm.parm.capture.timeperframe.numerator;
2481 }
2482 }
2483
2484 return ret;
2485}
2486
2487int V4LCamAdpt::enumFramerate ( int *fps, int *fps_num)
2488{
2489 int ret=0;
2490 int framerate=0;
2491 int temp_rate=0;
2492 struct v4l2_frmivalenum fival;
2493 int i,j;
2494
2495 int pixelfmt_tbl[]={
2496 V4L2_PIX_FMT_NV21,
2497 V4L2_PIX_FMT_YVU420,
2498 };
2499 struct v4l2_frmsize_discrete resolution_tbl[]={
2500 {1280,720},
2501 {640, 480},
2502 {320, 240},
2503 };
2504
2505 for( i = 0; i < (int) ARRAY_SIZE(pixelfmt_tbl); i++){
2506 for( j = 0; j < (int) ARRAY_SIZE(resolution_tbl); j++){
2507
2508 memset(&fival, 0, sizeof(fival));
2509 fival.index = 0;
2510 fival.pixel_format = pixelfmt_tbl[i];
2511 fival.width = resolution_tbl[j].width;
2512 fival.height = resolution_tbl[j].height;
2513
2514 while ((ret = ioctl( mCameraHandle,
2515 VIDIOC_ENUM_FRAMEINTERVALS, &fival)) == 0)
2516 {
2517 if (fival.type == V4L2_FRMIVAL_TYPE_DISCRETE)
2518 {
2519 temp_rate = fival.discrete.denominator/fival.discrete.numerator;
2520 if(framerate < temp_rate){
2521 framerate = temp_rate;
2522 }
2523 }
2524 else if (fival.type == V4L2_FRMIVAL_TYPE_CONTINUOUS)
2525 {
2526 framerate = fival.stepwise.max.denominator
2527 /fival.stepwise.max.numerator;
2528 CAMHAL_LOGDB("pixelfmt=%d,resolution:%dx%d,"
2529 "FRAME TYPE is continuous,step=%d/%d s\n",
2530 pixelfmt_tbl[i],
2531 resolution_tbl[j].width,
2532 resolution_tbl[j].height,
2533 fival.stepwise.max.numerator,
2534 fival.stepwise.max.denominator);
2535 break;
2536 }
2537 else if (fival.type == V4L2_FRMIVAL_TYPE_STEPWISE)
2538 {
2539 CAMHAL_LOGDB("pixelfmt=%d,resolution:%dx%d,"
2540 "FRAME TYPE is step wise,step=%d/%d s\n",
2541 pixelfmt_tbl[i],
2542 resolution_tbl[j].width,
2543 resolution_tbl[j].height,
2544 fival.stepwise.step.numerator,
2545 fival.stepwise.step.denominator);
2546 framerate = fival.stepwise.max.denominator
2547 /fival.stepwise.max.numerator;
2548 break;
2549 }
2550
2551 fival.index++;
2552 }
2553 }
2554 }
2555
2556 *fps = framerate;
2557 *fps_num = 1;
2558
2559 CAMHAL_LOGDB("enum framerate=%d\n", framerate);
2560 if( framerate <= 1){
2561 return -1;
2562 }
2563
2564 return 0;
2565}
2566#endif
2567
2568
2569int V4LCamAdpt::set_white_balance(int camera_fd,const char *swb)
2570{
2571 int ret = 0;
2572 struct v4l2_control ctl;
2573 if(camera_fd<0)
2574 return -1;
2575
2576 ctl.id = V4L2_CID_DO_WHITE_BALANCE;
2577
2578 if(strcasecmp(swb,"auto")==0)
2579 ctl.value=CAM_WB_AUTO;
2580 else if(strcasecmp(swb,"daylight")==0)
2581 ctl.value=CAM_WB_DAYLIGHT;
2582 else if(strcasecmp(swb,"incandescent")==0)
2583 ctl.value=CAM_WB_INCANDESCENCE;
2584 else if(strcasecmp(swb,"fluorescent")==0)
2585 ctl.value=CAM_WB_FLUORESCENT;
2586 else if(strcasecmp(swb,"cloudy-daylight")==0)
2587 ctl.value=CAM_WB_CLOUD;
2588 else if(strcasecmp(swb,"shade")==0)
2589 ctl.value=CAM_WB_SHADE;
2590 else if(strcasecmp(swb,"twilight")==0)
2591 ctl.value=CAM_WB_TWILIGHT;
2592 else if(strcasecmp(swb,"warm-fluorescent")==0)
2593 ctl.value=CAM_WB_WARM_FLUORESCENT;
2594
2595 if(mWhiteBalance == ctl.value){
2596 return 0;
2597 }else{
2598 mWhiteBalance = ctl.value;
2599 }
2600 ret = ioctl(camera_fd, VIDIOC_S_CTRL, &ctl);
2601 if(ret<0){
2602 CAMHAL_LOGDB("Set white balance fail: %s. ret=%d", strerror(errno),ret);
2603 }
2604 return ret ;
2605}
2606
2607status_t V4LCamAdpt::getFocusMoveStatus()
2608{
2609 struct v4l2_control ctl;
2610 int ret;
2611
2612 if( (cur_focus_mode != CAM_FOCUS_MODE_CONTI_VID) &&
2613 (cur_focus_mode != CAM_FOCUS_MODE_CONTI_PIC) &&
2614 (cur_focus_mode != CAM_FOCUS_MODE_AUTO)){
2615 mFocusMoveEnabled = false;
2616 return 0;
2617 }
2618
2619 mFocusWaitCount --;
2620 if(mFocusWaitCount >= 0){
2621 return 0;
2622 }
2623 mFocusWaitCount = 0;
2624
2625 memset( &ctl, 0, sizeof(ctl));
2626 ctl.id =V4L2_CID_AUTO_FOCUS_STATUS;
2627 ret = ioctl(mCameraHandle, VIDIOC_G_CTRL, &ctl);
2628 if ( 0 > ret ){
2629 CAMHAL_LOGDA("V4L2_CID_AUTO_FOCUS_STATUS failed\n");
2630 return -EINVAL;
2631 }
2632
2633 if( ctl.value == V4L2_AUTO_FOCUS_STATUS_BUSY ){
2634 if(!bFocusMoveState){
2635 bFocusMoveState = true;
2636 notifyFocusMoveSubscribers(FOCUS_MOVE_START);
2637 }
2638 }else {
2639 mFocusWaitCount = FOCUS_PROCESS_FRAMES;
2640 if(bFocusMoveState){
2641 bFocusMoveState = false;
2642 notifyFocusMoveSubscribers(FOCUS_MOVE_STOP);
2643 }
2644 }
2645
2646 return ctl.value;
2647}
2648
2649extern "C" int V4LCamAdpt::SetExposure(int camera_fd,const char *sbn)
2650{
2651 int ret = 0;
2652 struct v4l2_control ctl;
2653 int level;
2654
2655 if(camera_fd<0)
2656 return -1;
2657
2658 level = atoi(sbn);
2659 if(mEV == level){
2660 return 0;
2661 }else{
2662 mEV = level;
2663 }
2664
2665 memset(&ctl, 0, sizeof(ctl));
2666
2667 ctl.id = V4L2_CID_EXPOSURE;
2668 ctl.value = level + (mEVmax - mEVmin)/2;
2669
2670 ret = ioctl(camera_fd, VIDIOC_S_CTRL, &ctl);
2671 if(ret<0){
2672 CAMHAL_LOGDB("Set Exposure fail: %s. ret=%d", strerror(errno),ret);
2673 }
2674
2675 return ret ;
2676}
2677
2678int V4LCamAdpt::set_effect(int camera_fd,const char *sef)
2679{
2680 int ret = 0;
2681 struct v4l2_control ctl;
2682 if(camera_fd<0)
2683 return -1;
2684
2685 memset(&ctl, 0, sizeof(ctl));
2686 ctl.id = V4L2_CID_COLORFX;
2687
2688 if(strcasecmp(sef,"none")==0)
2689 ctl.value=CAM_EFFECT_ENC_NORMAL;
2690 else if(strcasecmp(sef,"negative")==0)
2691 ctl.value=CAM_EFFECT_ENC_COLORINV;
2692 else if(strcasecmp(sef,"sepia")==0)
2693 ctl.value=CAM_EFFECT_ENC_SEPIA;
2694 ret = ioctl(camera_fd, VIDIOC_S_CTRL, &ctl);
2695 if(ret<0){
2696 CAMHAL_LOGDB("Set effect fail: %s. ret=%d", strerror(errno),ret);
2697 }
2698
2699 return ret;
2700}
2701
2702int V4LCamAdpt::set_night_mode(int camera_fd,const char *snm)
2703{
2704 int ret = 0;
2705 struct v4l2_control ctl;
2706 if(camera_fd<0)
2707 return -1;
2708
2709 memset( &ctl, 0, sizeof(ctl));
2710 if(strcasecmp(snm,"auto")==0)
2711 ctl.value=CAM_NM_AUTO;
2712 else if(strcasecmp(snm,"night")==0)
2713 ctl.value=CAM_NM_ENABLE;
2714
2715 ctl.id = V4L2_CID_DO_WHITE_BALANCE;
2716
2717 ret = ioctl(camera_fd, VIDIOC_S_CTRL, &ctl);
2718 if(ret<0){
2719 CAMHAL_LOGDB("Set night mode fail: %s. ret=%d", strerror(errno),ret);
2720 }
2721
2722 return ret;
2723}
2724
2725extern "C" int V4LCamAdpt::set_banding(int camera_fd,const char *snm)
2726{
2727 int ret = 0;
2728 struct v4l2_control ctl;
2729
2730 memset( &ctl, 0, sizeof(ctl));
2731 if(strcasecmp(snm,"50hz")==0)
2732 ctl.value= CAM_ANTIBANDING_50HZ;
2733 else if(strcasecmp(snm,"60hz")==0)
2734 ctl.value= CAM_ANTIBANDING_60HZ;
2735 else if(strcasecmp(snm,"auto")==0)
2736 ctl.value= CAM_ANTIBANDING_AUTO;
2737 else if(strcasecmp(snm,"off")==0)
2738 ctl.value= CAM_ANTIBANDING_OFF;
2739
2740 ctl.id = V4L2_CID_POWER_LINE_FREQUENCY;
2741
2742 if(mAntiBanding == ctl.value){
2743 return 0;
2744 }else{
2745 mAntiBanding = ctl.value;
2746 }
2747 ret = ioctl(camera_fd, VIDIOC_S_CTRL, &ctl);
2748 if(ret<0){
2749 CAMHAL_LOGDB("Set banding fail: %s. ret=%d",
2750 strerror(errno),ret);
2751 }
2752 return ret ;
2753}
2754
2755bool V4LCamAdpt::get_flash_mode(char *flash_status,
2756 char *def_flash_status)
2757{
2758 struct v4l2_queryctrl qc;
2759 struct v4l2_querymenu qm;
2760 bool flash_enable = false;
2761 int ret = NO_ERROR;
2762 int status_count = 0;
2763
2764 memset(&qc, 0, sizeof(qc));
2765 qc.id = V4L2_CID_BACKLIGHT_COMPENSATION;
2766 ret = ioctl (mCameraHandle, VIDIOC_QUERYCTRL, &qc);
2767 if((qc.flags == V4L2_CTRL_FLAG_DISABLED) ||( ret < 0) || (qc.type != V4L2_CTRL_TYPE_MENU)){
2768 flash_enable = false;
2769 CAMHAL_LOGDB("can't support flash, %s, ret=%d, %s\n",
2770 (qc.flags == V4L2_CTRL_FLAG_DISABLED)? "disable":"",
2771 ret, qc.type != V4L2_CTRL_TYPE_MENU?"":"type not right");
2772 }else {
2773 memset(&qm, 0, sizeof(qm));
2774 qm.id = V4L2_CID_BACKLIGHT_COMPENSATION;
2775 qm.index = qc.default_value;
2776 if(ioctl ( mCameraHandle, VIDIOC_QUERYMENU, &qm) < 0){
2777 strcpy(def_flash_status, "off");
2778 } else {
2779 strcpy(def_flash_status, (char*)qm.name);
2780 }
2781 int index = 0;
2782 for (index = qc.minimum; index <= qc.maximum; index+= qc.step) {
2783 memset(&qm, 0, sizeof(struct v4l2_querymenu));
2784 qm.id = V4L2_CID_BACKLIGHT_COMPENSATION;
2785 qm.index = index;
2786 if(ioctl (mCameraHandle, VIDIOC_QUERYMENU, &qm) < 0){
2787 continue;
2788 } else {
2789 if(status_count>0)
2790 strcat(flash_status, ",");
2791 strcat(flash_status, (char*)qm.name);
2792 status_count++;
2793 }
2794 }
2795 if(status_count>0)
2796 flash_enable = true;
2797 }
2798 return flash_enable;
2799}
2800
2801int V4LCamAdpt::set_flash_mode(int camera_fd, const char *sfm)
2802{
2803 int ret = NO_ERROR;
2804 struct v4l2_control ctl;
2805
2806 memset(&ctl, 0, sizeof(ctl));
2807 if(strcasecmp(sfm,"auto")==0)
2808 ctl.value=FLASHLIGHT_AUTO;
2809 else if(strcasecmp(sfm,"on")==0)
2810 ctl.value=FLASHLIGHT_ON;
2811 else if(strcasecmp(sfm,"off")==0)
2812 ctl.value=FLASHLIGHT_OFF;
2813 else if(strcasecmp(sfm,"torch")==0)
2814 ctl.value=FLASHLIGHT_TORCH;
2815 else if(strcasecmp(sfm,"red-eye")==0)
2816 ctl.value=FLASHLIGHT_RED_EYE;
2817
2818 ctl.id = V4L2_CID_BACKLIGHT_COMPENSATION;
2819 ret = ioctl( camera_fd, VIDIOC_S_CTRL, &ctl);
2820 if( ret < 0 ){
2821 CAMHAL_LOGDB("BACKLIGHT_COMPENSATION failed, errno=%d\n", errno);
2822 }
2823
2824 return ret;
2825}
2826
2827int V4LCamAdpt::get_hflip_mode(int camera_fd)
2828{
2829 struct v4l2_queryctrl qc;
2830 int ret = 0;
2831
2832 if(camera_fd<0){
2833 CAMHAL_LOGEA("Get_hflip_mode --camera handle is invalid\n");
2834 return -1;
2835 }
2836
2837 memset(&qc, 0, sizeof(qc));
2838 qc.id = V4L2_CID_HFLIP;
2839 ret = ioctl (camera_fd, VIDIOC_QUERYCTRL, &qc);
2840 if((qc.flags == V4L2_CTRL_FLAG_DISABLED) ||( ret < 0) || (qc.type != V4L2_CTRL_TYPE_INTEGER)){
2841 ret = -1;
2842 CAMHAL_LOGDB("can't support HFlip! %s ret=%d %s\n",
2843 (qc.flags == V4L2_CTRL_FLAG_DISABLED)?"disable":"",
2844 ret, (qc.type != V4L2_CTRL_TYPE_INTEGER)?"":"type not right");
2845 }else{
2846 CAMHAL_LOGDB("camera handle %d supports HFlip!\n",camera_fd);
2847 }
2848 return ret;
2849}
2850
2851
2852int V4LCamAdpt::set_hflip_mode(int camera_fd, bool mode)
2853{
2854 int ret = 0;
2855 struct v4l2_control ctl;
2856 if(camera_fd<0)
2857 return -1;
2858
2859 memset(&ctl, 0,sizeof(ctl));
2860 ctl.value=mode?1:0;
2861
2862 ctl.id = V4L2_CID_HFLIP;
2863
2864 ret = ioctl(camera_fd, VIDIOC_S_CTRL, &ctl);
2865 if(ret<0){
2866 CAMHAL_LOGEB("Set hflip mode fail: %s. ret=%d", strerror(errno),ret);
2867 }
2868 return ret ;
2869}
2870
2871int V4LCamAdpt::get_supported_zoom(int camera_fd, char * zoom_str)
2872{
2873 int ret = 0;
2874 struct v4l2_queryctrl qc;
2875 char str_zoom_element[10];
2876 if((camera_fd<0)||(!zoom_str))
2877 return -1;
2878
2879 memset(&qc, 0, sizeof(qc));
2880 qc.id = V4L2_CID_ZOOM_ABSOLUTE;
2881 ret = ioctl (camera_fd, VIDIOC_QUERYCTRL, &qc);
2882 if((qc.flags == V4L2_CTRL_FLAG_DISABLED) ||( ret < 0) || (qc.type != V4L2_CTRL_TYPE_INTEGER)){
2883 ret = -1;
2884 CAMHAL_LOGDB("camera handle %d can't get zoom level!\n",camera_fd);
2885 }else{
2886 int i = 0;
2887 ret = (qc.maximum - qc.minimum)/qc.step;
2888 for (i=qc.minimum; i<=qc.maximum; i+=qc.step) {
2889 memset(str_zoom_element,0,sizeof(str_zoom_element));
2890 sprintf(str_zoom_element,"%d,", i);
2891 strcat(zoom_str,str_zoom_element);
2892 }
2893 }
2894 return ret ;
2895}
2896
2897int V4LCamAdpt::set_zoom_level(int camera_fd, int zoom)
2898{
2899 int ret = 0;
2900 struct v4l2_control ctl;
2901 if((camera_fd<0)||(zoom<0))
2902 return -1;
2903
2904 memset( &ctl, 0, sizeof(ctl));
2905 ctl.value=zoom;
2906 ctl.id = V4L2_CID_ZOOM_ABSOLUTE;
2907 ret = ioctl(camera_fd, VIDIOC_S_CTRL, &ctl);
2908 if(ret<0){
2909 CAMHAL_LOGEB("Set zoom level fail: %s. ret=%d", strerror(errno),ret);
2910 }
2911
2912 return ret ;
2913}
2914
2915int V4LCamAdpt::set_rotate_value(int camera_fd, int value)
2916{
2917 int ret = 0;
2918 struct v4l2_control ctl;
2919 if(camera_fd<0)
2920 return -1;
2921
2922 if((value!=0)&&(value!=90)&&(value!=180)&&(value!=270)){
2923 CAMHAL_LOGEB("Set rotate value invalid: %d.", value);
2924 return -1;
2925 }
2926
2927 memset( &ctl, 0, sizeof(ctl));
2928
2929 ctl.value=value;
2930
2931 ctl.id = V4L2_ROTATE_ID;
2932
2933 ret = ioctl(camera_fd, VIDIOC_S_CTRL, &ctl);
2934 if(ret<0){
2935 CAMHAL_LOGEB("Set rotate value fail: %s. ret=%d", strerror(errno),ret);
2936 }
2937
2938 return ret ;
2939}
2940
2941};
2942
2943
2944/*--------------------Camera Adapter Class ENDS here-----------------------------*/
2945
2946