summaryrefslogtreecommitdiff
path: root/v3/fake-pipeline2/Sensor.cpp (plain)
blob: cf54b5d9b0e0c4e3fe7b8656897493aa4cc2e70f
1/*
2 * Copyright (C) 2012 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//#define LOG_NDEBUG 0
18//#define LOG_NNDEBUG 0
19#define LOG_TAG "EmulatedCamera3_Sensor"
20
21#ifdef LOG_NNDEBUG
22#define ALOGVV(...) ALOGV(__VA_ARGS__)
23#else
24#define ALOGVV(...) ((void)0)
25#endif
26
27#include <utils/Log.h>
28#include <cutils/properties.h>
29
30#include "../EmulatedFakeCamera2.h"
31#include "Sensor.h"
32#include <cmath>
33#include <cstdlib>
34#include <hardware/camera3.h>
35#include "system/camera_metadata.h"
36#include "libyuv.h"
37#include "NV12_resize.h"
38#include "libyuv/scale.h"
39#include "ge2d_stream.h"
40#include "util.h"
41#include <sys/time.h>
42
43
44#define ARRAY_SIZE(x) (sizeof((x))/sizeof(((x)[0])))
45
46namespace android {
47
48const unsigned int Sensor::kResolution[2] = {1600, 1200};
49
50const nsecs_t Sensor::kExposureTimeRange[2] =
51 {1000L, 30000000000L} ; // 1 us - 30 sec
52const nsecs_t Sensor::kFrameDurationRange[2] =
53 {33331760L, 30000000000L}; // ~1/30 s - 30 sec
54const nsecs_t Sensor::kMinVerticalBlank = 10000L;
55
56const uint8_t Sensor::kColorFilterArrangement =
57 ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT_RGGB;
58
59// Output image data characteristics
60const uint32_t Sensor::kMaxRawValue = 4000;
61const uint32_t Sensor::kBlackLevel = 1000;
62
63// Sensor sensitivity
64const float Sensor::kSaturationVoltage = 0.520f;
65const uint32_t Sensor::kSaturationElectrons = 2000;
66const float Sensor::kVoltsPerLuxSecond = 0.100f;
67
68const float Sensor::kElectronsPerLuxSecond =
69 Sensor::kSaturationElectrons / Sensor::kSaturationVoltage
70 * Sensor::kVoltsPerLuxSecond;
71
72const float Sensor::kBaseGainFactor = (float)Sensor::kMaxRawValue /
73 Sensor::kSaturationElectrons;
74
75const float Sensor::kReadNoiseStddevBeforeGain = 1.177; // in electrons
76const float Sensor::kReadNoiseStddevAfterGain = 2.100; // in digital counts
77const float Sensor::kReadNoiseVarBeforeGain =
78 Sensor::kReadNoiseStddevBeforeGain *
79 Sensor::kReadNoiseStddevBeforeGain;
80const float Sensor::kReadNoiseVarAfterGain =
81 Sensor::kReadNoiseStddevAfterGain *
82 Sensor::kReadNoiseStddevAfterGain;
83
84// While each row has to read out, reset, and then expose, the (reset +
85// expose) sequence can be overlapped by other row readouts, so the final
86// minimum frame duration is purely a function of row readout time, at least
87// if there's a reasonable number of rows.
88const nsecs_t Sensor::kRowReadoutTime =
89 Sensor::kFrameDurationRange[0] / Sensor::kResolution[1];
90
91const int32_t Sensor::kSensitivityRange[2] = {100, 1600};
92const uint32_t Sensor::kDefaultSensitivity = 100;
93
94const uint32_t kUsbAvailableSize [10] = {176, 144, 320, 240, 352, 288, 640, 480, 1280, 720};
95
96/** A few utility functions for math, normal distributions */
97
98// Take advantage of IEEE floating-point format to calculate an approximate
99// square root. Accurate to within +-3.6%
100float sqrtf_approx(float r) {
101 // Modifier is based on IEEE floating-point representation; the
102 // manipulations boil down to finding approximate log2, dividing by two, and
103 // then inverting the log2. A bias is added to make the relative error
104 // symmetric about the real answer.
105 const int32_t modifier = 0x1FBB4000;
106
107 int32_t r_i = *(int32_t*)(&r);
108 r_i = (r_i >> 1) + modifier;
109
110 return *(float*)(&r_i);
111}
112
113void rgb24_memcpy(unsigned char *dst, unsigned char *src, int width, int height)
114{
115 int stride = (width + 31) & ( ~31);
116 int w, h;
117 for (h=0; h<height; h++)
118 {
119 memcpy( dst, src, width*3);
120 dst += width*3;
121 src += stride*3;
122 }
123}
124
125static int ALIGN(int x, int y) {
126 // y must be a power of 2.
127 return (x + y - 1) & ~(y - 1);
128}
129
130bool IsUsbAvailableSize(const uint32_t kUsbAvailableSize[], uint32_t width, uint32_t height, int count)
131{
132 int i;
133 bool ret = false;
134 for (i = 0; i < count; i += 2) {
135 if ((width == kUsbAvailableSize[i]) && (height == kUsbAvailableSize[i+1])) {
136 ret = true;
137 } else {
138 continue;
139 }
140 }
141 return ret;
142}
143
144void ReSizeNV21(struct VideoInfo *vinfo, uint8_t *src, uint8_t *img, uint32_t width, uint32_t height)
145{
146 structConvImage input = {(mmInt32)vinfo->preview.format.fmt.pix.width,
147 (mmInt32)vinfo->preview.format.fmt.pix.height,
148 (mmInt32)vinfo->preview.format.fmt.pix.width,
149 IC_FORMAT_YCbCr420_lp,
150 (mmByte *) src,
151 (mmByte *) src + vinfo->preview.format.fmt.pix.width * vinfo->preview.format.fmt.pix.height,
152 0};
153
154 structConvImage output = {(mmInt32)width,
155 (mmInt32)height,
156 (mmInt32)width,
157 IC_FORMAT_YCbCr420_lp,
158 (mmByte *) img,
159 (mmByte *) img + width * height,
160 0};
161
162 if (!VT_resizeFrame_Video_opt2_lp(&input, &output, NULL, 0))
163 ALOGE("Sclale NV21 frame down failed!\n");
164}
165
166Sensor::Sensor():
167 Thread(false),
168 mGotVSync(false),
169 mExposureTime(kFrameDurationRange[0]-kMinVerticalBlank),
170 mFrameDuration(kFrameDurationRange[0]),
171 mGainFactor(kDefaultSensitivity),
172 mNextBuffers(NULL),
173 mFrameNumber(0),
174 mCapturedBuffers(NULL),
175 mListener(NULL),
176 mIoctlSupport(0),
177 msupportrotate(0),
178 mScene(kResolution[0], kResolution[1], kElectronsPerLuxSecond)
179{
180
181}
182
183Sensor::~Sensor() {
184 shutDown();
185}
186
187status_t Sensor::startUp(int idx) {
188 ALOGV("%s: E", __FUNCTION__);
189 DBG_LOGA("ddd");
190
191 int res;
192 mCapturedBuffers = NULL;
193 res = run("EmulatedFakeCamera2::Sensor",
194 ANDROID_PRIORITY_URGENT_DISPLAY);
195
196 if (res != OK) {
197 ALOGE("Unable to start up sensor capture thread: %d", res);
198 }
199
200 vinfo = (struct VideoInfo *) calloc(1, sizeof(*vinfo));
201 vinfo->idx = idx;
202
203 res = camera_open(vinfo);
204 if (res < 0) {
205 ALOGE("Unable to open sensor %d, errno=%d\n", vinfo->idx, res);
206 }
207
208 mSensorType = SENSOR_MMAP;
209 if (strstr((const char *)vinfo->cap.driver, "uvcvideo")) {
210 mSensorType = SENSOR_USB;
211 }
212
213 if (strstr((const char *)vinfo->cap.card, "share_fd")) {
214 mSensorType = SENSOR_SHARE_FD;
215 }
216
217 if (strstr((const char *)vinfo->cap.card, "front"))
218 mSensorFace = SENSOR_FACE_FRONT;
219 else if (strstr((const char *)vinfo->cap.card, "back"))
220 mSensorFace = SENSOR_FACE_BACK;
221 else
222 mSensorFace = SENSOR_FACE_NONE;
223
224 return res;
225}
226
227sensor_type_e Sensor::getSensorType(void)
228{
229 return mSensorType;
230}
231status_t Sensor::IoctlStateProbe(void) {
232 struct v4l2_queryctrl qc;
233 int ret = 0;
234 mIoctlSupport = 0;
235 memset(&qc, 0, sizeof(struct v4l2_queryctrl));
236 qc.id = V4L2_ROTATE_ID;
237 ret = ioctl (vinfo->fd, VIDIOC_QUERYCTRL, &qc);
238 if((qc.flags == V4L2_CTRL_FLAG_DISABLED) ||( ret < 0)|| (qc.type != V4L2_CTRL_TYPE_INTEGER)){
239 mIoctlSupport &= ~IOCTL_MASK_ROTATE;
240 }else{
241 mIoctlSupport |= IOCTL_MASK_ROTATE;
242 }
243
244 if(mIoctlSupport & IOCTL_MASK_ROTATE){
245 msupportrotate = true;
246 DBG_LOGA("camera support capture rotate");
247 }
248 return mIoctlSupport;
249}
250
251uint32_t Sensor::getStreamUsage(int stream_type)
252{
253 uint32_t usage = GRALLOC_USAGE_HW_CAMERA_WRITE;
254
255 switch (stream_type) {
256 case CAMERA3_STREAM_OUTPUT:
257 usage = GRALLOC_USAGE_HW_CAMERA_WRITE;
258 break;
259 case CAMERA3_STREAM_INPUT:
260 usage = GRALLOC_USAGE_HW_CAMERA_READ;
261 break;
262 case CAMERA3_STREAM_BIDIRECTIONAL:
263 usage = GRALLOC_USAGE_HW_CAMERA_READ |
264 GRALLOC_USAGE_HW_CAMERA_WRITE;
265 break;
266 }
267 if ((mSensorType == SENSOR_MMAP)
268 || (mSensorType == SENSOR_USB)) {
269 usage = (GRALLOC_USAGE_HW_TEXTURE
270 | GRALLOC_USAGE_HW_RENDER
271 | GRALLOC_USAGE_SW_READ_MASK
272 | GRALLOC_USAGE_SW_WRITE_MASK
273 );
274 }
275
276 return usage;
277}
278
279status_t Sensor::setOutputFormat(int width, int height, int pixelformat, bool isjpeg)
280{
281 int res;
282
283 mFramecount = 0;
284 mCurFps = 0;
285 gettimeofday(&mTimeStart, NULL);
286
287 if (isjpeg) {
288 vinfo->picture.format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
289 vinfo->picture.format.fmt.pix.width = width;
290 vinfo->picture.format.fmt.pix.height = height;
291 vinfo->picture.format.fmt.pix.pixelformat = pixelformat;
292 } else {
293 vinfo->preview.format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
294 vinfo->preview.format.fmt.pix.width = width;
295 vinfo->preview.format.fmt.pix.height = height;
296 vinfo->preview.format.fmt.pix.pixelformat = pixelformat;
297
298 res = setBuffersFormat(vinfo);
299 if (res < 0) {
300 ALOGE("set buffer failed\n");
301 return res;
302 }
303 }
304
305 return OK;
306
307}
308
309status_t Sensor::streamOn() {
310
311 return start_capturing(vinfo);
312}
313
314bool Sensor::isStreaming() {
315
316 return vinfo->isStreaming;
317}
318
319bool Sensor::isNeedRestart(uint32_t width, uint32_t height, uint32_t pixelformat)
320{
321 if ((vinfo->preview.format.fmt.pix.width != width)
322 ||(vinfo->preview.format.fmt.pix.height != height)
323 //||(vinfo->format.fmt.pix.pixelformat != pixelformat)
324 ) {
325
326 return true;
327
328 }
329
330 return false;
331}
332status_t Sensor::streamOff() {
333 if (mSensorType == SENSOR_USB) {
334 return releasebuf_and_stop_capturing(vinfo);
335 } else {
336 return stop_capturing(vinfo);
337 }
338}
339
340int Sensor::getOutputFormat()
341{
342 struct v4l2_fmtdesc fmt;
343 int ret;
344 memset(&fmt,0,sizeof(fmt));
345 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
346
347 fmt.index = 0;
348 while ((ret = ioctl(vinfo->fd, VIDIOC_ENUM_FMT, &fmt)) == 0){
349 if (fmt.pixelformat == V4L2_PIX_FMT_MJPEG)
350 return V4L2_PIX_FMT_MJPEG;
351 fmt.index++;
352 }
353
354 fmt.index = 0;
355 while ((ret = ioctl(vinfo->fd, VIDIOC_ENUM_FMT, &fmt)) == 0){
356 if (fmt.pixelformat == V4L2_PIX_FMT_NV21)
357 return V4L2_PIX_FMT_NV21;
358 fmt.index++;
359 }
360
361 fmt.index = 0;
362 while ((ret = ioctl(vinfo->fd, VIDIOC_ENUM_FMT, &fmt)) == 0){
363 if (fmt.pixelformat == V4L2_PIX_FMT_YUYV)
364 return V4L2_PIX_FMT_YUYV;
365 fmt.index++;
366 }
367
368 ALOGE("Unable to find a supported sensor format!");
369 return BAD_VALUE;
370}
371
372/* if sensor supports MJPEG, return it first, otherwise
373 * trasform HAL format to v4l2 format then check whether
374 * it is supported.
375 */
376int Sensor::halFormatToSensorFormat(uint32_t pixelfmt)
377{
378 struct v4l2_fmtdesc fmt;
379 int ret;
380 memset(&fmt,0,sizeof(fmt));
381 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
382
383 if (pixelfmt == HAL_PIXEL_FORMAT_YV12) {
384 pixelfmt = V4L2_PIX_FMT_YVU420;
385 } else if (pixelfmt == HAL_PIXEL_FORMAT_YCrCb_420_SP) {
386 pixelfmt = V4L2_PIX_FMT_NV21;
387 } else if (pixelfmt == HAL_PIXEL_FORMAT_YCbCr_422_I) {
388 pixelfmt = V4L2_PIX_FMT_YUYV;
389 } else {
390 pixelfmt = V4L2_PIX_FMT_NV21;
391 }
392
393 fmt.index = 0;
394 while ((ret = ioctl(vinfo->fd, VIDIOC_ENUM_FMT, &fmt)) == 0){
395 if (fmt.pixelformat == V4L2_PIX_FMT_MJPEG)
396 return V4L2_PIX_FMT_MJPEG;
397 fmt.index++;
398 }
399
400 fmt.index = 0;
401 while ((ret = ioctl(vinfo->fd, VIDIOC_ENUM_FMT, &fmt)) == 0){
402 if (fmt.pixelformat == pixelfmt)
403 return pixelfmt;
404 fmt.index++;
405 }
406
407 ALOGE("Unable to find a supported sensor format!");
408 return BAD_VALUE;
409}
410
411void Sensor::setPictureRotate(int rotate)
412{
413 mRotateValue = rotate;
414}
415int Sensor::getPictureRotate()
416{
417 return mRotateValue;
418}
419status_t Sensor::shutDown() {
420 ALOGV("%s: E", __FUNCTION__);
421
422 int res;
423 res = requestExitAndWait();
424 if (res != OK) {
425 ALOGE("Unable to shut down sensor capture thread: %d", res);
426 }
427
428 if (vinfo != NULL) {
429 if (mSensorType == SENSOR_USB) {
430 releasebuf_and_stop_capturing(vinfo);
431 } else {
432 stop_capturing(vinfo);
433 }
434 }
435
436 camera_close(vinfo);
437
438 if (vinfo){
439 free(vinfo);
440 vinfo = NULL;
441 }
442 ALOGD("%s: Exit", __FUNCTION__);
443 return res;
444}
445
446Scene &Sensor::getScene() {
447 return mScene;
448}
449
450int Sensor::getZoom(int *zoomMin, int *zoomMax, int *zoomStep)
451{
452 int ret = 0;
453 struct v4l2_queryctrl qc;
454
455 memset(&qc, 0, sizeof(qc));
456 qc.id = V4L2_CID_ZOOM_ABSOLUTE;
457 ret = ioctl (vinfo->fd, VIDIOC_QUERYCTRL, &qc);
458
459 if ((qc.flags == V4L2_CTRL_FLAG_DISABLED) || ( ret < 0)
460 || (qc.type != V4L2_CTRL_TYPE_INTEGER)) {
461 ret = -1;
462 *zoomMin = 0;
463 *zoomMax = 0;
464 *zoomStep = 1;
465 CAMHAL_LOGDB("%s: Can't get zoom level!\n", __FUNCTION__);
466 } else {
467 *zoomMin = qc.minimum;
468 *zoomMax = qc.maximum;
469 *zoomStep = qc.step;
470 DBG_LOGB("zoomMin:%dzoomMax:%dzoomStep:%d\n", *zoomMin, *zoomMax, *zoomStep);
471 }
472
473 return ret ;
474}
475
476int Sensor::setZoom(int zoomValue)
477{
478 int ret = 0;
479 struct v4l2_control ctl;
480
481 memset( &ctl, 0, sizeof(ctl));
482 ctl.value = zoomValue;
483 ctl.id = V4L2_CID_ZOOM_ABSOLUTE;
484 ret = ioctl(vinfo->fd, VIDIOC_S_CTRL, &ctl);
485 if (ret < 0) {
486 ALOGE("%s: Set zoom level failed!\n", __FUNCTION__);
487 }
488 return ret ;
489}
490
491status_t Sensor::setEffect(uint8_t effect)
492{
493 int ret = 0;
494 struct v4l2_control ctl;
495 ctl.id = V4L2_CID_COLORFX;
496
497 switch (effect) {
498 case ANDROID_CONTROL_EFFECT_MODE_OFF:
499 ctl.value= CAM_EFFECT_ENC_NORMAL;
500 break;
501 case ANDROID_CONTROL_EFFECT_MODE_NEGATIVE:
502 ctl.value= CAM_EFFECT_ENC_COLORINV;
503 break;
504 case ANDROID_CONTROL_EFFECT_MODE_SEPIA:
505 ctl.value= CAM_EFFECT_ENC_SEPIA;
506 break;
507 default:
508 ALOGE("%s: Doesn't support effect mode %d",
509 __FUNCTION__, effect);
510 return BAD_VALUE;
511 }
512
513 DBG_LOGB("set effect mode:%d", effect);
514 ret = ioctl(vinfo->fd, VIDIOC_S_CTRL, &ctl);
515 if (ret < 0) {
516 CAMHAL_LOGDB("Set effect fail: %s. ret=%d", strerror(errno),ret);
517 }
518 return ret ;
519}
520
521#define MAX_LEVEL_FOR_EXPOSURE 16
522#define MIN_LEVEL_FOR_EXPOSURE 3
523
524int Sensor::getExposure(int *maxExp, int *minExp, int *def, camera_metadata_rational *step)
525{
526 struct v4l2_queryctrl qc;
527 int ret=0;
528 int level = 0;
529 int middle = 0;
530
531 memset( &qc, 0, sizeof(qc));
532
533 DBG_LOGA("getExposure\n");
534 qc.id = V4L2_CID_EXPOSURE;
535 ret = ioctl(vinfo->fd, VIDIOC_QUERYCTRL, &qc);
536 if(ret < 0) {
537 CAMHAL_LOGDB("QUERYCTRL failed, errno=%d\n", errno);
538 *minExp = -4;
539 *maxExp = 4;
540 *def = 0;
541 step->numerator = 1;
542 step->denominator = 1;
543 return ret;
544 }
545
546 if(0 < qc.step)
547 level = ( qc.maximum - qc.minimum + 1 )/qc.step;
548
549 if((level > MAX_LEVEL_FOR_EXPOSURE)
550 || (level < MIN_LEVEL_FOR_EXPOSURE)){
551 *minExp = -4;
552 *maxExp = 4;
553 *def = 0;
554 step->numerator = 1;
555 step->denominator = 1;
556 DBG_LOGB("not in[min,max], min=%d, max=%d, def=%d\n",
557 *minExp, *maxExp, *def);
558 return true;
559 }
560
561 middle = (qc.minimum+qc.maximum)/2;
562 *minExp = qc.minimum - middle;
563 *maxExp = qc.maximum - middle;
564 *def = qc.default_value - middle;
565 step->numerator = 1;
566 step->denominator = 2;//qc.step;
567 DBG_LOGB("min=%d, max=%d, step=%d\n", qc.minimum, qc.maximum, qc.step);
568 return ret;
569}
570
571status_t Sensor::setExposure(int expCmp)
572{
573 int ret = 0;
574 struct v4l2_control ctl;
575 struct v4l2_queryctrl qc;
576
577 if(mEV == expCmp){
578 return 0;
579 }else{
580 mEV = expCmp;
581 }
582 memset(&ctl, 0, sizeof(ctl));
583 memset(&qc, 0, sizeof(qc));
584
585 qc.id = V4L2_CID_EXPOSURE;
586
587 ret = ioctl(vinfo->fd, VIDIOC_QUERYCTRL, &qc);
588 if (ret < 0) {
589 CAMHAL_LOGDB("AMLOGIC CAMERA get Exposure fail: %s. ret=%d", strerror(errno),ret);
590 }
591
592 ctl.id = V4L2_CID_EXPOSURE;
593 ctl.value = expCmp + (qc.maximum - qc.minimum) / 2;
594
595 ret = ioctl(vinfo->fd, VIDIOC_S_CTRL, &ctl);
596 if (ret < 0) {
597 CAMHAL_LOGDB("AMLOGIC CAMERA Set Exposure fail: %s. ret=%d", strerror(errno),ret);
598 }
599 DBG_LOGB("setExposure value%d mEVmin%d mEVmax%d\n",ctl.value, qc.minimum, qc.maximum);
600 return ret ;
601}
602
603int Sensor::getAntiBanding(uint8_t *antiBanding, uint8_t maxCont)
604{
605 struct v4l2_queryctrl qc;
606 struct v4l2_querymenu qm;
607 int ret;
608 int mode_count = -1;
609
610 memset(&qc, 0, sizeof(struct v4l2_queryctrl));
611 qc.id = V4L2_CID_POWER_LINE_FREQUENCY;
612 ret = ioctl (vinfo->fd, VIDIOC_QUERYCTRL, &qc);
613 if ( (ret<0) || (qc.flags == V4L2_CTRL_FLAG_DISABLED)){
614 DBG_LOGB("camera handle %d can't support this ctrl",vinfo->fd);
615 } else if ( qc.type != V4L2_CTRL_TYPE_INTEGER) {
616 DBG_LOGB("this ctrl of camera handle %d can't support menu type",vinfo->fd);
617 } else {
618 memset(&qm, 0, sizeof(qm));
619
620 int index = 0;
621 mode_count = 1;
622 antiBanding[0] = ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF;
623
624 for (index = qc.minimum; index <= qc.maximum; index+= qc.step) {
625 if (mode_count >= maxCont)
626 break;
627
628 memset(&qm, 0, sizeof(struct v4l2_querymenu));
629 qm.id = V4L2_CID_POWER_LINE_FREQUENCY;
630 qm.index = index;
631 if(ioctl (vinfo->fd, VIDIOC_QUERYMENU, &qm) < 0){
632 continue;
633 } else {
634 if (strcmp((char*)qm.name,"50hz") == 0) {
635 antiBanding[mode_count] = ANDROID_CONTROL_AE_ANTIBANDING_MODE_50HZ;
636 mode_count++;
637 } else if (strcmp((char*)qm.name,"60hz") == 0) {
638 antiBanding[mode_count] = ANDROID_CONTROL_AE_ANTIBANDING_MODE_60HZ;
639 mode_count++;
640 } else if (strcmp((char*)qm.name,"auto") == 0) {
641 antiBanding[mode_count] = ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO;
642 mode_count++;
643 }
644
645 }
646 }
647 }
648
649 return mode_count;
650}
651
652status_t Sensor::setAntiBanding(uint8_t antiBanding)
653{
654 int ret = 0;
655 struct v4l2_control ctl;
656 ctl.id = V4L2_CID_POWER_LINE_FREQUENCY;
657
658 switch (antiBanding) {
659 case ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF:
660 ctl.value= CAM_ANTIBANDING_OFF;
661 break;
662 case ANDROID_CONTROL_AE_ANTIBANDING_MODE_50HZ:
663 ctl.value= CAM_ANTIBANDING_50HZ;
664 break;
665 case ANDROID_CONTROL_AE_ANTIBANDING_MODE_60HZ:
666 ctl.value= CAM_ANTIBANDING_60HZ;
667 break;
668 case ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO:
669 ctl.value= CAM_ANTIBANDING_AUTO;
670 break;
671 default:
672 ALOGE("%s: Doesn't support ANTIBANDING mode %d",
673 __FUNCTION__, antiBanding);
674 return BAD_VALUE;
675 }
676
677 DBG_LOGB("anti banding mode:%d", antiBanding);
678 ret = ioctl(vinfo->fd, VIDIOC_S_CTRL, &ctl);
679 if ( ret < 0) {
680 CAMHAL_LOGDA("failed to set anti banding mode!\n");
681 return BAD_VALUE;
682 }
683 return ret;
684}
685
686status_t Sensor::setFocuasArea(int32_t x0, int32_t y0, int32_t x1, int32_t y1)
687{
688 int ret = 0;
689 struct v4l2_control ctl;
690 ctl.id = V4L2_CID_FOCUS_ABSOLUTE;
691 ctl.value = ((x0 + x1) / 2 + 1000) << 16;
692 ctl.value |= ((y0 + y1) / 2 + 1000) & 0xffff;
693
694 ret = ioctl(vinfo->fd, VIDIOC_S_CTRL, &ctl);
695 return ret;
696}
697
698
699int Sensor::getAutoFocus(uint8_t *afMode, uint8_t maxCount)
700{
701 struct v4l2_queryctrl qc;
702 struct v4l2_querymenu qm;
703 int ret;
704 int mode_count = -1;
705
706 memset(&qc, 0, sizeof(struct v4l2_queryctrl));
707 qc.id = V4L2_CID_FOCUS_AUTO;
708 ret = ioctl (vinfo->fd, VIDIOC_QUERYCTRL, &qc);
709 if( (ret<0) || (qc.flags == V4L2_CTRL_FLAG_DISABLED)){
710 DBG_LOGB("camera handle %d can't support this ctrl",vinfo->fd);
711 }else if( qc.type != V4L2_CTRL_TYPE_MENU) {
712 DBG_LOGB("this ctrl of camera handle %d can't support menu type",vinfo->fd);
713 }else{
714 memset(&qm, 0, sizeof(qm));
715
716 int index = 0;
717 mode_count = 1;
718 afMode[0] = ANDROID_CONTROL_AF_MODE_OFF;
719
720 for (index = qc.minimum; index <= qc.maximum; index+= qc.step) {
721 if (mode_count >= maxCount)
722 break;
723
724 memset(&qm, 0, sizeof(struct v4l2_querymenu));
725 qm.id = V4L2_CID_FOCUS_AUTO;
726 qm.index = index;
727 if(ioctl (vinfo->fd, VIDIOC_QUERYMENU, &qm) < 0){
728 continue;
729 } else {
730 if (strcmp((char*)qm.name,"auto") == 0) {
731 afMode[mode_count] = ANDROID_CONTROL_AF_MODE_AUTO;
732 mode_count++;
733 } else if (strcmp((char*)qm.name,"continuous-video") == 0) {
734 afMode[mode_count] = ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO;
735 mode_count++;
736 } else if (strcmp((char*)qm.name,"continuous-picture") == 0) {
737 afMode[mode_count] = ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE;
738 mode_count++;
739 }
740
741 }
742 }
743 }
744
745 return mode_count;
746}
747
748status_t Sensor::setAutoFocuas(uint8_t afMode)
749{
750 struct v4l2_control ctl;
751 ctl.id = V4L2_CID_FOCUS_AUTO;
752
753 switch (afMode) {
754 case ANDROID_CONTROL_AF_MODE_AUTO:
755 ctl.value = CAM_FOCUS_MODE_AUTO;
756 break;
757 case ANDROID_CONTROL_AF_MODE_MACRO:
758 ctl.value = CAM_FOCUS_MODE_MACRO;
759 break;
760 case ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO:
761 ctl.value = CAM_FOCUS_MODE_CONTI_VID;
762 break;
763 case ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE:
764 ctl.value = CAM_FOCUS_MODE_CONTI_PIC;
765 break;
766 default:
767 ALOGE("%s: Emulator doesn't support AF mode %d",
768 __FUNCTION__, afMode);
769 return BAD_VALUE;
770 }
771
772 if (ioctl(vinfo->fd, VIDIOC_S_CTRL, &ctl) < 0) {
773 CAMHAL_LOGDA("failed to set camera focuas mode!\n");
774 return BAD_VALUE;
775 }
776
777 return OK;
778}
779
780int Sensor::getAWB(uint8_t *awbMode, uint8_t maxCount)
781{
782 struct v4l2_queryctrl qc;
783 struct v4l2_querymenu qm;
784 int ret;
785 int mode_count = -1;
786
787 memset(&qc, 0, sizeof(struct v4l2_queryctrl));
788 qc.id = V4L2_CID_DO_WHITE_BALANCE;
789 ret = ioctl (vinfo->fd, VIDIOC_QUERYCTRL, &qc);
790 if( (ret<0) || (qc.flags == V4L2_CTRL_FLAG_DISABLED)){
791 DBG_LOGB("camera handle %d can't support this ctrl",vinfo->fd);
792 }else if( qc.type != V4L2_CTRL_TYPE_MENU) {
793 DBG_LOGB("this ctrl of camera handle %d can't support menu type",vinfo->fd);
794 }else{
795 memset(&qm, 0, sizeof(qm));
796
797 int index = 0;
798 mode_count = 1;
799 awbMode[0] = ANDROID_CONTROL_AWB_MODE_OFF;
800
801 for (index = qc.minimum; index <= qc.maximum; index+= qc.step) {
802 if (mode_count >= maxCount)
803 break;
804
805 memset(&qm, 0, sizeof(struct v4l2_querymenu));
806 qm.id = V4L2_CID_DO_WHITE_BALANCE;
807 qm.index = index;
808 if(ioctl (vinfo->fd, VIDIOC_QUERYMENU, &qm) < 0){
809 continue;
810 } else {
811 if (strcmp((char*)qm.name,"auto") == 0) {
812 awbMode[mode_count] = ANDROID_CONTROL_AWB_MODE_AUTO;
813 mode_count++;
814 } else if (strcmp((char*)qm.name,"daylight") == 0) {
815 awbMode[mode_count] = ANDROID_CONTROL_AWB_MODE_DAYLIGHT;
816 mode_count++;
817 } else if (strcmp((char*)qm.name,"incandescent") == 0) {
818 awbMode[mode_count] = ANDROID_CONTROL_AWB_MODE_INCANDESCENT;
819 mode_count++;
820 } else if (strcmp((char*)qm.name,"fluorescent") == 0) {
821 awbMode[mode_count] = ANDROID_CONTROL_AWB_MODE_FLUORESCENT;
822 mode_count++;
823 } else if (strcmp((char*)qm.name,"warm-fluorescent") == 0) {
824 awbMode[mode_count] = ANDROID_CONTROL_AWB_MODE_WARM_FLUORESCENT;
825 mode_count++;
826 } else if (strcmp((char*)qm.name,"cloudy-daylight") == 0) {
827 awbMode[mode_count] = ANDROID_CONTROL_AWB_MODE_CLOUDY_DAYLIGHT;
828 mode_count++;
829 } else if (strcmp((char*)qm.name,"twilight") == 0) {
830 awbMode[mode_count] = ANDROID_CONTROL_AWB_MODE_TWILIGHT;
831 mode_count++;
832 } else if (strcmp((char*)qm.name,"shade") == 0) {
833 awbMode[mode_count] = ANDROID_CONTROL_AWB_MODE_SHADE;
834 mode_count++;
835 }
836
837 }
838 }
839 }
840
841 return mode_count;
842}
843
844status_t Sensor::setAWB(uint8_t awbMode)
845{
846 int ret = 0;
847 struct v4l2_control ctl;
848 ctl.id = V4L2_CID_DO_WHITE_BALANCE;
849
850 switch (awbMode) {
851 case ANDROID_CONTROL_AWB_MODE_AUTO:
852 ctl.value = CAM_WB_AUTO;
853 break;
854 case ANDROID_CONTROL_AWB_MODE_INCANDESCENT:
855 ctl.value = CAM_WB_INCANDESCENCE;
856 break;
857 case ANDROID_CONTROL_AWB_MODE_FLUORESCENT:
858 ctl.value = CAM_WB_FLUORESCENT;
859 break;
860 case ANDROID_CONTROL_AWB_MODE_DAYLIGHT:
861 ctl.value = CAM_WB_DAYLIGHT;
862 break;
863 case ANDROID_CONTROL_AWB_MODE_SHADE:
864 ctl.value = CAM_WB_SHADE;
865 break;
866 default:
867 ALOGE("%s: Emulator doesn't support AWB mode %d",
868 __FUNCTION__, awbMode);
869 return BAD_VALUE;
870 }
871 ret = ioctl(vinfo->fd, VIDIOC_S_CTRL, &ctl);
872 return ret;
873}
874
875void Sensor::setExposureTime(uint64_t ns) {
876 Mutex::Autolock lock(mControlMutex);
877 ALOGVV("Exposure set to %f", ns/1000000.f);
878 mExposureTime = ns;
879}
880
881void Sensor::setFrameDuration(uint64_t ns) {
882 Mutex::Autolock lock(mControlMutex);
883 ALOGVV("Frame duration set to %f", ns/1000000.f);
884 mFrameDuration = ns;
885}
886
887void Sensor::setSensitivity(uint32_t gain) {
888 Mutex::Autolock lock(mControlMutex);
889 ALOGVV("Gain set to %d", gain);
890 mGainFactor = gain;
891}
892
893void Sensor::setDestinationBuffers(Buffers *buffers) {
894 Mutex::Autolock lock(mControlMutex);
895 mNextBuffers = buffers;
896}
897
898void Sensor::setFrameNumber(uint32_t frameNumber) {
899 Mutex::Autolock lock(mControlMutex);
900 mFrameNumber = frameNumber;
901}
902
903bool Sensor::waitForVSync(nsecs_t reltime) {
904 int res;
905 Mutex::Autolock lock(mControlMutex);
906
907 mGotVSync = false;
908 res = mVSync.waitRelative(mControlMutex, reltime);
909 if (res != OK && res != TIMED_OUT) {
910 ALOGE("%s: Error waiting for VSync signal: %d", __FUNCTION__, res);
911 return false;
912 }
913 return mGotVSync;
914}
915
916bool Sensor::waitForNewFrame(nsecs_t reltime,
917 nsecs_t *captureTime) {
918 Mutex::Autolock lock(mReadoutMutex);
919 uint8_t *ret;
920 if (mCapturedBuffers == NULL) {
921 int res;
922 res = mReadoutAvailable.waitRelative(mReadoutMutex, reltime);
923 if (res == TIMED_OUT) {
924 return false;
925 } else if (res != OK || mCapturedBuffers == NULL) {
926 ALOGE("Error waiting for sensor readout signal: %d", res);
927 return false;
928 }
929 } else {
930 mReadoutComplete.signal();
931 }
932
933 *captureTime = mCaptureTime;
934 mCapturedBuffers = NULL;
935 return true;
936}
937
938Sensor::SensorListener::~SensorListener() {
939}
940
941void Sensor::setSensorListener(SensorListener *listener) {
942 Mutex::Autolock lock(mControlMutex);
943 mListener = listener;
944}
945
946status_t Sensor::readyToRun() {
947 int res;
948 ALOGV("Starting up sensor thread");
949 mStartupTime = systemTime();
950 mNextCaptureTime = 0;
951 mNextCapturedBuffers = NULL;
952
953 DBG_LOGA("");
954
955 return OK;
956}
957
958bool Sensor::threadLoop() {
959 /**
960 * Sensor capture operation main loop.
961 *
962 * Stages are out-of-order relative to a single frame's processing, but
963 * in-order in time.
964 */
965
966 /**
967 * Stage 1: Read in latest control parameters
968 */
969 uint64_t exposureDuration;
970 uint64_t frameDuration;
971 uint32_t gain;
972 Buffers *nextBuffers;
973 uint32_t frameNumber;
974 SensorListener *listener = NULL;
975 {
976 Mutex::Autolock lock(mControlMutex);
977 exposureDuration = mExposureTime;
978 frameDuration = mFrameDuration;
979 gain = mGainFactor;
980 nextBuffers = mNextBuffers;
981 frameNumber = mFrameNumber;
982 listener = mListener;
983 // Don't reuse a buffer set
984 mNextBuffers = NULL;
985
986 // Signal VSync for start of readout
987 ALOGVV("Sensor VSync");
988 mGotVSync = true;
989 mVSync.signal();
990 }
991
992 /**
993 * Stage 3: Read out latest captured image
994 */
995
996 Buffers *capturedBuffers = NULL;
997 nsecs_t captureTime = 0;
998
999 nsecs_t startRealTime = systemTime();
1000 // Stagefright cares about system time for timestamps, so base simulated
1001 // time on that.
1002 nsecs_t simulatedTime = startRealTime;
1003 nsecs_t frameEndRealTime = startRealTime + frameDuration;
1004 nsecs_t frameReadoutEndRealTime = startRealTime +
1005 kRowReadoutTime * kResolution[1];
1006
1007 if (mNextCapturedBuffers != NULL) {
1008 ALOGVV("Sensor starting readout");
1009 // Pretend we're doing readout now; will signal once enough time has elapsed
1010 capturedBuffers = mNextCapturedBuffers;
1011 captureTime = mNextCaptureTime;
1012 }
1013 simulatedTime += kRowReadoutTime + kMinVerticalBlank;
1014
1015 // TODO: Move this signal to another thread to simulate readout
1016 // time properly
1017 if (capturedBuffers != NULL) {
1018 ALOGVV("Sensor readout complete");
1019 Mutex::Autolock lock(mReadoutMutex);
1020 if (mCapturedBuffers != NULL) {
1021 ALOGV("Waiting for readout thread to catch up!");
1022 mReadoutComplete.wait(mReadoutMutex);
1023 }
1024
1025 mCapturedBuffers = capturedBuffers;
1026 mCaptureTime = captureTime;
1027 mReadoutAvailable.signal();
1028 capturedBuffers = NULL;
1029 }
1030
1031 /**
1032 * Stage 2: Capture new image
1033 */
1034 mNextCaptureTime = simulatedTime;
1035 mNextCapturedBuffers = nextBuffers;
1036
1037 if (mNextCapturedBuffers != NULL) {
1038 if (listener != NULL) {
1039 listener->onSensorEvent(frameNumber, SensorListener::EXPOSURE_START,
1040 mNextCaptureTime);
1041 }
1042
1043 ALOGVV("Starting next capture: Exposure: %f ms, gain: %d",
1044 (float)exposureDuration/1e6, gain);
1045 mScene.setExposureDuration((float)exposureDuration/1e9);
1046 mScene.calculateScene(mNextCaptureTime);
1047
1048 if ( mSensorType == SENSOR_SHARE_FD) {
1049 captureNewImageWithGe2d();
1050 } else {
1051 captureNewImage();
1052 }
1053 mFramecount ++;
1054 }
1055 if (mFramecount == 100) {
1056 gettimeofday(&mTimeEnd, NULL);
1057 int64_t interval = (mTimeEnd.tv_sec - mTimeStart.tv_sec) * 1000000L + (mTimeEnd.tv_usec - mTimeStart.tv_usec);
1058 mCurFps = mFramecount/(interval/1000000.0f);
1059 memcpy(&mTimeStart, &mTimeEnd, sizeof(mTimeEnd));
1060 mFramecount = 0;
1061 CAMHAL_LOGIB("interval=%lld, interval=%f, fps=%f\n", interval, interval/1000000.0f, mCurFps);
1062 }
1063 ALOGVV("Sensor vertical blanking interval");
1064 nsecs_t workDoneRealTime = systemTime();
1065 const nsecs_t timeAccuracy = 2e6; // 2 ms of imprecision is ok
1066 if (workDoneRealTime < frameEndRealTime - timeAccuracy) {
1067 timespec t;
1068 t.tv_sec = (frameEndRealTime - workDoneRealTime) / 1000000000L;
1069 t.tv_nsec = (frameEndRealTime - workDoneRealTime) % 1000000000L;
1070
1071 int ret;
1072 do {
1073 ret = nanosleep(&t, &t);
1074 } while (ret != 0);
1075 }
1076 nsecs_t endRealTime = systemTime();
1077 ALOGVV("Frame cycle took %d ms, target %d ms",
1078 (int)((endRealTime - startRealTime)/1000000),
1079 (int)(frameDuration / 1000000));
1080 return true;
1081};
1082
1083int Sensor::captureNewImageWithGe2d() {
1084
1085 uint32_t gain = mGainFactor;
1086 mKernelPhysAddr = 0;
1087
1088
1089 while ((mKernelPhysAddr = get_frame_phys(vinfo)) == 0) {
1090 usleep(5000);
1091 }
1092
1093 // Might be adding more buffers, so size isn't constant
1094 for (size_t i = 0; i < mNextCapturedBuffers->size(); i++) {
1095 const StreamBuffer &b = (*mNextCapturedBuffers)[i];
1096 fillStream(vinfo, mKernelPhysAddr, b);
1097 }
1098 putback_frame(vinfo);
1099 mKernelPhysAddr = 0;
1100
1101 return 0;
1102
1103}
1104
1105int Sensor::captureNewImage() {
1106 bool isjpeg = false;
1107 uint32_t gain = mGainFactor;
1108 mKernelBuffer = NULL;
1109
1110 // Might be adding more buffers, so size isn't constant
1111 DBG_LOGB("size=%d\n", mNextCapturedBuffers->size());
1112 for (size_t i = 0; i < mNextCapturedBuffers->size(); i++) {
1113 const StreamBuffer &b = (*mNextCapturedBuffers)[i];
1114 ALOGVV("Sensor capturing buffer %d: stream %d,"
1115 " %d x %d, format %x, stride %d, buf %p, img %p",
1116 i, b.streamId, b.width, b.height, b.format, b.stride,
1117 b.buffer, b.img);
1118 switch (b.format) {
1119 case HAL_PIXEL_FORMAT_RAW_SENSOR:
1120 captureRaw(b.img, gain, b.stride);
1121 break;
1122 case HAL_PIXEL_FORMAT_RGB_888:
1123 captureRGB(b.img, gain, b.stride);
1124 break;
1125 case HAL_PIXEL_FORMAT_RGBA_8888:
1126 captureRGBA(b.img, gain, b.stride);
1127 break;
1128 case HAL_PIXEL_FORMAT_BLOB:
1129 // Add auxillary buffer of the right size
1130 // Assumes only one BLOB (JPEG) buffer in
1131 // mNextCapturedBuffers
1132 isjpeg = true;
1133 StreamBuffer bAux;
1134 int orientation;
1135 orientation = getPictureRotate();
1136 ALOGD("bAux orientation=%d",orientation);
1137 if (!msupportrotate) {
1138 bAux.streamId = 0;
1139 bAux.width = b.width;
1140 bAux.height = b.height;
1141 bAux.format = HAL_PIXEL_FORMAT_RGB_888;
1142 bAux.stride = b.width;
1143 bAux.buffer = NULL;
1144 } else {
1145 if ((orientation == 90) || (orientation == 270)) {
1146 bAux.streamId = 0;
1147 bAux.width = b.height;
1148 bAux.height = b.width;
1149 bAux.format = HAL_PIXEL_FORMAT_RGB_888;
1150 bAux.stride = b.height;
1151 bAux.buffer = NULL;
1152 } else {
1153 bAux.streamId = 0;
1154 bAux.width = b.width;
1155 bAux.height = b.height;
1156 bAux.format = HAL_PIXEL_FORMAT_RGB_888;
1157 bAux.stride = b.width;
1158 bAux.buffer = NULL;
1159 }
1160 }
1161 // TODO: Reuse these
1162 bAux.img = new uint8_t[b.width * b.height * 3];
1163 mNextCapturedBuffers->push_back(bAux);
1164 break;
1165 case HAL_PIXEL_FORMAT_YCrCb_420_SP:
1166 case HAL_PIXEL_FORMAT_YCbCr_420_888:
1167 captureNV21(b, gain);
1168 break;
1169 case HAL_PIXEL_FORMAT_YV12:
1170 captureYV12(b, gain);
1171 break;
1172 case HAL_PIXEL_FORMAT_YCbCr_422_I:
1173 captureYUYV(b.img, gain, b.stride);
1174 break;
1175 default:
1176 ALOGE("%s: Unknown format %x, no output", __FUNCTION__,
1177 b.format);
1178 break;
1179 }
1180 }
1181 if (!isjpeg) { //jpeg buffer that is rgb888 has been save in the different buffer struct;
1182 // whose buffer putback separately.
1183 putback_frame(vinfo);
1184 }
1185 mKernelBuffer = NULL;
1186
1187 return 0;
1188}
1189
1190int Sensor::getStreamConfigurations(uint32_t picSizes[], const int32_t kAvailableFormats[], int size) {
1191 int res;
1192 int i, j, k, START;
1193 int count = 0;
1194 int pixelfmt;
1195 struct v4l2_frmsizeenum frmsize;
1196 char property[PROPERTY_VALUE_MAX];
1197 unsigned int support_w,support_h;
1198
1199 support_w = 10000;
1200 support_h = 10000;
1201 memset(property, 0, sizeof(property));
1202 if(property_get("ro.camera.preview.MaxSize", property, NULL) > 0){
1203 CAMHAL_LOGDB("support Max Preview Size :%s",property);
1204 if(sscanf(property,"%dx%d",&support_w,&support_h)!=2){
1205 support_w = 10000;
1206 support_h = 10000;
1207 }
1208 }
1209
1210 memset(&frmsize,0,sizeof(frmsize));
1211 frmsize.pixel_format = getOutputFormat();
1212
1213 START = 0;
1214 for (i = 0; ; i++) {
1215 frmsize.index = i;
1216 res = ioctl(vinfo->fd, VIDIOC_ENUM_FRAMESIZES, &frmsize);
1217 if (res < 0){
1218 DBG_LOGB("index=%d, break\n", i);
1219 break;
1220 }
1221
1222 if(frmsize.type == V4L2_FRMSIZE_TYPE_DISCRETE){ //only support this type
1223
1224 if (0 != (frmsize.discrete.width%16))
1225 continue;
1226
1227 if((frmsize.discrete.width > support_w) && (frmsize.discrete.height >support_h))
1228 continue;
1229
1230 if (count >= size)
1231 break;
1232
1233 if ((frmsize.pixel_format == V4L2_PIX_FMT_MJPEG) || (frmsize.pixel_format == V4L2_PIX_FMT_YUYV)) {
1234 int count = sizeof(kUsbAvailableSize)/sizeof(kUsbAvailableSize[0]);
1235 if (!IsUsbAvailableSize(kUsbAvailableSize, frmsize.discrete.width, frmsize.discrete.height,count))
1236 continue;
1237 }
1238
1239 picSizes[count+0] = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
1240 picSizes[count+1] = frmsize.discrete.width;
1241 picSizes[count+2] = frmsize.discrete.height;
1242 picSizes[count+3] = ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT;
1243
1244 DBG_LOGB("get output width=%d, height=%d, format=%d\n",
1245 frmsize.discrete.width, frmsize.discrete.height, frmsize.pixel_format);
1246 if (0 == i) {
1247 count += 4;
1248 continue;
1249 }
1250
1251 for (k = count; k > START; k -= 4) {
1252 if (frmsize.discrete.width * frmsize.discrete.height >
1253 picSizes[k - 3] * picSizes[k - 2]) {
1254 picSizes[k + 1] = picSizes[k - 3];
1255 picSizes[k + 2] = picSizes[k - 2];
1256
1257 } else {
1258 break;
1259 }
1260 }
1261 picSizes[k + 1] = frmsize.discrete.width;
1262 picSizes[k + 2] = frmsize.discrete.height;
1263
1264 count += 4;
1265 }
1266 }
1267
1268 START = count;
1269 for (i = 0; ; i++) {
1270 frmsize.index = i;
1271 res = ioctl(vinfo->fd, VIDIOC_ENUM_FRAMESIZES, &frmsize);
1272 if (res < 0){
1273 DBG_LOGB("index=%d, break\n", i);
1274 break;
1275 }
1276
1277 if(frmsize.type == V4L2_FRMSIZE_TYPE_DISCRETE){ //only support this type
1278
1279 if (0 != (frmsize.discrete.width%16))
1280 continue;
1281
1282 if((frmsize.discrete.width > support_w) && (frmsize.discrete.height >support_h))
1283 continue;
1284
1285 if (count >= size)
1286 break;
1287
1288 if ((frmsize.pixel_format == V4L2_PIX_FMT_MJPEG) || (frmsize.pixel_format == V4L2_PIX_FMT_YUYV)) {
1289 int count = sizeof(kUsbAvailableSize)/sizeof(kUsbAvailableSize[0]);
1290 if (!IsUsbAvailableSize(kUsbAvailableSize, frmsize.discrete.width, frmsize.discrete.height,count))
1291 continue;
1292 }
1293
1294 picSizes[count+0] = HAL_PIXEL_FORMAT_YCbCr_420_888;
1295 picSizes[count+1] = frmsize.discrete.width;
1296 picSizes[count+2] = frmsize.discrete.height;
1297 picSizes[count+3] = ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT;
1298
1299 DBG_LOGB("get output width=%d, height=%d, format =\
1300 HAL_PIXEL_FORMAT_YCbCr_420_888\n", frmsize.discrete.width,
1301 frmsize.discrete.height);
1302 if (0 == i) {
1303 count += 4;
1304 continue;
1305 }
1306
1307 for (k = count; k > START; k -= 4) {
1308 if (frmsize.discrete.width * frmsize.discrete.height >
1309 picSizes[k - 3] * picSizes[k - 2]) {
1310 picSizes[k + 1] = picSizes[k - 3];
1311 picSizes[k + 2] = picSizes[k - 2];
1312
1313 } else {
1314 break;
1315 }
1316 }
1317 picSizes[k + 1] = frmsize.discrete.width;
1318 picSizes[k + 2] = frmsize.discrete.height;
1319
1320 count += 4;
1321 }
1322 }
1323
1324#if 0
1325 if (frmsize.pixel_format == V4L2_PIX_FMT_YUYV) {
1326 START = count;
1327 for (i = 0; ; i++) {
1328 frmsize.index = i;
1329 res = ioctl(vinfo->fd, VIDIOC_ENUM_FRAMESIZES, &frmsize);
1330 if (res < 0){
1331 DBG_LOGB("index=%d, break\n", i);
1332 break;
1333 }
1334
1335 if(frmsize.type == V4L2_FRMSIZE_TYPE_DISCRETE){ //only support this type
1336
1337 if (0 != (frmsize.discrete.width%16))
1338 continue;
1339
1340 if((frmsize.discrete.width > support_w) && (frmsize.discrete.height >support_h))
1341 continue;
1342
1343 if (count >= size)
1344 break;
1345
1346 picSizes[count+0] = HAL_PIXEL_FORMAT_YCbCr_422_I;
1347 picSizes[count+1] = frmsize.discrete.width;
1348 picSizes[count+2] = frmsize.discrete.height;
1349 picSizes[count+3] = ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT;
1350
1351 DBG_LOGB("get output width=%d, height=%d, format =\
1352 HAL_PIXEL_FORMAT_YCbCr_420_888\n", frmsize.discrete.width,
1353 frmsize.discrete.height);
1354 if (0 == i) {
1355 count += 4;
1356 continue;
1357 }
1358
1359 for (k = count; k > START; k -= 4) {
1360 if (frmsize.discrete.width * frmsize.discrete.height >
1361 picSizes[k - 3] * picSizes[k - 2]) {
1362 picSizes[k + 1] = picSizes[k - 3];
1363 picSizes[k + 2] = picSizes[k - 2];
1364
1365 } else {
1366 break;
1367 }
1368 }
1369 picSizes[k + 1] = frmsize.discrete.width;
1370 picSizes[k + 2] = frmsize.discrete.height;
1371
1372 count += 4;
1373 }
1374 }
1375 }
1376#endif
1377
1378 uint32_t jpgSrcfmt[] = {
1379 V4L2_PIX_FMT_RGB24,
1380 V4L2_PIX_FMT_MJPEG,
1381 V4L2_PIX_FMT_YUYV,
1382 };
1383
1384 START = count;
1385 for (j = 0; j<(int)(sizeof(jpgSrcfmt)/sizeof(jpgSrcfmt[0])); j++) {
1386 memset(&frmsize,0,sizeof(frmsize));
1387 frmsize.pixel_format = jpgSrcfmt[j];
1388
1389 for (i = 0; ; i++) {
1390 frmsize.index = i;
1391 res = ioctl(vinfo->fd, VIDIOC_ENUM_FRAMESIZES, &frmsize);
1392 if (res < 0){
1393 DBG_LOGB("index=%d, break\n", i);
1394 break;
1395 }
1396
1397 if(frmsize.type == V4L2_FRMSIZE_TYPE_DISCRETE){ //only support this type
1398
1399 if (0 != (frmsize.discrete.width%16))
1400 continue;
1401
1402 //if((frmsize.discrete.width > support_w) && (frmsize.discrete.height >support_h))
1403 // continue;
1404
1405 if (count >= size)
1406 break;
1407
1408 picSizes[count+0] = HAL_PIXEL_FORMAT_BLOB;
1409 picSizes[count+1] = frmsize.discrete.width;
1410 picSizes[count+2] = frmsize.discrete.height;
1411 picSizes[count+3] = ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT;
1412
1413 if (0 == i) {
1414 count += 4;
1415 continue;
1416 }
1417
1418 //TODO insert in descend order
1419 for (k = count; k > START; k -= 4) {
1420 if (frmsize.discrete.width * frmsize.discrete.height >
1421 picSizes[k - 3] * picSizes[k - 2]) {
1422 picSizes[k + 1] = picSizes[k - 3];
1423 picSizes[k + 2] = picSizes[k - 2];
1424
1425 } else {
1426 break;
1427 }
1428 }
1429
1430 picSizes[k + 1] = frmsize.discrete.width;
1431 picSizes[k + 2] = frmsize.discrete.height;
1432
1433 count += 4;
1434 }
1435 }
1436
1437 if (frmsize.index > 0)
1438 break;
1439 }
1440
1441 if (frmsize.index == 0)
1442 CAMHAL_LOGDA("no support pixel fmt for jpeg");
1443
1444 return count;
1445
1446}
1447
1448int Sensor::getStreamConfigurationDurations(uint32_t picSizes[], int64_t duration[], int size)
1449{
1450 int ret=0; int framerate=0; int temp_rate=0;
1451 struct v4l2_frmivalenum fival;
1452 int i,j=0;
1453 int count = 0;
1454 int tmp_size = size;
1455 memset(duration, 0 ,sizeof(int64_t)*ARRAY_SIZE(duration));
1456 int pixelfmt_tbl[] = {
1457 V4L2_PIX_FMT_MJPEG,
1458 V4L2_PIX_FMT_YVU420,
1459 V4L2_PIX_FMT_NV21,
1460 V4L2_PIX_FMT_RGB24,
1461 V4L2_PIX_FMT_YUYV,
1462 // V4L2_PIX_FMT_YVU420
1463 };
1464
1465 for( i = 0; i < (int) ARRAY_SIZE(pixelfmt_tbl); i++)
1466 {
1467 for( ; size > 0; size-=4)
1468 {
1469 memset(&fival, 0, sizeof(fival));
1470
1471 for (fival.index = 0;;fival.index++)
1472 {
1473 fival.pixel_format = pixelfmt_tbl[i];
1474 fival.width = picSizes[size-3];
1475 fival.height = picSizes[size-2];
1476 if((ret = ioctl(vinfo->fd, VIDIOC_ENUM_FRAMEINTERVALS, &fival)) == 0) {
1477 if (fival.type == V4L2_FRMIVAL_TYPE_DISCRETE){
1478 temp_rate = fival.discrete.denominator/fival.discrete.numerator;
1479 if(framerate < temp_rate)
1480 framerate = temp_rate;
1481 duration[count+0] = (int64_t)(picSizes[size-4]);
1482 duration[count+1] = (int64_t)(picSizes[size-3]);
1483 duration[count+2] = (int64_t)(picSizes[size-2]);
1484 duration[count+3] = (int64_t)66666666L;//(int64_t)(framerate), here we can get frame interval from camera driver
1485 j++;
1486 } else if (fival.type == V4L2_FRMIVAL_TYPE_CONTINUOUS){
1487 temp_rate = fival.discrete.denominator/fival.discrete.numerator;
1488 if(framerate < temp_rate)
1489 framerate = temp_rate;
1490 duration[count+0] = (int64_t)picSizes[size-4];
1491 duration[count+1] = (int64_t)picSizes[size-3];
1492 duration[count+2] = (int64_t)picSizes[size-2];
1493 duration[count+3] = (int64_t)66666666L;//(int64_t)(framerate), here we can get frame interval from camera driver
1494 j++;
1495 } else if (fival.type == V4L2_FRMIVAL_TYPE_STEPWISE){
1496 temp_rate = fival.discrete.denominator/fival.discrete.numerator;
1497 if(framerate < temp_rate)
1498 framerate = temp_rate;
1499 duration[count+0] = (int64_t)picSizes[size-4];
1500 duration[count+1] = (int64_t)picSizes[size-3];
1501 duration[count+2] = (int64_t)picSizes[size-2];
1502 duration[count+3] = (int64_t)66666666L;//(int64_t)(framerate), here we can get frame interval from camera driver
1503 j++;
1504 }
1505 } else {
1506 if (j > 0) {
1507 if (count > tmp_size)
1508 break;
1509 duration[count+0] = (int64_t)(picSizes[size-4]);
1510 duration[count+1] = (int64_t)(picSizes[size-3]);
1511 duration[count+2] = (int64_t)(picSizes[size-2]);
1512 if (framerate == 5) {
1513 duration[count+3] = (int64_t)200000000L;
1514 } else if (framerate == 10) {
1515 duration[count+3] = (int64_t)100000000L;
1516 } else if (framerate == 15) {
1517 duration[count+3] = (int64_t)66666666L;
1518 } else if (framerate == 30) {
1519 duration[count+3] = (int64_t)33333333L;
1520 } else {
1521 duration[count+3] = (int64_t)66666666L;
1522 }
1523 count += 4;
1524 break;
1525 } else {
1526 break;
1527 }
1528 }
1529 }
1530 j=0;
1531 }
1532 size = tmp_size;
1533 }
1534
1535 return count;
1536
1537}
1538
1539int64_t Sensor::getMinFrameDuration()
1540{
1541 int64_t tmpDuration = 66666666L; // 1/15 s
1542 int64_t frameDuration = 66666666L; // 1/15 s
1543 struct v4l2_frmivalenum fival;
1544 int i,j;
1545
1546 uint32_t pixelfmt_tbl[]={
1547 V4L2_PIX_FMT_MJPEG,
1548 V4L2_PIX_FMT_YUYV,
1549 V4L2_PIX_FMT_NV21,
1550 };
1551 struct v4l2_frmsize_discrete resolution_tbl[]={
1552 {1920, 1080},
1553 {1280, 960},
1554 {640, 480},
1555 {320, 240},
1556 };
1557
1558 for (i = 0; i < (int)ARRAY_SIZE(pixelfmt_tbl); i++) {
1559 for (j = 0; j < (int) ARRAY_SIZE(resolution_tbl); j++) {
1560 memset(&fival, 0, sizeof(fival));
1561 fival.index = 0;
1562 fival.pixel_format = pixelfmt_tbl[i];
1563 fival.width = resolution_tbl[j].width;
1564 fival.height = resolution_tbl[j].height;
1565
1566 while (ioctl(vinfo->fd, VIDIOC_ENUM_FRAMEINTERVALS, &fival) == 0) {
1567 if (fival.type == V4L2_FRMIVAL_TYPE_DISCRETE) {
1568 tmpDuration =
1569 fival.discrete.numerator * 1000000000L / fival.discrete.denominator;
1570
1571 if (frameDuration > tmpDuration)
1572 frameDuration = tmpDuration;
1573 } else if (fival.type == V4L2_FRMIVAL_TYPE_CONTINUOUS) {
1574 frameDuration =
1575 fival.stepwise.max.numerator * 1000000000L / fival.stepwise.max.denominator;
1576 break;
1577 } else if (fival.type == V4L2_FRMIVAL_TYPE_STEPWISE) {
1578 frameDuration =
1579 fival.stepwise.max.numerator * 1000000000L / fival.stepwise.max.denominator;
1580 break;
1581 }
1582 fival.index++;
1583 }
1584 }
1585
1586 if (fival.index > 0) {
1587 break;
1588 }
1589 }
1590
1591 CAMHAL_LOGDB("enum frameDuration=%lld\n", frameDuration);
1592 return frameDuration;
1593}
1594
1595int Sensor::getPictureSizes(int32_t picSizes[], int size, bool preview) {
1596 int res;
1597 int i;
1598 int count = 0;
1599 struct v4l2_frmsizeenum frmsize;
1600 char property[PROPERTY_VALUE_MAX];
1601 unsigned int support_w,support_h;
1602 int preview_fmt;
1603
1604 support_w = 10000;
1605 support_h = 10000;
1606 memset(property, 0, sizeof(property));
1607 if(property_get("ro.camera.preview.MaxSize", property, NULL) > 0){
1608 CAMHAL_LOGDB("support Max Preview Size :%s",property);
1609 if(sscanf(property,"%dx%d",&support_w,&support_h)!=2){
1610 support_w = 10000;
1611 support_h = 10000;
1612 }
1613 }
1614
1615
1616 memset(&frmsize,0,sizeof(frmsize));
1617 preview_fmt = V4L2_PIX_FMT_NV21;//getOutputFormat();
1618
1619 if (preview_fmt == V4L2_PIX_FMT_MJPEG)
1620 frmsize.pixel_format = V4L2_PIX_FMT_MJPEG;
1621 else if (preview_fmt == V4L2_PIX_FMT_NV21) {
1622 if (preview == true)
1623 frmsize.pixel_format = V4L2_PIX_FMT_NV21;
1624 else
1625 frmsize.pixel_format = V4L2_PIX_FMT_RGB24;
1626 } else if (preview_fmt == V4L2_PIX_FMT_YVU420) {
1627 if (preview == true)
1628 frmsize.pixel_format = V4L2_PIX_FMT_YVU420;
1629 else
1630 frmsize.pixel_format = V4L2_PIX_FMT_RGB24;
1631 } else if (preview_fmt == V4L2_PIX_FMT_YUYV)
1632 frmsize.pixel_format = V4L2_PIX_FMT_YUYV;
1633
1634 for (i = 0; ; i++) {
1635 frmsize.index = i;
1636 res = ioctl(vinfo->fd, VIDIOC_ENUM_FRAMESIZES, &frmsize);
1637 if (res < 0){
1638 DBG_LOGB("index=%d, break\n", i);
1639 break;
1640 }
1641
1642
1643 if(frmsize.type == V4L2_FRMSIZE_TYPE_DISCRETE){ //only support this type
1644
1645 if (0 != (frmsize.discrete.width%16))
1646 continue;
1647
1648 if((frmsize.discrete.width > support_w) && (frmsize.discrete.height >support_h))
1649 continue;
1650
1651 if (count >= size)
1652 break;
1653
1654 picSizes[count] = frmsize.discrete.width;
1655 picSizes[count+1] = frmsize.discrete.height;
1656
1657 if (0 == i) {
1658 count += 2;
1659 continue;
1660 }
1661
1662 //TODO insert in descend order
1663 if (picSizes[count + 0] * picSizes[count + 1] > picSizes[count - 1] * picSizes[count - 2]) {
1664 picSizes[count + 0] = picSizes[count - 2];
1665 picSizes[count + 1] = picSizes[count - 1];
1666
1667 picSizes[count - 2] = frmsize.discrete.width;
1668 picSizes[count - 1] = frmsize.discrete.height;
1669 }
1670
1671 count += 2;
1672 }
1673 }
1674
1675 return count;
1676
1677}
1678
1679void Sensor::captureRaw(uint8_t *img, uint32_t gain, uint32_t stride) {
1680 float totalGain = gain/100.0 * kBaseGainFactor;
1681 float noiseVarGain = totalGain * totalGain;
1682 float readNoiseVar = kReadNoiseVarBeforeGain * noiseVarGain
1683 + kReadNoiseVarAfterGain;
1684
1685 int bayerSelect[4] = {Scene::R, Scene::Gr, Scene::Gb, Scene::B}; // RGGB
1686 mScene.setReadoutPixel(0,0);
1687 for (unsigned int y = 0; y < kResolution[1]; y++ ) {
1688 int *bayerRow = bayerSelect + (y & 0x1) * 2;
1689 uint16_t *px = (uint16_t*)img + y * stride;
1690 for (unsigned int x = 0; x < kResolution[0]; x++) {
1691 uint32_t electronCount;
1692 electronCount = mScene.getPixelElectrons()[bayerRow[x & 0x1]];
1693
1694 // TODO: Better pixel saturation curve?
1695 electronCount = (electronCount < kSaturationElectrons) ?
1696 electronCount : kSaturationElectrons;
1697
1698 // TODO: Better A/D saturation curve?
1699 uint16_t rawCount = electronCount * totalGain;
1700 rawCount = (rawCount < kMaxRawValue) ? rawCount : kMaxRawValue;
1701
1702 // Calculate noise value
1703 // TODO: Use more-correct Gaussian instead of uniform noise
1704 float photonNoiseVar = electronCount * noiseVarGain;
1705 float noiseStddev = sqrtf_approx(readNoiseVar + photonNoiseVar);
1706 // Scaled to roughly match gaussian/uniform noise stddev
1707 float noiseSample = std::rand() * (2.5 / (1.0 + RAND_MAX)) - 1.25;
1708
1709 rawCount += kBlackLevel;
1710 rawCount += noiseStddev * noiseSample;
1711
1712 *px++ = rawCount;
1713 }
1714 // TODO: Handle this better
1715 //simulatedTime += kRowReadoutTime;
1716 }
1717 ALOGVV("Raw sensor image captured");
1718}
1719
1720void Sensor::captureRGBA(uint8_t *img, uint32_t gain, uint32_t stride) {
1721 float totalGain = gain/100.0 * kBaseGainFactor;
1722 // In fixed-point math, calculate total scaling from electrons to 8bpp
1723 int scale64x = 64 * totalGain * 255 / kMaxRawValue;
1724 uint32_t inc = kResolution[0] / stride;
1725
1726 for (unsigned int y = 0, outY = 0; y < kResolution[1]; y+=inc, outY++ ) {
1727 uint8_t *px = img + outY * stride * 4;
1728 mScene.setReadoutPixel(0, y);
1729 for (unsigned int x = 0; x < kResolution[0]; x+=inc) {
1730 uint32_t rCount, gCount, bCount;
1731 // TODO: Perfect demosaicing is a cheat
1732 const uint32_t *pixel = mScene.getPixelElectrons();
1733 rCount = pixel[Scene::R] * scale64x;
1734 gCount = pixel[Scene::Gr] * scale64x;
1735 bCount = pixel[Scene::B] * scale64x;
1736
1737 *px++ = rCount < 255*64 ? rCount / 64 : 255;
1738 *px++ = gCount < 255*64 ? gCount / 64 : 255;
1739 *px++ = bCount < 255*64 ? bCount / 64 : 255;
1740 *px++ = 255;
1741 for (unsigned int j = 1; j < inc; j++)
1742 mScene.getPixelElectrons();
1743 }
1744 // TODO: Handle this better
1745 //simulatedTime += kRowReadoutTime;
1746 }
1747 ALOGVV("RGBA sensor image captured");
1748}
1749
1750void Sensor::captureRGB(uint8_t *img, uint32_t gain, uint32_t stride) {
1751#if 0
1752 float totalGain = gain/100.0 * kBaseGainFactor;
1753 // In fixed-point math, calculate total scaling from electrons to 8bpp
1754 int scale64x = 64 * totalGain * 255 / kMaxRawValue;
1755 uint32_t inc = kResolution[0] / stride;
1756
1757 for (unsigned int y = 0, outY = 0; y < kResolution[1]; y += inc, outY++ ) {
1758 mScene.setReadoutPixel(0, y);
1759 uint8_t *px = img + outY * stride * 3;
1760 for (unsigned int x = 0; x < kResolution[0]; x += inc) {
1761 uint32_t rCount, gCount, bCount;
1762 // TODO: Perfect demosaicing is a cheat
1763 const uint32_t *pixel = mScene.getPixelElectrons();
1764 rCount = pixel[Scene::R] * scale64x;
1765 gCount = pixel[Scene::Gr] * scale64x;
1766 bCount = pixel[Scene::B] * scale64x;
1767
1768 *px++ = rCount < 255*64 ? rCount / 64 : 255;
1769 *px++ = gCount < 255*64 ? gCount / 64 : 255;
1770 *px++ = bCount < 255*64 ? bCount / 64 : 255;
1771 for (unsigned int j = 1; j < inc; j++)
1772 mScene.getPixelElectrons();
1773 }
1774 // TODO: Handle this better
1775 //simulatedTime += kRowReadoutTime;
1776 }
1777#else
1778 uint8_t *src = NULL;
1779 int ret = 0, rotate = 0;
1780 uint32_t width = 0, height = 0;
1781
1782 rotate = getPictureRotate();
1783 width = vinfo->picture.format.fmt.pix.width;
1784 height = vinfo->picture.format.fmt.pix.height;
1785
1786 if (mSensorType == SENSOR_USB) {
1787 releasebuf_and_stop_capturing(vinfo);
1788 } else {
1789 stop_capturing(vinfo);
1790 }
1791
1792 ret = start_picture(vinfo,rotate);
1793 if (ret < 0)
1794 {
1795 ALOGD("start picture failed!");
1796 }
1797 while(1)
1798 {
1799 src = (uint8_t *)get_picture(vinfo);
1800 if (NULL != src) {
1801 if (vinfo->picture.format.fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) {
1802 uint8_t *tmp_buffer = new uint8_t[width * height * 3 / 2];
1803 if ( tmp_buffer == NULL) {
1804 ALOGE("new buffer failed!\n");
1805 return;
1806 }
1807 if (ConvertMjpegToNV21(src, vinfo->picture.buf.bytesused, tmp_buffer,
1808 width, tmp_buffer + width * height, (width + 1) / 2, width,
1809 height, width, height, libyuv::FOURCC_MJPG) != 0) {
1810 DBG_LOGA("Decode MJPEG frame failed\n");
1811 putback_picture_frame(vinfo);
1812 usleep(5000);
1813 } else {
1814 nv21_to_rgb24(tmp_buffer,img,width,height);
1815 if (tmp_buffer != NULL)
1816 delete [] tmp_buffer;
1817 break;
1818 }
1819 } else if (vinfo->picture.format.fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV) {
1820 if (vinfo->picture.buf.length == vinfo->picture.buf.bytesused) {
1821 yuyv422_to_rgb24(src,img,width,height);
1822 break;
1823 } else {
1824 putback_picture_frame(vinfo);
1825 usleep(5000);
1826 }
1827 } else if (vinfo->picture.format.fmt.pix.pixelformat == V4L2_PIX_FMT_RGB24) {
1828 if (vinfo->picture.buf.length == width * height * 3) {
1829 memcpy(img, src, vinfo->picture.buf.length);
1830 } else {
1831 rgb24_memcpy(img, src, width, height);
1832 }
1833 break;
1834 }
1835 }
1836 }
1837 ALOGD("get picture success !");
1838
1839 if (mSensorType == SENSOR_USB) {
1840 releasebuf_and_stop_picture(vinfo);
1841 } else {
1842 stop_picture(vinfo);
1843 }
1844
1845#endif
1846}
1847
1848void Sensor::YUYVToNV21(uint8_t *src, uint8_t *dst, int width, int height)
1849{
1850 for (int i = 0; i < width * height * 2; i += 2) {
1851 *dst++ = *(src + i);
1852 }
1853
1854 for (int y = 0; y < height - 1; y +=2) {
1855 for (int j = 0; j < width * 2; j += 4) {
1856 *dst++ = (*(src + 3 + j) + *(src + 3 + j + width * 2) + 1) >> 1; //v
1857 *dst++ = (*(src + 1 + j) + *(src + 1 + j + width * 2) + 1) >> 1; //u
1858 }
1859 src += width * 2 * 2;
1860 }
1861
1862 if (height & 1)
1863 for (int j = 0; j < width * 2; j += 4) {
1864 *dst++ = *(src + 3 + j); //v
1865 *dst++ = *(src + 1 + j); //u
1866 }
1867}
1868
1869void Sensor::YUYVToYV12(uint8_t *src, uint8_t *dst, int width, int height)
1870{
1871 //width should be an even number.
1872 //uv ALIGN 32.
1873 int i,j,stride,c_stride,c_size,y_size,cb_offset,cr_offset;
1874 unsigned char *dst_copy,*src_copy;
1875
1876 dst_copy = dst;
1877 src_copy = src;
1878
1879 y_size = width*height;
1880 c_stride = ALIGN(width/2, 16);
1881 c_size = c_stride * height/2;
1882 cr_offset = y_size;
1883 cb_offset = y_size+c_size;
1884
1885 for(i=0;i< y_size;i++){
1886 *dst++ = *src;
1887 src += 2;
1888 }
1889
1890 dst = dst_copy;
1891 src = src_copy;
1892
1893 for(i=0;i<height;i+=2){
1894 for(j=1;j<width*2;j+=4){//one line has 2*width bytes for yuyv.
1895 //ceil(u1+u2)/2
1896 *(dst+cr_offset+j/4)= (*(src+j+2) + *(src+j+2+width*2) + 1)/2;
1897 *(dst+cb_offset+j/4)= (*(src+j) + *(src+j+width*2) + 1)/2;
1898 }
1899 dst += c_stride;
1900 src += width*4;
1901 }
1902}
1903
1904
1905void Sensor::captureNV21(StreamBuffer b, uint32_t gain) {
1906#if 0
1907 float totalGain = gain/100.0 * kBaseGainFactor;
1908 // Using fixed-point math with 6 bits of fractional precision.
1909 // In fixed-point math, calculate total scaling from electrons to 8bpp
1910 const int scale64x = 64 * totalGain * 255 / kMaxRawValue;
1911 // In fixed-point math, saturation point of sensor after gain
1912 const int saturationPoint = 64 * 255;
1913 // Fixed-point coefficients for RGB-YUV transform
1914 // Based on JFIF RGB->YUV transform.
1915 // Cb/Cr offset scaled by 64x twice since they're applied post-multiply
1916 const int rgbToY[] = {19, 37, 7};
1917 const int rgbToCb[] = {-10,-21, 32, 524288};
1918 const int rgbToCr[] = {32,-26, -5, 524288};
1919 // Scale back to 8bpp non-fixed-point
1920 const int scaleOut = 64;
1921 const int scaleOutSq = scaleOut * scaleOut; // after multiplies
1922
1923 uint32_t inc = kResolution[0] / stride;
1924 uint32_t outH = kResolution[1] / inc;
1925 for (unsigned int y = 0, outY = 0;
1926 y < kResolution[1]; y+=inc, outY++) {
1927 uint8_t *pxY = img + outY * stride;
1928 uint8_t *pxVU = img + (outH + outY / 2) * stride;
1929 mScene.setReadoutPixel(0,y);
1930 for (unsigned int outX = 0; outX < stride; outX++) {
1931 int32_t rCount, gCount, bCount;
1932 // TODO: Perfect demosaicing is a cheat
1933 const uint32_t *pixel = mScene.getPixelElectrons();
1934 rCount = pixel[Scene::R] * scale64x;
1935 rCount = rCount < saturationPoint ? rCount : saturationPoint;
1936 gCount = pixel[Scene::Gr] * scale64x;
1937 gCount = gCount < saturationPoint ? gCount : saturationPoint;
1938 bCount = pixel[Scene::B] * scale64x;
1939 bCount = bCount < saturationPoint ? bCount : saturationPoint;
1940
1941 *pxY++ = (rgbToY[0] * rCount +
1942 rgbToY[1] * gCount +
1943 rgbToY[2] * bCount) / scaleOutSq;
1944 if (outY % 2 == 0 && outX % 2 == 0) {
1945 *pxVU++ = (rgbToCr[0] * rCount +
1946 rgbToCr[1] * gCount +
1947 rgbToCr[2] * bCount +
1948 rgbToCr[3]) / scaleOutSq;
1949 *pxVU++ = (rgbToCb[0] * rCount +
1950 rgbToCb[1] * gCount +
1951 rgbToCb[2] * bCount +
1952 rgbToCb[3]) / scaleOutSq;
1953 }
1954 for (unsigned int j = 1; j < inc; j++)
1955 mScene.getPixelElectrons();
1956 }
1957 }
1958#else
1959 uint8_t *src;
1960
1961 if (mKernelBuffer) {
1962 src = mKernelBuffer;
1963 if (vinfo->preview.format.fmt.pix.pixelformat == V4L2_PIX_FMT_NV21) {
1964 uint32_t width = vinfo->preview.format.fmt.pix.width;
1965 uint32_t height = vinfo->preview.format.fmt.pix.height;
1966 if ((width == b.width) && (height == b.height)) {
1967 memcpy(b.img, src, b.width * b.height * 3/2);
1968 } else {
1969 ReSizeNV21(vinfo, src, b.img, b.width, b.height);
1970 }
1971 } else if (vinfo->preview.format.fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV) {
1972 uint32_t width = vinfo->preview.format.fmt.pix.width;
1973 uint32_t height = vinfo->preview.format.fmt.pix.height;
1974
1975 if ((width == b.width) && (height == b.height)) {
1976 memcpy(b.img, src, b.width * b.height * 3/2);
1977 } else {
1978 ReSizeNV21(vinfo, src, b.img, b.width, b.height);
1979 }
1980 } else if (vinfo->preview.format.fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) {
1981 uint32_t width = vinfo->preview.format.fmt.pix.width;
1982 uint32_t height = vinfo->preview.format.fmt.pix.height;
1983
1984 if ((width == b.width) && (height == b.height)) {
1985 memcpy(b.img, src, b.width * b.height * 3/2);
1986 } else {
1987 ReSizeNV21(vinfo, src, b.img, b.width, b.height);
1988 }
1989 } else {
1990 ALOGE("Unable known sensor format: %d", vinfo->preview.format.fmt.pix.pixelformat);
1991 }
1992 return ;
1993 }
1994 while(1){
1995 src = (uint8_t *)get_frame(vinfo);
1996 if (NULL == src) {
1997 CAMHAL_LOGDA("get frame NULL, sleep 5ms");
1998 usleep(5000);
1999 continue;
2000 }
2001 if (vinfo->preview.format.fmt.pix.pixelformat == V4L2_PIX_FMT_NV21) {
2002 if (vinfo->preview.buf.length == b.width * b.height * 3/2) {
2003 memcpy(b.img, src, vinfo->preview.buf.length);
2004 } else {
2005 nv21_memcpy_align32 (b.img, src, b.width, b.height);
2006 }
2007 mKernelBuffer = b.img;
2008 } else if (vinfo->preview.format.fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV) {
2009 int width = vinfo->preview.format.fmt.pix.width;
2010 int height = vinfo->preview.format.fmt.pix.height;
2011 YUYVToNV21(src, b.img, width, height);
2012 mKernelBuffer = b.img;
2013 } else if (vinfo->preview.format.fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) {
2014 int width = vinfo->preview.format.fmt.pix.width;
2015 int height = vinfo->preview.format.fmt.pix.height;
2016 if (ConvertMjpegToNV21(src, vinfo->preview.buf.bytesused, b.img,
2017 width, b.img + width * height, (width + 1) / 2, width,
2018 height, width, height, libyuv::FOURCC_MJPG) != 0) {
2019 putback_frame(vinfo);
2020 DBG_LOGA("Decode MJPEG frame failed\n");
2021 continue;
2022 }
2023 mKernelBuffer = b.img;
2024 }
2025
2026 break;
2027 }
2028#endif
2029
2030 ALOGVV("NV21 sensor image captured");
2031}
2032
2033void Sensor::captureYV12(StreamBuffer b, uint32_t gain) {
2034#if 0
2035 float totalGain = gain/100.0 * kBaseGainFactor;
2036 // Using fixed-point math with 6 bits of fractional precision.
2037 // In fixed-point math, calculate total scaling from electrons to 8bpp
2038 const int scale64x = 64 * totalGain * 255 / kMaxRawValue;
2039 // In fixed-point math, saturation point of sensor after gain
2040 const int saturationPoint = 64 * 255;
2041 // Fixed-point coefficients for RGB-YUV transform
2042 // Based on JFIF RGB->YUV transform.
2043 // Cb/Cr offset scaled by 64x twice since they're applied post-multiply
2044 const int rgbToY[] = {19, 37, 7};
2045 const int rgbToCb[] = {-10,-21, 32, 524288};
2046 const int rgbToCr[] = {32,-26, -5, 524288};
2047 // Scale back to 8bpp non-fixed-point
2048 const int scaleOut = 64;
2049 const int scaleOutSq = scaleOut * scaleOut; // after multiplies
2050
2051 uint32_t inc = kResolution[0] / stride;
2052 uint32_t outH = kResolution[1] / inc;
2053 for (unsigned int y = 0, outY = 0;
2054 y < kResolution[1]; y+=inc, outY++) {
2055 uint8_t *pxY = img + outY * stride;
2056 uint8_t *pxVU = img + (outH + outY / 2) * stride;
2057 mScene.setReadoutPixel(0,y);
2058 for (unsigned int outX = 0; outX < stride; outX++) {
2059 int32_t rCount, gCount, bCount;
2060 // TODO: Perfect demosaicing is a cheat
2061 const uint32_t *pixel = mScene.getPixelElectrons();
2062 rCount = pixel[Scene::R] * scale64x;
2063 rCount = rCount < saturationPoint ? rCount : saturationPoint;
2064 gCount = pixel[Scene::Gr] * scale64x;
2065 gCount = gCount < saturationPoint ? gCount : saturationPoint;
2066 bCount = pixel[Scene::B] * scale64x;
2067 bCount = bCount < saturationPoint ? bCount : saturationPoint;
2068
2069 *pxY++ = (rgbToY[0] * rCount +
2070 rgbToY[1] * gCount +
2071 rgbToY[2] * bCount) / scaleOutSq;
2072 if (outY % 2 == 0 && outX % 2 == 0) {
2073 *pxVU++ = (rgbToCr[0] * rCount +
2074 rgbToCr[1] * gCount +
2075 rgbToCr[2] * bCount +
2076 rgbToCr[3]) / scaleOutSq;
2077 *pxVU++ = (rgbToCb[0] * rCount +
2078 rgbToCb[1] * gCount +
2079 rgbToCb[2] * bCount +
2080 rgbToCb[3]) / scaleOutSq;
2081 }
2082 for (unsigned int j = 1; j < inc; j++)
2083 mScene.getPixelElectrons();
2084 }
2085 }
2086#else
2087 uint8_t *src;
2088 if (mKernelBuffer) {
2089 src = mKernelBuffer;
2090 if (vinfo->preview.format.fmt.pix.pixelformat == V4L2_PIX_FMT_YVU420) {
2091 //memcpy(b.img, src, 200 * 100 * 3 / 2 /*vinfo->preview.buf.length*/);
2092 ALOGI("Sclale YV12 frame down \n");
2093
2094 int width = vinfo->preview.format.fmt.pix.width;
2095 int height = vinfo->preview.format.fmt.pix.height;
2096 int ret = libyuv::I420Scale(src, width,
2097 src + width * height, width / 2,
2098 src + width * height + width * height / 4, width / 2,
2099 width, height,
2100 b.img, b.width,
2101 b.img + b.width * b.height, b.width / 2,
2102 b.img + b.width * b.height + b.width * b.height / 4, b.width / 2,
2103 b.width, b.height,
2104 libyuv::kFilterNone);
2105 if (ret < 0)
2106 ALOGE("Sclale YV12 frame down failed!\n");
2107 } else if (vinfo->preview.format.fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV) {
2108 int width = vinfo->preview.format.fmt.pix.width;
2109 int height = vinfo->preview.format.fmt.pix.height;
2110 uint8_t *tmp_buffer = new uint8_t[width * height * 3 / 2];
2111
2112 if ( tmp_buffer == NULL) {
2113 ALOGE("new buffer failed!\n");
2114 return;
2115 }
2116
2117 YUYVToYV12(src, tmp_buffer, width, height);
2118
2119 int ret = libyuv::I420Scale(tmp_buffer, width,
2120 tmp_buffer + width * height, width / 2,
2121 tmp_buffer + width * height + width * height / 4, width / 2,
2122 width, height,
2123 b.img, b.width,
2124 b.img + b.width * b.height, b.width / 2,
2125 b.img + b.width * b.height + b.width * b.height / 4, b.width / 2,
2126 b.width, b.height,
2127 libyuv::kFilterNone);
2128 if (ret < 0)
2129 ALOGE("Sclale YV12 frame down failed!\n");
2130 delete [] tmp_buffer;
2131 } else if (vinfo->preview.format.fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) {
2132 int width = vinfo->preview.format.fmt.pix.width;
2133 int height = vinfo->preview.format.fmt.pix.height;
2134 uint8_t *tmp_buffer = new uint8_t[width * height * 3 / 2];
2135
2136 if ( tmp_buffer == NULL) {
2137 ALOGE("new buffer failed!\n");
2138 return;
2139 }
2140
2141 if (ConvertToI420(src, vinfo->preview.buf.bytesused, tmp_buffer, width, tmp_buffer + width * height + width * height / 4, (width + 1) / 2,
2142 tmp_buffer + width * height, (width + 1) / 2, 0, 0, width, height,
2143 width, height, libyuv::kRotate0, libyuv::FOURCC_MJPG) != 0) {
2144 DBG_LOGA("Decode MJPEG frame failed\n");
2145 }
2146
2147 int ret = libyuv::I420Scale(tmp_buffer, width,
2148 tmp_buffer + width * height, width / 2,
2149 tmp_buffer + width * height + width * height / 4, width / 2,
2150 width, height,
2151 b.img, b.width,
2152 b.img + b.width * b.height, b.width / 2,
2153 b.img + b.width * b.height + b.width * b.height / 4, b.width / 2,
2154 b.width, b.height,
2155 libyuv::kFilterNone);
2156 if (ret < 0)
2157 ALOGE("Sclale YV12 frame down failed!\n");
2158
2159 delete [] tmp_buffer;
2160 } else {
2161 ALOGE("Unable known sensor format: %d", vinfo->preview.format.fmt.pix.pixelformat);
2162 }
2163 return ;
2164 }
2165 while(1){
2166 src = (uint8_t *)get_frame(vinfo);
2167
2168 if (NULL == src) {
2169 CAMHAL_LOGDA("get frame NULL, sleep 5ms");
2170 usleep(5000);
2171 continue;
2172 }
2173 if (vinfo->preview.format.fmt.pix.pixelformat == V4L2_PIX_FMT_YVU420) {
2174 if (vinfo->preview.buf.length == b.width * b.height * 3/2) {
2175 memcpy(b.img, src, vinfo->preview.buf.length);
2176 } else {
2177 yv12_memcpy_align32 (b.img, src, b.width, b.height);
2178 }
2179 } else if (vinfo->preview.format.fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV) {
2180 int width = vinfo->preview.format.fmt.pix.width;
2181 int height = vinfo->preview.format.fmt.pix.height;
2182 YUYVToYV12(src, b.img, width, height);
2183 } else if (vinfo->preview.format.fmt.pix.pixelformat == V4L2_PIX_FMT_MJPEG) {
2184 int width = vinfo->preview.format.fmt.pix.width;
2185 int height = vinfo->preview.format.fmt.pix.height;
2186 if (ConvertToI420(src, vinfo->preview.buf.bytesused, b.img, width, b.img + width * height + width * height / 4, (width + 1) / 2,
2187 b.img + width * height, (width + 1) / 2, 0, 0, width, height,
2188 width, height, libyuv::kRotate0, libyuv::FOURCC_MJPG) != 0) {
2189 putback_frame(vinfo);
2190 DBG_LOGA("Decode MJPEG frame failed\n");
2191 continue;
2192 }
2193 } else {
2194 ALOGE("Unable known sensor format: %d", vinfo->preview.format.fmt.pix.pixelformat);
2195 }
2196
2197 break;
2198 }
2199#endif
2200 mKernelBuffer = src;
2201 ALOGVV("YV12 sensor image captured");
2202}
2203
2204void Sensor::captureYUYV(uint8_t *img, uint32_t gain, uint32_t stride) {
2205#if 0
2206 float totalGain = gain/100.0 * kBaseGainFactor;
2207 // Using fixed-point math with 6 bits of fractional precision.
2208 // In fixed-point math, calculate total scaling from electrons to 8bpp
2209 const int scale64x = 64 * totalGain * 255 / kMaxRawValue;
2210 // In fixed-point math, saturation point of sensor after gain
2211 const int saturationPoint = 64 * 255;
2212 // Fixed-point coefficients for RGB-YUV transform
2213 // Based on JFIF RGB->YUV transform.
2214 // Cb/Cr offset scaled by 64x twice since they're applied post-multiply
2215 const int rgbToY[] = {19, 37, 7};
2216 const int rgbToCb[] = {-10,-21, 32, 524288};
2217 const int rgbToCr[] = {32,-26, -5, 524288};
2218 // Scale back to 8bpp non-fixed-point
2219 const int scaleOut = 64;
2220 const int scaleOutSq = scaleOut * scaleOut; // after multiplies
2221
2222 uint32_t inc = kResolution[0] / stride;
2223 uint32_t outH = kResolution[1] / inc;
2224 for (unsigned int y = 0, outY = 0;
2225 y < kResolution[1]; y+=inc, outY++) {
2226 uint8_t *pxY = img + outY * stride;
2227 uint8_t *pxVU = img + (outH + outY / 2) * stride;
2228 mScene.setReadoutPixel(0,y);
2229 for (unsigned int outX = 0; outX < stride; outX++) {
2230 int32_t rCount, gCount, bCount;
2231 // TODO: Perfect demosaicing is a cheat
2232 const uint32_t *pixel = mScene.getPixelElectrons();
2233 rCount = pixel[Scene::R] * scale64x;
2234 rCount = rCount < saturationPoint ? rCount : saturationPoint;
2235 gCount = pixel[Scene::Gr] * scale64x;
2236 gCount = gCount < saturationPoint ? gCount : saturationPoint;
2237 bCount = pixel[Scene::B] * scale64x;
2238 bCount = bCount < saturationPoint ? bCount : saturationPoint;
2239
2240 *pxY++ = (rgbToY[0] * rCount +
2241 rgbToY[1] * gCount +
2242 rgbToY[2] * bCount) / scaleOutSq;
2243 if (outY % 2 == 0 && outX % 2 == 0) {
2244 *pxVU++ = (rgbToCr[0] * rCount +
2245 rgbToCr[1] * gCount +
2246 rgbToCr[2] * bCount +
2247 rgbToCr[3]) / scaleOutSq;
2248 *pxVU++ = (rgbToCb[0] * rCount +
2249 rgbToCb[1] * gCount +
2250 rgbToCb[2] * bCount +
2251 rgbToCb[3]) / scaleOutSq;
2252 }
2253 for (unsigned int j = 1; j < inc; j++)
2254 mScene.getPixelElectrons();
2255 }
2256 }
2257#else
2258 uint8_t *src;
2259 if (mKernelBuffer) {
2260 src = mKernelBuffer;
2261 if (vinfo->preview.format.fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV) {
2262 //TODO YUYV scale
2263 //memcpy(img, src, vinfo->preview.buf.length);
2264
2265 } else
2266 ALOGE("Unable known sensor format: %d", vinfo->preview.format.fmt.pix.pixelformat);
2267
2268 return ;
2269 }
2270
2271 while(1) {
2272 src = (uint8_t *)get_frame(vinfo);
2273 if (NULL == src) {
2274 CAMHAL_LOGDA("get frame NULL, sleep 5ms");
2275 usleep(5000);
2276 continue;
2277 }
2278 if (vinfo->preview.format.fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV) {
2279 memcpy(img, src, vinfo->preview.buf.length);
2280 } else {
2281 ALOGE("Unable known sensor format: %d", vinfo->preview.format.fmt.pix.pixelformat);
2282 }
2283
2284 break;
2285 }
2286#endif
2287 mKernelBuffer = src;
2288 ALOGVV("YUYV sensor image captured");
2289}
2290
2291void Sensor::dump(int fd) {
2292 String8 result;
2293 result = String8::format("%s, sensor preview information: \n", __FILE__);
2294 result.appendFormat("camera preview fps: %.2f\n", mCurFps);
2295 result.appendFormat("camera preview width: %d , height =%d\n",
2296 vinfo->preview.format.fmt.pix.width,vinfo->preview.format.fmt.pix.height);
2297
2298 result.appendFormat("camera preview format: %.4s\n\n",
2299 (char *) &vinfo->preview.format.fmt.pix.pixelformat);
2300
2301 write(fd, result.string(), result.size());
2302}
2303
2304} // namespace android
2305
2306