• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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