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 <cutils/log.h> 29 #include <stdio.h> 30#include "EmulatedCamera.h" 31//#include "EmulatedFakeCameraDevice.h" 32#include "Converters.h" 33 34/* Defines whether we should trace parameter changes. */ 35#define DEBUG_PARAM 1 36 37namespace android { 38 39static const char* kValidFocusModes[] = { 40 CameraParameters::FOCUS_MODE_AUTO, 41 CameraParameters::FOCUS_MODE_INFINITY, 42 CameraParameters::FOCUS_MODE_MACRO, 43 CameraParameters::FOCUS_MODE_FIXED, 44 CameraParameters::FOCUS_MODE_EDOF, 45 CameraParameters::FOCUS_MODE_CONTINUOUS_VIDEO, 46 CameraParameters::FOCUS_MODE_CONTINUOUS_PICTURE, 47}; 48 49#if DEBUG_PARAM 50/* Calculates and logs parameter changes. 51 * Param: 52 * current - Current set of camera parameters. 53 * new_par - String representation of new parameters. 54 */ 55static void PrintParamDiff(const CameraParameters& current, const char* new_par); 56#else 57#define PrintParamDiff(current, new_par) (void(0)) 58#endif /* DEBUG_PARAM */ 59 60/* A helper routine that adds a value to the camera parameter. 61 * Param: 62 * param - Camera parameter to add a value to. 63 * val - Value to add. 64 * Return: 65 * A new string containing parameter with the added value on success, or NULL on 66 * a failure. If non-NULL string is returned, the caller is responsible for 67 * freeing it with 'free'. 68 */ 69static char* AddValue(const char* param, const char* val); 70 71/* 72 * Check if a given string |value| equals at least one of the strings in |list| 73 */ 74template<size_t N> 75static bool IsValueInList(const char* value, const char* const (&list)[N]) 76{ 77 for (size_t i = 0; i < N; ++i) { 78 if (strcmp(value, list[i]) == 0) { 79 return true; 80 } 81 } 82 return false; 83} 84 85static bool StringsEqual(const char* str1, const char* str2) { 86 if (str1 == nullptr && str2 == nullptr) { 87 return true; 88 } 89 if (str1 == nullptr || str2 == nullptr) { 90 return false; 91 } 92 return strcmp(str1, str2) == 0; 93} 94 95static bool GetFourCcFormatFromCameraParam(const char* fmt_str, 96 uint32_t* fmt_val) { 97 if (strcmp(fmt_str, CameraParameters::PIXEL_FORMAT_YUV420P) == 0) { 98 // Despite the name above this is a YVU format, specifically YV12 99 *fmt_val = V4L2_PIX_FMT_YVU420; 100 return true; 101 } else if (strcmp(fmt_str, CameraParameters::PIXEL_FORMAT_RGBA8888) == 0) { 102 *fmt_val = V4L2_PIX_FMT_RGB32; 103 return true; 104 } else if (strcmp(fmt_str, CameraParameters::PIXEL_FORMAT_YUV420SP) == 0) { 105 *fmt_val = V4L2_PIX_FMT_NV21; 106 return true; 107 } 108 return false; 109} 110 111EmulatedCamera::EmulatedCamera(int cameraId, 112 struct hw_module_t* module) 113 : EmulatedBaseCamera(cameraId, 114 HARDWARE_DEVICE_API_VERSION(1, 0), 115 &common, 116 module), 117 mPreviewWindow(), 118 mCallbackNotifier() 119{ 120 /* camera_device v1 fields. */ 121 common.close = EmulatedCamera::close; 122 ops = &mDeviceOps; 123 priv = this; 124} 125 126EmulatedCamera::~EmulatedCamera() 127{ 128} 129 130/**************************************************************************** 131 * Public API 132 ***************************************************************************/ 133 134status_t EmulatedCamera::Initialize() 135{ 136 /* Preview formats supported by this HAL. */ 137 char preview_formats[1024]; 138 snprintf(preview_formats, sizeof(preview_formats), "%s,%s,%s", 139 CameraParameters::PIXEL_FORMAT_YUV420SP, 140 CameraParameters::PIXEL_FORMAT_YUV420P, 141 CameraParameters::PIXEL_FORMAT_RGBA8888); 142 143 /* 144 * Fake required parameters. 145 */ 146 147 mParameters.set(CameraParameters::KEY_RECORDING_HINT, 148 CameraParameters::FALSE); 149 mParameters.set(CameraParameters::KEY_SUPPORTED_JPEG_THUMBNAIL_SIZES, "320x240,0x0"); 150 151 mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_WIDTH, "320"); 152 mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_HEIGHT, "240"); 153 mParameters.set(CameraParameters::KEY_JPEG_QUALITY, "90"); 154 // Camera values for a Logitech B910 HD Webcam 155 // Focal length: 4.90 mm (from specs) 156 // Horizontal view angle: 61 degrees for 4:3 sizes, 157 // 70 degrees for 16:9 sizes (empirical) 158 // Vertical view angle: 45.8 degrees (= 61 * 3 / 4) 159 // (The Mac has only "4:3" image sizes; the correct angle 160 // is 51.0 degrees. [MacBook Pro (Retina, 15-inch, Mid 2014)]) 161 mParameters.set(CameraParameters::KEY_FOCAL_LENGTH, "4.90"); 162 mParameters.set(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, "61.0"); 163 mParameters.set(CameraParameters::KEY_VERTICAL_VIEW_ANGLE, "45.8"); 164 mParameters.set(CameraParameters::KEY_JPEG_THUMBNAIL_QUALITY, "90"); 165 166 /* Preview format settings used here are related to panoramic view only. It's 167 * not related to the preview window that works only with RGB frames, which 168 * is explicitly stated when set_buffers_geometry is called on the preview 169 * window object. */ 170 mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FORMATS, 171 preview_formats); 172 mParameters.setPreviewFormat(CameraParameters::PIXEL_FORMAT_YUV420SP); 173 174 /* We don't rely on the actual frame rates supported by the camera device, 175 * since we will emulate them through timeouts in the emulated camera device 176 * worker thread. */ 177 mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES, 178 "30,24,20,15,10,5"); 179 mParameters.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE, "(30000,30000)"); 180 mParameters.set(CameraParameters::KEY_PREVIEW_FPS_RANGE, "30000,30000"); 181 mParameters.setPreviewFrameRate(30); 182 183 /* Only PIXEL_FORMAT_YUV420P is accepted by video framework in emulator! */ 184 mParameters.set(CameraParameters::KEY_VIDEO_FRAME_FORMAT, 185 CameraParameters::PIXEL_FORMAT_YUV420P); 186 mParameters.set(CameraParameters::KEY_SUPPORTED_PICTURE_FORMATS, 187 CameraParameters::PIXEL_FORMAT_JPEG); 188 mParameters.setPictureFormat(CameraParameters::PIXEL_FORMAT_JPEG); 189 190 /* Set exposure compensation. */ 191 mParameters.set(CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION, "6"); 192 mParameters.set(CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION, "-6"); 193 mParameters.set(CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP, "0.5"); 194 mParameters.set(CameraParameters::KEY_EXPOSURE_COMPENSATION, "0"); 195 196 /* Sets the white balance modes and the device-dependent scale factors. */ 197 char supported_white_balance[1024]; 198 snprintf(supported_white_balance, sizeof(supported_white_balance), 199 "%s,%s,%s,%s", 200 CameraParameters::WHITE_BALANCE_AUTO, 201 CameraParameters::WHITE_BALANCE_INCANDESCENT, 202 CameraParameters::WHITE_BALANCE_DAYLIGHT, 203 CameraParameters::WHITE_BALANCE_TWILIGHT); 204 mParameters.set(CameraParameters::KEY_SUPPORTED_WHITE_BALANCE, 205 supported_white_balance); 206 mParameters.set(CameraParameters::KEY_WHITE_BALANCE, 207 CameraParameters::WHITE_BALANCE_AUTO); 208 getCameraDevice()->initializeWhiteBalanceModes( 209 CameraParameters::WHITE_BALANCE_AUTO, 1.0f, 1.0f); 210 getCameraDevice()->initializeWhiteBalanceModes( 211 CameraParameters::WHITE_BALANCE_INCANDESCENT, 1.38f, 0.60f); 212 getCameraDevice()->initializeWhiteBalanceModes( 213 CameraParameters::WHITE_BALANCE_DAYLIGHT, 1.09f, 0.92f); 214 getCameraDevice()->initializeWhiteBalanceModes( 215 CameraParameters::WHITE_BALANCE_TWILIGHT, 0.92f, 1.22f); 216 getCameraDevice()->setWhiteBalanceMode(CameraParameters::WHITE_BALANCE_AUTO); 217 218 /* Set suported antibanding values */ 219 mParameters.set(CameraParameters::KEY_SUPPORTED_ANTIBANDING, 220 CameraParameters::ANTIBANDING_AUTO); 221 mParameters.set(CameraParameters::KEY_ANTIBANDING, 222 CameraParameters::ANTIBANDING_AUTO); 223 224 /* Set control effect mode 225 * Bug: 30862244 226 * */ 227 mParameters.set(CameraParameters::KEY_SUPPORTED_EFFECTS, 228 CameraParameters::EFFECT_NONE); 229 mParameters.set(CameraParameters::KEY_EFFECT, 230 CameraParameters::EFFECT_NONE); 231 232 /* Set focus distances for "near,optimal,far" */ 233 mParameters.set(CameraParameters::KEY_FOCUS_DISTANCES, 234 "Infinity,Infinity,Infinity"); 235 236 /* Not supported features 237 */ 238 mParameters.set(CameraParameters::KEY_SUPPORTED_FOCUS_MODES, 239 CameraParameters::FOCUS_MODE_FIXED); 240 mParameters.set(CameraParameters::KEY_FOCUS_MODE, 241 CameraParameters::FOCUS_MODE_FIXED); 242 243 return NO_ERROR; 244} 245 246void EmulatedCamera::onNextFrameAvailable(nsecs_t timestamp, 247 EmulatedCameraDevice* camera_dev) 248{ 249 /* Notify the preview window first. */ 250 mPreviewWindow.onNextFrameAvailable(timestamp, camera_dev); 251 252 /* Notify callback notifier next. */ 253 mCallbackNotifier.onNextFrameAvailable(timestamp, camera_dev); 254} 255 256void EmulatedCamera::onCameraDeviceError(int err) 257{ 258 /* Errors are reported through the callback notifier */ 259 mCallbackNotifier.onCameraDeviceError(err); 260} 261 262void EmulatedCamera::setTakingPicture(bool takingPicture) { 263 mCallbackNotifier.setTakingPicture(takingPicture); 264} 265/**************************************************************************** 266 * Camera API implementation. 267 ***************************************************************************/ 268 269status_t EmulatedCamera::connectCamera(hw_device_t** device) 270{ 271 ALOGV("%s", __FUNCTION__); 272 273 status_t res = EINVAL; 274 EmulatedCameraDevice* const camera_dev = getCameraDevice(); 275 ALOGE_IF(camera_dev == NULL, "%s: No camera device instance.", __FUNCTION__); 276 277 if (camera_dev != NULL) { 278 /* Connect to the camera device. */ 279 res = getCameraDevice()->connectDevice(); 280 if (res == NO_ERROR) { 281 *device = &common; 282 } 283 } 284 285 return -res; 286} 287 288status_t EmulatedCamera::closeCamera() 289{ 290 ALOGV("%s", __FUNCTION__); 291 292 return cleanupCamera(); 293} 294 295status_t EmulatedCamera::getCameraInfo(struct camera_info* info) 296{ 297 ALOGV("%s", __FUNCTION__); 298 299 const char* valstr = NULL; 300 301 valstr = mParameters.get(EmulatedCamera::FACING_KEY); 302 if (valstr != NULL) { 303 if (strcmp(valstr, EmulatedCamera::FACING_FRONT) == 0) { 304 info->facing = CAMERA_FACING_FRONT; 305 } 306 else if (strcmp(valstr, EmulatedCamera::FACING_BACK) == 0) { 307 info->facing = CAMERA_FACING_BACK; 308 } 309 } else { 310 info->facing = CAMERA_FACING_BACK; 311 } 312 313 valstr = mParameters.get(EmulatedCamera::ORIENTATION_KEY); 314 if (valstr != NULL) { 315 info->orientation = atoi(valstr); 316 } else { 317 info->orientation = 0; 318 } 319 320 return EmulatedBaseCamera::getCameraInfo(info); 321} 322 323void EmulatedCamera::autoFocusComplete() { 324 mCallbackNotifier.autoFocusComplete(); 325} 326 327status_t EmulatedCamera::setPreviewWindow(struct preview_stream_ops* window) 328{ 329 /* Callback should return a negative errno. */ 330 return -mPreviewWindow.setPreviewWindow(window, 331 mParameters.getPreviewFrameRate()); 332} 333 334void EmulatedCamera::setCallbacks(camera_notify_callback notify_cb, 335 camera_data_callback data_cb, 336 camera_data_timestamp_callback data_cb_timestamp, 337 camera_request_memory get_memory, 338 void* user) 339{ 340 mCallbackNotifier.setCallbacks(notify_cb, data_cb, data_cb_timestamp, 341 get_memory, user); 342} 343 344void EmulatedCamera::enableMsgType(int32_t msg_type) 345{ 346 mCallbackNotifier.enableMessage(msg_type); 347} 348 349void EmulatedCamera::disableMsgType(int32_t msg_type) 350{ 351 mCallbackNotifier.disableMessage(msg_type); 352} 353 354int EmulatedCamera::isMsgTypeEnabled(int32_t msg_type) 355{ 356 return mCallbackNotifier.isMessageEnabled(msg_type); 357} 358 359status_t EmulatedCamera::startPreview() 360{ 361 /* Callback should return a negative errno. */ 362 return -doStartPreview(); 363} 364 365void EmulatedCamera::stopPreview() 366{ 367 /* The camera client will not pass on calls to set the preview window to 368 * NULL if the preview is not enabled. If preview is not enabled the camera 369 * client will instead simply destroy the preview window without notifying 370 * the HAL. Later on when preview is enabled again that means the HAL will 371 * attempt to use the old, destroyed window which will cause a crash. 372 * Instead we need to clear the preview window here, the client will set 373 * a preview window when needed. The preview window is cleared here instead 374 * of inside doStopPreview to prevent the window from being cleared when 375 * restarting the preview because of a parameter change. */ 376 mPreviewWindow.setPreviewWindow(nullptr, 0); 377 378 doStopPreview(); 379} 380 381int EmulatedCamera::isPreviewEnabled() 382{ 383 return mPreviewWindow.isPreviewEnabled(); 384} 385 386status_t EmulatedCamera::storeMetaDataInBuffers(int enable) 387{ 388 /* Callback should return a negative errno. */ 389 return mCallbackNotifier.storeMetaDataInBuffers(enable); 390} 391 392status_t EmulatedCamera::startRecording() 393{ 394 /* This callback should return a negative errno, hence all the negations */ 395 if (!mPreviewWindow.isPreviewEnabled()) { 396 ALOGE("%s: start recording without preview enabled", 397 __FUNCTION__); 398 return INVALID_OPERATION; 399 } 400 int frameRate = mParameters.getPreviewFrameRate(); 401 status_t res = mCallbackNotifier.enableVideoRecording(frameRate); 402 if (res != NO_ERROR) { 403 ALOGE("%s: CallbackNotifier failed to enable video recording", 404 __FUNCTION__); 405 stopRecording(); 406 return -res; 407 } 408 EmulatedCameraDevice* const camera_dev = getCameraDevice(); 409 if (camera_dev == nullptr || !camera_dev->isStarted()) { 410 // No need for restarts, the next preview start will use correct params 411 return NO_ERROR; 412 } 413 414 // If the camera is running we might have to restart it to accomodate 415 // whatever pixel format and frame size the caller wants. 416 uint32_t conf_fmt = 0; 417 res = getConfiguredPixelFormat(&conf_fmt); 418 if (res != NO_ERROR) { 419 stopRecording(); 420 return -res; 421 } 422 uint32_t cur_fmt = camera_dev->getOriginalPixelFormat(); 423 int conf_width = -1, conf_height = -1; 424 res = getConfiguredFrameSize(&conf_width, &conf_height); 425 if (res != NO_ERROR) { 426 stopRecording(); 427 return -res; 428 } 429 int cur_width = camera_dev->getFrameWidth(); 430 int cur_height = camera_dev->getFrameHeight(); 431 432 if (cur_fmt != conf_fmt || 433 cur_width != conf_width || 434 cur_height != conf_height) { 435 // We need to perform a restart to use the new format or size and it 436 // has to be an asynchronous restart or this might block if the camera 437 // thread is currently delivering a frame. 438 if (!camera_dev->requestRestart(conf_width, conf_height, conf_fmt, 439 false /* takingPicture */, 440 false /* oneBurst */)) { 441 ALOGE("%s: Could not restart preview with new pixel format", 442 __FUNCTION__); 443 stopRecording(); 444 return -EINVAL; 445 } 446 } 447 ALOGD("go all the way to the end"); 448 return NO_ERROR; 449} 450 451void EmulatedCamera::stopRecording() 452{ 453 mCallbackNotifier.disableVideoRecording(); 454} 455 456int EmulatedCamera::isRecordingEnabled() 457{ 458 return mCallbackNotifier.isVideoRecordingEnabled(); 459} 460 461void EmulatedCamera::releaseRecordingFrame(const void* opaque) 462{ 463 mCallbackNotifier.releaseRecordingFrame(opaque); 464} 465 466status_t EmulatedCamera::setAutoFocus() 467{ 468 // Make sure to check that a preview is in progress. Otherwise this will 469 // silently fail because no callback will be called until the preview starts 470 // which might be never. 471 if (!isPreviewEnabled()) { 472 return EINVAL; 473 } 474 EmulatedCameraDevice* const camera_dev = getCameraDevice(); 475 if (camera_dev && camera_dev->isStarted()) { 476 return camera_dev->setAutoFocus(); 477 } 478 return EINVAL; 479} 480 481status_t EmulatedCamera::cancelAutoFocus() 482{ 483 // In this case we don't check if a preview is in progress or not. Unlike 484 // setAutoFocus this call will not silently fail without the check. If an 485 // auto-focus request is somehow pending without having preview enabled this 486 // will correctly cancel that pending auto-focus which seems reasonable. 487 EmulatedCameraDevice* const camera_dev = getCameraDevice(); 488 if (camera_dev && camera_dev->isStarted()) { 489 return camera_dev->cancelAutoFocus(); 490 } 491 return EINVAL; 492} 493 494status_t EmulatedCamera::takePicture() 495{ 496 ALOGV("%s", __FUNCTION__); 497 498 status_t res; 499 int width, height; 500 uint32_t org_fmt; 501 502 /* Collect frame info for the picture. */ 503 mParameters.getPictureSize(&width, &height); 504 const char* pix_fmt = mParameters.getPictureFormat(); 505 if (!GetFourCcFormatFromCameraParam(pix_fmt, &org_fmt)) { 506 // Also check for JPEG here, the function above does not do this since 507 // this is very specific to this use case. 508 if (strcmp(pix_fmt, CameraParameters::PIXEL_FORMAT_JPEG) == 0) { 509 /* We only have JPEG converted for NV21 format. */ 510 org_fmt = V4L2_PIX_FMT_NV21; 511 } else { 512 ALOGE("%s: Unsupported pixel format %s", __FUNCTION__, pix_fmt); 513 return EINVAL; 514 } 515 } 516 517 /* Get JPEG quality. */ 518 int jpeg_quality = mParameters.getInt(CameraParameters::KEY_JPEG_QUALITY); 519 if (jpeg_quality <= 0) { 520 jpeg_quality = 90; /* Fall back to default. */ 521 } 522 523 /* 524 * Make sure preview is not running, and device is stopped before taking 525 * picture. 526 */ 527 528 EmulatedCameraDevice* const camera_dev = getCameraDevice(); 529 mCallbackNotifier.setJpegQuality(jpeg_quality); 530 mCallbackNotifier.setCameraParameters(mParameters); 531 532 ALOGD("Starting camera for picture: %.4s(%s)[%dx%d]", 533 reinterpret_cast<const char*>(&org_fmt), pix_fmt, width, height); 534 if (mPreviewWindow.isPreviewEnabled()) { 535 mPreviewWindow.stopPreview(); 536 /* If the camera preview is enabled we need to perform an asynchronous 537 * restart. A blocking restart could deadlock this thread as it's 538 * currently holding the camera client lock and the frame delivery could 539 * be stuck on waiting for that lock. If this was synchronous then this 540 * thread would in turn get stuck on waiting for the delivery thread. */ 541 if (!camera_dev->requestRestart(width, height, org_fmt, 542 true /* takingPicture */, 543 true /* oneBurst */)) { 544 return UNKNOWN_ERROR; 545 } 546 return NO_ERROR; 547 } else { 548 ALOGE("%s: preview has not been enabled", __FUNCTION__); 549 return EINVAL; 550 } 551} 552 553status_t EmulatedCamera::cancelPicture() 554{ 555 ALOGV("%s", __FUNCTION__); 556 return NO_ERROR; 557} 558 559status_t EmulatedCamera::setParameters(const char* parms) 560{ 561 ALOGV("%s", __FUNCTION__); 562 PrintParamDiff(mParameters, parms); 563 564 CameraParameters new_param; 565 String8 str8_param(parms); 566 new_param.unflatten(str8_param); 567 bool restartPreview = false; 568 569 /* 570 * Check for new exposure compensation parameter. 571 */ 572 int new_exposure_compensation = new_param.getInt( 573 CameraParameters::KEY_EXPOSURE_COMPENSATION); 574 const int min_exposure_compensation = new_param.getInt( 575 CameraParameters::KEY_MIN_EXPOSURE_COMPENSATION); 576 const int max_exposure_compensation = new_param.getInt( 577 CameraParameters::KEY_MAX_EXPOSURE_COMPENSATION); 578 579 // Checks if the exposure compensation change is supported. 580 if ((min_exposure_compensation != 0) || (max_exposure_compensation != 0)) { 581 if (new_exposure_compensation > max_exposure_compensation) { 582 new_exposure_compensation = max_exposure_compensation; 583 } 584 if (new_exposure_compensation < min_exposure_compensation) { 585 new_exposure_compensation = min_exposure_compensation; 586 } 587 588 const int current_exposure_compensation = mParameters.getInt( 589 CameraParameters::KEY_EXPOSURE_COMPENSATION); 590 if (current_exposure_compensation != new_exposure_compensation) { 591 const float exposure_value = new_exposure_compensation * 592 new_param.getFloat( 593 CameraParameters::KEY_EXPOSURE_COMPENSATION_STEP); 594 595 getCameraDevice()->setExposureCompensation( 596 exposure_value); 597 } 598 } 599 600 const char* new_white_balance = new_param.get( 601 CameraParameters::KEY_WHITE_BALANCE); 602 const char* supported_white_balance = new_param.get( 603 CameraParameters::KEY_SUPPORTED_WHITE_BALANCE); 604 605 if ((supported_white_balance != NULL) && (new_white_balance != NULL) && 606 (strstr(supported_white_balance, new_white_balance) != NULL)) { 607 608 const char* current_white_balance = mParameters.get( 609 CameraParameters::KEY_WHITE_BALANCE); 610 if ((current_white_balance == NULL) || 611 (strcmp(current_white_balance, new_white_balance) != 0)) { 612 ALOGV("Setting white balance to %s", new_white_balance); 613 getCameraDevice()->setWhiteBalanceMode(new_white_balance); 614 } 615 } 616 int old_frame_rate = mParameters.getPreviewFrameRate(); 617 int new_frame_rate = new_param.getPreviewFrameRate(); 618 if (old_frame_rate != new_frame_rate) { 619 getCameraDevice()->setPreviewFrameRate(new_frame_rate); 620 } 621 622 // Validate focus mode 623 const char* focus_mode = new_param.get(CameraParameters::KEY_FOCUS_MODE); 624 if (focus_mode && !IsValueInList(focus_mode, kValidFocusModes)) { 625 return BAD_VALUE; 626 } 627 628 // Validate preview size, if there is no preview size the initial values of 629 // the integers below will be preserved thus intentionally failing the test 630 int new_preview_width = -1, new_preview_height = -1; 631 new_param.getPreviewSize(&new_preview_width, &new_preview_height); 632 if (new_preview_width < 0 || new_preview_height < 0) { 633 return BAD_VALUE; 634 } 635 // If the preview size has changed we have to restart the preview to make 636 // sure we provide frames of the correct size. The receiver assumes the 637 // frame size is correct and will copy all data provided into a buffer whose 638 // size is determined by the preview size without checks, potentially 639 // causing buffer overruns or underruns if there is a size mismatch. 640 int old_preview_width = -1, old_preview_height = -1; 641 mParameters.getPreviewSize(&old_preview_width, &old_preview_height); 642 if (old_preview_width != new_preview_width || 643 old_preview_height != new_preview_height) { 644 restartPreview = true; 645 } 646 647 // For the same reasons as with the preview size we have to look for changes 648 // in video size and restart the preview if the size has changed. 649 int old_video_width = -1, old_video_height = -1; 650 int new_video_width = -1, new_video_height = -1; 651 mParameters.getVideoSize(&old_video_width, &old_video_height); 652 new_param.getVideoSize(&new_video_width, &new_video_height); 653 if (old_video_width != new_video_width || 654 old_video_height != new_video_height) { 655 restartPreview = true; 656 } 657 // Restart the preview if the pixel format changes to make sure we serve 658 // the selected encoding to the client. 659 const char* old_format = mParameters.getPreviewFormat(); 660 const char* new_format = new_param.getPreviewFormat(); 661 if (!StringsEqual(old_format, new_format)) { 662 restartPreview = true; 663 } 664 665 const char* old_hint = 666 mParameters.get(CameraParameters::KEY_RECORDING_HINT); 667 const char* new_hint = new_param.get(CameraParameters::KEY_RECORDING_HINT); 668 if (!StringsEqual(old_hint, new_hint)) { 669 // The recording hint changed, this indicates we transitioned from 670 // recording to non-recording or the other way around. We need to look 671 // at a new pixel format for this and that requires a restart. 672 restartPreview = true; 673 } 674 675 mParameters = new_param; 676 677 // Now that the parameters have been assigned check if the preview needs to 678 // be restarted. If necessary this will then use the new parameters to set 679 // up the preview as requested by the caller. 680 if (restartPreview && isPreviewEnabled()) { 681 status_t status = doStopPreview(); 682 if (status != NO_ERROR) { 683 ALOGE("%s: Stopping preview failed: %d", __FUNCTION__, status); 684 return status; 685 } 686 status = doStartPreview(); 687 if (status != NO_ERROR) { 688 ALOGE("%s: Starting preview failed: %d", __FUNCTION__, status); 689 return status; 690 } 691 } 692 return NO_ERROR; 693} 694 695/* A dumb variable indicating "no params" / error on the exit from 696 * EmulatedCamera::getParameters(). */ 697static char lNoParam = '\0'; 698char* EmulatedCamera::getParameters() 699{ 700 // Read the image size and set the camera's Field of View. 701 // These values are valid for a Logitech B910 HD Webcam. 702 int width=0, height=0; 703 mParameters.getPictureSize(&width, &height); 704 if (height > 0) { 705 if (((double)width / height) < 1.55) { 706 // Closer to 4:3 (1.33), set the FOV to 61.0 degrees 707 mParameters.set(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, "61.0"); 708 } else { 709 // Closer to 16:9 (1.77), set the FOV to 70.0 degrees 710 mParameters.set(CameraParameters::KEY_HORIZONTAL_VIEW_ANGLE, "70.0"); 711 } 712 } 713 714 String8 params(mParameters.flatten()); 715 char* ret_str = 716 reinterpret_cast<char*>(malloc(sizeof(char) * (params.length()+1))); 717 memset(ret_str, 0, params.length()+1); 718 if (ret_str != NULL) { 719 strncpy(ret_str, params.string(), params.length()+1); 720 return ret_str; 721 } else { 722 ALOGE("%s: Unable to allocate string for %s", __FUNCTION__, params.string()); 723 /* Apparently, we can't return NULL fron this routine. */ 724 return &lNoParam; 725 } 726} 727 728void EmulatedCamera::putParameters(char* params) 729{ 730 /* This method simply frees parameters allocated in getParameters(). */ 731 if (params != NULL && params != &lNoParam) { 732 free(params); 733 } 734} 735 736status_t EmulatedCamera::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) 737{ 738 ALOGV("%s: cmd = %d, arg1 = %d, arg2 = %d", __FUNCTION__, cmd, arg1, arg2); 739 740 switch (cmd) { 741 case CAMERA_CMD_START_FACE_DETECTION: 742 case CAMERA_CMD_STOP_FACE_DETECTION: 743 // We do not support hardware face detection so we need to indicate 744 // that any attempt to start/stop face detection is invalid 745 return BAD_VALUE; 746 } 747 /* TODO: Future enhancements. */ 748 return 0; 749} 750 751void EmulatedCamera::releaseCamera() 752{ 753 ALOGV("%s", __FUNCTION__); 754 755 cleanupCamera(); 756} 757 758status_t EmulatedCamera::dumpCamera(int fd) 759{ 760 ALOGV("%s", __FUNCTION__); 761 762 /* TODO: Future enhancements. */ 763 dprintf(fd, "dump camera unimplemented\n"); 764 return 0; 765} 766 767status_t EmulatedCamera::getConfiguredPixelFormat(uint32_t* pixelFormat) const { 768 const char* pix_fmt = nullptr; 769 const char* recordingHint = 770 mParameters.get(CameraParameters::KEY_RECORDING_HINT); 771 bool recordingHintOn = recordingHint && strcmp(recordingHint, 772 CameraParameters::TRUE) == 0; 773 bool recordingEnabled = mCallbackNotifier.isVideoRecordingEnabled(); 774 if (recordingHintOn || recordingEnabled) { 775 // We're recording a video, use the video pixel format 776 pix_fmt = mParameters.get(CameraParameters::KEY_VIDEO_FRAME_FORMAT); 777 } 778 if (pix_fmt == nullptr) { 779 pix_fmt = mParameters.getPreviewFormat(); 780 } 781 if (pix_fmt == nullptr) { 782 ALOGE("%s: Unable to obtain configured pixel format", __FUNCTION__); 783 return EINVAL; 784 } 785 /* Convert framework's pixel format to the FOURCC one. */ 786 if (!GetFourCcFormatFromCameraParam(pix_fmt, pixelFormat)) { 787 ALOGE("%s: Unsupported pixel format %s", __FUNCTION__, pix_fmt); 788 return EINVAL; 789 } 790 return NO_ERROR; 791} 792 793status_t EmulatedCamera::getConfiguredFrameSize(int* outWidth, 794 int* outHeight) const { 795 int width = -1, height = -1; 796 if (mParameters.get(CameraParameters::KEY_VIDEO_SIZE) != nullptr) { 797 mParameters.getVideoSize(&width, &height); 798 } else { 799 mParameters.getPreviewSize(&width, &height); 800 } 801 if (width < 0 || height < 0) { 802 ALOGE("%s: No frame size configured for camera", __FUNCTION__); 803 return EINVAL; 804 } 805 // Only modify the out parameters once we know we succeeded 806 *outWidth = width; 807 *outHeight = height; 808 return NO_ERROR; 809} 810 811/**************************************************************************** 812 * Preview management. 813 ***************************************************************************/ 814 815status_t EmulatedCamera::doStartPreview() 816{ 817 ALOGV("%s", __FUNCTION__); 818 819 EmulatedCameraDevice* camera_dev = getCameraDevice(); 820 if (camera_dev->isStarted()) { 821 camera_dev->stopDeliveringFrames(); 822 camera_dev->stopDevice(); 823 } 824 825 status_t res = mPreviewWindow.startPreview(); 826 if (res != NO_ERROR) { 827 return res; 828 } 829 830 /* Make sure camera device is connected. */ 831 if (!camera_dev->isConnected()) { 832 res = camera_dev->connectDevice(); 833 if (res != NO_ERROR) { 834 mPreviewWindow.stopPreview(); 835 return res; 836 } 837 } 838 839 /* Lets see what should we use for frame width, and height. */ 840 int width, height; 841 res = getConfiguredFrameSize(&width, &height); 842 if (res != NO_ERROR) { 843 mPreviewWindow.stopPreview(); 844 return res; 845 } 846 847 uint32_t org_fmt = 0; 848 res = getConfiguredPixelFormat(&org_fmt); 849 if (res != NO_ERROR) { 850 mPreviewWindow.stopPreview(); 851 return res; 852 } 853 854 camera_dev->setPreviewFrameRate(mParameters.getPreviewFrameRate()); 855 ALOGD("Starting camera: %dx%d -> %.4s", 856 width, height, reinterpret_cast<const char*>(&org_fmt)); 857 res = camera_dev->startDevice(width, height, org_fmt); 858 if (res != NO_ERROR) { 859 mPreviewWindow.stopPreview(); 860 return res; 861 } 862 863 res = camera_dev->startDeliveringFrames(false); 864 if (res != NO_ERROR) { 865 camera_dev->stopDevice(); 866 mPreviewWindow.stopPreview(); 867 } 868 869 return res; 870} 871 872status_t EmulatedCamera::doStopPreview() 873{ 874 ALOGV("%s", __FUNCTION__); 875 876 status_t res = NO_ERROR; 877 if (mPreviewWindow.isPreviewEnabled()) { 878 /* Stop the camera. */ 879 if (getCameraDevice()->isStarted()) { 880 getCameraDevice()->stopDeliveringFrames(); 881 res = getCameraDevice()->stopDevice(); 882 } 883 884 if (res == NO_ERROR) { 885 /* Disable preview as well. */ 886 mPreviewWindow.stopPreview(); 887 } 888 } 889 890 return NO_ERROR; 891} 892 893/**************************************************************************** 894 * Private API. 895 ***************************************************************************/ 896 897status_t EmulatedCamera::cleanupCamera() 898{ 899 status_t res = NO_ERROR; 900 901 /* If preview is running - stop it. */ 902 res = doStopPreview(); 903 if (res != NO_ERROR) { 904 return -res; 905 } 906 907 /* Stop and disconnect the camera device. */ 908 EmulatedCameraDevice* const camera_dev = getCameraDevice(); 909 if (camera_dev != NULL) { 910 if (camera_dev->isStarted()) { 911 camera_dev->stopDeliveringFrames(); 912 res = camera_dev->stopDevice(); 913 if (res != NO_ERROR) { 914 return -res; 915 } 916 } 917 if (camera_dev->isConnected()) { 918 res = camera_dev->disconnectDevice(); 919 if (res != NO_ERROR) { 920 return -res; 921 } 922 } 923 } 924 925 mCallbackNotifier.cleanupCBNotifier(); 926 927 /* Re-init the camera settings in case settings were changed */ 928 Initialize(); 929 930 return NO_ERROR; 931} 932 933/**************************************************************************** 934 * Camera API callbacks as defined by camera_device_ops structure. 935 * 936 * Callbacks here simply dispatch the calls to an appropriate method inside 937 * EmulatedCamera instance, defined by the 'dev' parameter. 938 ***************************************************************************/ 939 940int EmulatedCamera::set_preview_window(struct camera_device* dev, 941 struct preview_stream_ops* window) 942{ 943 EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv); 944 if (ec == NULL) { 945 ALOGE("%s: Unexpected NULL camera device", __FUNCTION__); 946 return -EINVAL; 947 } 948 return ec->setPreviewWindow(window); 949} 950 951void EmulatedCamera::set_callbacks( 952 struct camera_device* dev, 953 camera_notify_callback notify_cb, 954 camera_data_callback data_cb, 955 camera_data_timestamp_callback data_cb_timestamp, 956 camera_request_memory get_memory, 957 void* user) 958{ 959 EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv); 960 if (ec == NULL) { 961 ALOGE("%s: Unexpected NULL camera device", __FUNCTION__); 962 return; 963 } 964 ec->setCallbacks(notify_cb, data_cb, data_cb_timestamp, get_memory, user); 965} 966 967void EmulatedCamera::enable_msg_type(struct camera_device* dev, int32_t msg_type) 968{ 969 EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv); 970 if (ec == NULL) { 971 ALOGE("%s: Unexpected NULL camera device", __FUNCTION__); 972 return; 973 } 974 ec->enableMsgType(msg_type); 975} 976 977void EmulatedCamera::disable_msg_type(struct camera_device* dev, int32_t msg_type) 978{ 979 EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv); 980 if (ec == NULL) { 981 ALOGE("%s: Unexpected NULL camera device", __FUNCTION__); 982 return; 983 } 984 ec->disableMsgType(msg_type); 985} 986 987int EmulatedCamera::msg_type_enabled(struct camera_device* dev, int32_t msg_type) 988{ 989 EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv); 990 if (ec == NULL) { 991 ALOGE("%s: Unexpected NULL camera device", __FUNCTION__); 992 return -EINVAL; 993 } 994 return ec->isMsgTypeEnabled(msg_type); 995} 996 997int EmulatedCamera::start_preview(struct camera_device* dev) 998{ 999 EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv); 1000 if (ec == NULL) { 1001 ALOGE("%s: Unexpected NULL camera device", __FUNCTION__); 1002 return -EINVAL; 1003 } 1004 return ec->startPreview(); 1005} 1006 1007void EmulatedCamera::stop_preview(struct camera_device* dev) 1008{ 1009 EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv); 1010 if (ec == NULL) { 1011 ALOGE("%s: Unexpected NULL camera device", __FUNCTION__); 1012 return; 1013 } 1014 ec->stopPreview(); 1015} 1016 1017int EmulatedCamera::preview_enabled(struct camera_device* dev) 1018{ 1019 EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv); 1020 if (ec == NULL) { 1021 ALOGE("%s: Unexpected NULL camera device", __FUNCTION__); 1022 return -EINVAL; 1023 } 1024 return ec->isPreviewEnabled(); 1025} 1026 1027int EmulatedCamera::store_meta_data_in_buffers(struct camera_device* dev, 1028 int enable) 1029{ 1030 EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv); 1031 if (ec == NULL) { 1032 ALOGE("%s: Unexpected NULL camera device", __FUNCTION__); 1033 return -EINVAL; 1034 } 1035 return ec->storeMetaDataInBuffers(enable); 1036} 1037 1038int EmulatedCamera::start_recording(struct camera_device* dev) 1039{ 1040 EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv); 1041 if (ec == NULL) { 1042 ALOGE("%s: Unexpected NULL camera device", __FUNCTION__); 1043 return -EINVAL; 1044 } 1045 return ec->startRecording(); 1046} 1047 1048void EmulatedCamera::stop_recording(struct camera_device* dev) 1049{ 1050 EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv); 1051 if (ec == NULL) { 1052 ALOGE("%s: Unexpected NULL camera device", __FUNCTION__); 1053 return; 1054 } 1055 ec->stopRecording(); 1056} 1057 1058int EmulatedCamera::recording_enabled(struct camera_device* dev) 1059{ 1060 EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv); 1061 if (ec == NULL) { 1062 ALOGE("%s: Unexpected NULL camera device", __FUNCTION__); 1063 return -EINVAL; 1064 } 1065 return ec->isRecordingEnabled(); 1066} 1067 1068void EmulatedCamera::release_recording_frame(struct camera_device* dev, 1069 const void* opaque) 1070{ 1071 EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv); 1072 if (ec == NULL) { 1073 ALOGE("%s: Unexpected NULL camera device", __FUNCTION__); 1074 return; 1075 } 1076 ec->releaseRecordingFrame(opaque); 1077} 1078 1079int EmulatedCamera::auto_focus(struct camera_device* dev) 1080{ 1081 EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv); 1082 if (ec == NULL) { 1083 ALOGE("%s: Unexpected NULL camera device", __FUNCTION__); 1084 return -EINVAL; 1085 } 1086 return ec->setAutoFocus(); 1087} 1088 1089int EmulatedCamera::cancel_auto_focus(struct camera_device* dev) 1090{ 1091 EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv); 1092 if (ec == NULL) { 1093 ALOGE("%s: Unexpected NULL camera device", __FUNCTION__); 1094 return -EINVAL; 1095 } 1096 return ec->cancelAutoFocus(); 1097} 1098 1099int EmulatedCamera::take_picture(struct camera_device* dev) 1100{ 1101 EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv); 1102 if (ec == NULL) { 1103 ALOGE("%s: Unexpected NULL camera device", __FUNCTION__); 1104 return -EINVAL; 1105 } 1106 return ec->takePicture(); 1107} 1108 1109int EmulatedCamera::cancel_picture(struct camera_device* dev) 1110{ 1111 EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv); 1112 if (ec == NULL) { 1113 ALOGE("%s: Unexpected NULL camera device", __FUNCTION__); 1114 return -EINVAL; 1115 } 1116 return ec->cancelPicture(); 1117} 1118 1119int EmulatedCamera::set_parameters(struct camera_device* dev, const char* parms) 1120{ 1121 EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv); 1122 if (ec == NULL) { 1123 ALOGE("%s: Unexpected NULL camera device", __FUNCTION__); 1124 return -EINVAL; 1125 } 1126 return ec->setParameters(parms); 1127} 1128 1129char* EmulatedCamera::get_parameters(struct camera_device* dev) 1130{ 1131 EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv); 1132 if (ec == NULL) { 1133 ALOGE("%s: Unexpected NULL camera device", __FUNCTION__); 1134 return NULL; 1135 } 1136 return ec->getParameters(); 1137} 1138 1139void EmulatedCamera::put_parameters(struct camera_device* dev, char* params) 1140{ 1141 EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv); 1142 if (ec == NULL) { 1143 ALOGE("%s: Unexpected NULL camera device", __FUNCTION__); 1144 return; 1145 } 1146 ec->putParameters(params); 1147} 1148 1149int EmulatedCamera::send_command(struct camera_device* dev, 1150 int32_t cmd, 1151 int32_t arg1, 1152 int32_t arg2) 1153{ 1154 EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv); 1155 if (ec == NULL) { 1156 ALOGE("%s: Unexpected NULL camera device", __FUNCTION__); 1157 return -EINVAL; 1158 } 1159 return ec->sendCommand(cmd, arg1, arg2); 1160} 1161 1162void EmulatedCamera::release(struct camera_device* dev) 1163{ 1164 EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv); 1165 if (ec == NULL) { 1166 ALOGE("%s: Unexpected NULL camera device", __FUNCTION__); 1167 return; 1168 } 1169 ec->releaseCamera(); 1170} 1171 1172int EmulatedCamera::dump(struct camera_device* dev, int fd) 1173{ 1174 EmulatedCamera* ec = reinterpret_cast<EmulatedCamera*>(dev->priv); 1175 if (ec == NULL) { 1176 ALOGE("%s: Unexpected NULL camera device", __FUNCTION__); 1177 return -EINVAL; 1178 } 1179 return ec->dumpCamera(fd); 1180} 1181 1182int EmulatedCamera::close(struct hw_device_t* device) 1183{ 1184 EmulatedCamera* ec = 1185 reinterpret_cast<EmulatedCamera*>(reinterpret_cast<struct camera_device*>(device)->priv); 1186 if (ec == NULL) { 1187 ALOGE("%s: Unexpected NULL camera device", __FUNCTION__); 1188 return -EINVAL; 1189 } 1190 return ec->closeCamera(); 1191} 1192 1193/**************************************************************************** 1194 * Static initializer for the camera callback API 1195 ****************************************************************************/ 1196 1197camera_device_ops_t EmulatedCamera::mDeviceOps = { 1198 EmulatedCamera::set_preview_window, 1199 EmulatedCamera::set_callbacks, 1200 EmulatedCamera::enable_msg_type, 1201 EmulatedCamera::disable_msg_type, 1202 EmulatedCamera::msg_type_enabled, 1203 EmulatedCamera::start_preview, 1204 EmulatedCamera::stop_preview, 1205 EmulatedCamera::preview_enabled, 1206 EmulatedCamera::store_meta_data_in_buffers, 1207 EmulatedCamera::start_recording, 1208 EmulatedCamera::stop_recording, 1209 EmulatedCamera::recording_enabled, 1210 EmulatedCamera::release_recording_frame, 1211 EmulatedCamera::auto_focus, 1212 EmulatedCamera::cancel_auto_focus, 1213 EmulatedCamera::take_picture, 1214 EmulatedCamera::cancel_picture, 1215 EmulatedCamera::set_parameters, 1216 EmulatedCamera::get_parameters, 1217 EmulatedCamera::put_parameters, 1218 EmulatedCamera::send_command, 1219 EmulatedCamera::release, 1220 EmulatedCamera::dump 1221}; 1222 1223/**************************************************************************** 1224 * Common keys 1225 ***************************************************************************/ 1226 1227const char EmulatedCamera::FACING_KEY[] = "prop-facing"; 1228const char EmulatedCamera::ORIENTATION_KEY[] = "prop-orientation"; 1229const char EmulatedCamera::RECORDING_HINT_KEY[] = "recording-hint"; 1230 1231/**************************************************************************** 1232 * Common string values 1233 ***************************************************************************/ 1234 1235const char EmulatedCamera::FACING_BACK[] = "back"; 1236const char EmulatedCamera::FACING_FRONT[] = "front"; 1237 1238/**************************************************************************** 1239 * Helper routines 1240 ***************************************************************************/ 1241 1242static char* AddValue(const char* param, const char* val) 1243{ 1244 const size_t len1 = strlen(param); 1245 const size_t len2 = strlen(val); 1246 char* ret = reinterpret_cast<char*>(malloc(len1 + len2 + 2)); 1247 ALOGE_IF(ret == NULL, "%s: Memory failure", __FUNCTION__); 1248 if (ret != NULL) { 1249 memcpy(ret, param, len1); 1250 ret[len1] = ','; 1251 memcpy(ret + len1 + 1, val, len2); 1252 ret[len1 + len2 + 1] = '\0'; 1253 } 1254 return ret; 1255} 1256 1257/**************************************************************************** 1258 * Parameter debugging helpers 1259 ***************************************************************************/ 1260 1261#if DEBUG_PARAM 1262static void PrintParamDiff(const CameraParameters& current, 1263 const char* new_par) 1264{ 1265 char tmp[2048]; 1266 const char* wrk = new_par; 1267 1268 /* Divided with ';' */ 1269 const char* next = strchr(wrk, ';'); 1270 while (next != NULL) { 1271 snprintf(tmp, sizeof(tmp), "%.*s", (int)(intptr_t)(next-wrk), wrk); 1272 /* in the form key=value */ 1273 char* val = strchr(tmp, '='); 1274 if (val != NULL) { 1275 *val = '\0'; val++; 1276 const char* in_current = current.get(tmp); 1277 if (in_current != NULL) { 1278 if (strcmp(in_current, val)) { 1279 ALOGD("=== Value changed: %s: %s -> %s", tmp, in_current, val); 1280 } 1281 } else { 1282 ALOGD("+++ New parameter: %s=%s", tmp, val); 1283 } 1284 } else { 1285 ALOGW("No value separator in %s", tmp); 1286 } 1287 wrk = next + 1; 1288 next = strchr(wrk, ';'); 1289 } 1290} 1291#endif /* DEBUG_PARAM */ 1292 1293}; /* namespace android */ 1294