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