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