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