blob: 09a8cdaf57c65fc1dac22ddf5dcfda3ccba790f7
1 | /* |
2 | * Copyright (C) 2013 The Android Open Source Project |
3 | * |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | * you may not use this file except in compliance with the License. |
6 | * You may obtain a copy of the License at |
7 | * |
8 | * http://www.apache.org/licenses/LICENSE-2.0 |
9 | * |
10 | * Unless required by applicable law or agreed to in writing, software |
11 | * distributed under the License is distributed on an "AS IS" BASIS, |
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | * See the License for the specific language governing permissions and |
14 | * limitations under the License. |
15 | */ |
16 | |
17 | /* |
18 | * Contains implementation of a class EmulatedFakeCamera3 that encapsulates |
19 | * functionality of an advanced fake camera. |
20 | */ |
21 | |
22 | #include <inttypes.h> |
23 | |
24 | #define LOG_NDEBUG 0 |
25 | //#define LOG_NNDEBUG 0 |
26 | #define LOG_TAG "EmulatedCamera_FakeCamera3" |
27 | #include <utils/Log.h> |
28 | |
29 | #include "EmulatedFakeCamera3.h" |
30 | #include "EmulatedCameraFactory.h" |
31 | #include <ui/Fence.h> |
32 | #include <ui/Rect.h> |
33 | #include <ui/GraphicBufferMapper.h> |
34 | #include <sys/types.h> |
35 | |
36 | #include <cutils/properties.h> |
37 | #include "fake-pipeline2/Sensor.h" |
38 | #include "fake-pipeline2/JpegCompressor.h" |
39 | #include <cmath> |
40 | #include <gralloc_priv.h> |
41 | #include <binder/IPCThreadState.h> |
42 | |
43 | #if defined(LOG_NNDEBUG) && LOG_NNDEBUG == 0 |
44 | #define ALOGVV ALOGV |
45 | #else |
46 | #define ALOGVV(...) ((void)0) |
47 | #endif |
48 | |
49 | namespace android { |
50 | |
51 | /** |
52 | * Constants for camera capabilities |
53 | */ |
54 | |
55 | const int64_t USEC = 1000LL; |
56 | const int64_t MSEC = USEC * 1000LL; |
57 | const int64_t SEC = MSEC * 1000LL; |
58 | |
59 | |
60 | const int32_t EmulatedFakeCamera3::kAvailableFormats[] = { |
61 | //HAL_PIXEL_FORMAT_RAW_SENSOR, |
62 | HAL_PIXEL_FORMAT_BLOB, |
63 | //HAL_PIXEL_FORMAT_RGBA_8888, |
64 | HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED, |
65 | // These are handled by YCbCr_420_888 |
66 | HAL_PIXEL_FORMAT_YV12, |
67 | HAL_PIXEL_FORMAT_YCrCb_420_SP, |
68 | //HAL_PIXEL_FORMAT_YCbCr_422_I, |
69 | HAL_PIXEL_FORMAT_YCbCr_420_888 |
70 | }; |
71 | |
72 | const uint32_t EmulatedFakeCamera3::kAvailableRawSizes[2] = { |
73 | 640, 480 |
74 | // Sensor::kResolution[0], Sensor::kResolution[1] |
75 | }; |
76 | |
77 | const uint64_t EmulatedFakeCamera3::kAvailableRawMinDurations[1] = { |
78 | (const uint64_t)Sensor::kFrameDurationRange[0] |
79 | }; |
80 | |
81 | const uint32_t EmulatedFakeCamera3::kAvailableProcessedSizesBack[6] = { |
82 | 640, 480, 320, 240,// 1280, 720 |
83 | // Sensor::kResolution[0], Sensor::kResolution[1] |
84 | }; |
85 | |
86 | const uint32_t EmulatedFakeCamera3::kAvailableProcessedSizesFront[4] = { |
87 | 640, 480, 320, 240 |
88 | // Sensor::kResolution[0], Sensor::kResolution[1] |
89 | }; |
90 | |
91 | const uint64_t EmulatedFakeCamera3::kAvailableProcessedMinDurations[1] = { |
92 | (const uint64_t)Sensor::kFrameDurationRange[0] |
93 | }; |
94 | |
95 | const uint32_t EmulatedFakeCamera3::kAvailableJpegSizesBack[2] = { |
96 | 1280,720 |
97 | // Sensor::kResolution[0], Sensor::kResolution[1] |
98 | }; |
99 | |
100 | const uint32_t EmulatedFakeCamera3::kAvailableJpegSizesFront[2] = { |
101 | 640, 480 |
102 | // Sensor::kResolution[0], Sensor::kResolution[1] |
103 | }; |
104 | |
105 | |
106 | const uint64_t EmulatedFakeCamera3::kAvailableJpegMinDurations[1] = { |
107 | (const uint64_t)Sensor::kFrameDurationRange[0] |
108 | }; |
109 | |
110 | /** |
111 | * 3A constants |
112 | */ |
113 | |
114 | // Default exposure and gain targets for different scenarios |
115 | const nsecs_t EmulatedFakeCamera3::kNormalExposureTime = 10 * MSEC; |
116 | const nsecs_t EmulatedFakeCamera3::kFacePriorityExposureTime = 30 * MSEC; |
117 | const int EmulatedFakeCamera3::kNormalSensitivity = 100; |
118 | const int EmulatedFakeCamera3::kFacePrioritySensitivity = 400; |
119 | const float EmulatedFakeCamera3::kExposureTrackRate = 0.1; |
120 | const int EmulatedFakeCamera3::kPrecaptureMinFrames = 10; |
121 | const int EmulatedFakeCamera3::kStableAeMaxFrames = 100; |
122 | const float EmulatedFakeCamera3::kExposureWanderMin = -2; |
123 | const float EmulatedFakeCamera3::kExposureWanderMax = 1; |
124 | |
125 | /** |
126 | * Camera device lifecycle methods |
127 | */ |
128 | static const ssize_t kMinJpegBufferSize = 256 * 1024 + sizeof(camera3_jpeg_blob); |
129 | jpegsize EmulatedFakeCamera3::getMaxJpegResolution(uint32_t picSizes[],int count) { |
130 | uint32_t maxJpegWidth = 0, maxJpegHeight = 0; |
131 | jpegsize maxJpegResolution; |
132 | for (int i=0; i < count; i+= 4) { |
133 | uint32_t width = picSizes[i+1]; |
134 | uint32_t height = picSizes[i+2]; |
135 | if (picSizes[i+0] == HAL_PIXEL_FORMAT_BLOB && |
136 | (width * height > maxJpegWidth * maxJpegHeight)) { |
137 | maxJpegWidth = width; |
138 | maxJpegHeight = height; |
139 | } |
140 | } |
141 | maxJpegResolution.width = maxJpegWidth; |
142 | maxJpegResolution.height = maxJpegHeight; |
143 | return maxJpegResolution; |
144 | } |
145 | ssize_t EmulatedFakeCamera3::getJpegBufferSize(int width, int height) { |
146 | if (maxJpegResolution.width == 0) { |
147 | return BAD_VALUE; |
148 | } |
149 | ssize_t maxJpegBufferSize = JpegCompressor::kMaxJpegSize; |
150 | |
151 | // Calculate final jpeg buffer size for the given resolution. |
152 | float scaleFactor = ((float) (width * height)) / |
153 | (maxJpegResolution.width * maxJpegResolution.height); |
154 | ssize_t jpegBufferSize = scaleFactor * maxJpegBufferSize; |
155 | // Bound the buffer size to [MIN_JPEG_BUFFER_SIZE, maxJpegBufferSize]. |
156 | if (jpegBufferSize > maxJpegBufferSize) { |
157 | jpegBufferSize = maxJpegBufferSize; |
158 | } else if (jpegBufferSize < kMinJpegBufferSize) { |
159 | jpegBufferSize = kMinJpegBufferSize; |
160 | } |
161 | return jpegBufferSize; |
162 | } |
163 | |
164 | EmulatedFakeCamera3::EmulatedFakeCamera3(int cameraId, struct hw_module_t* module) : |
165 | EmulatedCamera3(cameraId, module) { |
166 | ALOGI("Constructing emulated fake camera 3 cameraID:%d", mCameraID); |
167 | |
168 | for (size_t i = 0; i < CAMERA3_TEMPLATE_COUNT; i++) { |
169 | mDefaultTemplates[i] = NULL; |
170 | } |
171 | |
172 | /** |
173 | * Front cameras = limited mode |
174 | * Back cameras = full mode |
175 | */ |
176 | //TODO limited or full mode, read this from camera driver |
177 | //mFullMode = facingBack; |
178 | mCameraStatus = CAMERA_INIT; |
179 | mSupportCap = 0; |
180 | mSupportRotate = 0; |
181 | mFullMode = 0; |
182 | mFlushTag = false; |
183 | mPlugged = false; |
184 | |
185 | gLoadXml.parseXMLFile(); |
186 | } |
187 | |
188 | EmulatedFakeCamera3::~EmulatedFakeCamera3() { |
189 | for (size_t i = 0; i < CAMERA3_TEMPLATE_COUNT; i++) { |
190 | if (mDefaultTemplates[i] != NULL) { |
191 | free_camera_metadata(mDefaultTemplates[i]); |
192 | } |
193 | } |
194 | |
195 | if (mCameraInfo != NULL) { |
196 | CAMHAL_LOGIA("free mCameraInfo"); |
197 | free_camera_metadata(mCameraInfo); |
198 | mCameraInfo = NULL; |
199 | } |
200 | } |
201 | |
202 | status_t EmulatedFakeCamera3::Initialize() { |
203 | DBG_LOGB("mCameraID=%d,mStatus=%d,ddd\n", mCameraID, mStatus); |
204 | status_t res; |
205 | |
206 | #ifdef HAVE_VERSION_INFO |
207 | CAMHAL_LOGIB("\n--------------------------------\n" |
208 | "author:aml.sh multi-media team\n" |
209 | "branch name: %s\n" |
210 | "git version: %s \n" |
211 | "last changed: %s\n" |
212 | "build-time: %s\n" |
213 | "build-name: %s\n" |
214 | "uncommitted-file-num:%d\n" |
215 | "ssh user@%s, cd %s\n" |
216 | "hostname %s\n" |
217 | "--------------------------------\n", |
218 | CAMHAL_BRANCH_NAME, |
219 | CAMHAL_GIT_VERSION, |
220 | CAMHAL_LAST_CHANGED, |
221 | CAMHAL_BUILD_TIME, |
222 | CAMHAL_BUILD_NAME, |
223 | CAMHAL_GIT_UNCOMMIT_FILE_NUM, |
224 | CAMHAL_IP, CAMHAL_PATH, CAMHAL_HOSTNAME |
225 | ); |
226 | #endif |
227 | |
228 | |
229 | if (mStatus != STATUS_ERROR) { |
230 | ALOGE("%s: Already initialized!", __FUNCTION__); |
231 | return INVALID_OPERATION; |
232 | } |
233 | |
234 | res = constructStaticInfo(); |
235 | if (res != OK) { |
236 | ALOGE("%s: Unable to allocate static info: %s (%d)", |
237 | __FUNCTION__, strerror(-res), res); |
238 | return res; |
239 | } |
240 | |
241 | return EmulatedCamera3::Initialize(); |
242 | } |
243 | |
244 | status_t EmulatedFakeCamera3::connectCamera(hw_device_t** device) { |
245 | ALOGV("%s: E", __FUNCTION__); |
246 | DBG_LOGB("%s, ddd", __FUNCTION__); |
247 | Mutex::Autolock l(mLock); |
248 | status_t res; |
249 | DBG_LOGB("%s , mStatus = %d" , __FUNCTION__, mStatus); |
250 | |
251 | if ((mStatus != STATUS_CLOSED) || !mPlugged) { |
252 | ALOGE("%s: Can't connect in state %d, mPlugged=%d", |
253 | __FUNCTION__, mStatus, mPlugged); |
254 | return INVALID_OPERATION; |
255 | } |
256 | |
257 | mSensor = new Sensor(); |
258 | mSensor->setSensorListener(this); |
259 | |
260 | res = mSensor->startUp(mCameraID); |
261 | DBG_LOGB("mSensor startUp, mCameraID=%d\n", mCameraID); |
262 | if (res != NO_ERROR) return res; |
263 | |
264 | mSupportCap = mSensor->IoctlStateProbe(); |
265 | if (mSupportCap & IOCTL_MASK_ROTATE) { |
266 | mSupportRotate = true; |
267 | } |
268 | |
269 | mReadoutThread = new ReadoutThread(this); |
270 | mJpegCompressor = new JpegCompressor(); |
271 | |
272 | res = mReadoutThread->setJpegCompressorListener(this); |
273 | if (res != NO_ERROR) { |
274 | return res; |
275 | } |
276 | res = mReadoutThread->startJpegCompressor(this); |
277 | if (res != NO_ERROR) { |
278 | return res; |
279 | } |
280 | |
281 | res = mReadoutThread->run("EmuCam3::readoutThread"); |
282 | if (res != NO_ERROR) return res; |
283 | |
284 | // Initialize fake 3A |
285 | |
286 | mControlMode = ANDROID_CONTROL_MODE_AUTO; |
287 | mFacePriority = false; |
288 | mAeMode = ANDROID_CONTROL_AE_MODE_ON; |
289 | mAfMode = ANDROID_CONTROL_AF_MODE_AUTO; |
290 | mAwbMode = ANDROID_CONTROL_AWB_MODE_AUTO; |
291 | mAeState = ANDROID_CONTROL_AE_STATE_CONVERGED;//ANDROID_CONTROL_AE_STATE_INACTIVE; |
292 | mAfState = ANDROID_CONTROL_AF_STATE_INACTIVE; |
293 | mAwbState = ANDROID_CONTROL_AWB_STATE_INACTIVE; |
294 | mAfTriggerId = 0; |
295 | mAeCurrentExposureTime = kNormalExposureTime; |
296 | mAeCurrentSensitivity = kNormalSensitivity; |
297 | |
298 | return EmulatedCamera3::connectCamera(device); |
299 | } |
300 | |
301 | status_t EmulatedFakeCamera3::plugCamera() { |
302 | { |
303 | Mutex::Autolock l(mLock); |
304 | |
305 | if (!mPlugged) { |
306 | CAMHAL_LOGIB("%s: Plugged back in", __FUNCTION__); |
307 | mPlugged = true; |
308 | } |
309 | } |
310 | |
311 | return NO_ERROR; |
312 | } |
313 | |
314 | status_t EmulatedFakeCamera3::unplugCamera() { |
315 | { |
316 | Mutex::Autolock l(mLock); |
317 | |
318 | if (mPlugged) { |
319 | CAMHAL_LOGIB("%s: Unplugged camera", __FUNCTION__); |
320 | mPlugged = false; |
321 | } |
322 | } |
323 | return true; |
324 | } |
325 | |
326 | camera_device_status_t EmulatedFakeCamera3::getHotplugStatus() { |
327 | Mutex::Autolock l(mLock); |
328 | return mPlugged ? |
329 | CAMERA_DEVICE_STATUS_PRESENT : |
330 | CAMERA_DEVICE_STATUS_NOT_PRESENT; |
331 | } |
332 | |
333 | bool EmulatedFakeCamera3::getCameraStatus() |
334 | { |
335 | CAMHAL_LOGVB("%s, mCameraStatus = %d",__FUNCTION__,mCameraStatus); |
336 | bool ret = false; |
337 | if (mStatus == STATUS_CLOSED) { |
338 | ret = true; |
339 | } else { |
340 | ret = false; |
341 | } |
342 | return ret; |
343 | } |
344 | |
345 | status_t EmulatedFakeCamera3::closeCamera() { |
346 | DBG_LOGB("%s, %d\n", __FUNCTION__, __LINE__); |
347 | status_t res; |
348 | { |
349 | Mutex::Autolock l(mLock); |
350 | if (mStatus == STATUS_CLOSED) return OK; |
351 | } |
352 | |
353 | CAMHAL_LOGDB("%s, %d\n", __FUNCTION__, __LINE__); |
354 | mReadoutThread->sendFlushSingnal(); |
355 | mSensor->sendExitSingalToSensor(); |
356 | res = mSensor->shutDown(); |
357 | if (res != NO_ERROR) { |
358 | ALOGE("%s: Unable to shut down sensor: %d", __FUNCTION__, res); |
359 | return res; |
360 | } |
361 | mSensor.clear(); |
362 | CAMHAL_LOGDB("%s, %d\n", __FUNCTION__, __LINE__); |
363 | |
364 | { |
365 | Mutex::Autolock l(mLock); |
366 | res = mReadoutThread->shutdownJpegCompressor(this); |
367 | if (res != OK) { |
368 | ALOGE("%s: Unable to shut down JpegCompressor: %d", __FUNCTION__, res); |
369 | return res; |
370 | } |
371 | mReadoutThread->sendExitReadoutThreadSignal(); |
372 | mReadoutThread->requestExit(); |
373 | } |
374 | CAMHAL_LOGDB("%s, %d\n", __FUNCTION__, __LINE__); |
375 | |
376 | mReadoutThread->join(); |
377 | DBG_LOGA("Sucess exit ReadOutThread"); |
378 | { |
379 | Mutex::Autolock l(mLock); |
380 | // Clear out private stream information |
381 | for (StreamIterator s = mStreams.begin(); s != mStreams.end(); s++) { |
382 | PrivateStreamInfo *privStream = |
383 | static_cast<PrivateStreamInfo*>((*s)->priv); |
384 | delete privStream; |
385 | (*s)->priv = NULL; |
386 | } |
387 | mStreams.clear(); |
388 | mReadoutThread.clear(); |
389 | } |
390 | CAMHAL_LOGDB("%s, %d\n", __FUNCTION__, __LINE__); |
391 | return EmulatedCamera3::closeCamera(); |
392 | } |
393 | |
394 | status_t EmulatedFakeCamera3::getCameraInfo(struct camera_info *info) { |
395 | char property[PROPERTY_VALUE_MAX]; |
396 | char* tempApkName = gLoadXml.getApkPackageName(IPCThreadState::self()->getCallingPid()); |
397 | List_Or * temp=new List_Or(); |
398 | info->facing = mFacingBack ? CAMERA_FACING_BACK : CAMERA_FACING_FRONT; |
399 | if (mSensorType == SENSOR_USB) { |
400 | if (mFacingBack) { |
401 | property_get("hw.camera.orientation.back", property, "0"); |
402 | } else { |
403 | property_get("hw.camera.orientation.front", property, "0"); |
404 | } |
405 | int32_t orientation = atoi(property); |
406 | |
407 | if (gLoadXml.findApkCp(tempApkName, temp)) { |
408 | orientation = atoi(temp->pro); |
409 | } |
410 | if (temp != NULL) { |
411 | delete temp; |
412 | temp = NULL; |
413 | } |
414 | |
415 | property_get("hw.camera.usb.orientation_offset", property, "0"); |
416 | orientation += atoi(property); |
417 | orientation %= 360; |
418 | info->orientation = orientation ; |
419 | } else { |
420 | if (mFacingBack) { |
421 | property_get("hw.camera.orientation.back", property, "270"); |
422 | } else { |
423 | property_get("hw.camera.orientation.front", property, "90"); |
424 | } |
425 | info->orientation = atoi(property); |
426 | } |
427 | return EmulatedCamera3::getCameraInfo(info); |
428 | } |
429 | |
430 | /** |
431 | * Camera3 interface methods |
432 | */ |
433 | |
434 | void EmulatedFakeCamera3::getValidJpegSize(uint32_t picSizes[], uint32_t availablejpegsize[], int count) { |
435 | int i,j,k; |
436 | bool valid = true; |
437 | for (i=0,j=0; i < count; i+= 4) { |
438 | for (k= 0; k<=j ;k+=2) { |
439 | if ((availablejpegsize[k]*availablejpegsize[k+1]) == (picSizes[i+1]*picSizes[i+2])) { |
440 | |
441 | valid = false; |
442 | } |
443 | } |
444 | if (valid) { |
445 | availablejpegsize[j] = picSizes[i+1]; |
446 | availablejpegsize[j+1] = picSizes[i+2]; |
447 | j+=2; |
448 | } |
449 | valid = true; |
450 | } |
451 | } |
452 | |
453 | status_t EmulatedFakeCamera3::checkValidJpegSize(uint32_t width, uint32_t height) { |
454 | |
455 | int validsizecount = 0; |
456 | uint32_t count = sizeof(mAvailableJpegSize)/sizeof(mAvailableJpegSize[0]); |
457 | for (uint32_t f = 0; f < count; f+=2) { |
458 | if (mAvailableJpegSize[f] != 0) { |
459 | if ((mAvailableJpegSize[f] == width)&&(mAvailableJpegSize[f+1] == height)) { |
460 | validsizecount++; |
461 | } |
462 | } else { |
463 | break; |
464 | } |
465 | } |
466 | if (validsizecount == 0) |
467 | return BAD_VALUE; |
468 | return OK; |
469 | } |
470 | |
471 | status_t EmulatedFakeCamera3::configureStreams( |
472 | camera3_stream_configuration *streamList) { |
473 | Mutex::Autolock l(mLock); |
474 | uint32_t width, height, pixelfmt; |
475 | bool isRestart = false; |
476 | mFlushTag = false; |
477 | DBG_LOGB("%s: %d streams", __FUNCTION__, streamList->num_streams); |
478 | |
479 | if (mStatus != STATUS_OPEN && mStatus != STATUS_READY) { |
480 | ALOGE("%s: Cannot configure streams in state %d", |
481 | __FUNCTION__, mStatus); |
482 | return NO_INIT; |
483 | } |
484 | |
485 | /** |
486 | * Sanity-check input list. |
487 | */ |
488 | if (streamList == NULL) { |
489 | ALOGE("%s: NULL stream configuration", __FUNCTION__); |
490 | return BAD_VALUE; |
491 | } |
492 | |
493 | if (streamList->streams == NULL) { |
494 | ALOGE("%s: NULL stream list", __FUNCTION__); |
495 | return BAD_VALUE; |
496 | } |
497 | |
498 | if (streamList->num_streams < 1) { |
499 | ALOGE("%s: Bad number of streams requested: %d", __FUNCTION__, |
500 | streamList->num_streams); |
501 | return BAD_VALUE; |
502 | } |
503 | |
504 | camera3_stream_t *inputStream = NULL; |
505 | for (size_t i = 0; i < streamList->num_streams; i++) { |
506 | camera3_stream_t *newStream = streamList->streams[i]; |
507 | |
508 | if (newStream == NULL) { |
509 | ALOGE("%s: Stream index %zu was NULL", |
510 | __FUNCTION__, i); |
511 | return BAD_VALUE; |
512 | } |
513 | |
514 | if (newStream->max_buffers <= 0) { |
515 | isRestart = true;//mSensor->isNeedRestart(newStream->width, newStream->height, newStream->format); |
516 | DBG_LOGB("format=%x, w*h=%dx%d, stream_type=%d, max_buffers=%d, isRestart=%d\n", |
517 | newStream->format, newStream->width, newStream->height, |
518 | newStream->stream_type, newStream->max_buffers, |
519 | isRestart); |
520 | } |
521 | ALOGV("%s: Stream %p (id %zu), type %d, usage 0x%x, format 0x%x", |
522 | __FUNCTION__, newStream, i, newStream->stream_type, |
523 | newStream->usage, |
524 | newStream->format); |
525 | |
526 | if (newStream->stream_type == CAMERA3_STREAM_INPUT || |
527 | newStream->stream_type == CAMERA3_STREAM_BIDIRECTIONAL) { |
528 | if (inputStream != NULL) { |
529 | |
530 | ALOGE("%s: Multiple input streams requested!", __FUNCTION__); |
531 | return BAD_VALUE; |
532 | } |
533 | inputStream = newStream; |
534 | } |
535 | |
536 | bool validFormat = false; |
537 | for (size_t f = 0; |
538 | f < sizeof(kAvailableFormats)/sizeof(kAvailableFormats[0]); |
539 | f++) { |
540 | if (newStream->format == kAvailableFormats[f]) { |
541 | validFormat = true; |
542 | //HAL_PIXEL_FORMAT_YCrCb_420_SP, |
543 | if (HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED == newStream->format) |
544 | newStream->format = HAL_PIXEL_FORMAT_YCrCb_420_SP; |
545 | |
546 | break; |
547 | } |
548 | DBG_LOGB("stream_type=%d\n", newStream->stream_type); |
549 | } |
550 | if (!validFormat) { |
551 | ALOGE("%s: Unsupported stream format 0x%x requested", |
552 | __FUNCTION__, newStream->format); |
553 | return BAD_VALUE; |
554 | } |
555 | |
556 | status_t ret = checkValidJpegSize(newStream->width, newStream->height); |
557 | if (ret != OK) { |
558 | return BAD_VALUE; |
559 | } |
560 | |
561 | } |
562 | mInputStream = inputStream; |
563 | width = 0; |
564 | height = 0; |
565 | for (size_t i = 0; i < streamList->num_streams; i++) { |
566 | camera3_stream_t *newStream = streamList->streams[i]; |
567 | DBG_LOGB("find propert width and height, format=%x, w*h=%dx%d, stream_type=%d, max_buffers=%d\n", |
568 | newStream->format, newStream->width, newStream->height, newStream->stream_type, newStream->max_buffers); |
569 | if ((HAL_PIXEL_FORMAT_BLOB != newStream->format) && |
570 | (CAMERA3_STREAM_OUTPUT == newStream->stream_type)) { |
571 | |
572 | if (width < newStream->width) |
573 | width = newStream->width; |
574 | |
575 | if (height < newStream->height) |
576 | height = newStream->height; |
577 | |
578 | pixelfmt = (uint32_t)newStream->format; |
579 | if (HAL_PIXEL_FORMAT_YCbCr_420_888 == pixelfmt) |
580 | pixelfmt = HAL_PIXEL_FORMAT_YCrCb_420_SP; |
581 | } |
582 | |
583 | } |
584 | |
585 | //TODO modify this ugly code |
586 | if (isRestart) { |
587 | isRestart = mSensor->isNeedRestart(width, height, pixelfmt); |
588 | } |
589 | |
590 | if (isRestart) { |
591 | mSensor->streamOff(); |
592 | pixelfmt = mSensor->halFormatToSensorFormat(pixelfmt); |
593 | mSensor->setOutputFormat(width, height, pixelfmt, 0); |
594 | mSensor->streamOn(); |
595 | DBG_LOGB("width=%d, height=%d, pixelfmt=%.4s\n", |
596 | width, height, (char*)&pixelfmt); |
597 | } |
598 | |
599 | /** |
600 | * Initially mark all existing streams as not alive |
601 | */ |
602 | for (StreamIterator s = mStreams.begin(); s != mStreams.end(); ++s) { |
603 | PrivateStreamInfo *privStream = |
604 | static_cast<PrivateStreamInfo*>((*s)->priv); |
605 | privStream->alive = false; |
606 | } |
607 | |
608 | /** |
609 | * Find new streams and mark still-alive ones |
610 | */ |
611 | for (size_t i = 0; i < streamList->num_streams; i++) { |
612 | camera3_stream_t *newStream = streamList->streams[i]; |
613 | if (newStream->priv == NULL) { |
614 | // New stream, construct info |
615 | PrivateStreamInfo *privStream = new PrivateStreamInfo(); |
616 | privStream->alive = true; |
617 | privStream->registered = false; |
618 | |
619 | newStream->usage = |
620 | mSensor->getStreamUsage(newStream->stream_type); |
621 | |
622 | DBG_LOGB("stream_type=%d\n", newStream->stream_type); |
623 | newStream->max_buffers = kMaxBufferCount; |
624 | newStream->priv = privStream; |
625 | mStreams.push_back(newStream); |
626 | } else { |
627 | // Existing stream, mark as still alive. |
628 | PrivateStreamInfo *privStream = |
629 | static_cast<PrivateStreamInfo*>(newStream->priv); |
630 | CAMHAL_LOGDA("Existing stream ?"); |
631 | privStream->alive = true; |
632 | } |
633 | DBG_LOGB("%d, newStream=%p, stream_type=%d, usage=%x, priv=%p, w*h=%dx%d\n", |
634 | i, newStream, newStream->stream_type, newStream->usage, newStream->priv, newStream->width, newStream->height); |
635 | } |
636 | |
637 | /** |
638 | * Reap the dead streams |
639 | */ |
640 | for (StreamIterator s = mStreams.begin(); s != mStreams.end();) { |
641 | PrivateStreamInfo *privStream = |
642 | static_cast<PrivateStreamInfo*>((*s)->priv); |
643 | if (!privStream->alive) { |
644 | DBG_LOGA("delete not alive streams"); |
645 | (*s)->priv = NULL; |
646 | delete privStream; |
647 | s = mStreams.erase(s); |
648 | } else { |
649 | ++s; |
650 | } |
651 | } |
652 | |
653 | /** |
654 | * Can't reuse settings across configure call |
655 | */ |
656 | mPrevSettings.clear(); |
657 | |
658 | return OK; |
659 | } |
660 | |
661 | status_t EmulatedFakeCamera3::registerStreamBuffers( |
662 | const camera3_stream_buffer_set *bufferSet) { |
663 | DBG_LOGB("%s: E", __FUNCTION__); |
664 | Mutex::Autolock l(mLock); |
665 | |
666 | /** |
667 | * Sanity checks |
668 | */ |
669 | DBG_LOGA("==========sanity checks\n"); |
670 | |
671 | // OK: register streams at any time during configure |
672 | // (but only once per stream) |
673 | if (mStatus != STATUS_READY && mStatus != STATUS_ACTIVE) { |
674 | ALOGE("%s: Cannot register buffers in state %d", |
675 | __FUNCTION__, mStatus); |
676 | return NO_INIT; |
677 | } |
678 | |
679 | if (bufferSet == NULL) { |
680 | ALOGE("%s: NULL buffer set!", __FUNCTION__); |
681 | return BAD_VALUE; |
682 | } |
683 | |
684 | StreamIterator s = mStreams.begin(); |
685 | for (; s != mStreams.end(); ++s) { |
686 | if (bufferSet->stream == *s) break; |
687 | } |
688 | if (s == mStreams.end()) { |
689 | ALOGE("%s: Trying to register buffers for a non-configured stream!", |
690 | __FUNCTION__); |
691 | return BAD_VALUE; |
692 | } |
693 | |
694 | /** |
695 | * Register the buffers. This doesn't mean anything to the emulator besides |
696 | * marking them off as registered. |
697 | */ |
698 | |
699 | PrivateStreamInfo *privStream = |
700 | static_cast<PrivateStreamInfo*>((*s)->priv); |
701 | |
702 | #if 0 |
703 | if (privStream->registered) { |
704 | ALOGE("%s: Illegal to register buffer more than once", __FUNCTION__); |
705 | return BAD_VALUE; |
706 | } |
707 | #endif |
708 | |
709 | privStream->registered = true; |
710 | |
711 | return OK; |
712 | } |
713 | |
714 | const camera_metadata_t* EmulatedFakeCamera3::constructDefaultRequestSettings( |
715 | int type) { |
716 | DBG_LOGB("%s: E", __FUNCTION__); |
717 | Mutex::Autolock l(mLock); |
718 | |
719 | if (type < 0 || type >= CAMERA3_TEMPLATE_COUNT) { |
720 | ALOGE("%s: Unknown request settings template: %d", |
721 | __FUNCTION__, type); |
722 | return NULL; |
723 | } |
724 | |
725 | /** |
726 | * Cache is not just an optimization - pointer returned has to live at |
727 | * least as long as the camera device instance does. |
728 | */ |
729 | if (mDefaultTemplates[type] != NULL) { |
730 | return mDefaultTemplates[type]; |
731 | } |
732 | |
733 | CameraMetadata settings; |
734 | |
735 | /** android.request */ |
736 | static const uint8_t requestType = ANDROID_REQUEST_TYPE_CAPTURE; |
737 | settings.update(ANDROID_REQUEST_TYPE, &requestType, 1); |
738 | |
739 | static const uint8_t metadataMode = ANDROID_REQUEST_METADATA_MODE_FULL; |
740 | settings.update(ANDROID_REQUEST_METADATA_MODE, &metadataMode, 1); |
741 | |
742 | static const int32_t id = 0; |
743 | settings.update(ANDROID_REQUEST_ID, &id, 1); |
744 | |
745 | static const int32_t frameCount = 0; |
746 | settings.update(ANDROID_REQUEST_FRAME_COUNT, &frameCount, 1); |
747 | |
748 | /** android.lens */ |
749 | |
750 | static const float focusDistance = 0; |
751 | settings.update(ANDROID_LENS_FOCUS_DISTANCE, &focusDistance, 1); |
752 | |
753 | static const float aperture = 2.8f; |
754 | settings.update(ANDROID_LENS_APERTURE, &aperture, 1); |
755 | |
756 | // static const float focalLength = 5.0f; |
757 | static const float focalLength = 3.299999952316284f; |
758 | settings.update(ANDROID_LENS_FOCAL_LENGTH, &focalLength, 1); |
759 | |
760 | static const float filterDensity = 0; |
761 | settings.update(ANDROID_LENS_FILTER_DENSITY, &filterDensity, 1); |
762 | |
763 | static const uint8_t opticalStabilizationMode = |
764 | ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF; |
765 | settings.update(ANDROID_LENS_OPTICAL_STABILIZATION_MODE, |
766 | &opticalStabilizationMode, 1); |
767 | |
768 | // FOCUS_RANGE set only in frame |
769 | |
770 | /** android.sensor */ |
771 | |
772 | static const int32_t testAvailablePattern = ANDROID_SENSOR_TEST_PATTERN_MODE_OFF; |
773 | settings.update(ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES, &testAvailablePattern, 1); |
774 | static const int32_t testPattern = ANDROID_SENSOR_TEST_PATTERN_MODE_OFF; |
775 | settings.update(ANDROID_SENSOR_TEST_PATTERN_MODE, &testPattern, 1); |
776 | static const int64_t exposureTime = 10 * MSEC; |
777 | settings.update(ANDROID_SENSOR_EXPOSURE_TIME, &exposureTime, 1); |
778 | |
779 | int64_t frameDuration = mSensor->getMinFrameDuration(); |
780 | settings.update(ANDROID_SENSOR_FRAME_DURATION, &frameDuration, 1); |
781 | |
782 | static const int32_t sensitivity = 100; |
783 | settings.update(ANDROID_SENSOR_SENSITIVITY, &sensitivity, 1); |
784 | |
785 | static const int64_t rollingShutterSkew = 0; |
786 | settings.update(ANDROID_SENSOR_ROLLING_SHUTTER_SKEW, &rollingShutterSkew, 1); |
787 | // TIMESTAMP set only in frame |
788 | |
789 | /** android.flash */ |
790 | |
791 | static const uint8_t flashstate = ANDROID_FLASH_STATE_UNAVAILABLE; |
792 | settings.update(ANDROID_FLASH_STATE, &flashstate, 1); |
793 | |
794 | static const uint8_t flashMode = ANDROID_FLASH_MODE_OFF; |
795 | settings.update(ANDROID_FLASH_MODE, &flashMode, 1); |
796 | |
797 | static const uint8_t flashPower = 10; |
798 | settings.update(ANDROID_FLASH_FIRING_POWER, &flashPower, 1); |
799 | |
800 | static const int64_t firingTime = 0; |
801 | settings.update(ANDROID_FLASH_FIRING_TIME, &firingTime, 1); |
802 | |
803 | /** Processing block modes */ |
804 | uint8_t hotPixelMode = 0; |
805 | uint8_t demosaicMode = 0; |
806 | uint8_t noiseMode = 0; |
807 | uint8_t shadingMode = 0; |
808 | uint8_t colorMode = 0; |
809 | uint8_t tonemapMode = 0; |
810 | uint8_t edgeMode = 0; |
811 | switch (type) { |
812 | |
813 | case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT: |
814 | case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG: |
815 | noiseMode = ANDROID_NOISE_REDUCTION_MODE_HIGH_QUALITY; |
816 | // fall-through |
817 | case CAMERA3_TEMPLATE_STILL_CAPTURE: |
818 | hotPixelMode = ANDROID_HOT_PIXEL_MODE_HIGH_QUALITY; |
819 | demosaicMode = ANDROID_DEMOSAIC_MODE_HIGH_QUALITY; |
820 | shadingMode = ANDROID_SHADING_MODE_HIGH_QUALITY; |
821 | colorMode = ANDROID_COLOR_CORRECTION_MODE_HIGH_QUALITY; |
822 | tonemapMode = ANDROID_TONEMAP_MODE_HIGH_QUALITY; |
823 | edgeMode = ANDROID_EDGE_MODE_HIGH_QUALITY; |
824 | break; |
825 | case CAMERA3_TEMPLATE_PREVIEW: |
826 | // fall-through |
827 | case CAMERA3_TEMPLATE_VIDEO_RECORD: |
828 | // fall-through |
829 | case CAMERA3_TEMPLATE_MANUAL: |
830 | // fall-through |
831 | default: |
832 | hotPixelMode = ANDROID_HOT_PIXEL_MODE_FAST; |
833 | demosaicMode = ANDROID_DEMOSAIC_MODE_FAST; |
834 | noiseMode = ANDROID_NOISE_REDUCTION_MODE_FAST; |
835 | shadingMode = ANDROID_SHADING_MODE_FAST; |
836 | colorMode = ANDROID_COLOR_CORRECTION_MODE_FAST; |
837 | tonemapMode = ANDROID_TONEMAP_MODE_FAST; |
838 | edgeMode = ANDROID_EDGE_MODE_FAST; |
839 | break; |
840 | } |
841 | settings.update(ANDROID_HOT_PIXEL_MODE, &hotPixelMode, 1); |
842 | settings.update(ANDROID_DEMOSAIC_MODE, &demosaicMode, 1); |
843 | settings.update(ANDROID_NOISE_REDUCTION_MODE, &noiseMode, 1); |
844 | settings.update(ANDROID_SHADING_MODE, &shadingMode, 1); |
845 | settings.update(ANDROID_COLOR_CORRECTION_MODE, &colorMode, 1); |
846 | settings.update(ANDROID_TONEMAP_MODE, &tonemapMode, 1); |
847 | settings.update(ANDROID_EDGE_MODE, &edgeMode, 1); |
848 | |
849 | /** android.noise */ |
850 | static const uint8_t noiseStrength = 5; |
851 | settings.update(ANDROID_NOISE_REDUCTION_STRENGTH, &noiseStrength, 1); |
852 | static uint8_t availableNBModes[] = { |
853 | ANDROID_NOISE_REDUCTION_MODE_OFF, |
854 | ANDROID_NOISE_REDUCTION_MODE_FAST, |
855 | ANDROID_NOISE_REDUCTION_MODE_HIGH_QUALITY, |
856 | }; |
857 | settings.update(ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES, |
858 | availableNBModes, sizeof(availableNBModes)/sizeof(availableNBModes)); |
859 | |
860 | |
861 | /** android.color */ |
862 | static const float colorTransform[9] = { |
863 | 1.0f, 0.f, 0.f, |
864 | 0.f, 1.f, 0.f, |
865 | 0.f, 0.f, 1.f |
866 | }; |
867 | settings.update(ANDROID_COLOR_CORRECTION_TRANSFORM, colorTransform, 9); |
868 | |
869 | /** android.tonemap */ |
870 | static const float tonemapCurve[4] = { |
871 | 0.f, 0.f, |
872 | 1.f, 1.f |
873 | }; |
874 | settings.update(ANDROID_TONEMAP_CURVE_RED, tonemapCurve, 4); |
875 | settings.update(ANDROID_TONEMAP_CURVE_GREEN, tonemapCurve, 4); |
876 | settings.update(ANDROID_TONEMAP_CURVE_BLUE, tonemapCurve, 4); |
877 | |
878 | /** android.edge */ |
879 | static const uint8_t edgeStrength = 5; |
880 | settings.update(ANDROID_EDGE_STRENGTH, &edgeStrength, 1); |
881 | |
882 | /** android.scaler */ |
883 | static const uint8_t croppingType = ANDROID_SCALER_CROPPING_TYPE_CENTER_ONLY; |
884 | settings.update(ANDROID_SCALER_CROPPING_TYPE, &croppingType, 1); |
885 | |
886 | static const int32_t cropRegion[] = { |
887 | 0, 0, (int32_t)Sensor::kResolution[0], (int32_t)Sensor::kResolution[1], |
888 | }; |
889 | settings.update(ANDROID_SCALER_CROP_REGION, cropRegion, 4); |
890 | |
891 | /** android.jpeg */ |
892 | static const uint8_t jpegQuality = 80; |
893 | settings.update(ANDROID_JPEG_QUALITY, &jpegQuality, 1); |
894 | |
895 | static const int32_t thumbnailSize[2] = { |
896 | 160, 120 |
897 | }; |
898 | settings.update(ANDROID_JPEG_THUMBNAIL_SIZE, thumbnailSize, 2); |
899 | |
900 | static const uint8_t thumbnailQuality = 80; |
901 | settings.update(ANDROID_JPEG_THUMBNAIL_QUALITY, &thumbnailQuality, 1); |
902 | |
903 | static const double gpsCoordinates[3] = { |
904 | 0, 0, 0 |
905 | }; |
906 | settings.update(ANDROID_JPEG_GPS_COORDINATES, gpsCoordinates, 3); //default 2 value |
907 | |
908 | static const uint8_t gpsProcessingMethod[32] = "None"; |
909 | settings.update(ANDROID_JPEG_GPS_PROCESSING_METHOD, gpsProcessingMethod, 32); |
910 | |
911 | static const int64_t gpsTimestamp = 0; |
912 | settings.update(ANDROID_JPEG_GPS_TIMESTAMP, &gpsTimestamp, 1); |
913 | |
914 | static const int32_t jpegOrientation = 0; |
915 | settings.update(ANDROID_JPEG_ORIENTATION, &jpegOrientation, 1); |
916 | |
917 | /** android.stats */ |
918 | |
919 | static const uint8_t faceDetectMode = |
920 | ANDROID_STATISTICS_FACE_DETECT_MODE_OFF; |
921 | settings.update(ANDROID_STATISTICS_FACE_DETECT_MODE, &faceDetectMode, 1); |
922 | |
923 | static const uint8_t histogramMode = ANDROID_STATISTICS_HISTOGRAM_MODE_OFF; |
924 | settings.update(ANDROID_STATISTICS_HISTOGRAM_MODE, &histogramMode, 1); |
925 | |
926 | static const uint8_t sharpnessMapMode = |
927 | ANDROID_STATISTICS_SHARPNESS_MAP_MODE_OFF; |
928 | settings.update(ANDROID_STATISTICS_SHARPNESS_MAP_MODE, &sharpnessMapMode, 1); |
929 | |
930 | static const uint8_t hotPixelMapMode = ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE_OFF; |
931 | settings.update(ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE,&hotPixelMapMode, 1); |
932 | static const uint8_t sceneFlicker = ANDROID_STATISTICS_SCENE_FLICKER_NONE; |
933 | settings.update(ANDROID_STATISTICS_SCENE_FLICKER,&sceneFlicker, 1); |
934 | static const uint8_t lensShadingMapMode = ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF; |
935 | settings.update(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,&lensShadingMapMode, 1); |
936 | // faceRectangles, faceScores, faceLandmarks, faceIds, histogram, |
937 | // sharpnessMap only in frames |
938 | |
939 | /** android.control */ |
940 | |
941 | uint8_t controlIntent = 0; |
942 | uint8_t controlMode = ANDROID_CONTROL_MODE_AUTO; //default value |
943 | uint8_t aeMode = ANDROID_CONTROL_AE_MODE_ON; |
944 | uint8_t awbMode = ANDROID_CONTROL_AWB_MODE_AUTO; |
945 | switch (type) { |
946 | case CAMERA3_TEMPLATE_PREVIEW: |
947 | controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW; |
948 | break; |
949 | case CAMERA3_TEMPLATE_STILL_CAPTURE: |
950 | controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE; |
951 | break; |
952 | case CAMERA3_TEMPLATE_VIDEO_RECORD: |
953 | controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD; |
954 | break; |
955 | case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT: |
956 | controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT; |
957 | break; |
958 | case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG: |
959 | controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG; |
960 | break; |
961 | case CAMERA3_TEMPLATE_MANUAL: |
962 | controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_MANUAL; |
963 | controlMode = ANDROID_CONTROL_MODE_OFF; |
964 | aeMode = ANDROID_CONTROL_AE_MODE_OFF; |
965 | awbMode = ANDROID_CONTROL_AWB_MODE_OFF; |
966 | break; |
967 | default: |
968 | controlIntent = ANDROID_CONTROL_CAPTURE_INTENT_CUSTOM; |
969 | break; |
970 | } |
971 | settings.update(ANDROID_CONTROL_CAPTURE_INTENT, &controlIntent, 1); |
972 | settings.update(ANDROID_CONTROL_MODE, &controlMode, 1); |
973 | |
974 | static const uint8_t effectMode = ANDROID_CONTROL_EFFECT_MODE_OFF; |
975 | settings.update(ANDROID_CONTROL_EFFECT_MODE, &effectMode, 1); |
976 | |
977 | static const uint8_t sceneMode = ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY; |
978 | settings.update(ANDROID_CONTROL_SCENE_MODE, &sceneMode, 1); |
979 | |
980 | settings.update(ANDROID_CONTROL_AE_MODE, &aeMode, 1); |
981 | |
982 | static const uint8_t aeLock = ANDROID_CONTROL_AE_LOCK_OFF; |
983 | settings.update(ANDROID_CONTROL_AE_LOCK, &aeLock, 1); |
984 | |
985 | static const uint8_t aePrecaptureTrigger = |
986 | ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE; |
987 | settings.update(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER, &aePrecaptureTrigger, 1); |
988 | |
989 | static const int32_t mAfTriggerId = 0; |
990 | settings.update(ANDROID_CONTROL_AF_TRIGGER_ID,&mAfTriggerId, 1); |
991 | static const uint8_t afTrigger = ANDROID_CONTROL_AF_TRIGGER_IDLE; |
992 | settings.update(ANDROID_CONTROL_AF_TRIGGER, &afTrigger, 1); |
993 | |
994 | static const int32_t controlRegions[5] = { |
995 | 0, 0, (int32_t)Sensor::kResolution[0], (int32_t)Sensor::kResolution[1], |
996 | 1000 |
997 | }; |
998 | // settings.update(ANDROID_CONTROL_AE_REGIONS, controlRegions, 5); |
999 | |
1000 | static const int32_t aeExpCompensation = 0; |
1001 | settings.update(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION, &aeExpCompensation, 1); |
1002 | |
1003 | static const int32_t aeTargetFpsRange[2] = { |
1004 | 30, 30 |
1005 | }; |
1006 | settings.update(ANDROID_CONTROL_AE_TARGET_FPS_RANGE, aeTargetFpsRange, 2); |
1007 | |
1008 | static const uint8_t aeAntibandingMode = |
1009 | ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO; |
1010 | settings.update(ANDROID_CONTROL_AE_ANTIBANDING_MODE, &aeAntibandingMode, 1); |
1011 | |
1012 | settings.update(ANDROID_CONTROL_AWB_MODE, &awbMode, 1); |
1013 | |
1014 | static const uint8_t awbLock = ANDROID_CONTROL_AWB_LOCK_OFF; |
1015 | settings.update(ANDROID_CONTROL_AWB_LOCK, &awbLock, 1); |
1016 | |
1017 | // settings.update(ANDROID_CONTROL_AWB_REGIONS, controlRegions, 5); |
1018 | |
1019 | uint8_t afMode = 0; |
1020 | switch (type) { |
1021 | case CAMERA3_TEMPLATE_PREVIEW: |
1022 | afMode = ANDROID_CONTROL_AF_MODE_AUTO; |
1023 | break; |
1024 | case CAMERA3_TEMPLATE_STILL_CAPTURE: |
1025 | afMode = ANDROID_CONTROL_AF_MODE_AUTO; |
1026 | break; |
1027 | case CAMERA3_TEMPLATE_VIDEO_RECORD: |
1028 | afMode = ANDROID_CONTROL_AF_MODE_AUTO; |
1029 | //afMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO; |
1030 | break; |
1031 | case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT: |
1032 | afMode = ANDROID_CONTROL_AF_MODE_AUTO; |
1033 | //afMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO; |
1034 | break; |
1035 | case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG: |
1036 | afMode = ANDROID_CONTROL_AF_MODE_AUTO; |
1037 | //afMode = ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE; |
1038 | break; |
1039 | case CAMERA3_TEMPLATE_MANUAL: |
1040 | afMode = ANDROID_CONTROL_AF_MODE_OFF; |
1041 | break; |
1042 | default: |
1043 | afMode = ANDROID_CONTROL_AF_MODE_AUTO; |
1044 | break; |
1045 | } |
1046 | settings.update(ANDROID_CONTROL_AF_MODE, &afMode, 1); |
1047 | |
1048 | static const uint8_t afstate = ANDROID_CONTROL_AF_STATE_INACTIVE; |
1049 | settings.update(ANDROID_CONTROL_AF_STATE,&afstate,1); |
1050 | |
1051 | // settings.update(ANDROID_CONTROL_AF_REGIONS, controlRegions, 5); |
1052 | |
1053 | static const uint8_t aestate = ANDROID_CONTROL_AE_STATE_CONVERGED; |
1054 | settings.update(ANDROID_CONTROL_AE_STATE,&aestate,1); |
1055 | static const uint8_t awbstate = ANDROID_CONTROL_AWB_STATE_INACTIVE; |
1056 | settings.update(ANDROID_CONTROL_AWB_STATE,&awbstate,1); |
1057 | static const uint8_t vstabMode = |
1058 | ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF; |
1059 | settings.update(ANDROID_CONTROL_VIDEO_STABILIZATION_MODE, &vstabMode, 1); |
1060 | |
1061 | // aeState, awbState, afState only in frame |
1062 | |
1063 | mDefaultTemplates[type] = settings.release(); |
1064 | |
1065 | return mDefaultTemplates[type]; |
1066 | } |
1067 | |
1068 | status_t EmulatedFakeCamera3::processCaptureRequest( |
1069 | camera3_capture_request *request) { |
1070 | status_t res; |
1071 | nsecs_t exposureTime; |
1072 | nsecs_t frameDuration; |
1073 | uint32_t sensitivity; |
1074 | uint32_t frameNumber; |
1075 | bool mHaveThumbnail = false; |
1076 | CameraMetadata settings; |
1077 | Buffers *sensorBuffers = NULL; |
1078 | HalBufferVector *buffers = NULL; |
1079 | |
1080 | if (mFlushTag) { |
1081 | DBG_LOGA("already flush, but still send Capture Request .\n"); |
1082 | } |
1083 | |
1084 | { |
1085 | Mutex::Autolock l(mLock); |
1086 | |
1087 | /** Validation */ |
1088 | |
1089 | if (mStatus < STATUS_READY) { |
1090 | ALOGE("%s: Can't submit capture requests in state %d", __FUNCTION__, |
1091 | mStatus); |
1092 | return INVALID_OPERATION; |
1093 | } |
1094 | |
1095 | if (request == NULL) { |
1096 | ALOGE("%s: NULL request!", __FUNCTION__); |
1097 | return BAD_VALUE; |
1098 | } |
1099 | |
1100 | frameNumber = request->frame_number; |
1101 | |
1102 | if (request->settings == NULL && mPrevSettings.isEmpty()) { |
1103 | ALOGE("%s: Request %d: NULL settings for first request after" |
1104 | "configureStreams()", __FUNCTION__, frameNumber); |
1105 | return BAD_VALUE; |
1106 | } |
1107 | |
1108 | if (request->input_buffer != NULL && |
1109 | request->input_buffer->stream != mInputStream) { |
1110 | DBG_LOGB("%s: Request %d: Input buffer not from input stream!", |
1111 | __FUNCTION__, frameNumber); |
1112 | DBG_LOGB("%s: Bad stream %p, expected: %p", |
1113 | __FUNCTION__, request->input_buffer->stream, |
1114 | mInputStream); |
1115 | DBG_LOGB("%s: Bad stream type %d, expected stream type %d", |
1116 | __FUNCTION__, request->input_buffer->stream->stream_type, |
1117 | mInputStream ? mInputStream->stream_type : -1); |
1118 | |
1119 | return BAD_VALUE; |
1120 | } |
1121 | |
1122 | if (request->num_output_buffers < 1 || request->output_buffers == NULL) { |
1123 | ALOGE("%s: Request %d: No output buffers provided!", |
1124 | __FUNCTION__, frameNumber); |
1125 | return BAD_VALUE; |
1126 | } |
1127 | |
1128 | // Validate all buffers, starting with input buffer if it's given |
1129 | |
1130 | ssize_t idx; |
1131 | const camera3_stream_buffer_t *b; |
1132 | if (request->input_buffer != NULL) { |
1133 | idx = -1; |
1134 | b = request->input_buffer; |
1135 | } else { |
1136 | idx = 0; |
1137 | b = request->output_buffers; |
1138 | } |
1139 | do { |
1140 | PrivateStreamInfo *priv = |
1141 | static_cast<PrivateStreamInfo*>(b->stream->priv); |
1142 | if (priv == NULL) { |
1143 | ALOGE("%s: Request %d: Buffer %zu: Unconfigured stream!", |
1144 | __FUNCTION__, frameNumber, idx); |
1145 | return BAD_VALUE; |
1146 | } |
1147 | #if 0 |
1148 | if (!priv->alive || !priv->registered) { |
1149 | ALOGE("%s: Request %d: Buffer %zu: Unregistered or dead stream! alive=%d, registered=%d\n", |
1150 | __FUNCTION__, frameNumber, idx, |
1151 | priv->alive, priv->registered); |
1152 | //return BAD_VALUE; |
1153 | } |
1154 | #endif |
1155 | if (b->status != CAMERA3_BUFFER_STATUS_OK) { |
1156 | ALOGE("%s: Request %d: Buffer %zu: Status not OK!", |
1157 | __FUNCTION__, frameNumber, idx); |
1158 | return BAD_VALUE; |
1159 | } |
1160 | if (b->release_fence != -1) { |
1161 | ALOGE("%s: Request %d: Buffer %zu: Has a release fence!", |
1162 | __FUNCTION__, frameNumber, idx); |
1163 | return BAD_VALUE; |
1164 | } |
1165 | if (b->buffer == NULL) { |
1166 | ALOGE("%s: Request %d: Buffer %zu: NULL buffer handle!", |
1167 | __FUNCTION__, frameNumber, idx); |
1168 | return BAD_VALUE; |
1169 | } |
1170 | idx++; |
1171 | b = &(request->output_buffers[idx]); |
1172 | } while (idx < (ssize_t)request->num_output_buffers); |
1173 | |
1174 | // TODO: Validate settings parameters |
1175 | |
1176 | /** |
1177 | * Start processing this request |
1178 | */ |
1179 | mStatus = STATUS_ACTIVE; |
1180 | |
1181 | camera_metadata_entry e; |
1182 | |
1183 | if (request->settings == NULL) { |
1184 | settings.acquire(mPrevSettings); |
1185 | } else { |
1186 | settings = request->settings; |
1187 | |
1188 | uint8_t antiBanding = 0; |
1189 | uint8_t effectMode = 0; |
1190 | int exposureCmp = 0; |
1191 | |
1192 | e = settings.find(ANDROID_CONTROL_AE_ANTIBANDING_MODE); |
1193 | if (e.count == 0) { |
1194 | ALOGE("%s: No antibanding entry!", __FUNCTION__); |
1195 | return BAD_VALUE; |
1196 | } |
1197 | antiBanding = e.data.u8[0]; |
1198 | mSensor->setAntiBanding(antiBanding); |
1199 | |
1200 | e = settings.find(ANDROID_CONTROL_EFFECT_MODE); |
1201 | if (e.count == 0) { |
1202 | ALOGE("%s: No antibanding entry!", __FUNCTION__); |
1203 | return BAD_VALUE; |
1204 | } |
1205 | effectMode = e.data.u8[0]; |
1206 | mSensor->setEffect(effectMode); |
1207 | |
1208 | e = settings.find(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION); |
1209 | if (e.count == 0) { |
1210 | ALOGE("%s: No exposure entry!", __FUNCTION__); |
1211 | //return BAD_VALUE; |
1212 | } else { |
1213 | exposureCmp = e.data.i32[0]; |
1214 | DBG_LOGB("set expsore compensaton %d\n", exposureCmp); |
1215 | mSensor->setExposure(exposureCmp); |
1216 | } |
1217 | |
1218 | int32_t cropRegion[4]; |
1219 | int32_t cropWidth; |
1220 | int32_t outputWidth = request->output_buffers[0].stream->width; |
1221 | |
1222 | e = settings.find(ANDROID_SCALER_CROP_REGION); |
1223 | if (e.count == 0) { |
1224 | ALOGE("%s: No corp region entry!", __FUNCTION__); |
1225 | //return BAD_VALUE; |
1226 | } else { |
1227 | cropRegion[0] = e.data.i32[0]; |
1228 | cropRegion[1] = e.data.i32[1]; |
1229 | cropWidth = cropRegion[2] = e.data.i32[2]; |
1230 | cropRegion[3] = e.data.i32[3]; |
1231 | for (int i = mZoomMin; i <= mZoomMax; i += mZoomStep) { |
1232 | //if ( (float) i / mZoomMin >= (float) outputWidth / cropWidth) { |
1233 | if ( i * cropWidth >= outputWidth * mZoomMin ) { |
1234 | mSensor->setZoom(i); |
1235 | break; |
1236 | } |
1237 | } |
1238 | DBG_LOGB("cropRegion:%d, %d, %d, %d\n", cropRegion[0], cropRegion[1],cropRegion[2],cropRegion[3]); |
1239 | } |
1240 | } |
1241 | |
1242 | uint8_t len[] = {1}; |
1243 | settings.update(ANDROID_REQUEST_PIPELINE_DEPTH, (uint8_t *)len, 1); |
1244 | |
1245 | uint8_t maxlen[] = {0}; |
1246 | settings.update(ANDROID_REQUEST_PIPELINE_MAX_DEPTH, (uint8_t *)maxlen, 1); |
1247 | |
1248 | res = process3A(settings); |
1249 | if (res != OK) { |
1250 | ALOGVV("%s: process3A failed!", __FUNCTION__); |
1251 | //return res; |
1252 | } |
1253 | |
1254 | // TODO: Handle reprocessing |
1255 | |
1256 | /** |
1257 | * Get ready for sensor config |
1258 | */ |
1259 | |
1260 | bool needJpeg = false; |
1261 | ssize_t jpegbuffersize; |
1262 | uint32_t jpegpixelfmt; |
1263 | |
1264 | exposureTime = settings.find(ANDROID_SENSOR_EXPOSURE_TIME).data.i64[0]; |
1265 | frameDuration = settings.find(ANDROID_SENSOR_FRAME_DURATION).data.i64[0]; |
1266 | sensitivity = settings.find(ANDROID_SENSOR_SENSITIVITY).data.i32[0]; |
1267 | |
1268 | sensorBuffers = new Buffers(); |
1269 | buffers = new HalBufferVector(); |
1270 | |
1271 | sensorBuffers->setCapacity(request->num_output_buffers); |
1272 | buffers->setCapacity(request->num_output_buffers); |
1273 | |
1274 | // Process all the buffers we got for output, constructing internal buffer |
1275 | // structures for them, and lock them for writing. |
1276 | for (size_t i = 0; i < request->num_output_buffers; i++) { |
1277 | const camera3_stream_buffer &srcBuf = request->output_buffers[i]; |
1278 | const private_handle_t *privBuffer = |
1279 | (const private_handle_t*)(*srcBuf.buffer); |
1280 | StreamBuffer destBuf; |
1281 | destBuf.streamId = kGenericStreamId; |
1282 | destBuf.width = srcBuf.stream->width; |
1283 | destBuf.height = srcBuf.stream->height; |
1284 | destBuf.format = privBuffer->format; // Use real private format |
1285 | destBuf.stride = srcBuf.stream->width; // TODO: query from gralloc |
1286 | destBuf.buffer = srcBuf.buffer; |
1287 | destBuf.share_fd = privBuffer->share_fd; |
1288 | |
1289 | if (destBuf.format == HAL_PIXEL_FORMAT_BLOB) { |
1290 | needJpeg = true; |
1291 | memset(&info,0,sizeof(struct ExifInfo)); |
1292 | info.orientation = settings.find(ANDROID_JPEG_ORIENTATION).data.i32[0]; |
1293 | jpegpixelfmt = mSensor->getOutputFormat(); |
1294 | if (!mSupportRotate) { |
1295 | info.mainwidth = srcBuf.stream->width; |
1296 | info.mainheight = srcBuf.stream->height; |
1297 | } else { |
1298 | if ((info.orientation == 90) || (info.orientation == 270)) { |
1299 | info.mainwidth = srcBuf.stream->height; |
1300 | info.mainheight = srcBuf.stream->width; |
1301 | } else { |
1302 | info.mainwidth = srcBuf.stream->width; |
1303 | info.mainheight = srcBuf.stream->height; |
1304 | } |
1305 | } |
1306 | if ((jpegpixelfmt == V4L2_PIX_FMT_MJPEG) || (jpegpixelfmt == V4L2_PIX_FMT_YUYV)) { |
1307 | mSensor->setOutputFormat(info.mainwidth,info.mainheight,jpegpixelfmt,1); |
1308 | } else { |
1309 | mSensor->setOutputFormat(info.mainwidth,info.mainheight,V4L2_PIX_FMT_RGB24,1); |
1310 | } |
1311 | } |
1312 | |
1313 | // Wait on fence |
1314 | sp<Fence> bufferAcquireFence = new Fence(srcBuf.acquire_fence); |
1315 | res = bufferAcquireFence->wait(kFenceTimeoutMs); |
1316 | if (res == TIMED_OUT) { |
1317 | ALOGE("%s: Request %d: Buffer %zu: Fence timed out after %d ms", |
1318 | __FUNCTION__, frameNumber, i, kFenceTimeoutMs); |
1319 | } |
1320 | if (res == OK) { |
1321 | // Lock buffer for writing |
1322 | const Rect rect(destBuf.width, destBuf.height); |
1323 | if (srcBuf.stream->format == HAL_PIXEL_FORMAT_YCbCr_420_888) { |
1324 | if (privBuffer->format == HAL_PIXEL_FORMAT_YCbCr_420_888/*HAL_PIXEL_FORMAT_YCrCb_420_SP*/) { |
1325 | android_ycbcr ycbcr = android_ycbcr(); |
1326 | res = GraphicBufferMapper::get().lockYCbCr( |
1327 | *(destBuf.buffer), |
1328 | GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK, |
1329 | rect, |
1330 | &ycbcr); |
1331 | // This is only valid because we know that emulator's |
1332 | // YCbCr_420_888 is really contiguous NV21 under the hood |
1333 | destBuf.img = static_cast<uint8_t*>(ycbcr.y); |
1334 | } else { |
1335 | ALOGE("Unexpected private format for flexible YUV: 0x%x", |
1336 | privBuffer->format); |
1337 | res = INVALID_OPERATION; |
1338 | } |
1339 | } else { |
1340 | res = GraphicBufferMapper::get().lock(*(destBuf.buffer), |
1341 | GRALLOC_USAGE_SW_READ_MASK | GRALLOC_USAGE_SW_WRITE_MASK, |
1342 | rect, |
1343 | (void**)&(destBuf.img)); |
1344 | } |
1345 | if (res != OK) { |
1346 | ALOGE("%s: Request %d: Buffer %zu: Unable to lock buffer", |
1347 | __FUNCTION__, frameNumber, i); |
1348 | } |
1349 | } |
1350 | |
1351 | if (res != OK) { |
1352 | // Either waiting or locking failed. Unlock locked buffers and bail |
1353 | // out. |
1354 | for (size_t j = 0; j < i; j++) { |
1355 | GraphicBufferMapper::get().unlock( |
1356 | *(request->output_buffers[i].buffer)); |
1357 | } |
1358 | ALOGE("line:%d, format for this usage: %d x %d, usage %x, format=%x, returned\n", |
1359 | __LINE__, destBuf.width, destBuf.height, privBuffer->usage, privBuffer->format); |
1360 | return NO_INIT; |
1361 | } |
1362 | sensorBuffers->push_back(destBuf); |
1363 | buffers->push_back(srcBuf); |
1364 | } |
1365 | |
1366 | if (needJpeg) { |
1367 | if (!mSupportRotate) { |
1368 | info.thumbwidth = settings.find(ANDROID_JPEG_THUMBNAIL_SIZE).data.i32[0]; |
1369 | info.thumbheight = settings.find(ANDROID_JPEG_THUMBNAIL_SIZE).data.i32[1]; |
1370 | } else { |
1371 | if ((info.orientation == 90) || (info.orientation == 270)) { |
1372 | info.thumbwidth = settings.find(ANDROID_JPEG_THUMBNAIL_SIZE).data.i32[1]; |
1373 | info.thumbheight = settings.find(ANDROID_JPEG_THUMBNAIL_SIZE).data.i32[0]; |
1374 | } else { |
1375 | info.thumbwidth = settings.find(ANDROID_JPEG_THUMBNAIL_SIZE).data.i32[0]; |
1376 | info.thumbheight = settings.find(ANDROID_JPEG_THUMBNAIL_SIZE).data.i32[1]; |
1377 | } |
1378 | } |
1379 | if (settings.exists(ANDROID_JPEG_GPS_COORDINATES)) { |
1380 | info.latitude = settings.find(ANDROID_JPEG_GPS_COORDINATES).data.d[0]; |
1381 | info.longitude = settings.find(ANDROID_JPEG_GPS_COORDINATES).data.d[1]; |
1382 | info.altitude = settings.find(ANDROID_JPEG_GPS_COORDINATES).data.d[2]; |
1383 | info.has_latitude = true; |
1384 | info.has_longitude = true; |
1385 | info.has_altitude = true; |
1386 | } else { |
1387 | info.has_latitude = false; |
1388 | info.has_longitude = false; |
1389 | info.has_altitude = false; |
1390 | } |
1391 | if (settings.exists(ANDROID_JPEG_GPS_PROCESSING_METHOD)) { |
1392 | uint8_t * gpsString = settings.find(ANDROID_JPEG_GPS_PROCESSING_METHOD).data.u8; |
1393 | memcpy(info.gpsProcessingMethod, gpsString , sizeof(info.gpsProcessingMethod)-1); |
1394 | info.has_gpsProcessingMethod = true; |
1395 | } else { |
1396 | info.has_gpsProcessingMethod = false; |
1397 | } |
1398 | if (settings.exists(ANDROID_JPEG_GPS_TIMESTAMP)) { |
1399 | info.gpsTimestamp = settings.find(ANDROID_JPEG_GPS_TIMESTAMP).data.i64[0]; |
1400 | info.has_gpsTimestamp = true; |
1401 | } else { |
1402 | info.has_gpsTimestamp = false; |
1403 | } |
1404 | if (settings.exists(ANDROID_LENS_FOCAL_LENGTH)) { |
1405 | info.focallen = settings.find(ANDROID_LENS_FOCAL_LENGTH).data.f[0]; |
1406 | info.has_focallen = true; |
1407 | } else { |
1408 | info.has_focallen = false; |
1409 | } |
1410 | jpegbuffersize = getJpegBufferSize(info.mainwidth,info.mainheight); |
1411 | |
1412 | mJpegCompressor->SetMaxJpegBufferSize(jpegbuffersize); |
1413 | mJpegCompressor->SetExifInfo(info); |
1414 | mSensor->setPictureRotate(info.orientation); |
1415 | if ((info.thumbwidth > 0) && (info.thumbheight > 0)) { |
1416 | mHaveThumbnail = true; |
1417 | } |
1418 | DBG_LOGB("%s::thumbnailSize_width=%d,thumbnailSize_height=%d,mainsize_width=%d,mainsize_height=%d,jpegOrientation=%d",__FUNCTION__, |
1419 | info.thumbwidth,info.thumbheight,info.mainwidth,info.mainheight,info.orientation); |
1420 | } |
1421 | /** |
1422 | * Wait for JPEG compressor to not be busy, if needed |
1423 | */ |
1424 | #if 0 |
1425 | if (needJpeg) { |
1426 | bool ready = mJpegCompressor->waitForDone(kFenceTimeoutMs); |
1427 | if (!ready) { |
1428 | ALOGE("%s: Timeout waiting for JPEG compression to complete!", |
1429 | __FUNCTION__); |
1430 | return NO_INIT; |
1431 | } |
1432 | } |
1433 | #else |
1434 | while (needJpeg) { |
1435 | bool ready = mJpegCompressor->waitForDone(kFenceTimeoutMs); |
1436 | if (ready) { |
1437 | break; |
1438 | } |
1439 | } |
1440 | #endif |
1441 | } |
1442 | /** |
1443 | * Wait until the in-flight queue has room |
1444 | */ |
1445 | res = mReadoutThread->waitForReadout(); |
1446 | if (res != OK) { |
1447 | ALOGE("%s: Timeout waiting for previous requests to complete!", |
1448 | __FUNCTION__); |
1449 | return NO_INIT; |
1450 | } |
1451 | |
1452 | /** |
1453 | * Wait until sensor's ready. This waits for lengthy amounts of time with |
1454 | * mLock held, but the interface spec is that no other calls may by done to |
1455 | * the HAL by the framework while process_capture_request is happening. |
1456 | */ |
1457 | { |
1458 | Mutex::Autolock l(mLock); |
1459 | int syncTimeoutCount = 0; |
1460 | while (!mSensor->waitForVSync(kSyncWaitTimeout)) { |
1461 | if (mStatus == STATUS_ERROR) { |
1462 | return NO_INIT; |
1463 | } |
1464 | if (syncTimeoutCount == kMaxSyncTimeoutCount) { |
1465 | ALOGE("%s: Request %d: Sensor sync timed out after %" PRId64 " ms", |
1466 | __FUNCTION__, frameNumber, |
1467 | kSyncWaitTimeout * kMaxSyncTimeoutCount / 1000000); |
1468 | return NO_INIT; |
1469 | } |
1470 | syncTimeoutCount++; |
1471 | } |
1472 | |
1473 | /** |
1474 | * Configure sensor and queue up the request to the readout thread |
1475 | */ |
1476 | mSensor->setExposureTime(exposureTime); |
1477 | mSensor->setFrameDuration(frameDuration); |
1478 | mSensor->setSensitivity(sensitivity); |
1479 | mSensor->setDestinationBuffers(sensorBuffers); |
1480 | mSensor->setFrameNumber(request->frame_number); |
1481 | |
1482 | ReadoutThread::Request r; |
1483 | r.frameNumber = request->frame_number; |
1484 | r.settings = settings; |
1485 | r.sensorBuffers = sensorBuffers; |
1486 | r.buffers = buffers; |
1487 | r.havethumbnail = mHaveThumbnail; |
1488 | |
1489 | mReadoutThread->queueCaptureRequest(r); |
1490 | ALOGVV("%s: Queued frame %d", __FUNCTION__, request->frame_number); |
1491 | |
1492 | // Cache the settings for next time |
1493 | mPrevSettings.acquire(settings); |
1494 | } |
1495 | CAMHAL_LOGVB("%s , X" , __FUNCTION__); |
1496 | return OK; |
1497 | } |
1498 | |
1499 | /** Debug methods */ |
1500 | |
1501 | void EmulatedFakeCamera3::dump(int fd) { |
1502 | |
1503 | String8 result; |
1504 | uint32_t count = sizeof(mAvailableJpegSize)/sizeof(mAvailableJpegSize[0]); |
1505 | result = String8::format("%s, valid resolution\n", __FILE__); |
1506 | |
1507 | for (uint32_t f = 0; f < count; f+=2) { |
1508 | if (mAvailableJpegSize[f] == 0) |
1509 | break; |
1510 | result.appendFormat("width: %d , height =%d\n", |
1511 | mAvailableJpegSize[f], mAvailableJpegSize[f+1]); |
1512 | } |
1513 | result.appendFormat("\nmZoomMin: %d , mZoomMax =%d, mZoomStep=%d\n", |
1514 | mZoomMin, mZoomMax, mZoomStep); |
1515 | |
1516 | if (mZoomStep <= 0) { |
1517 | result.appendFormat("!!!!!!!!!camera apk may have no picture out\n"); |
1518 | } |
1519 | |
1520 | write(fd, result.string(), result.size()); |
1521 | |
1522 | if (mSensor.get() != NULL) { |
1523 | mSensor->dump(fd); |
1524 | } |
1525 | |
1526 | } |
1527 | //flush all request |
1528 | //TODO returned buffers every request held immediately with |
1529 | //CAMERA3_BUFFER_STATUS_ERROR flag. |
1530 | int EmulatedFakeCamera3::flush_all_requests() { |
1531 | DBG_LOGA("flush all request"); |
1532 | mFlushTag = true; |
1533 | mReadoutThread->flushAllRequest(true); |
1534 | mReadoutThread->setFlushFlag(false); |
1535 | mSensor->setFlushFlag(false); |
1536 | return 0; |
1537 | } |
1538 | /** Tag query methods */ |
1539 | const char* EmulatedFakeCamera3::getVendorSectionName(uint32_t tag) { |
1540 | return NULL; |
1541 | } |
1542 | |
1543 | const char* EmulatedFakeCamera3::getVendorTagName(uint32_t tag) { |
1544 | return NULL; |
1545 | } |
1546 | |
1547 | int EmulatedFakeCamera3::getVendorTagType(uint32_t tag) { |
1548 | return 0; |
1549 | } |
1550 | |
1551 | /** |
1552 | * Private methods |
1553 | */ |
1554 | |
1555 | camera_metadata_ro_entry_t EmulatedFakeCamera3::staticInfo(const CameraMetadata *info, uint32_t tag, |
1556 | size_t minCount, size_t maxCount, bool required) const { |
1557 | |
1558 | camera_metadata_ro_entry_t entry = info->find(tag); |
1559 | |
1560 | if (CC_UNLIKELY( entry.count == 0 ) && required) { |
1561 | const char* tagSection = get_camera_metadata_section_name(tag); |
1562 | if (tagSection == NULL) tagSection = "<unknown>"; |
1563 | const char* tagName = get_camera_metadata_tag_name(tag); |
1564 | if (tagName == NULL) tagName = "<unknown>"; |
1565 | |
1566 | ALOGE("Error finding static metadata entry '%s.%s' (%x)", |
1567 | tagSection, tagName, tag); |
1568 | } else if (CC_UNLIKELY( |
1569 | (minCount != 0 && entry.count < minCount) || |
1570 | (maxCount != 0 && entry.count > maxCount) ) ) { |
1571 | const char* tagSection = get_camera_metadata_section_name(tag); |
1572 | if (tagSection == NULL) tagSection = "<unknown>"; |
1573 | const char* tagName = get_camera_metadata_tag_name(tag); |
1574 | if (tagName == NULL) tagName = "<unknown>"; |
1575 | ALOGE("Malformed static metadata entry '%s.%s' (%x):" |
1576 | "Expected between %zu and %zu values, but got %zu values", |
1577 | tagSection, tagName, tag, minCount, maxCount, entry.count); |
1578 | } |
1579 | |
1580 | return entry; |
1581 | } |
1582 | |
1583 | //this is only for debug |
1584 | void EmulatedFakeCamera3::getStreamConfigurationp(CameraMetadata *info) { |
1585 | const int STREAM_CONFIGURATION_SIZE = 4; |
1586 | const int STREAM_FORMAT_OFFSET = 0; |
1587 | const int STREAM_WIDTH_OFFSET = 1; |
1588 | const int STREAM_HEIGHT_OFFSET = 2; |
1589 | const int STREAM_IS_INPUT_OFFSET = 3; |
1590 | |
1591 | camera_metadata_ro_entry_t availableStreamConfigs = |
1592 | staticInfo(info, ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS); |
1593 | CAMHAL_LOGDB(" stream, availableStreamConfigs.count=%d\n", availableStreamConfigs.count); |
1594 | |
1595 | for (size_t i=0; i < availableStreamConfigs.count; i+= STREAM_CONFIGURATION_SIZE) { |
1596 | int32_t format = availableStreamConfigs.data.i32[i + STREAM_FORMAT_OFFSET]; |
1597 | int32_t width = availableStreamConfigs.data.i32[i + STREAM_WIDTH_OFFSET]; |
1598 | int32_t height = availableStreamConfigs.data.i32[i + STREAM_HEIGHT_OFFSET]; |
1599 | int32_t isInput = availableStreamConfigs.data.i32[i + STREAM_IS_INPUT_OFFSET]; |
1600 | CAMHAL_LOGDB("f=%x, w*h=%dx%d, du=%d\n", format, width, height, isInput); |
1601 | } |
1602 | |
1603 | } |
1604 | |
1605 | //this is only for debug |
1606 | void EmulatedFakeCamera3::getStreamConfigurationDurations(CameraMetadata *info) { |
1607 | const int STREAM_CONFIGURATION_SIZE = 4; |
1608 | const int STREAM_FORMAT_OFFSET = 0; |
1609 | const int STREAM_WIDTH_OFFSET = 1; |
1610 | const int STREAM_HEIGHT_OFFSET = 2; |
1611 | const int STREAM_IS_INPUT_OFFSET = 3; |
1612 | |
1613 | camera_metadata_ro_entry_t availableStreamConfigs = |
1614 | staticInfo(info, ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS); |
1615 | CAMHAL_LOGDB("availableStreamConfigs.count=%d\n", availableStreamConfigs.count); |
1616 | |
1617 | for (size_t i=0; i < availableStreamConfigs.count; i+= STREAM_CONFIGURATION_SIZE) { |
1618 | int64_t format = availableStreamConfigs.data.i64[i + STREAM_FORMAT_OFFSET]; |
1619 | int64_t width = availableStreamConfigs.data.i64[i + STREAM_WIDTH_OFFSET]; |
1620 | int64_t height = availableStreamConfigs.data.i64[i + STREAM_HEIGHT_OFFSET]; |
1621 | int64_t isInput = availableStreamConfigs.data.i64[i + STREAM_IS_INPUT_OFFSET]; |
1622 | CAMHAL_LOGDB("f=%llx, w*h=%lldx%lld, du=%lld\n", format, width, height, isInput); |
1623 | } |
1624 | } |
1625 | |
1626 | void EmulatedFakeCamera3::updateCameraMetaData(CameraMetadata *info) { |
1627 | |
1628 | } |
1629 | |
1630 | status_t EmulatedFakeCamera3::constructStaticInfo() { |
1631 | |
1632 | status_t ret = OK; |
1633 | CameraMetadata info; |
1634 | uint32_t picSizes[64 * 8]; |
1635 | int64_t* duration = NULL; |
1636 | int count, duration_count, availablejpegsize; |
1637 | uint8_t maxCount = 10; |
1638 | char property[PROPERTY_VALUE_MAX]; |
1639 | unsigned int supportrotate; |
1640 | availablejpegsize = ARRAY_SIZE(mAvailableJpegSize); |
1641 | memset(mAvailableJpegSize,0,(sizeof(uint32_t))*availablejpegsize); |
1642 | sp<Sensor> s = new Sensor(); |
1643 | ret = s->startUp(mCameraID); |
1644 | if (ret != OK) { |
1645 | DBG_LOGA("sensor start up failed"); |
1646 | return ret; |
1647 | } |
1648 | |
1649 | mSensorType = s->getSensorType(); |
1650 | |
1651 | if ( mSensorType == SENSOR_USB) { |
1652 | char property[PROPERTY_VALUE_MAX]; |
1653 | property_get("rw.camera.usb.faceback", property, "false"); |
1654 | if (strstr(property, "true")) |
1655 | mFacingBack = 1; |
1656 | else |
1657 | mFacingBack = 0; |
1658 | ALOGI("Setting usb camera cameraID:%d to back camera:%s\n", |
1659 | mCameraID, property); |
1660 | } else { |
1661 | if (s->mSensorFace == SENSOR_FACE_FRONT) { |
1662 | mFacingBack = 0; |
1663 | } else if (s->mSensorFace == SENSOR_FACE_BACK) { |
1664 | mFacingBack = 1; |
1665 | } else if (s->mSensorFace == SENSOR_FACE_NONE) { |
1666 | if (gEmulatedCameraFactory.getEmulatedCameraNum() == 1) { |
1667 | mFacingBack = 1; |
1668 | } else if ( mCameraID == 0) { |
1669 | mFacingBack = 1; |
1670 | } else { |
1671 | mFacingBack = 0; |
1672 | } |
1673 | } |
1674 | |
1675 | ALOGI("Setting on board camera cameraID:%d to back camera:%d[0 false, 1 true]\n", |
1676 | mCameraID, mFacingBack); |
1677 | } |
1678 | |
1679 | mSupportCap = s->IoctlStateProbe(); |
1680 | if (mSupportCap & IOCTL_MASK_ROTATE) { |
1681 | supportrotate = true; |
1682 | } else { |
1683 | supportrotate = false; |
1684 | } |
1685 | // android.lens |
1686 | |
1687 | // 5 cm min focus distance for back camera, infinity (fixed focus) for front |
1688 | // TODO read this ioctl from camera driver |
1689 | DBG_LOGB("mCameraID=%d,mCameraInfo=%p\n", mCameraID, mCameraInfo); |
1690 | const float minFocusDistance = 0.0; |
1691 | info.update(ANDROID_LENS_INFO_MINIMUM_FOCUS_DISTANCE, |
1692 | &minFocusDistance, 1); |
1693 | |
1694 | // 5 m hyperfocal distance for back camera, infinity (fixed focus) for front |
1695 | const float hyperFocalDistance = mFacingBack ? 1.0/5.0 : 0.0; |
1696 | info.update(ANDROID_LENS_INFO_HYPERFOCAL_DISTANCE, |
1697 | &minFocusDistance, 1); |
1698 | |
1699 | static const float focalLength = 3.30f; // mm |
1700 | info.update(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS, |
1701 | &focalLength, 1); |
1702 | static const float aperture = 2.8f; |
1703 | info.update(ANDROID_LENS_INFO_AVAILABLE_APERTURES, |
1704 | &aperture, 1); |
1705 | static const float filterDensity = 0; |
1706 | info.update(ANDROID_LENS_INFO_AVAILABLE_FILTER_DENSITIES, |
1707 | &filterDensity, 1); |
1708 | static const uint8_t availableOpticalStabilization = |
1709 | ANDROID_LENS_OPTICAL_STABILIZATION_MODE_OFF; |
1710 | info.update(ANDROID_LENS_INFO_AVAILABLE_OPTICAL_STABILIZATION, |
1711 | &availableOpticalStabilization, 1); |
1712 | |
1713 | static const int32_t lensShadingMapSize[] = {1, 1}; |
1714 | info.update(ANDROID_LENS_INFO_SHADING_MAP_SIZE, lensShadingMapSize, |
1715 | sizeof(lensShadingMapSize)/sizeof(int32_t)); |
1716 | |
1717 | uint8_t lensFacing = mFacingBack ? |
1718 | ANDROID_LENS_FACING_BACK : ANDROID_LENS_FACING_FRONT; |
1719 | info.update(ANDROID_LENS_FACING, &lensFacing, 1); |
1720 | |
1721 | float lensPosition[3]; |
1722 | if (mFacingBack) { |
1723 | // Back-facing camera is center-top on device |
1724 | lensPosition[0] = 0; |
1725 | lensPosition[1] = 20; |
1726 | lensPosition[2] = -5; |
1727 | } else { |
1728 | // Front-facing camera is center-right on device |
1729 | lensPosition[0] = 20; |
1730 | lensPosition[1] = 20; |
1731 | lensPosition[2] = 0; |
1732 | } |
1733 | #if PLATFORM_SDK_VERSION <= 22 |
1734 | info.update(ANDROID_LENS_POSITION, lensPosition, sizeof(lensPosition)/ |
1735 | sizeof(float)); |
1736 | #endif |
1737 | static const uint8_t lensCalibration = ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION_UNCALIBRATED; |
1738 | info.update(ANDROID_LENS_INFO_FOCUS_DISTANCE_CALIBRATION,&lensCalibration,1); |
1739 | |
1740 | // android.sensor |
1741 | |
1742 | static const int32_t testAvailablePattern = ANDROID_SENSOR_TEST_PATTERN_MODE_OFF; |
1743 | info.update(ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES, &testAvailablePattern, 1); |
1744 | static const int32_t testPattern = ANDROID_SENSOR_TEST_PATTERN_MODE_OFF; |
1745 | info.update(ANDROID_SENSOR_TEST_PATTERN_MODE, &testPattern, 1); |
1746 | info.update(ANDROID_SENSOR_INFO_EXPOSURE_TIME_RANGE, |
1747 | Sensor::kExposureTimeRange, 2); |
1748 | |
1749 | info.update(ANDROID_SENSOR_INFO_MAX_FRAME_DURATION, |
1750 | &Sensor::kFrameDurationRange[1], 1); |
1751 | |
1752 | info.update(ANDROID_SENSOR_INFO_SENSITIVITY_RANGE, |
1753 | Sensor::kSensitivityRange, |
1754 | sizeof(Sensor::kSensitivityRange) |
1755 | /sizeof(int32_t)); |
1756 | |
1757 | info.update(ANDROID_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT, |
1758 | &Sensor::kColorFilterArrangement, 1); |
1759 | |
1760 | static const float sensorPhysicalSize[2] = {3.20f, 2.40f}; // mm |
1761 | info.update(ANDROID_SENSOR_INFO_PHYSICAL_SIZE, |
1762 | sensorPhysicalSize, 2); |
1763 | |
1764 | info.update(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE, |
1765 | (int32_t*)Sensor::kResolution, 2); |
1766 | |
1767 | //(int32_t*)Sensor::kResolution, 2); |
1768 | |
1769 | info.update(ANDROID_SENSOR_INFO_WHITE_LEVEL, |
1770 | (int32_t*)&Sensor::kMaxRawValue, 1); |
1771 | |
1772 | static const int32_t blackLevelPattern[4] = { |
1773 | (int32_t)Sensor::kBlackLevel, (int32_t)Sensor::kBlackLevel, |
1774 | (int32_t)Sensor::kBlackLevel, (int32_t)Sensor::kBlackLevel |
1775 | }; |
1776 | info.update(ANDROID_SENSOR_BLACK_LEVEL_PATTERN, |
1777 | blackLevelPattern, sizeof(blackLevelPattern)/sizeof(int32_t)); |
1778 | |
1779 | static const uint8_t timestampSource = ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_UNKNOWN; |
1780 | info.update(ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE, ×tampSource, 1); |
1781 | if (mSensorType == SENSOR_USB) { |
1782 | if (mFacingBack) { |
1783 | property_get("hw.camera.orientation.back", property, "0"); |
1784 | } else { |
1785 | property_get("hw.camera.orientation.front", property, "0"); |
1786 | } |
1787 | int32_t orientation = atoi(property); |
1788 | property_get("hw.camera.usb.orientation_offset", property, "0"); |
1789 | orientation += atoi(property); |
1790 | orientation %= 360; |
1791 | info.update(ANDROID_SENSOR_ORIENTATION, &orientation, 1); |
1792 | } else { |
1793 | if (mFacingBack) { |
1794 | property_get("hw.camera.orientation.back", property, "270"); |
1795 | const int32_t orientation = atoi(property); |
1796 | info.update(ANDROID_SENSOR_ORIENTATION, &orientation, 1); |
1797 | } else { |
1798 | property_get("hw.camera.orientation.front", property, "90"); |
1799 | const int32_t orientation = atoi(property); |
1800 | info.update(ANDROID_SENSOR_ORIENTATION, &orientation, 1); |
1801 | } |
1802 | } |
1803 | |
1804 | static const int64_t rollingShutterSkew = 0; |
1805 | info.update(ANDROID_SENSOR_ROLLING_SHUTTER_SKEW, &rollingShutterSkew, 1); |
1806 | |
1807 | //TODO: sensor color calibration fields |
1808 | |
1809 | // android.flash |
1810 | static const uint8_t flashAvailable = 0; |
1811 | info.update(ANDROID_FLASH_INFO_AVAILABLE, &flashAvailable, 1); |
1812 | |
1813 | static const uint8_t flashstate = ANDROID_FLASH_STATE_UNAVAILABLE; |
1814 | info.update(ANDROID_FLASH_STATE, &flashstate, 1); |
1815 | |
1816 | static const int64_t flashChargeDuration = 0; |
1817 | info.update(ANDROID_FLASH_INFO_CHARGE_DURATION, &flashChargeDuration, 1); |
1818 | |
1819 | /** android.noise */ |
1820 | static const uint8_t availableNBModes = ANDROID_NOISE_REDUCTION_MODE_OFF; |
1821 | info.update(ANDROID_NOISE_REDUCTION_AVAILABLE_NOISE_REDUCTION_MODES, &availableNBModes, 1); |
1822 | |
1823 | // android.tonemap |
1824 | |
1825 | static const int32_t tonemapCurvePoints = 128; |
1826 | info.update(ANDROID_TONEMAP_MAX_CURVE_POINTS, &tonemapCurvePoints, 1); |
1827 | |
1828 | // android.scaler |
1829 | |
1830 | static const uint8_t croppingType = ANDROID_SCALER_CROPPING_TYPE_CENTER_ONLY; |
1831 | info.update(ANDROID_SCALER_CROPPING_TYPE, &croppingType, 1); |
1832 | |
1833 | info.update(ANDROID_SCALER_AVAILABLE_FORMATS, |
1834 | kAvailableFormats, |
1835 | sizeof(kAvailableFormats)/sizeof(int32_t)); |
1836 | |
1837 | info.update(ANDROID_SCALER_AVAILABLE_RAW_MIN_DURATIONS, |
1838 | (int64_t*)kAvailableRawMinDurations, |
1839 | sizeof(kAvailableRawMinDurations)/sizeof(uint64_t)); |
1840 | |
1841 | //for version 3.2 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS |
1842 | count = sizeof(picSizes)/sizeof(picSizes[0]); |
1843 | count = s->getStreamConfigurations(picSizes, kAvailableFormats, count); |
1844 | |
1845 | info.update(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, |
1846 | (int32_t*)picSizes, count); |
1847 | |
1848 | if (count < availablejpegsize) { |
1849 | availablejpegsize = count; |
1850 | } |
1851 | getValidJpegSize(picSizes,mAvailableJpegSize,availablejpegsize); |
1852 | |
1853 | maxJpegResolution = getMaxJpegResolution(picSizes,count); |
1854 | int32_t full_size[4]; |
1855 | if (mFacingBack) { |
1856 | full_size[0] = 0; |
1857 | full_size[1] = 0; |
1858 | full_size[2] = maxJpegResolution.width; |
1859 | full_size[3] = maxJpegResolution.height; |
1860 | } else { |
1861 | full_size[0] = 0; |
1862 | full_size[1] = 0; |
1863 | full_size[2] = maxJpegResolution.width; |
1864 | full_size[3] = maxJpegResolution.height; |
1865 | } |
1866 | info.update(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE, |
1867 | (int32_t*)full_size, |
1868 | sizeof(full_size)/sizeof(full_size[0])); |
1869 | duration = new int64_t[count]; |
1870 | if (duration == NULL) { |
1871 | DBG_LOGA("allocate memory for duration failed"); |
1872 | return NO_MEMORY; |
1873 | } else { |
1874 | memset(duration,0,sizeof(int64_t)*count); |
1875 | } |
1876 | duration_count = s->getStreamConfigurationDurations(picSizes, duration , count); |
1877 | |
1878 | info.update(ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS, |
1879 | duration, duration_count); |
1880 | info.update(ANDROID_SCALER_AVAILABLE_STALL_DURATIONS, |
1881 | duration, duration_count); |
1882 | |
1883 | info.update(ANDROID_SCALER_AVAILABLE_PROCESSED_MIN_DURATIONS, |
1884 | (int64_t*)kAvailableProcessedMinDurations, |
1885 | sizeof(kAvailableProcessedMinDurations)/sizeof(uint64_t)); |
1886 | |
1887 | info.update(ANDROID_SCALER_AVAILABLE_JPEG_MIN_DURATIONS, |
1888 | (int64_t*)kAvailableJpegMinDurations, |
1889 | sizeof(kAvailableJpegMinDurations)/sizeof(uint64_t)); |
1890 | |
1891 | |
1892 | // android.jpeg |
1893 | |
1894 | static const int32_t jpegThumbnailSizes[] = { |
1895 | 0, 0, |
1896 | 160, 120, |
1897 | 320, 240 |
1898 | }; |
1899 | info.update(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES, |
1900 | jpegThumbnailSizes, sizeof(jpegThumbnailSizes)/sizeof(int32_t)); |
1901 | |
1902 | static const int32_t jpegMaxSize = JpegCompressor::kMaxJpegSize; |
1903 | info.update(ANDROID_JPEG_MAX_SIZE, &jpegMaxSize, 1); |
1904 | |
1905 | // android.stats |
1906 | |
1907 | static const uint8_t availableFaceDetectModes[] = { |
1908 | ANDROID_STATISTICS_FACE_DETECT_MODE_OFF, |
1909 | ANDROID_STATISTICS_FACE_DETECT_MODE_SIMPLE, |
1910 | ANDROID_STATISTICS_FACE_DETECT_MODE_FULL |
1911 | }; |
1912 | |
1913 | info.update(ANDROID_STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES, |
1914 | availableFaceDetectModes, |
1915 | sizeof(availableFaceDetectModes)); |
1916 | |
1917 | static const int32_t maxFaceCount = 8; |
1918 | info.update(ANDROID_STATISTICS_INFO_MAX_FACE_COUNT, |
1919 | &maxFaceCount, 1); |
1920 | |
1921 | static const int32_t histogramSize = 64; |
1922 | info.update(ANDROID_STATISTICS_INFO_HISTOGRAM_BUCKET_COUNT, |
1923 | &histogramSize, 1); |
1924 | |
1925 | static const int32_t maxHistogramCount = 1000; |
1926 | info.update(ANDROID_STATISTICS_INFO_MAX_HISTOGRAM_COUNT, |
1927 | &maxHistogramCount, 1); |
1928 | |
1929 | static const int32_t sharpnessMapSize[2] = {64, 64}; |
1930 | info.update(ANDROID_STATISTICS_INFO_SHARPNESS_MAP_SIZE, |
1931 | sharpnessMapSize, sizeof(sharpnessMapSize)/sizeof(int32_t)); |
1932 | |
1933 | static const int32_t maxSharpnessMapValue = 1000; |
1934 | info.update(ANDROID_STATISTICS_INFO_MAX_SHARPNESS_MAP_VALUE, |
1935 | &maxSharpnessMapValue, 1); |
1936 | static const uint8_t hotPixelMapMode = ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE_OFF; |
1937 | info.update(ANDROID_STATISTICS_HOT_PIXEL_MAP_MODE,&hotPixelMapMode, 1); |
1938 | |
1939 | static const uint8_t sceneFlicker = ANDROID_STATISTICS_SCENE_FLICKER_NONE; |
1940 | info.update(ANDROID_STATISTICS_SCENE_FLICKER,&sceneFlicker, 1); |
1941 | static const uint8_t lensShadingMapMode = ANDROID_STATISTICS_LENS_SHADING_MAP_MODE_OFF; |
1942 | info.update(ANDROID_STATISTICS_LENS_SHADING_MAP_MODE,&lensShadingMapMode, 1); |
1943 | // android.control |
1944 | |
1945 | static const uint8_t sceneMode = ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY; |
1946 | info.update(ANDROID_CONTROL_SCENE_MODE, &sceneMode, 1); |
1947 | |
1948 | static const uint8_t availableSceneModes[] = { |
1949 | // ANDROID_CONTROL_SCENE_MODE_DISABLED, |
1950 | ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY |
1951 | }; |
1952 | info.update(ANDROID_CONTROL_AVAILABLE_SCENE_MODES, |
1953 | availableSceneModes, sizeof(availableSceneModes)); |
1954 | |
1955 | static const uint8_t availableEffects[] = { |
1956 | ANDROID_CONTROL_EFFECT_MODE_OFF |
1957 | }; |
1958 | info.update(ANDROID_CONTROL_AVAILABLE_EFFECTS, |
1959 | availableEffects, sizeof(availableEffects)); |
1960 | |
1961 | static const int32_t max3aRegions[] = {/*AE*/ 0,/*AWB*/ 0,/*AF*/ 0}; |
1962 | info.update(ANDROID_CONTROL_MAX_REGIONS, |
1963 | max3aRegions, sizeof(max3aRegions)/sizeof(max3aRegions[0])); |
1964 | |
1965 | static const uint8_t availableAeModes[] = { |
1966 | ANDROID_CONTROL_AE_MODE_OFF, |
1967 | ANDROID_CONTROL_AE_MODE_ON |
1968 | }; |
1969 | info.update(ANDROID_CONTROL_AE_AVAILABLE_MODES, |
1970 | availableAeModes, sizeof(availableAeModes)); |
1971 | |
1972 | |
1973 | static const int32_t availableTargetFpsRanges[] = { |
1974 | 5, 15, 15, 15, 5, 25, 25, 25, 5, 30, 30, 30, |
1975 | }; |
1976 | info.update(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, |
1977 | availableTargetFpsRanges, |
1978 | sizeof(availableTargetFpsRanges)/sizeof(int32_t)); |
1979 | |
1980 | uint8_t awbModes[maxCount]; |
1981 | count = s->getAWB(awbModes, maxCount); |
1982 | if (count < 0) { |
1983 | static const uint8_t availableAwbModes[] = { |
1984 | ANDROID_CONTROL_AWB_MODE_OFF, |
1985 | ANDROID_CONTROL_AWB_MODE_AUTO, |
1986 | ANDROID_CONTROL_AWB_MODE_INCANDESCENT, |
1987 | ANDROID_CONTROL_AWB_MODE_FLUORESCENT, |
1988 | ANDROID_CONTROL_AWB_MODE_DAYLIGHT, |
1989 | ANDROID_CONTROL_AWB_MODE_SHADE |
1990 | }; |
1991 | info.update(ANDROID_CONTROL_AWB_AVAILABLE_MODES, |
1992 | availableAwbModes, sizeof(availableAwbModes)); |
1993 | } else { |
1994 | DBG_LOGB("getAWB %d ",count); |
1995 | info.update(ANDROID_CONTROL_AWB_AVAILABLE_MODES, |
1996 | awbModes, count); |
1997 | } |
1998 | |
1999 | static const uint8_t afstate = ANDROID_CONTROL_AF_STATE_INACTIVE; |
2000 | info.update(ANDROID_CONTROL_AF_STATE,&afstate,1); |
2001 | |
2002 | static const uint8_t availableAfModesFront[] = { |
2003 | ANDROID_CONTROL_AF_MODE_OFF |
2004 | }; |
2005 | |
2006 | if (mFacingBack) { |
2007 | uint8_t afMode[maxCount]; |
2008 | count = s->getAutoFocus(afMode, maxCount); |
2009 | if (count < 0) { |
2010 | static const uint8_t availableAfModesBack[] = { |
2011 | ANDROID_CONTROL_AF_MODE_OFF, |
2012 | //ANDROID_CONTROL_AF_MODE_AUTO, |
2013 | //ANDROID_CONTROL_AF_MODE_MACRO, |
2014 | //ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO, |
2015 | //ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE, |
2016 | }; |
2017 | |
2018 | info.update(ANDROID_CONTROL_AF_AVAILABLE_MODES, |
2019 | availableAfModesBack, sizeof(availableAfModesBack)); |
2020 | } else { |
2021 | info.update(ANDROID_CONTROL_AF_AVAILABLE_MODES, |
2022 | afMode, count); |
2023 | } |
2024 | } else { |
2025 | info.update(ANDROID_CONTROL_AF_AVAILABLE_MODES, |
2026 | availableAfModesFront, sizeof(availableAfModesFront)); |
2027 | } |
2028 | |
2029 | uint8_t antiBanding[maxCount]; |
2030 | count = s->getAntiBanding(antiBanding, maxCount); |
2031 | if (count < 0) { |
2032 | static const uint8_t availableAntibanding[] = { |
2033 | ANDROID_CONTROL_AE_ANTIBANDING_MODE_OFF, |
2034 | ANDROID_CONTROL_AE_ANTIBANDING_MODE_AUTO, |
2035 | }; |
2036 | info.update(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES, |
2037 | availableAntibanding, sizeof(availableAntibanding)); |
2038 | } else { |
2039 | info.update(ANDROID_CONTROL_AE_AVAILABLE_ANTIBANDING_MODES, |
2040 | antiBanding, count); |
2041 | } |
2042 | |
2043 | camera_metadata_rational step; |
2044 | int maxExp, minExp, def; |
2045 | ret = s->getExposure(&maxExp, &minExp, &def, &step); |
2046 | if (ret < 0) { |
2047 | static const int32_t aeExpCompensation = 0; |
2048 | info.update(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION, &aeExpCompensation, 1); |
2049 | |
2050 | static const camera_metadata_rational exposureCompensationStep = { |
2051 | 1, 3 |
2052 | }; |
2053 | info.update(ANDROID_CONTROL_AE_COMPENSATION_STEP, |
2054 | &exposureCompensationStep, 1); |
2055 | |
2056 | int32_t exposureCompensationRange[] = {0, 0}; |
2057 | info.update(ANDROID_CONTROL_AE_COMPENSATION_RANGE, |
2058 | exposureCompensationRange, |
2059 | sizeof(exposureCompensationRange)/sizeof(int32_t)); |
2060 | } else { |
2061 | DBG_LOGB("exposure compensation support:(%d, %d)\n", minExp, maxExp); |
2062 | int32_t exposureCompensationRange[] = {minExp, maxExp}; |
2063 | info.update(ANDROID_CONTROL_AE_COMPENSATION_RANGE, |
2064 | exposureCompensationRange, |
2065 | sizeof(exposureCompensationRange)/sizeof(int32_t)); |
2066 | info.update(ANDROID_CONTROL_AE_COMPENSATION_STEP, |
2067 | &step, 1); |
2068 | info.update(ANDROID_CONTROL_AE_EXPOSURE_COMPENSATION, &def, 1); |
2069 | } |
2070 | |
2071 | ret = s->getZoom(&mZoomMin, &mZoomMax, &mZoomStep); |
2072 | if (ret < 0) { |
2073 | float maxZoom = 1.0; |
2074 | info.update(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM, |
2075 | &maxZoom, 1); |
2076 | } else { |
2077 | float maxZoom = mZoomMax / mZoomMin; |
2078 | info.update(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM, |
2079 | &maxZoom, 1); |
2080 | } |
2081 | |
2082 | static const uint8_t availableVstabModes[] = { |
2083 | ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_OFF |
2084 | }; |
2085 | info.update(ANDROID_CONTROL_AVAILABLE_VIDEO_STABILIZATION_MODES, |
2086 | availableVstabModes, sizeof(availableVstabModes)); |
2087 | |
2088 | static const uint8_t aestate = ANDROID_CONTROL_AE_STATE_CONVERGED; |
2089 | info.update(ANDROID_CONTROL_AE_STATE,&aestate,1); |
2090 | static const uint8_t awbstate = ANDROID_CONTROL_AWB_STATE_INACTIVE; |
2091 | info.update(ANDROID_CONTROL_AWB_STATE,&awbstate,1); |
2092 | // android.info |
2093 | const uint8_t supportedHardwareLevel = ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED; |
2094 | //mFullMode ? ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_FULL : |
2095 | // ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED; |
2096 | info.update(ANDROID_INFO_SUPPORTED_HARDWARE_LEVEL, |
2097 | &supportedHardwareLevel, |
2098 | /*count*/1); |
2099 | |
2100 | int32_t android_sync_max_latency = ANDROID_SYNC_MAX_LATENCY_UNKNOWN; |
2101 | info.update(ANDROID_SYNC_MAX_LATENCY, &android_sync_max_latency, 1); |
2102 | |
2103 | uint8_t len[] = {1}; |
2104 | info.update(ANDROID_REQUEST_PIPELINE_DEPTH, (uint8_t *)len, 1); |
2105 | |
2106 | uint8_t maxlen[] = {2}; |
2107 | info.update(ANDROID_REQUEST_PIPELINE_MAX_DEPTH, (uint8_t *)maxlen, 1); |
2108 | uint8_t cap[] = { |
2109 | ANDROID_REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE, |
2110 | }; |
2111 | info.update(ANDROID_REQUEST_AVAILABLE_CAPABILITIES, |
2112 | (uint8_t *)cap, sizeof(cap)/sizeof(cap[0])); |
2113 | |
2114 | |
2115 | int32_t partialResultCount = 1; |
2116 | info.update(ANDROID_REQUEST_PARTIAL_RESULT_COUNT,&partialResultCount,1); |
2117 | int32_t maxNumOutputStreams[3] = {0,2,1}; |
2118 | info.update(ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS,maxNumOutputStreams,3); |
2119 | uint8_t aberrationMode[] = {ANDROID_COLOR_CORRECTION_ABERRATION_MODE_OFF}; |
2120 | info.update(ANDROID_COLOR_CORRECTION_ABERRATION_MODE, |
2121 | aberrationMode, 1); |
2122 | info.update(ANDROID_COLOR_CORRECTION_AVAILABLE_ABERRATION_MODES, |
2123 | aberrationMode, 1); |
2124 | |
2125 | getAvailableChKeys(&info, supportedHardwareLevel); |
2126 | |
2127 | if (mCameraInfo != NULL) { |
2128 | CAMHAL_LOGDA("mCameraInfo is not null, mem leak?"); |
2129 | } |
2130 | mCameraInfo = info.release(); |
2131 | DBG_LOGB("mCameraID=%d,mCameraInfo=%p\n", mCameraID, mCameraInfo); |
2132 | |
2133 | if (duration != NULL) { |
2134 | delete [] duration; |
2135 | } |
2136 | |
2137 | s->shutDown(); |
2138 | s.clear(); |
2139 | mPlugged = true; |
2140 | |
2141 | return OK; |
2142 | } |
2143 | |
2144 | status_t EmulatedFakeCamera3::process3A(CameraMetadata &settings) { |
2145 | /** |
2146 | * Extract top-level 3A controls |
2147 | */ |
2148 | status_t res; |
2149 | |
2150 | bool facePriority = false; |
2151 | |
2152 | camera_metadata_entry e; |
2153 | |
2154 | e = settings.find(ANDROID_CONTROL_MODE); |
2155 | if (e.count == 0) { |
2156 | ALOGE("%s: No control mode entry!", __FUNCTION__); |
2157 | return BAD_VALUE; |
2158 | } |
2159 | uint8_t controlMode = e.data.u8[0]; |
2160 | |
2161 | e = settings.find(ANDROID_CONTROL_SCENE_MODE); |
2162 | if (e.count == 0) { |
2163 | ALOGE("%s: No scene mode entry!", __FUNCTION__); |
2164 | return BAD_VALUE; |
2165 | } |
2166 | uint8_t sceneMode = e.data.u8[0]; |
2167 | |
2168 | if (controlMode == ANDROID_CONTROL_MODE_OFF) { |
2169 | mAeState = ANDROID_CONTROL_AE_STATE_INACTIVE; |
2170 | mAfState = ANDROID_CONTROL_AF_STATE_INACTIVE; |
2171 | mAwbState = ANDROID_CONTROL_AWB_STATE_INACTIVE; |
2172 | update3A(settings); |
2173 | return OK; |
2174 | } else if (controlMode == ANDROID_CONTROL_MODE_USE_SCENE_MODE) { |
2175 | switch(sceneMode) { |
2176 | case ANDROID_CONTROL_SCENE_MODE_FACE_PRIORITY: |
2177 | mFacePriority = true; |
2178 | break; |
2179 | default: |
2180 | ALOGE("%s: Emulator doesn't support scene mode %d", |
2181 | __FUNCTION__, sceneMode); |
2182 | return BAD_VALUE; |
2183 | } |
2184 | } else { |
2185 | mFacePriority = false; |
2186 | } |
2187 | |
2188 | // controlMode == AUTO or sceneMode = FACE_PRIORITY |
2189 | // Process individual 3A controls |
2190 | |
2191 | res = doFakeAE(settings); |
2192 | if (res != OK) return res; |
2193 | |
2194 | res = doFakeAF(settings); |
2195 | if (res != OK) return res; |
2196 | |
2197 | res = doFakeAWB(settings); |
2198 | if (res != OK) return res; |
2199 | |
2200 | update3A(settings); |
2201 | return OK; |
2202 | } |
2203 | |
2204 | status_t EmulatedFakeCamera3::doFakeAE(CameraMetadata &settings) { |
2205 | camera_metadata_entry e; |
2206 | |
2207 | e = settings.find(ANDROID_CONTROL_AE_MODE); |
2208 | if (e.count == 0) { |
2209 | ALOGE("%s: No AE mode entry!", __FUNCTION__); |
2210 | return BAD_VALUE; |
2211 | } |
2212 | uint8_t aeMode = e.data.u8[0]; |
2213 | |
2214 | switch (aeMode) { |
2215 | case ANDROID_CONTROL_AE_MODE_OFF: |
2216 | // AE is OFF |
2217 | mAeState = ANDROID_CONTROL_AE_STATE_INACTIVE; |
2218 | return OK; |
2219 | case ANDROID_CONTROL_AE_MODE_ON: |
2220 | // OK for AUTO modes |
2221 | break; |
2222 | default: |
2223 | ALOGVV("%s: Emulator doesn't support AE mode %d", |
2224 | __FUNCTION__, aeMode); |
2225 | return BAD_VALUE; |
2226 | } |
2227 | |
2228 | e = settings.find(ANDROID_CONTROL_AE_LOCK); |
2229 | if (e.count == 0) { |
2230 | ALOGE("%s: No AE lock entry!", __FUNCTION__); |
2231 | return BAD_VALUE; |
2232 | } |
2233 | bool aeLocked = (e.data.u8[0] == ANDROID_CONTROL_AE_LOCK_ON); |
2234 | |
2235 | e = settings.find(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER); |
2236 | bool precaptureTrigger = false; |
2237 | if (e.count != 0) { |
2238 | precaptureTrigger = |
2239 | (e.data.u8[0] == ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_START); |
2240 | } |
2241 | |
2242 | if (precaptureTrigger) { |
2243 | ALOGVV("%s: Pre capture trigger = %d", __FUNCTION__, precaptureTrigger); |
2244 | } else if (e.count > 0) { |
2245 | ALOGVV("%s: Pre capture trigger was present? %zu", |
2246 | __FUNCTION__, |
2247 | e.count); |
2248 | } |
2249 | |
2250 | if (precaptureTrigger || mAeState == ANDROID_CONTROL_AE_STATE_PRECAPTURE) { |
2251 | // Run precapture sequence |
2252 | if (mAeState != ANDROID_CONTROL_AE_STATE_PRECAPTURE) { |
2253 | mAeCounter = 0; |
2254 | } |
2255 | |
2256 | if (mFacePriority) { |
2257 | mAeTargetExposureTime = kFacePriorityExposureTime; |
2258 | } else { |
2259 | mAeTargetExposureTime = kNormalExposureTime; |
2260 | } |
2261 | |
2262 | if (mAeCounter > kPrecaptureMinFrames && |
2263 | (mAeTargetExposureTime - mAeCurrentExposureTime) < |
2264 | mAeTargetExposureTime / 10) { |
2265 | // Done with precapture |
2266 | mAeCounter = 0; |
2267 | mAeState = aeLocked ? ANDROID_CONTROL_AE_STATE_LOCKED : |
2268 | ANDROID_CONTROL_AE_STATE_CONVERGED; |
2269 | } else { |
2270 | // Converge some more |
2271 | mAeCurrentExposureTime += |
2272 | (mAeTargetExposureTime - mAeCurrentExposureTime) * |
2273 | kExposureTrackRate; |
2274 | mAeCounter++; |
2275 | mAeState = ANDROID_CONTROL_AE_STATE_PRECAPTURE; |
2276 | } |
2277 | |
2278 | } else if (!aeLocked) { |
2279 | // Run standard occasional AE scan |
2280 | switch (mAeState) { |
2281 | case ANDROID_CONTROL_AE_STATE_CONVERGED: |
2282 | case ANDROID_CONTROL_AE_STATE_INACTIVE: |
2283 | mAeCounter++; |
2284 | if (mAeCounter > kStableAeMaxFrames) { |
2285 | mAeTargetExposureTime = |
2286 | mFacePriority ? kFacePriorityExposureTime : |
2287 | kNormalExposureTime; |
2288 | float exposureStep = ((double)rand() / RAND_MAX) * |
2289 | (kExposureWanderMax - kExposureWanderMin) + |
2290 | kExposureWanderMin; |
2291 | mAeTargetExposureTime *= std::pow(2, exposureStep); |
2292 | mAeState = ANDROID_CONTROL_AE_STATE_SEARCHING; |
2293 | } |
2294 | break; |
2295 | case ANDROID_CONTROL_AE_STATE_SEARCHING: |
2296 | mAeCurrentExposureTime += |
2297 | (mAeTargetExposureTime - mAeCurrentExposureTime) * |
2298 | kExposureTrackRate; |
2299 | if (abs(mAeTargetExposureTime - mAeCurrentExposureTime) < |
2300 | mAeTargetExposureTime / 10) { |
2301 | // Close enough |
2302 | mAeState = ANDROID_CONTROL_AE_STATE_CONVERGED; |
2303 | mAeCounter = 0; |
2304 | } |
2305 | break; |
2306 | case ANDROID_CONTROL_AE_STATE_LOCKED: |
2307 | mAeState = ANDROID_CONTROL_AE_STATE_CONVERGED; |
2308 | mAeCounter = 0; |
2309 | break; |
2310 | default: |
2311 | ALOGE("%s: Emulator in unexpected AE state %d", |
2312 | __FUNCTION__, mAeState); |
2313 | return INVALID_OPERATION; |
2314 | } |
2315 | } else { |
2316 | // AE is locked |
2317 | mAeState = ANDROID_CONTROL_AE_STATE_LOCKED; |
2318 | } |
2319 | |
2320 | return OK; |
2321 | } |
2322 | |
2323 | status_t EmulatedFakeCamera3::doFakeAF(CameraMetadata &settings) { |
2324 | camera_metadata_entry e; |
2325 | |
2326 | e = settings.find(ANDROID_CONTROL_AF_MODE); |
2327 | if (e.count == 0) { |
2328 | ALOGE("%s: No AF mode entry!", __FUNCTION__); |
2329 | return BAD_VALUE; |
2330 | } |
2331 | uint8_t afMode = e.data.u8[0]; |
2332 | |
2333 | e = settings.find(ANDROID_CONTROL_AF_TRIGGER); |
2334 | typedef camera_metadata_enum_android_control_af_trigger af_trigger_t; |
2335 | af_trigger_t afTrigger; |
2336 | // If we have an afTrigger, afTriggerId should be set too |
2337 | if (e.count != 0) { |
2338 | afTrigger = static_cast<af_trigger_t>(e.data.u8[0]); |
2339 | |
2340 | e = settings.find(ANDROID_CONTROL_AF_TRIGGER_ID); |
2341 | |
2342 | if (e.count == 0) { |
2343 | ALOGE("%s: When android.control.afTrigger is set " |
2344 | " in the request, afTriggerId needs to be set as well", |
2345 | __FUNCTION__); |
2346 | return BAD_VALUE; |
2347 | } |
2348 | |
2349 | mAfTriggerId = e.data.i32[0]; |
2350 | |
2351 | ALOGVV("%s: AF trigger set to 0x%x", __FUNCTION__, afTrigger); |
2352 | ALOGVV("%s: AF trigger ID set to 0x%x", __FUNCTION__, mAfTriggerId); |
2353 | ALOGVV("%s: AF mode is 0x%x", __FUNCTION__, afMode); |
2354 | } else { |
2355 | afTrigger = ANDROID_CONTROL_AF_TRIGGER_IDLE; |
2356 | } |
2357 | if (!mFacingBack) { |
2358 | afMode = ANDROID_CONTROL_AF_MODE_OFF; |
2359 | } |
2360 | |
2361 | switch (afMode) { |
2362 | case ANDROID_CONTROL_AF_MODE_OFF: |
2363 | mAfState = ANDROID_CONTROL_AF_STATE_INACTIVE; |
2364 | return OK; |
2365 | case ANDROID_CONTROL_AF_MODE_AUTO: |
2366 | case ANDROID_CONTROL_AF_MODE_MACRO: |
2367 | case ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO: |
2368 | case ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE: |
2369 | if (!mFacingBack) { |
2370 | ALOGE("%s: Front camera doesn't support AF mode %d", |
2371 | __FUNCTION__, afMode); |
2372 | return BAD_VALUE; |
2373 | } |
2374 | mSensor->setAutoFocuas(afMode); |
2375 | // OK, handle transitions lower on |
2376 | break; |
2377 | default: |
2378 | ALOGE("%s: Emulator doesn't support AF mode %d", |
2379 | __FUNCTION__, afMode); |
2380 | return BAD_VALUE; |
2381 | } |
2382 | #if 0 |
2383 | e = settings.find(ANDROID_CONTROL_AF_REGIONS); |
2384 | if (e.count == 0) { |
2385 | ALOGE("%s:Get ANDROID_CONTROL_AF_REGIONS failed\n", __FUNCTION__); |
2386 | return BAD_VALUE; |
2387 | } |
2388 | int32_t x0 = e.data.i32[0]; |
2389 | int32_t y0 = e.data.i32[1]; |
2390 | int32_t x1 = e.data.i32[2]; |
2391 | int32_t y1 = e.data.i32[3]; |
2392 | mSensor->setFocuasArea(x0, y0, x1, y1); |
2393 | DBG_LOGB(" x0:%d, y0:%d,x1:%d,y1:%d,\n", x0, y0, x1, y1); |
2394 | #endif |
2395 | |
2396 | |
2397 | bool afModeChanged = mAfMode != afMode; |
2398 | mAfMode = afMode; |
2399 | |
2400 | /** |
2401 | * Simulate AF triggers. Transition at most 1 state per frame. |
2402 | * - Focusing always succeeds (goes into locked, or PASSIVE_SCAN). |
2403 | */ |
2404 | |
2405 | bool afTriggerStart = false; |
2406 | bool afTriggerCancel = false; |
2407 | switch (afTrigger) { |
2408 | case ANDROID_CONTROL_AF_TRIGGER_IDLE: |
2409 | break; |
2410 | case ANDROID_CONTROL_AF_TRIGGER_START: |
2411 | afTriggerStart = true; |
2412 | break; |
2413 | case ANDROID_CONTROL_AF_TRIGGER_CANCEL: |
2414 | afTriggerCancel = true; |
2415 | // Cancel trigger always transitions into INACTIVE |
2416 | mAfState = ANDROID_CONTROL_AF_STATE_INACTIVE; |
2417 | |
2418 | ALOGV("%s: AF State transition to STATE_INACTIVE", __FUNCTION__); |
2419 | |
2420 | // Stay in 'inactive' until at least next frame |
2421 | return OK; |
2422 | default: |
2423 | ALOGE("%s: Unknown af trigger value %d", __FUNCTION__, afTrigger); |
2424 | return BAD_VALUE; |
2425 | } |
2426 | |
2427 | // If we get down here, we're either in an autofocus mode |
2428 | // or in a continuous focus mode (and no other modes) |
2429 | |
2430 | int oldAfState = mAfState; |
2431 | switch (mAfState) { |
2432 | case ANDROID_CONTROL_AF_STATE_INACTIVE: |
2433 | if (afTriggerStart) { |
2434 | switch (afMode) { |
2435 | case ANDROID_CONTROL_AF_MODE_AUTO: |
2436 | // fall-through |
2437 | case ANDROID_CONTROL_AF_MODE_MACRO: |
2438 | mAfState = ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN; |
2439 | break; |
2440 | case ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO: |
2441 | // fall-through |
2442 | case ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE: |
2443 | mAfState = ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED; |
2444 | break; |
2445 | } |
2446 | } else { |
2447 | // At least one frame stays in INACTIVE |
2448 | if (!afModeChanged) { |
2449 | switch (afMode) { |
2450 | case ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO: |
2451 | // fall-through |
2452 | case ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE: |
2453 | mAfState = ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN; |
2454 | break; |
2455 | } |
2456 | } |
2457 | } |
2458 | break; |
2459 | case ANDROID_CONTROL_AF_STATE_PASSIVE_SCAN: |
2460 | /** |
2461 | * When the AF trigger is activated, the algorithm should finish |
2462 | * its PASSIVE_SCAN if active, and then transition into AF_FOCUSED |
2463 | * or AF_NOT_FOCUSED as appropriate |
2464 | */ |
2465 | if (afTriggerStart) { |
2466 | // Randomly transition to focused or not focused |
2467 | if (rand() % 3) { |
2468 | mAfState = ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED; |
2469 | } else { |
2470 | mAfState = ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED; |
2471 | } |
2472 | } |
2473 | /** |
2474 | * When the AF trigger is not involved, the AF algorithm should |
2475 | * start in INACTIVE state, and then transition into PASSIVE_SCAN |
2476 | * and PASSIVE_FOCUSED states |
2477 | */ |
2478 | else if (!afTriggerCancel) { |
2479 | // Randomly transition to passive focus |
2480 | if (rand() % 3 == 0) { |
2481 | mAfState = ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED; |
2482 | } |
2483 | } |
2484 | |
2485 | break; |
2486 | case ANDROID_CONTROL_AF_STATE_PASSIVE_FOCUSED: |
2487 | if (afTriggerStart) { |
2488 | // Randomly transition to focused or not focused |
2489 | if (rand() % 3) { |
2490 | mAfState = ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED; |
2491 | } else { |
2492 | mAfState = ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED; |
2493 | } |
2494 | } |
2495 | // TODO: initiate passive scan (PASSIVE_SCAN) |
2496 | break; |
2497 | case ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN: |
2498 | // Simulate AF sweep completing instantaneously |
2499 | |
2500 | // Randomly transition to focused or not focused |
2501 | if (rand() % 3) { |
2502 | mAfState = ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED; |
2503 | } else { |
2504 | mAfState = ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED; |
2505 | } |
2506 | break; |
2507 | case ANDROID_CONTROL_AF_STATE_FOCUSED_LOCKED: |
2508 | if (afTriggerStart) { |
2509 | switch (afMode) { |
2510 | case ANDROID_CONTROL_AF_MODE_AUTO: |
2511 | // fall-through |
2512 | case ANDROID_CONTROL_AF_MODE_MACRO: |
2513 | mAfState = ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN; |
2514 | break; |
2515 | case ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO: |
2516 | // fall-through |
2517 | case ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE: |
2518 | // continuous autofocus => trigger start has no effect |
2519 | break; |
2520 | } |
2521 | } |
2522 | break; |
2523 | case ANDROID_CONTROL_AF_STATE_NOT_FOCUSED_LOCKED: |
2524 | if (afTriggerStart) { |
2525 | switch (afMode) { |
2526 | case ANDROID_CONTROL_AF_MODE_AUTO: |
2527 | // fall-through |
2528 | case ANDROID_CONTROL_AF_MODE_MACRO: |
2529 | mAfState = ANDROID_CONTROL_AF_STATE_ACTIVE_SCAN; |
2530 | break; |
2531 | case ANDROID_CONTROL_AF_MODE_CONTINUOUS_VIDEO: |
2532 | // fall-through |
2533 | case ANDROID_CONTROL_AF_MODE_CONTINUOUS_PICTURE: |
2534 | // continuous autofocus => trigger start has no effect |
2535 | break; |
2536 | } |
2537 | } |
2538 | break; |
2539 | default: |
2540 | ALOGE("%s: Bad af state %d", __FUNCTION__, mAfState); |
2541 | } |
2542 | |
2543 | { |
2544 | char afStateString[100] = {0,}; |
2545 | camera_metadata_enum_snprint(ANDROID_CONTROL_AF_STATE, |
2546 | oldAfState, |
2547 | afStateString, |
2548 | sizeof(afStateString)); |
2549 | |
2550 | char afNewStateString[100] = {0,}; |
2551 | camera_metadata_enum_snprint(ANDROID_CONTROL_AF_STATE, |
2552 | mAfState, |
2553 | afNewStateString, |
2554 | sizeof(afNewStateString)); |
2555 | ALOGVV("%s: AF state transitioned from %s to %s", |
2556 | __FUNCTION__, afStateString, afNewStateString); |
2557 | } |
2558 | |
2559 | |
2560 | return OK; |
2561 | } |
2562 | |
2563 | status_t EmulatedFakeCamera3::doFakeAWB(CameraMetadata &settings) { |
2564 | camera_metadata_entry e; |
2565 | |
2566 | e = settings.find(ANDROID_CONTROL_AWB_MODE); |
2567 | if (e.count == 0) { |
2568 | ALOGE("%s: No AWB mode entry!", __FUNCTION__); |
2569 | return BAD_VALUE; |
2570 | } |
2571 | uint8_t awbMode = e.data.u8[0]; |
2572 | //DBG_LOGB(" awbMode%d\n", awbMode); |
2573 | |
2574 | // TODO: Add white balance simulation |
2575 | |
2576 | switch (awbMode) { |
2577 | case ANDROID_CONTROL_AWB_MODE_OFF: |
2578 | mAwbState = ANDROID_CONTROL_AWB_STATE_INACTIVE; |
2579 | return OK; |
2580 | case ANDROID_CONTROL_AWB_MODE_AUTO: |
2581 | case ANDROID_CONTROL_AWB_MODE_INCANDESCENT: |
2582 | case ANDROID_CONTROL_AWB_MODE_FLUORESCENT: |
2583 | case ANDROID_CONTROL_AWB_MODE_DAYLIGHT: |
2584 | case ANDROID_CONTROL_AWB_MODE_SHADE: |
2585 | mAwbState = ANDROID_CONTROL_AWB_STATE_CONVERGED; //add for cts |
2586 | return mSensor->setAWB(awbMode); |
2587 | // OK |
2588 | break; |
2589 | default: |
2590 | ALOGE("%s: Emulator doesn't support AWB mode %d", |
2591 | __FUNCTION__, awbMode); |
2592 | return BAD_VALUE; |
2593 | } |
2594 | |
2595 | return OK; |
2596 | } |
2597 | |
2598 | |
2599 | void EmulatedFakeCamera3::update3A(CameraMetadata &settings) { |
2600 | if (mAeState != ANDROID_CONTROL_AE_STATE_INACTIVE) { |
2601 | settings.update(ANDROID_SENSOR_EXPOSURE_TIME, |
2602 | &mAeCurrentExposureTime, 1); |
2603 | settings.update(ANDROID_SENSOR_SENSITIVITY, |
2604 | &mAeCurrentSensitivity, 1); |
2605 | } |
2606 | |
2607 | settings.update(ANDROID_CONTROL_AE_STATE, |
2608 | &mAeState, 1); |
2609 | settings.update(ANDROID_CONTROL_AF_STATE, |
2610 | &mAfState, 1); |
2611 | settings.update(ANDROID_CONTROL_AWB_STATE, |
2612 | &mAwbState, 1); |
2613 | /** |
2614 | * TODO: Trigger IDs need a think-through |
2615 | */ |
2616 | settings.update(ANDROID_CONTROL_AF_TRIGGER_ID, |
2617 | &mAfTriggerId, 1); |
2618 | } |
2619 | |
2620 | void EmulatedFakeCamera3::signalReadoutIdle() { |
2621 | Mutex::Autolock l(mLock); |
2622 | CAMHAL_LOGVB("%s , E" , __FUNCTION__); |
2623 | // Need to chek isIdle again because waiting on mLock may have allowed |
2624 | // something to be placed in the in-flight queue. |
2625 | if (mStatus == STATUS_ACTIVE && mReadoutThread->isIdle()) { |
2626 | ALOGV("Now idle"); |
2627 | mStatus = STATUS_READY; |
2628 | } |
2629 | CAMHAL_LOGVB("%s , X , mStatus = %d " , __FUNCTION__, mStatus); |
2630 | } |
2631 | |
2632 | void EmulatedFakeCamera3::onSensorEvent(uint32_t frameNumber, Event e, |
2633 | nsecs_t timestamp) { |
2634 | switch(e) { |
2635 | case Sensor::SensorListener::EXPOSURE_START: { |
2636 | ALOGVV("%s: Frame %d: Sensor started exposure at %lld", |
2637 | __FUNCTION__, frameNumber, timestamp); |
2638 | // Trigger shutter notify to framework |
2639 | camera3_notify_msg_t msg; |
2640 | msg.type = CAMERA3_MSG_SHUTTER; |
2641 | msg.message.shutter.frame_number = frameNumber; |
2642 | msg.message.shutter.timestamp = timestamp; |
2643 | sendNotify(&msg); |
2644 | break; |
2645 | } |
2646 | case Sensor::SensorListener::ERROR_CAMERA_DEVICE: { |
2647 | camera3_notify_msg_t msg; |
2648 | msg.type = CAMERA3_MSG_ERROR; |
2649 | msg.message.error.frame_number = frameNumber; |
2650 | msg.message.error.error_stream = NULL; |
2651 | msg.message.error.error_code = 1; |
2652 | sendNotify(&msg); |
2653 | break; |
2654 | } |
2655 | default: |
2656 | ALOGW("%s: Unexpected sensor event %d at %" PRId64, __FUNCTION__, |
2657 | e, timestamp); |
2658 | break; |
2659 | } |
2660 | } |
2661 | |
2662 | EmulatedFakeCamera3::ReadoutThread::ReadoutThread(EmulatedFakeCamera3 *parent) : |
2663 | mParent(parent), mJpegWaiting(false) { |
2664 | mExitReadoutThread = false; |
2665 | mFlushFlag = false; |
2666 | } |
2667 | |
2668 | EmulatedFakeCamera3::ReadoutThread::~ReadoutThread() { |
2669 | for (List<Request>::iterator i = mInFlightQueue.begin(); |
2670 | i != mInFlightQueue.end(); i++) { |
2671 | delete i->buffers; |
2672 | delete i->sensorBuffers; |
2673 | } |
2674 | } |
2675 | |
2676 | status_t EmulatedFakeCamera3::ReadoutThread::flushAllRequest(bool flag) { |
2677 | status_t res; |
2678 | mFlushFlag = flag; |
2679 | Mutex::Autolock l(mLock); |
2680 | CAMHAL_LOGDB("count = %d" , mInFlightQueue.size()); |
2681 | if (mInFlightQueue.size() > 0) { |
2682 | mParent->mSensor->setFlushFlag(true); |
2683 | res = mFlush.waitRelative(mLock, kSyncWaitTimeout * 15); |
2684 | if (res != OK && res != TIMED_OUT) { |
2685 | ALOGE("%s: Error waiting for mFlush singnal : %d", |
2686 | __FUNCTION__, res); |
2687 | return INVALID_OPERATION; |
2688 | } |
2689 | DBG_LOGA("finish flush all request"); |
2690 | } |
2691 | return 0; |
2692 | } |
2693 | |
2694 | void EmulatedFakeCamera3::ReadoutThread::sendFlushSingnal(void) { |
2695 | Mutex::Autolock l(mLock); |
2696 | mFlush.signal(); |
2697 | } |
2698 | |
2699 | void EmulatedFakeCamera3::ReadoutThread::setFlushFlag(bool flag) { |
2700 | mFlushFlag = flag; |
2701 | } |
2702 | |
2703 | void EmulatedFakeCamera3::ReadoutThread::queueCaptureRequest(const Request &r) { |
2704 | Mutex::Autolock l(mLock); |
2705 | |
2706 | mInFlightQueue.push_back(r); |
2707 | mInFlightSignal.signal(); |
2708 | } |
2709 | |
2710 | bool EmulatedFakeCamera3::ReadoutThread::isIdle() { |
2711 | Mutex::Autolock l(mLock); |
2712 | return mInFlightQueue.empty() && !mThreadActive; |
2713 | } |
2714 | |
2715 | status_t EmulatedFakeCamera3::ReadoutThread::waitForReadout() { |
2716 | status_t res; |
2717 | Mutex::Autolock l(mLock); |
2718 | CAMHAL_LOGVB("%s , E" , __FUNCTION__); |
2719 | int loopCount = 0; |
2720 | while (mInFlightQueue.size() >= kMaxQueueSize) { |
2721 | res = mInFlightSignal.waitRelative(mLock, kWaitPerLoop); |
2722 | if (res != OK && res != TIMED_OUT) { |
2723 | ALOGE("%s: Error waiting for in-flight queue to shrink", |
2724 | __FUNCTION__); |
2725 | return INVALID_OPERATION; |
2726 | } |
2727 | if (loopCount == kMaxWaitLoops) { |
2728 | ALOGE("%s: Timed out waiting for in-flight queue to shrink", |
2729 | __FUNCTION__); |
2730 | return TIMED_OUT; |
2731 | } |
2732 | loopCount++; |
2733 | } |
2734 | return OK; |
2735 | } |
2736 | |
2737 | status_t EmulatedFakeCamera3::ReadoutThread::setJpegCompressorListener(EmulatedFakeCamera3 *parent) { |
2738 | status_t res; |
2739 | res = mParent->mJpegCompressor->setlistener(this); |
2740 | if (res != NO_ERROR) { |
2741 | ALOGE("%s: set JpegCompressor Listner failed",__FUNCTION__); |
2742 | } |
2743 | return res; |
2744 | } |
2745 | |
2746 | status_t EmulatedFakeCamera3::ReadoutThread::startJpegCompressor(EmulatedFakeCamera3 *parent) { |
2747 | status_t res; |
2748 | res = mParent->mJpegCompressor->start(); |
2749 | if (res != NO_ERROR) { |
2750 | ALOGE("%s: JpegCompressor start failed",__FUNCTION__); |
2751 | } |
2752 | return res; |
2753 | } |
2754 | |
2755 | status_t EmulatedFakeCamera3::ReadoutThread::shutdownJpegCompressor(EmulatedFakeCamera3 *parent) { |
2756 | status_t res; |
2757 | res = mParent->mJpegCompressor->cancel(); |
2758 | if (res != OK) { |
2759 | ALOGE("%s: JpegCompressor cancel failed",__FUNCTION__); |
2760 | } |
2761 | return res; |
2762 | } |
2763 | |
2764 | void EmulatedFakeCamera3::ReadoutThread::sendExitReadoutThreadSignal(void) { |
2765 | mExitReadoutThread = true; |
2766 | mInFlightSignal.signal(); |
2767 | } |
2768 | |
2769 | bool EmulatedFakeCamera3::ReadoutThread::threadLoop() { |
2770 | status_t res; |
2771 | ALOGVV("%s: ReadoutThread waiting for request", __FUNCTION__); |
2772 | |
2773 | // First wait for a request from the in-flight queue |
2774 | if (mExitReadoutThread) { |
2775 | return false; |
2776 | } |
2777 | |
2778 | { |
2779 | Mutex::Autolock l(mLock); |
2780 | if ((mInFlightQueue.size() == 0) && (mFlushFlag) && |
2781 | (mCurrentRequest.settings.isEmpty())) { |
2782 | mFlush.signal(); |
2783 | } |
2784 | } |
2785 | |
2786 | if (mCurrentRequest.settings.isEmpty()) { |
2787 | Mutex::Autolock l(mLock); |
2788 | if (mInFlightQueue.empty()) { |
2789 | res = mInFlightSignal.waitRelative(mLock, kWaitPerLoop); |
2790 | if (res == TIMED_OUT) { |
2791 | ALOGVV("%s: ReadoutThread: Timed out waiting for request", |
2792 | __FUNCTION__); |
2793 | return true; |
2794 | } else if (res != NO_ERROR) { |
2795 | ALOGE("%s: Error waiting for capture requests: %d", |
2796 | __FUNCTION__, res); |
2797 | return false; |
2798 | } |
2799 | } |
2800 | |
2801 | if (mExitReadoutThread) { |
2802 | return false; |
2803 | } |
2804 | |
2805 | mCurrentRequest.frameNumber = mInFlightQueue.begin()->frameNumber; |
2806 | mCurrentRequest.settings.acquire(mInFlightQueue.begin()->settings); |
2807 | mCurrentRequest.buffers = mInFlightQueue.begin()->buffers; |
2808 | mCurrentRequest.sensorBuffers = mInFlightQueue.begin()->sensorBuffers; |
2809 | mCurrentRequest.havethumbnail = mInFlightQueue.begin()->havethumbnail; |
2810 | mInFlightQueue.erase(mInFlightQueue.begin()); |
2811 | mInFlightSignal.signal(); |
2812 | mThreadActive = true; |
2813 | ALOGVV("%s: Beginning readout of frame %d", __FUNCTION__, |
2814 | mCurrentRequest.frameNumber); |
2815 | } |
2816 | |
2817 | // Then wait for it to be delivered from the sensor |
2818 | ALOGVV("%s: ReadoutThread: Wait for frame to be delivered from sensor", |
2819 | __FUNCTION__); |
2820 | |
2821 | nsecs_t captureTime; |
2822 | status_t gotFrame = |
2823 | mParent->mSensor->waitForNewFrame(kWaitPerLoop, &captureTime); |
2824 | if (gotFrame == 0) { |
2825 | ALOGVV("%s: ReadoutThread: Timed out waiting for sensor frame", |
2826 | __FUNCTION__); |
2827 | return true; |
2828 | } |
2829 | |
2830 | if (gotFrame == -1) { |
2831 | DBG_LOGA("Sensor thread had exited , here should exit ReadoutThread Loop"); |
2832 | return false; |
2833 | } |
2834 | |
2835 | ALOGVV("Sensor done with readout for frame %d, captured at %lld ", |
2836 | mCurrentRequest.frameNumber, captureTime); |
2837 | |
2838 | // Check if we need to JPEG encode a buffer, and send it for async |
2839 | // compression if so. Otherwise prepare the buffer for return. |
2840 | bool needJpeg = false; |
2841 | HalBufferVector::iterator buf = mCurrentRequest.buffers->begin(); |
2842 | while (buf != mCurrentRequest.buffers->end()) { |
2843 | bool goodBuffer = true; |
2844 | if ( buf->stream->format == |
2845 | HAL_PIXEL_FORMAT_BLOB) { |
2846 | Mutex::Autolock jl(mJpegLock); |
2847 | needJpeg = true; |
2848 | CaptureRequest currentcapture; |
2849 | currentcapture.frameNumber = mCurrentRequest.frameNumber; |
2850 | currentcapture.sensorBuffers = mCurrentRequest.sensorBuffers; |
2851 | currentcapture.buf = buf; |
2852 | currentcapture.mNeedThumbnail = mCurrentRequest.havethumbnail; |
2853 | mParent->mJpegCompressor->queueRequest(currentcapture); |
2854 | //this sensorBuffers delete in the jpegcompress; |
2855 | mCurrentRequest.sensorBuffers = NULL; |
2856 | buf = mCurrentRequest.buffers->erase(buf); |
2857 | continue; |
2858 | } |
2859 | GraphicBufferMapper::get().unlock(*(buf->buffer)); |
2860 | |
2861 | buf->status = goodBuffer ? CAMERA3_BUFFER_STATUS_OK : |
2862 | CAMERA3_BUFFER_STATUS_ERROR; |
2863 | buf->acquire_fence = -1; |
2864 | buf->release_fence = -1; |
2865 | |
2866 | ++buf; |
2867 | } // end while |
2868 | |
2869 | // Construct result for all completed buffers and results |
2870 | |
2871 | camera3_capture_result result; |
2872 | |
2873 | mCurrentRequest.settings.update(ANDROID_SENSOR_TIMESTAMP, |
2874 | &captureTime, 1); |
2875 | |
2876 | memset(&result, 0, sizeof(result)); |
2877 | result.frame_number = mCurrentRequest.frameNumber; |
2878 | result.result = mCurrentRequest.settings.getAndLock(); |
2879 | result.num_output_buffers = mCurrentRequest.buffers->size(); |
2880 | result.output_buffers = mCurrentRequest.buffers->array(); |
2881 | result.partial_result = 1; |
2882 | |
2883 | // Go idle if queue is empty, before sending result |
2884 | |
2885 | bool signalIdle = false; |
2886 | { |
2887 | Mutex::Autolock l(mLock); |
2888 | if (mInFlightQueue.empty()) { |
2889 | mThreadActive = false; |
2890 | signalIdle = true; |
2891 | } |
2892 | } |
2893 | |
2894 | if (signalIdle) mParent->signalReadoutIdle(); |
2895 | |
2896 | // Send it off to the framework |
2897 | ALOGVV("%s: ReadoutThread: Send result to framework", |
2898 | __FUNCTION__); |
2899 | mParent->sendCaptureResult(&result); |
2900 | |
2901 | // Clean up |
2902 | mCurrentRequest.settings.unlock(result.result); |
2903 | |
2904 | delete mCurrentRequest.buffers; |
2905 | mCurrentRequest.buffers = NULL; |
2906 | if (!needJpeg) { |
2907 | delete mCurrentRequest.sensorBuffers; |
2908 | mCurrentRequest.sensorBuffers = NULL; |
2909 | } |
2910 | mCurrentRequest.settings.clear(); |
2911 | CAMHAL_LOGVB("%s , X " , __FUNCTION__); |
2912 | return true; |
2913 | } |
2914 | |
2915 | void EmulatedFakeCamera3::ReadoutThread::onJpegDone( |
2916 | const StreamBuffer &jpegBuffer, bool success , CaptureRequest &r) { |
2917 | Mutex::Autolock jl(mJpegLock); |
2918 | GraphicBufferMapper::get().unlock(*(jpegBuffer.buffer)); |
2919 | |
2920 | mJpegHalBuffer = *(r.buf); |
2921 | mJpegHalBuffer.status = success ? |
2922 | CAMERA3_BUFFER_STATUS_OK : CAMERA3_BUFFER_STATUS_ERROR; |
2923 | mJpegHalBuffer.acquire_fence = -1; |
2924 | mJpegHalBuffer.release_fence = -1; |
2925 | mJpegWaiting = false; |
2926 | |
2927 | camera3_capture_result result; |
2928 | result.frame_number = r.frameNumber; |
2929 | result.result = NULL; |
2930 | result.num_output_buffers = 1; |
2931 | result.output_buffers = &mJpegHalBuffer; |
2932 | result.partial_result = 1; |
2933 | |
2934 | if (!success) { |
2935 | ALOGE("%s: Compression failure, returning error state buffer to" |
2936 | " framework", __FUNCTION__); |
2937 | } else { |
2938 | DBG_LOGB("%s: Compression complete, returning buffer to framework", |
2939 | __FUNCTION__); |
2940 | } |
2941 | |
2942 | mParent->sendCaptureResult(&result); |
2943 | |
2944 | } |
2945 | |
2946 | void EmulatedFakeCamera3::ReadoutThread::onJpegInputDone( |
2947 | const StreamBuffer &inputBuffer) { |
2948 | // Should never get here, since the input buffer has to be returned |
2949 | // by end of processCaptureRequest |
2950 | ALOGE("%s: Unexpected input buffer from JPEG compressor!", __FUNCTION__); |
2951 | } |
2952 | |
2953 | |
2954 | }; // namespace android |
2955 |