1 /*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 /*
18 * Contains implementation of a class EmulatedCamera that encapsulates
19 * functionality common to all emulated cameras ("fake", "webcam", "video file",
20 * etc.). Instances of this class (for each emulated camera) are created during
21 * the construction of the EmulatedCameraFactory instance. This class serves as
22 * an entry point for all camera API calls that defined by camera_device_ops_t
23 * API.
24 */
25
26 #define LOG_NDEBUG 0
27 #define LOG_TAG "EmulatedCamera_Camera"
28 #include <log/log.h>
29 #include "EmulatedCamera.h"
30 //#include "EmulatedFakeCameraDevice.h"
31 #include "Converters.h"
32
33 /* Defines whether we should trace parameter changes. */
34 #define DEBUG_PARAM 1
35
36 namespace android {
37 namespace {
38 const char* kSupportedFlashModes[] = {
39 CameraParameters::FLASH_MODE_OFF, CameraParameters::FLASH_MODE_AUTO,
40 CameraParameters::FLASH_MODE_ON, CameraParameters::FLASH_MODE_RED_EYE,
41 CameraParameters::FLASH_MODE_TORCH, NULL};
42
BuildParameterValue(const char ** value_array)43 std::string BuildParameterValue(const char** value_array) {
44 std::string result;
45
46 for (int index = 0; value_array[index] != NULL; ++index) {
47 if (index) result.append(",");
48 result.append(value_array[index]);
49 }
50 return result;
51 }
52
CheckParameterValue(const char * value,const char ** supported_values)53 bool CheckParameterValue(const char* value, const char** supported_values) {
54 for (int index = 0; supported_values[index] != NULL; ++index) {
55 if (!strcmp(value, supported_values[index])) return true;
56 }
57 return false;
58 }
59
60 } // namespace
61
62 #if DEBUG_PARAM
63 /* Calculates and logs parameter changes.
64 * Param:
65 * current - Current set of camera parameters.
66 * new_par - String representation of new parameters.
67 */
68 static void PrintParamDiff(const CameraParameters& current,
69 const char* new_par);
70 #else
71 #define PrintParamDiff(current, new_par) (void(0))
72 #endif /* DEBUG_PARAM */
73
EmulatedCamera(int cameraId,struct hw_module_t * module)74 EmulatedCamera::EmulatedCamera(int cameraId, struct hw_module_t* module)
75 : EmulatedBaseCamera(cameraId, HARDWARE_DEVICE_API_VERSION(1, 0), &common,
76 module),
77 mPreviewWindow(),
78 mCallbackNotifier() {
79 /* camera_device v1 fields. */
80 common.close = EmulatedCamera::close;
81 ops = &mDeviceOps;
82 priv = this;
83 }
84
~EmulatedCamera()85 EmulatedCamera::~EmulatedCamera() {}
86
87 /****************************************************************************
88 * Public API
89 ***************************************************************************/
90
Initialize(const cuttlefish::CameraDefinition &)91 status_t EmulatedCamera::Initialize(const cuttlefish::CameraDefinition&) {
92 /* Preview formats supported by this HAL. */
93 char preview_formats[1024];
94 snprintf(preview_formats, sizeof(preview_formats), "%s,%s,%s",
95 CameraParameters::PIXEL_FORMAT_YUV420SP,
96 CameraParameters::PIXEL_FORMAT_YUV420P,
97 CameraParameters::PIXEL_FORMAT_RGBA8888);
98
99 /*
100 * Fake required parameters.
101 */
102
103 mParameters.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES,
104 "320x240,0x0");
105
106 mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, "512");
107 mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, "384");
108 mParameters.set(CameraParameters::KEY_JPEG_QUALITY, "90");
109 mParameters.set(CameraParameters::KEY_FOCAL_LENGTH, "4.31");
110 mParameters.set(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, "54.8");
111 mParameters.set(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, "42.5");
112 mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, "90");
113
114 /* Preview format settings used here are related to panoramic view only. It's
115 * not related to the preview window that works only with RGB frames, which
116 * is explicitly stated when set_buffers_geometry is called on the preview
117 * window object. */
118 mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS,
119 preview_formats);
120 mParameters.setPreviewFormat(CameraParameters::PIXEL_FORMAT_YUV420SP);
121
122 /* We don't relay on the actual frame rates supported by the camera device,
123 * since we will emulate them through timeouts in the emulated camera device
124 * worker thread. */
125 mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES,
126 "30,24,20,15,10,5");
127 mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE,
128 "(5000,30000),(15000,15000),(30000,30000)");
129 mParameters.set(CameraParameters::KEY_PREVIEW_FPS_RANGE, "5000,30000");
130 mParameters.setPreviewFrameRate(30000);
131
132 /* Only PIXEL_FORMAT_YUV420P is accepted by video framework in emulator! */
133 mParameters.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT,
134 CameraParameters::PIXEL_FORMAT_YUV420P);
135 mParameters.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS,
136 CameraParameters::PIXEL_FORMAT_JPEG);
137 mParameters.setPictureFormat(CameraParameters::PIXEL_FORMAT_JPEG);
138
139 /* Set exposure compensation. */
140 mParameters.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION, "6");
141 mParameters.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION, "-6");
142 mParameters.set(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP, "0.5");
143 mParameters.set(CameraParameters::KEY_EXPOSURE_COMPENSATION, "0");
144
145 /* Sets the white balance modes and the device-dependent scale factors. */
146 char supported_white_balance[1024];
147 snprintf(supported_white_balance, sizeof(supported_white_balance),
148 "%s,%s,%s,%s", CameraParameters::WHITE_BALANCE_AUTO,
149 CameraParameters::WHITE_BALANCE_INCANDESCENT,
150 CameraParameters::WHITE_BALANCE_DAYLIGHT,
151 CameraParameters::WHITE_BALANCE_TWILIGHT);
152 mParameters.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE,
153 supported_white_balance);
154 mParameters.set(CameraParameters::KEY_WHITE_BALANCE,
155 CameraParameters::WHITE_BALANCE_AUTO);
156 getCameraDevice()->initializeWhiteBalanceModes(
157 CameraParameters::WHITE_BALANCE_AUTO, 1.0f, 1.0f);
158 getCameraDevice()->initializeWhiteBalanceModes(
159 CameraParameters::WHITE_BALANCE_INCANDESCENT, 1.38f, 0.60f);
160 getCameraDevice()->initializeWhiteBalanceModes(
161 CameraParameters::WHITE_BALANCE_DAYLIGHT, 1.09f, 0.92f);
162 getCameraDevice()->initializeWhiteBalanceModes(
163 CameraParameters::WHITE_BALANCE_TWILIGHT, 0.92f, 1.22f);
164 getCameraDevice()->setWhiteBalanceMode(CameraParameters::WHITE_BALANCE_AUTO);
165
166 /*
167 * Not supported features
168 */
169 mParameters.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES,
170 CameraParameters::FOCUS_MODE_FIXED);
171 mParameters.set(CameraParameters::KEY_FOCUS_MODE,
172 CameraParameters::FOCUS_MODE_FIXED);
173 mParameters.set(CameraParameters::KEY_SUPPORTED_FLASH_MODES,
174 BuildParameterValue(kSupportedFlashModes).c_str());
175 mParameters.set(CameraParameters::KEY_FLASH_MODE,
176 CameraParameters::FLASH_MODE_OFF);
177 mParameters.set(CameraParameters::KEY_FOCUS_DISTANCES, "0.1,0.1,0.1");
178 mParameters.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW, "0");
179 mParameters.set(CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW, "0");
180 mParameters.set(CameraParameters::KEY_ZOOM_RATIOS, "100");
181 mParameters.set(CameraParameters::KEY_ZOOM_SUPPORTED,
182 CameraParameters::FALSE);
183 mParameters.set(CameraParameters::KEY_SMOOTH_ZOOM_SUPPORTED,
184 CameraParameters::FALSE);
185 mParameters.set(CameraParameters::KEY_ZOOM, "0");
186 mParameters.set(CameraParameters::KEY_MAX_ZOOM, "0");
187
188 return NO_ERROR;
189 }
190
onNextFrameAvailable(const void * frame,nsecs_t timestamp,EmulatedCameraDevice * camera_dev)191 void EmulatedCamera::onNextFrameAvailable(const void* frame, nsecs_t timestamp,
192 EmulatedCameraDevice* camera_dev) {
193 /* Notify the preview window first. */
194 mPreviewWindow.onNextFrameAvailable(frame, timestamp, camera_dev);
195
196 /* Notify callback notifier next. */
197 mCallbackNotifier.onNextFrameAvailable(frame, timestamp, camera_dev);
198 }
199
onCameraDeviceError(int err)200 void EmulatedCamera::onCameraDeviceError(int err) {
201 /* Errors are reported through the callback notifier */
202 mCallbackNotifier.onCameraDeviceError(err);
203 }
204
onCameraFocusAcquired()205 void EmulatedCamera::onCameraFocusAcquired() {
206 mCallbackNotifier.onCameraFocusAcquired();
207 }
208
209 /****************************************************************************
210 * Camera API implementation.
211 ***************************************************************************/
212
connectCamera(hw_device_t ** device)213 status_t EmulatedCamera::connectCamera(hw_device_t** device) {
214 ALOGV("%s", __FUNCTION__);
215
216 status_t res = EINVAL;
217 EmulatedCameraDevice* const camera_dev = getCameraDevice();
218 ALOGE_IF(camera_dev == NULL, "%s: No camera device instance.", __FUNCTION__);
219
220 if (camera_dev != NULL) {
221 /* Connect to the camera device. */
222 res = getCameraDevice()->connectDevice();
223 if (res == NO_ERROR) {
224 *device = &common;
225 }
226 }
227
228 return -res;
229 }
230
closeCamera()231 status_t EmulatedCamera::closeCamera() {
232 ALOGV("%s", __FUNCTION__);
233
234 return cleanupCamera();
235 }
236
getCameraInfo(struct camera_info * info)237 status_t EmulatedCamera::getCameraInfo(struct camera_info* info) {
238 ALOGV("%s", __FUNCTION__);
239
240 const char* valstr = NULL;
241
242 valstr = mParameters.get(EmulatedCamera::FACING_KEY);
243 if (valstr != NULL) {
244 if (strcmp(valstr, EmulatedCamera::FACING_FRONT) == 0) {
245 info->facing = CAMERA_FACING_FRONT;
246 } else if (strcmp(valstr, EmulatedCamera::FACING_BACK) == 0) {
247 info->facing = CAMERA_FACING_BACK;
248 }
249 } else {
250 info->facing = CAMERA_FACING_BACK;
251 }
252
253 valstr = mParameters.get(EmulatedCamera::ORIENTATION_KEY);
254 if (valstr != NULL) {
255 info->orientation = atoi(valstr);
256 } else {
257 info->orientation = 0;
258 }
259
260 info->resource_cost = 100;
261 info->conflicting_devices = NULL;
262 info->conflicting_devices_length = 0;
263
264 return EmulatedBaseCamera::getCameraInfo(info);
265 }
266
getCameraParameters()267 const CameraParameters* EmulatedCamera::getCameraParameters() {
268 return &mParameters;
269 }
270
setPreviewWindow(struct preview_stream_ops * window)271 status_t EmulatedCamera::setPreviewWindow(struct preview_stream_ops* window) {
272 /* Callback should return a negative errno. */
273 return -mPreviewWindow.setPreviewWindow(window,
274 mParameters.getPreviewFrameRate());
275 }
276
setCallbacks(camera_notify_callback notify_cb,camera_data_callback data_cb,camera_data_timestamp_callback data_cb_timestamp,camera_request_memory get_memory,void * user)277 void EmulatedCamera::setCallbacks(
278 camera_notify_callback notify_cb, camera_data_callback data_cb,
279 camera_data_timestamp_callback data_cb_timestamp,
280 camera_request_memory get_memory, void* user) {
281 mCallbackNotifier.setCallbacks(notify_cb, data_cb, data_cb_timestamp,
282 get_memory, user);
283 }
284
enableMsgType(int32_t msg_type)285 void EmulatedCamera::enableMsgType(int32_t msg_type) {
286 mCallbackNotifier.enableMessage(msg_type);
287 }
288
disableMsgType(int32_t msg_type)289 void EmulatedCamera::disableMsgType(int32_t msg_type) {
290 mCallbackNotifier.disableMessage(msg_type);
291 }
292
isMsgTypeEnabled(int32_t msg_type)293 int EmulatedCamera::isMsgTypeEnabled(int32_t msg_type) {
294 return mCallbackNotifier.isMessageEnabled(msg_type);
295 }
296
startPreview()297 status_t EmulatedCamera::startPreview() {
298 /* Callback should return a negative errno. */
299 return -doStartPreview();
300 }
301
stopPreview()302 void EmulatedCamera::stopPreview() { doStopPreview(); }
303
isPreviewEnabled()304 int EmulatedCamera::isPreviewEnabled() {
305 return mPreviewWindow.isPreviewEnabled();
306 }
307
storeMetaDataInBuffers(int enable)308 status_t EmulatedCamera::storeMetaDataInBuffers(int enable) {
309 /* Callback should return a negative errno. */
310 return -mCallbackNotifier.storeMetaDataInBuffers(enable);
311 }
312
startRecording()313 status_t EmulatedCamera::startRecording() {
314 /* Callback should return a negative errno. */
315 return -mCallbackNotifier.enableVideoRecording(
316 mParameters.getPreviewFrameRate());
317 }
318
stopRecording()319 void EmulatedCamera::stopRecording() {
320 mCallbackNotifier.disableVideoRecording();
321 }
322
isRecordingEnabled()323 int EmulatedCamera::isRecordingEnabled() {
324 return mCallbackNotifier.isVideoRecordingEnabled();
325 }
326
releaseRecordingFrame(const void * opaque)327 void EmulatedCamera::releaseRecordingFrame(const void* opaque) {
328 mCallbackNotifier.releaseRecordingFrame(opaque);
329 }
330
setAutoFocus()331 status_t EmulatedCamera::setAutoFocus() {
332 ALOGV("%s", __FUNCTION__);
333
334 /* Trigger auto-focus. Focus response cannot be sent directly from here. */
335 getCameraDevice()->startAutoFocus();
336
337 /* TODO: Future enhancements. */
338 return NO_ERROR;
339 }
340
cancelAutoFocus()341 status_t EmulatedCamera::cancelAutoFocus() {
342 ALOGV("%s", __FUNCTION__);
343
344 /* TODO: Future enhancements. */
345 return NO_ERROR;
346 }
347
takePicture()348 status_t EmulatedCamera::takePicture() {
349 ALOGV("%s", __FUNCTION__);
350
351 status_t res;
352 int width, height;
353 uint32_t org_fmt;
354
355 /* Collect frame info for the picture. */
356 mParameters.getPictureSize(&width, &height);
357 const char* pix_fmt = mParameters.getPictureFormat();
358 if (strcmp(pix_fmt, CameraParameters::PIXEL_FORMAT_YUV420P) == 0) {
359 org_fmt = V4L2_PIX_FMT_YUV420;
360 } else if (strcmp(pix_fmt, CameraParameters::PIXEL_FORMAT_RGBA8888) == 0) {
361 org_fmt = V4L2_PIX_FMT_RGB32;
362 } else if (strcmp(pix_fmt, CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) {
363 org_fmt = V4L2_PIX_FMT_NV21;
364 } else if (strcmp(pix_fmt, CameraParameters::PIXEL_FORMAT_JPEG) == 0) {
365 /* We only have JPEG converted for NV21 format. */
366 org_fmt = V4L2_PIX_FMT_NV21;
367 } else {
368 ALOGE("%s: Unsupported pixel format %s", __FUNCTION__, pix_fmt);
369 return EINVAL;
370 }
371 /* Get JPEG quality. */
372 int jpeg_quality = mParameters.getInt(CameraParameters::KEY_JPEG_QUALITY);
373 if (jpeg_quality <= 0) {
374 jpeg_quality = 90; /* Fall back to default. */
375 }
376
377 /*
378 * Make sure preview is not running, and device is stopped before taking
379 * picture.
380 */
381
382 const bool preview_on = mPreviewWindow.isPreviewEnabled();
383 if (preview_on) {
384 doStopPreview();
385 }
386
387 /* Camera device should have been stopped when the shutter message has been
388 * enabled. */
389 EmulatedCameraDevice* const camera_dev = getCameraDevice();
390 if (camera_dev->isStarted()) {
391 ALOGW("%s: Camera device is started", __FUNCTION__);
392 camera_dev->stopDeliveringFrames();
393 camera_dev->stopDevice();
394 }
395
396 /* Compute target FPS rate.
397 * Pretend to simulate generation of (max_fps_rate) */
398 int min_fps_rate, max_fps_rate;
399 mParameters.getPreviewFpsRange(&min_fps_rate, &max_fps_rate);
400
401 /*
402 * Take the picture now.
403 */
404
405 /* Start camera device for the picture frame. */
406 ALOGD("Starting camera for picture: %.4s(%s)[%dx%d]",
407 reinterpret_cast<const char*>(&org_fmt), pix_fmt, width, height);
408 res = camera_dev->startDevice(width, height, org_fmt, max_fps_rate);
409 if (res != NO_ERROR) {
410 if (preview_on) {
411 doStartPreview();
412 }
413 return res;
414 }
415
416 /* Deliver one frame only. */
417 mCallbackNotifier.setJpegQuality(jpeg_quality);
418 mCallbackNotifier.setTakingPicture(true);
419 res = camera_dev->startDeliveringFrames(true);
420 if (res != NO_ERROR) {
421 mCallbackNotifier.setTakingPicture(false);
422 if (preview_on) {
423 doStartPreview();
424 }
425 }
426 return res;
427 }
428
cancelPicture()429 status_t EmulatedCamera::cancelPicture() {
430 ALOGV("%s", __FUNCTION__);
431
432 return NO_ERROR;
433 }
434
setParameters(const char * parms)435 status_t EmulatedCamera::setParameters(const char* parms) {
436 ALOGV("%s", __FUNCTION__);
437 PrintParamDiff(mParameters, parms);
438
439 CameraParameters new_param;
440 String8 str8_param(parms);
441 new_param.unflatten(str8_param);
442
443 /*
444 * Check if requested dimensions are valid.
445 */
446 if (!CheckParameterValue(new_param.get(CameraParameters::KEY_FLASH_MODE),
447 kSupportedFlashModes)) {
448 ALOGE("%s: Unsupported flash mode: %s", __FUNCTION__,
449 new_param.get(CameraParameters::KEY_FLASH_MODE));
450 return -EINVAL;
451 }
452 if (strcmp(new_param.get(CameraParameters::KEY_FOCUS_MODE),
453 CameraParameters::FOCUS_MODE_FIXED)) {
454 ALOGE("%s: Unsupported flash mode: %s", __FUNCTION__,
455 new_param.get(CameraParameters::KEY_FOCUS_MODE));
456 return -EINVAL;
457 }
458
459 int preview_width, preview_height;
460 new_param.getPreviewSize(&preview_width, &preview_height);
461 if (preview_width <= 0 || preview_height <= 0) return -EINVAL;
462
463 /*
464 * Check for new exposure compensation parameter.
465 */
466 int new_exposure_compensation =
467 new_param.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION);
468 const int min_exposure_compensation =
469 new_param.getInt(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION);
470 const int max_exposure_compensation =
471 new_param.getInt(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION);
472
473 // Checks if the exposure compensation change is supported.
474 if ((min_exposure_compensation != 0) || (max_exposure_compensation != 0)) {
475 if (new_exposure_compensation > max_exposure_compensation) {
476 new_exposure_compensation = max_exposure_compensation;
477 }
478 if (new_exposure_compensation < min_exposure_compensation) {
479 new_exposure_compensation = min_exposure_compensation;
480 }
481
482 const int current_exposure_compensation =
483 mParameters.getInt(CameraParameters::KEY_EXPOSURE_COMPENSATION);
484 if (current_exposure_compensation != new_exposure_compensation) {
485 const float exposure_value =
486 new_exposure_compensation *
487 new_param.getFloat(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP);
488
489 getCameraDevice()->setExposureCompensation(exposure_value);
490 }
491 }
492
493 const char* new_white_balance =
494 new_param.get(CameraParameters::KEY_WHITE_BALANCE);
495 const char* supported_white_balance =
496 new_param.get(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE);
497
498 if ((supported_white_balance != NULL) && (new_white_balance != NULL) &&
499 (strstr(supported_white_balance, new_white_balance) != NULL)) {
500 const char* current_white_balance =
501 mParameters.get(CameraParameters::KEY_WHITE_BALANCE);
502 if ((current_white_balance == NULL) ||
503 (strcmp(current_white_balance, new_white_balance) != 0)) {
504 ALOGV("Setting white balance to %s", new_white_balance);
505 getCameraDevice()->setWhiteBalanceMode(new_white_balance);
506 }
507 }
508
509 mParameters = new_param;
510
511 return NO_ERROR;
512 }
513
514 /* A variable indicating "no params" / error on the exit from
515 * EmulatedCamera::getParameters(). */
516 static char lNoParam = '\0';
getParameters()517 char* EmulatedCamera::getParameters() {
518 String8 params(mParameters.flatten());
519 char* ret_str =
520 reinterpret_cast<char*>(malloc(sizeof(char) * (params.length() + 1)));
521 memset(ret_str, 0, params.length() + 1);
522 if (ret_str != NULL) {
523 strncpy(ret_str, params.string(), params.length() + 1);
524 return ret_str;
525 } else {
526 ALOGE("%s: Unable to allocate string for %s", __FUNCTION__,
527 params.string());
528 /* Apparently, we can't return NULL fron this routine. */
529 return &lNoParam;
530 }
531 }
532
putParameters(char * params)533 void EmulatedCamera::putParameters(char* params) {
534 /* This method simply frees parameters allocated in getParameters(). */
535 if (params != NULL && params != &lNoParam) {
536 free(params);
537 }
538 }
539
sendCommand(int32_t cmd,int32_t arg1,int32_t arg2)540 status_t EmulatedCamera::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) {
541 ALOGV("%s: cmd = %d, arg1 = %d, arg2 = %d", __FUNCTION__, cmd, arg1, arg2);
542
543 switch (cmd) {
544 case CAMERA_CMD_START_FACE_DETECTION:
545 case CAMERA_CMD_STOP_FACE_DETECTION:
546 return -EINVAL;
547 }
548
549 /* TODO: Future enhancements. */
550 return 0;
551 }
552
releaseCamera()553 void EmulatedCamera::releaseCamera() {
554 ALOGV("%s", __FUNCTION__);
555
556 cleanupCamera();
557 }
558
dumpCamera(int)559 status_t EmulatedCamera::dumpCamera(int /*fd*/) {
560 ALOGV("%s", __FUNCTION__);
561
562 /* TODO: Future enhancements. */
563 return -EINVAL;
564 }
565
566 /****************************************************************************
567 * Preview management.
568 ***************************************************************************/
569
doStartPreview()570 status_t EmulatedCamera::doStartPreview() {
571 ALOGV("%s", __FUNCTION__);
572
573 EmulatedCameraDevice* camera_dev = getCameraDevice();
574 if (camera_dev->isStarted()) {
575 camera_dev->stopDeliveringFrames();
576 camera_dev->stopDevice();
577 }
578
579 status_t res = mPreviewWindow.startPreview();
580 if (res != NO_ERROR) {
581 return res;
582 }
583
584 /* Make sure camera device is connected. */
585 if (!camera_dev->isConnected()) {
586 res = camera_dev->connectDevice();
587 if (res != NO_ERROR) {
588 mPreviewWindow.stopPreview();
589 return res;
590 }
591 }
592
593 int width, height;
594 /* Lets see what should we use for frame width, and height. */
595 if (mParameters.get(CameraParameters::KEY_VIDEO_SIZE) != NULL) {
596 mParameters.getVideoSize(&width, &height);
597 } else {
598 mParameters.getPreviewSize(&width, &height);
599 }
600 /* Lets see what should we use for the frame pixel format. Note that there
601 * are two parameters that define pixel formats for frames sent to the
602 * application via notification callbacks:
603 * - KEY_VIDEO_FRAME_FORMAT, that is used when recording video, and
604 * - KEY_PREVIEW_FORMAT, that is used for preview frame notification.
605 * We choose one or the other, depending on "recording-hint" property set by
606 * the framework that indicating intention: video, or preview. */
607 const char* pix_fmt = NULL;
608 const char* is_video = mParameters.get(EmulatedCamera::RECORDING_HINT_KEY);
609 if (is_video == NULL) {
610 is_video = CameraParameters::FALSE;
611 }
612 if (strcmp(is_video, CameraParameters::TRUE) == 0) {
613 /* Video recording is requested. Lets see if video frame format is set. */
614 pix_fmt = mParameters.get(CameraParameters::KEY_VIDEO_FRAME_FORMAT);
615 }
616 /* If this was not video recording, or video frame format is not set, lets
617 * use preview pixel format for the main framebuffer. */
618 if (pix_fmt == NULL) {
619 pix_fmt = mParameters.getPreviewFormat();
620 }
621 if (pix_fmt == NULL) {
622 ALOGE("%s: Unable to obtain video format", __FUNCTION__);
623 mPreviewWindow.stopPreview();
624 return EINVAL;
625 }
626
627 /* Convert framework's pixel format to the FOURCC one. */
628 uint32_t org_fmt;
629 if (strcmp(pix_fmt, CameraParameters::PIXEL_FORMAT_YUV420P) == 0) {
630 org_fmt = V4L2_PIX_FMT_YUV420;
631 } else if (strcmp(pix_fmt, CameraParameters::PIXEL_FORMAT_RGBA8888) == 0) {
632 org_fmt = V4L2_PIX_FMT_RGB32;
633 } else if (strcmp(pix_fmt, CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) {
634 org_fmt = V4L2_PIX_FMT_NV21;
635 } else {
636 ALOGE("%s: Unsupported pixel format %s", __FUNCTION__, pix_fmt);
637 mPreviewWindow.stopPreview();
638 return EINVAL;
639 }
640
641 /* Fetch the desired frame rate. */
642 int min_fps_rate, max_fps_rate;
643 mParameters.getPreviewFpsRange(&min_fps_rate, &max_fps_rate);
644
645 ALOGD("Starting camera: %dx%d -> %.4s(%s)", width, height,
646 reinterpret_cast<const char*>(&org_fmt), pix_fmt);
647 res = camera_dev->startDevice(width, height, org_fmt, max_fps_rate);
648 if (res != NO_ERROR) {
649 mPreviewWindow.stopPreview();
650 return res;
651 }
652
653 res = camera_dev->startDeliveringFrames(false);
654 if (res != NO_ERROR) {
655 camera_dev->stopDevice();
656 mPreviewWindow.stopPreview();
657 }
658
659 return res;
660 }
661
doStopPreview()662 status_t EmulatedCamera::doStopPreview() {
663 ALOGV("%s", __FUNCTION__);
664
665 status_t res = NO_ERROR;
666 if (mPreviewWindow.isPreviewEnabled()) {
667 /* Stop the camera. */
668 if (getCameraDevice()->isStarted()) {
669 getCameraDevice()->stopDeliveringFrames();
670 res = getCameraDevice()->stopDevice();
671 }
672
673 if (res == NO_ERROR) {
674 /* Disable preview as well. */
675 mPreviewWindow.stopPreview();
676 }
677 }
678
679 return NO_ERROR;
680 }
681
682 /****************************************************************************
683 * Private API.
684 ***************************************************************************/
685
cleanupCamera()686 status_t EmulatedCamera::cleanupCamera() {
687 status_t res = NO_ERROR;
688
689 /* If preview is running - stop it. */
690 res = doStopPreview();
691 if (res != NO_ERROR) {
692 return -res;
693 }
694
695 /* Stop and disconnect the camera device. */
696 EmulatedCameraDevice* const camera_dev = getCameraDevice();
697 if (camera_dev != NULL) {
698 if (camera_dev->isStarted()) {
699 camera_dev->stopDeliveringFrames();
700 res = camera_dev->stopDevice();
701 if (res != NO_ERROR) {
702 return -res;
703 }
704 }
705 if (camera_dev->isConnected()) {
706 res = camera_dev->disconnectDevice();
707 if (res != NO_ERROR) {
708 return -res;
709 }
710 }
711 }
712
713 mCallbackNotifier.cleanupCBNotifier();
714
715 return NO_ERROR;
716 }
717
718 /****************************************************************************
719 * Camera API callbacks as defined by camera_device_ops structure.
720 *
721 * Callbacks here simply dispatch the calls to an appropriate method inside
722 * EmulatedCamera instance, defined by the 'dev' parameter.
723 ***************************************************************************/
724
set_preview_window(struct camera_device * dev,struct preview_stream_ops * window)725 int EmulatedCamera::set_preview_window(struct camera_device* dev,
726 struct preview_stream_ops* window) {
727 EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
728 if (ec == NULL) {
729 ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
730 return -EINVAL;
731 }
732 return ec->setPreviewWindow(window);
733 }
734
set_callbacks(struct camera_device * dev,camera_notify_callback notify_cb,camera_data_callback data_cb,camera_data_timestamp_callback data_cb_timestamp,camera_request_memory get_memory,void * user)735 void EmulatedCamera::set_callbacks(
736 struct camera_device* dev, camera_notify_callback notify_cb,
737 camera_data_callback data_cb,
738 camera_data_timestamp_callback data_cb_timestamp,
739 camera_request_memory get_memory, void* user) {
740 EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
741 if (ec == NULL) {
742 ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
743 return;
744 }
745 ec->setCallbacks(notify_cb, data_cb, data_cb_timestamp, get_memory, user);
746 }
747
enable_msg_type(struct camera_device * dev,int32_t msg_type)748 void EmulatedCamera::enable_msg_type(struct camera_device* dev,
749 int32_t msg_type) {
750 EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
751 if (ec == NULL) {
752 ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
753 return;
754 }
755 ec->enableMsgType(msg_type);
756 }
757
disable_msg_type(struct camera_device * dev,int32_t msg_type)758 void EmulatedCamera::disable_msg_type(struct camera_device* dev,
759 int32_t msg_type) {
760 EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
761 if (ec == NULL) {
762 ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
763 return;
764 }
765 ec->disableMsgType(msg_type);
766 }
767
msg_type_enabled(struct camera_device * dev,int32_t msg_type)768 int EmulatedCamera::msg_type_enabled(struct camera_device* dev,
769 int32_t msg_type) {
770 EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
771 if (ec == NULL) {
772 ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
773 return -EINVAL;
774 }
775 return ec->isMsgTypeEnabled(msg_type);
776 }
777
start_preview(struct camera_device * dev)778 int EmulatedCamera::start_preview(struct camera_device* dev) {
779 EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
780 if (ec == NULL) {
781 ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
782 return -EINVAL;
783 }
784 return ec->startPreview();
785 }
786
stop_preview(struct camera_device * dev)787 void EmulatedCamera::stop_preview(struct camera_device* dev) {
788 EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
789 if (ec == NULL) {
790 ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
791 return;
792 }
793 ec->stopPreview();
794 }
795
preview_enabled(struct camera_device * dev)796 int EmulatedCamera::preview_enabled(struct camera_device* dev) {
797 EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
798 if (ec == NULL) {
799 ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
800 return -EINVAL;
801 }
802 return ec->isPreviewEnabled();
803 }
804
store_meta_data_in_buffers(struct camera_device * dev,int enable)805 int EmulatedCamera::store_meta_data_in_buffers(struct camera_device* dev,
806 int enable) {
807 EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
808 if (ec == NULL) {
809 ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
810 return -EINVAL;
811 }
812 return ec->storeMetaDataInBuffers(enable);
813 }
814
start_recording(struct camera_device * dev)815 int EmulatedCamera::start_recording(struct camera_device* dev) {
816 EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
817 if (ec == NULL) {
818 ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
819 return -EINVAL;
820 }
821 return ec->startRecording();
822 }
823
stop_recording(struct camera_device * dev)824 void EmulatedCamera::stop_recording(struct camera_device* dev) {
825 EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
826 if (ec == NULL) {
827 ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
828 return;
829 }
830 ec->stopRecording();
831 }
832
recording_enabled(struct camera_device * dev)833 int EmulatedCamera::recording_enabled(struct camera_device* dev) {
834 EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
835 if (ec == NULL) {
836 ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
837 return -EINVAL;
838 }
839 return ec->isRecordingEnabled();
840 }
841
release_recording_frame(struct camera_device * dev,const void * opaque)842 void EmulatedCamera::release_recording_frame(struct camera_device* dev,
843 const void* opaque) {
844 EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
845 if (ec == NULL) {
846 ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
847 return;
848 }
849 ec->releaseRecordingFrame(opaque);
850 }
851
auto_focus(struct camera_device * dev)852 int EmulatedCamera::auto_focus(struct camera_device* dev) {
853 EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
854 if (ec == NULL) {
855 ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
856 return -EINVAL;
857 }
858 return ec->setAutoFocus();
859 }
860
cancel_auto_focus(struct camera_device * dev)861 int EmulatedCamera::cancel_auto_focus(struct camera_device* dev) {
862 EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
863 if (ec == NULL) {
864 ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
865 return -EINVAL;
866 }
867 return ec->cancelAutoFocus();
868 }
869
take_picture(struct camera_device * dev)870 int EmulatedCamera::take_picture(struct camera_device* dev) {
871 EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
872 if (ec == NULL) {
873 ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
874 return -EINVAL;
875 }
876 return ec->takePicture();
877 }
878
cancel_picture(struct camera_device * dev)879 int EmulatedCamera::cancel_picture(struct camera_device* dev) {
880 EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
881 if (ec == NULL) {
882 ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
883 return -EINVAL;
884 }
885 return ec->cancelPicture();
886 }
887
set_parameters(struct camera_device * dev,const char * parms)888 int EmulatedCamera::set_parameters(struct camera_device* dev,
889 const char* parms) {
890 EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
891 if (ec == NULL) {
892 ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
893 return -EINVAL;
894 }
895 return ec->setParameters(parms);
896 }
897
get_parameters(struct camera_device * dev)898 char* EmulatedCamera::get_parameters(struct camera_device* dev) {
899 EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
900 if (ec == NULL) {
901 ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
902 return NULL;
903 }
904 return ec->getParameters();
905 }
906
put_parameters(struct camera_device * dev,char * params)907 void EmulatedCamera::put_parameters(struct camera_device* dev, char* params) {
908 EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
909 if (ec == NULL) {
910 ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
911 return;
912 }
913 ec->putParameters(params);
914 }
915
send_command(struct camera_device * dev,int32_t cmd,int32_t arg1,int32_t arg2)916 int EmulatedCamera::send_command(struct camera_device* dev, int32_t cmd,
917 int32_t arg1, int32_t arg2) {
918 EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
919 if (ec == NULL) {
920 ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
921 return -EINVAL;
922 }
923 return ec->sendCommand(cmd, arg1, arg2);
924 }
925
release(struct camera_device * dev)926 void EmulatedCamera::release(struct camera_device* dev) {
927 EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
928 if (ec == NULL) {
929 ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
930 return;
931 }
932 ec->releaseCamera();
933 }
934
dump(struct camera_device * dev,int fd)935 int EmulatedCamera::dump(struct camera_device* dev, int fd) {
936 EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv);
937 if (ec == NULL) {
938 ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
939 return -EINVAL;
940 }
941 return ec->dumpCamera(fd);
942 }
943
close(struct hw_device_t * device)944 int EmulatedCamera::close(struct hw_device_t* device) {
945 EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(
946 reinterpret_cast<struct camera_device*>(device)->priv);
947 if (ec == NULL) {
948 ALOGE("%s: Unexpected NULL camera device", __FUNCTION__);
949 return -EINVAL;
950 }
951 return ec->closeCamera();
952 }
953
954 /****************************************************************************
955 * Static initializer for the camera callback API
956 ****************************************************************************/
957
958 camera_device_ops_t EmulatedCamera::mDeviceOps = {
959 EmulatedCamera::set_preview_window,
960 EmulatedCamera::set_callbacks,
961 EmulatedCamera::enable_msg_type,
962 EmulatedCamera::disable_msg_type,
963 EmulatedCamera::msg_type_enabled,
964 EmulatedCamera::start_preview,
965 EmulatedCamera::stop_preview,
966 EmulatedCamera::preview_enabled,
967 EmulatedCamera::store_meta_data_in_buffers,
968 EmulatedCamera::start_recording,
969 EmulatedCamera::stop_recording,
970 EmulatedCamera::recording_enabled,
971 EmulatedCamera::release_recording_frame,
972 EmulatedCamera::auto_focus,
973 EmulatedCamera::cancel_auto_focus,
974 EmulatedCamera::take_picture,
975 EmulatedCamera::cancel_picture,
976 EmulatedCamera::set_parameters,
977 EmulatedCamera::get_parameters,
978 EmulatedCamera::put_parameters,
979 EmulatedCamera::send_command,
980 EmulatedCamera::release,
981 EmulatedCamera::dump};
982
983 /****************************************************************************
984 * Common keys
985 ***************************************************************************/
986
987 const char EmulatedCamera::FACING_KEY[] = "prop-facing";
988 const char EmulatedCamera::ORIENTATION_KEY[] = "prop-orientation";
989 const char EmulatedCamera::RECORDING_HINT_KEY[] = "recording-hint";
990
991 /****************************************************************************
992 * Common string values
993 ***************************************************************************/
994
995 const char EmulatedCamera::FACING_BACK[] = "back";
996 const char EmulatedCamera::FACING_FRONT[] = "front";
997
998 /****************************************************************************
999 * Parameter debugging helpers
1000 ***************************************************************************/
1001
1002 #if DEBUG_PARAM
PrintParamDiff(const CameraParameters & current,const char * new_par)1003 static void PrintParamDiff(const CameraParameters& current,
1004 const char* new_par) {
1005 char tmp[2048];
1006 const char* wrk = new_par;
1007
1008 /* Divided with ';' */
1009 const char* next = strchr(wrk, ';');
1010 while (next != NULL) {
1011 snprintf(tmp, sizeof(tmp), "%.*s", (int)(intptr_t)(next - wrk), wrk);
1012 /* in the form key=value */
1013 char* val = strchr(tmp, '=');
1014 if (val != NULL) {
1015 *val = '\0';
1016 val++;
1017 const char* in_current = current.get(tmp);
1018 if (in_current != NULL) {
1019 if (strcmp(in_current, val)) {
1020 ALOGD("=== Value changed: %s: %s -> %s", tmp, in_current, val);
1021 }
1022 } else {
1023 ALOGD("+++ New parameter: %s=%s", tmp, val);
1024 }
1025 } else {
1026 ALOGW("No value separator in %s", tmp);
1027 }
1028 wrk = next + 1;
1029 next = strchr(wrk, ';');
1030 }
1031 }
1032 #endif /* DEBUG_PARAM */
1033
1034 }; /* namespace android */
1035