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