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