summaryrefslogtreecommitdiffstats
path: root/modules/camera
diff options
context:
space:
mode:
authorAlex Ray <aray@google.com>2013-07-03 17:54:19 -0700
committerAlex Ray <aray@google.com>2013-10-17 16:50:48 -0700
commit61f7a0c1c1aa481d798116e5a218df04630886e6 (patch)
treef402943f42231adf3ed56edb22947ea6a8f08d5f /modules/camera
parentf75ccb96b103c70199fe84d2b9ff0a9d027e326e (diff)
downloadhardware_libhardware-61f7a0c1c1aa481d798116e5a218df04630886e6.zip
hardware_libhardware-61f7a0c1c1aa481d798116e5a218df04630886e6.tar.gz
hardware_libhardware-61f7a0c1c1aa481d798116e5a218df04630886e6.tar.bz2
modules: camera: Abstract device-specific camera
ExampleCamera represents a specific (e.g. front or back) camera device, and contains all the device and logic for that device/sensor. Change-Id: Iecc1a1d905501a66edb6e3994ff93d8761b82f8b
Diffstat (limited to 'modules/camera')
-rw-r--r--modules/camera/Android.mk1
-rw-r--r--modules/camera/Camera.cpp205
-rw-r--r--modules/camera/Camera.h26
-rw-r--r--modules/camera/CameraHAL.cpp15
-rw-r--r--modules/camera/ExampleCamera.cpp208
-rw-r--r--modules/camera/ExampleCamera.h43
6 files changed, 310 insertions, 188 deletions
diff --git a/modules/camera/Android.mk b/modules/camera/Android.mk
index ba6852f..31062ea 100644
--- a/modules/camera/Android.mk
+++ b/modules/camera/Android.mk
@@ -26,6 +26,7 @@ LOCAL_C_INCLUDES += \
LOCAL_SRC_FILES := \
CameraHAL.cpp \
Camera.cpp \
+ ExampleCamera.cpp \
Metadata.cpp \
Stream.cpp \
diff --git a/modules/camera/Camera.cpp b/modules/camera/Camera.cpp
index 764bb8f..4e9c18d 100644
--- a/modules/camera/Camera.cpp
+++ b/modules/camera/Camera.cpp
@@ -35,8 +35,6 @@
#define CAMERA_SYNC_TIMEOUT 5000 // in msecs
-#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
-
namespace default_camera_hal {
extern "C" {
@@ -61,6 +59,7 @@ Camera::Camera(int id)
pthread_mutex_init(&mMutex, NULL);
pthread_mutex_init(&mStaticInfoMutex, NULL);
+ memset(&mTemplates, 0, sizeof(mTemplates));
memset(&mDevice, 0, sizeof(mDevice));
mDevice.common.tag = HARDWARE_DEVICE_TAG;
mDevice.common.version = CAMERA_DEVICE_API_VERSION_3_0;
@@ -73,6 +72,9 @@ Camera::~Camera()
{
pthread_mutex_destroy(&mMutex);
pthread_mutex_destroy(&mStaticInfoMutex);
+ if (mStaticInfo != NULL) {
+ free_camera_metadata(mStaticInfo);
+ }
}
int Camera::open(const hw_module_t *module, hw_device_t **device)
@@ -132,173 +134,19 @@ int Camera::close()
int Camera::initialize(const camera3_callback_ops_t *callback_ops)
{
+ int res;
+
ALOGV("%s:%d: callback_ops=%p", __func__, mId, callback_ops);
mCallbackOps = callback_ops;
- // Create standard settings templates
- // 0 is invalid as template
- mTemplates[0] = NULL;
- // CAMERA3_TEMPLATE_PREVIEW = 1
- mTemplates[1] = new Metadata(ANDROID_CONTROL_MODE_OFF,
- ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW);
- // CAMERA3_TEMPLATE_STILL_CAPTURE = 2
- mTemplates[2] = new Metadata(ANDROID_CONTROL_MODE_OFF,
- ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE);
- // CAMERA3_TEMPLATE_VIDEO_RECORD = 3
- mTemplates[3] = new Metadata(ANDROID_CONTROL_MODE_OFF,
- ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD);
- // CAMERA3_TEMPLATE_VIDEO_SNAPSHOT = 4
- mTemplates[4] = new Metadata(ANDROID_CONTROL_MODE_OFF,
- ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT);
- // CAMERA3_TEMPLATE_STILL_ZERO_SHUTTER_LAG = 5
- mTemplates[5] = new Metadata(ANDROID_CONTROL_MODE_OFF,
- ANDROID_CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG);
- // Pre-generate metadata structures
- for (int i = 1; i < CAMERA3_TEMPLATE_COUNT; i++) {
- mTemplates[i]->generate();
+ // per-device specific initialization
+ res = initDevice();
+ if (res != 0) {
+ ALOGE("%s:%d: Failed to initialize device!", __func__, mId);
+ return res;
}
- // TODO: create vendor templates
return 0;
}
-camera_metadata_t *Camera::initStaticInfo()
-{
- /*
- * Setup static camera info. This will have to customized per camera
- * device.
- */
- Metadata m;
-
- /* android.control */
- int32_t android_control_ae_available_target_fps_ranges[] = {30, 30};
- m.addInt32(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
- ARRAY_SIZE(android_control_ae_available_target_fps_ranges),
- android_control_ae_available_target_fps_ranges);
-
- int32_t android_control_ae_compensation_range[] = {-4, 4};
- m.addInt32(ANDROID_CONTROL_AE_COMPENSATION_RANGE,
- ARRAY_SIZE(android_control_ae_compensation_range),
- android_control_ae_compensation_range);
-
- camera_metadata_rational_t android_control_ae_compensation_step[] = {{2,1}};
- m.addRational(ANDROID_CONTROL_AE_COMPENSATION_STEP,
- ARRAY_SIZE(android_control_ae_compensation_step),
- android_control_ae_compensation_step);
-
- int32_t android_control_max_regions[] = {1};
- m.addInt32(ANDROID_CONTROL_MAX_REGIONS,
- ARRAY_SIZE(android_control_max_regions),
- android_control_max_regions);
-
- /* android.jpeg */
- int32_t android_jpeg_available_thumbnail_sizes[] = {0, 0, 128, 96};
- m.addInt32(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
- ARRAY_SIZE(android_jpeg_available_thumbnail_sizes),
- android_jpeg_available_thumbnail_sizes);
-
- int32_t android_jpeg_max_size[] = {13 * 1024 * 1024}; // 13MB
- m.addInt32(ANDROID_JPEG_MAX_SIZE,
- ARRAY_SIZE(android_jpeg_max_size),
- android_jpeg_max_size);
-
- /* android.lens */
- float android_lens_info_available_focal_lengths[] = {1.0};
- m.addFloat(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
- ARRAY_SIZE(android_lens_info_available_focal_lengths),
- android_lens_info_available_focal_lengths);
-
- /* android.request */
- int32_t android_request_max_num_output_streams[] = {0, 3, 1};
- m.addInt32(ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS,
- ARRAY_SIZE(android_request_max_num_output_streams),
- android_request_max_num_output_streams);
-
- /* android.scaler */
- int32_t android_scaler_available_formats[] = {
- HAL_PIXEL_FORMAT_RAW_SENSOR,
- HAL_PIXEL_FORMAT_BLOB,
- HAL_PIXEL_FORMAT_RGBA_8888,
- HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
- // These are handled by YCbCr_420_888
- // HAL_PIXEL_FORMAT_YV12,
- // HAL_PIXEL_FORMAT_YCrCb_420_SP,
- HAL_PIXEL_FORMAT_YCbCr_420_888};
- m.addInt32(ANDROID_SCALER_AVAILABLE_FORMATS,
- ARRAY_SIZE(android_scaler_available_formats),
- android_scaler_available_formats);
-
- int64_t android_scaler_available_jpeg_min_durations[] = {1};
- m.addInt64(ANDROID_SCALER_AVAILABLE_JPEG_MIN_DURATIONS,
- ARRAY_SIZE(android_scaler_available_jpeg_min_durations),
- android_scaler_available_jpeg_min_durations);
-
- int32_t android_scaler_available_jpeg_sizes[] = {640, 480};
- m.addInt32(ANDROID_SCALER_AVAILABLE_JPEG_SIZES,
- ARRAY_SIZE(android_scaler_available_jpeg_sizes),
- android_scaler_available_jpeg_sizes);
-
- float android_scaler_available_max_digital_zoom[] = {1};
- m.addFloat(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
- ARRAY_SIZE(android_scaler_available_max_digital_zoom),
- android_scaler_available_max_digital_zoom);
-
- int64_t android_scaler_available_processed_min_durations[] = {1};
- m.addInt64(ANDROID_SCALER_AVAILABLE_PROCESSED_MIN_DURATIONS,
- ARRAY_SIZE(android_scaler_available_processed_min_durations),
- android_scaler_available_processed_min_durations);
-
- int32_t android_scaler_available_processed_sizes[] = {640, 480};
- m.addInt32(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES,
- ARRAY_SIZE(android_scaler_available_processed_sizes),
- android_scaler_available_processed_sizes);
-
- int64_t android_scaler_available_raw_min_durations[] = {1};
- m.addInt64(ANDROID_SCALER_AVAILABLE_RAW_MIN_DURATIONS,
- ARRAY_SIZE(android_scaler_available_raw_min_durations),
- android_scaler_available_raw_min_durations);
-
- int32_t android_scaler_available_raw_sizes[] = {640, 480};
- m.addInt32(ANDROID_SCALER_AVAILABLE_RAW_SIZES,
- ARRAY_SIZE(android_scaler_available_raw_sizes),
- android_scaler_available_raw_sizes);
-
- /* android.sensor */
-
- int32_t android_sensor_info_active_array_size[] = {0, 0, 640, 480};
- m.addInt32(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
- ARRAY_SIZE(android_sensor_info_active_array_size),
- android_sensor_info_active_array_size);
-
- int32_t android_sensor_info_sensitivity_range[] =
- {100, 1600};
- m.addInt32(ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
- ARRAY_SIZE(android_sensor_info_sensitivity_range),
- android_sensor_info_sensitivity_range);
-
- int64_t android_sensor_info_max_frame_duration[] = {30000000000};
- m.addInt64(ANDROID_SENSOR_INFO_MAX_FRAME_DURATION,
- ARRAY_SIZE(android_sensor_info_max_frame_duration),
- android_sensor_info_max_frame_duration);
-
- float android_sensor_info_physical_size[] = {3.2, 2.4};
- m.addFloat(ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
- ARRAY_SIZE(android_sensor_info_physical_size),
- android_sensor_info_physical_size);
-
- int32_t android_sensor_info_pixel_array_size[] = {640, 480};
- m.addInt32(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
- ARRAY_SIZE(android_sensor_info_pixel_array_size),
- android_sensor_info_pixel_array_size);
-
- int32_t android_sensor_orientation[] = {0};
- m.addInt32(ANDROID_SENSOR_ORIENTATION,
- ARRAY_SIZE(android_sensor_orientation),
- android_sensor_orientation);
-
- /* End of static camera characteristics */
-
- return clone_camera_metadata(m.generate());
-}
-
int Camera::configureStreams(camera3_stream_configuration_t *stream_config)
{
camera3_stream_t *astream;
@@ -473,15 +321,20 @@ int Camera::registerStreamBuffers(const camera3_stream_buffer_set_t *buf_set)
return stream->registerBuffers(buf_set);
}
+bool Camera::isValidTemplateType(int type)
+{
+ return type < 1 || type >= CAMERA3_TEMPLATE_COUNT;
+}
+
const camera_metadata_t* Camera::constructDefaultRequestSettings(int type)
{
ALOGV("%s:%d: type=%d", __func__, mId, type);
- if (type < 1 || type >= CAMERA3_TEMPLATE_COUNT) {
+ if (!isValidTemplateType(type)) {
ALOGE("%s:%d: Invalid template request type: %d", __func__, mId, type);
return NULL;
}
- return mTemplates[type]->generate();
+ return mTemplates[type];
}
int Camera::processCaptureRequest(camera3_capture_request_t *request)
@@ -569,12 +422,6 @@ void Camera::setSettings(const camera_metadata_t *new_settings)
mSettings = clone_camera_metadata(new_settings);
}
-bool Camera::isValidCaptureSettings(const camera_metadata_t* /*settings*/)
-{
- // TODO: reject settings that cannot be captured
- return true;
-}
-
bool Camera::isValidReprocessSettings(const camera_metadata_t* /*settings*/)
{
// TODO: reject settings that cannot be reprocessed
@@ -647,6 +494,22 @@ void Camera::dump(int fd)
// TODO: dprintf all relevant state to fd
}
+void Camera::setTemplate(int type, camera_metadata_t *settings)
+{
+ if (!isValidTemplateType(type)) {
+ ALOGE("%s:%d: Invalid template request type: %d", __func__, mId, type);
+ return;
+ }
+ pthread_mutex_lock(&mMutex);
+ if (mTemplates[type] != NULL) {
+ ALOGE("%s:%d: Setting already constructed template type %d: %p to %p!",
+ __func__, mId, type, mStaticInfo, settings);
+ free_camera_metadata(mTemplates[type]);
+ }
+ mTemplates[type] = clone_camera_metadata(settings);
+ pthread_mutex_unlock(&mMutex);
+}
+
extern "C" {
// Get handle to camera from device priv data
static Camera *camdev_to_camera(const camera3_device_t *dev)
diff --git a/modules/camera/Camera.h b/modules/camera/Camera.h
index be672f9..53672ae 100644
--- a/modules/camera/Camera.h
+++ b/modules/camera/Camera.h
@@ -28,12 +28,14 @@ namespace default_camera_hal {
// This is constructed when the HAL module is loaded, one per physical camera.
// It is opened by the framework, and must be closed before it can be opened
// again.
+// This is an abstract class, containing all logic and data shared between all
+// camera devices (front, back, etc) and common to the ISP.
class Camera {
public:
// id is used to distinguish cameras. 0 <= id < NUM_CAMERAS.
// module is a handle to the HAL module, used when the device is opened.
Camera(int id);
- ~Camera();
+ virtual ~Camera();
// Common Camera Device Operations (see <hardware/camera_common.h>)
int open(const hw_module_t *module, hw_device_t **device);
@@ -49,12 +51,20 @@ class Camera {
void getMetadataVendorTagOps(vendor_tag_query_ops_t *ops);
void dump(int fd);
- // Camera device handle returned to framework for use
- camera3_device_t mDevice;
+
+ protected:
+ // Initialize static camera characteristics for individual device
+ virtual camera_metadata_t *initStaticInfo() = 0;
+ // Verify settings are valid for a capture
+ virtual bool isValidCaptureSettings(const camera_metadata_t *) = 0;
+ // Separate initialization method for individual devices when opened
+ virtual int initDevice() = 0;
+ // Accessor used by initDevice()
+ void setTemplate(int type, camera_metadata_t *static_info);
private:
- // Separate initialization method for static metadata
- camera_metadata_t *initStaticInfo();
+ // Camera device handle returned to framework for use
+ camera3_device_t mDevice;
// Reuse a stream already created by this device
Stream *reuseStream(camera3_stream_t *astream);
// Destroy all streams in a stream array, and the array itself
@@ -65,8 +75,6 @@ class Camera {
void setupStreams(Stream **array, int count);
// Copy new settings for re-use and clean up old settings.
void setSettings(const camera_metadata_t *new_settings);
- // Verify settings are valid for a capture
- bool isValidCaptureSettings(const camera_metadata_t *settings);
// Verify settings are valid for reprocessing an input buffer
bool isValidReprocessSettings(const camera_metadata_t *settings);
// Process an output buffer
@@ -74,6 +82,8 @@ class Camera {
camera3_stream_buffer_t *out);
// Send a shutter notify message with start of exposure time
void notifyShutter(uint32_t frame_number, uint64_t timestamp);
+ // Is type a valid template type (and valid index into mTemplates)
+ bool isValidTemplateType(int type);
// Identifier used by framework to distinguish cameras
const int mId;
@@ -97,7 +107,7 @@ class Camera {
// Number of streams in mStreams
int mNumStreams;
// Static array of standard camera settings templates
- Metadata *mTemplates[CAMERA3_TEMPLATE_COUNT];
+ camera_metadata_t *mTemplates[CAMERA3_TEMPLATE_COUNT];
// Most recent request settings seen, memoized to be reused
camera_metadata_t *mSettings;
};
diff --git a/modules/camera/CameraHAL.cpp b/modules/camera/CameraHAL.cpp
index dfbbe4c..9a13c98 100644
--- a/modules/camera/CameraHAL.cpp
+++ b/modules/camera/CameraHAL.cpp
@@ -17,7 +17,7 @@
#include <cstdlib>
#include <hardware/camera_common.h>
#include <hardware/hardware.h>
-#include "Camera.h"
+#include "ExampleCamera.h"
//#define LOG_NDEBUG 0
#define LOG_TAG "DefaultCameraHAL"
@@ -43,20 +43,17 @@ CameraHAL::CameraHAL(int num_cameras)
: mNumberOfCameras(num_cameras),
mCallbacks(NULL)
{
- int i;
-
// Allocate camera array and instantiate camera devices
mCameras = new Camera*[mNumberOfCameras];
- for (i = 0; i < mNumberOfCameras; i++) {
- mCameras[i] = new Camera(i);
- }
+ // Rear camera
+ mCameras[0] = new ExampleCamera(0);
+ // Front camera
+ mCameras[1] = new ExampleCamera(1);
}
CameraHAL::~CameraHAL()
{
- int i;
-
- for (i = 0; i < mNumberOfCameras; i++) {
+ for (int i = 0; i < mNumberOfCameras; i++) {
delete mCameras[i];
}
delete [] mCameras;
diff --git a/modules/camera/ExampleCamera.cpp b/modules/camera/ExampleCamera.cpp
new file mode 100644
index 0000000..8cf2ef0
--- /dev/null
+++ b/modules/camera/ExampleCamera.cpp
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <system/camera_metadata.h>
+#include "Camera.h"
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "ExampleCamera"
+#include <cutils/log.h>
+
+#define ATRACE_TAG (ATRACE_TAG_CAMERA | ATRACE_TAG_HAL)
+#include <utils/Trace.h>
+
+#include "ExampleCamera.h"
+
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
+
+namespace default_camera_hal {
+
+ExampleCamera::ExampleCamera(int id) : Camera(id)
+{
+}
+
+ExampleCamera::~ExampleCamera()
+{
+}
+
+camera_metadata_t *ExampleCamera::initStaticInfo()
+{
+ /*
+ * Setup static camera info. This will have to customized per camera
+ * device.
+ */
+ Metadata m;
+
+ /* android.control */
+ int32_t android_control_ae_available_target_fps_ranges[] = {30, 30};
+ m.addInt32(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES,
+ ARRAY_SIZE(android_control_ae_available_target_fps_ranges),
+ android_control_ae_available_target_fps_ranges);
+
+ int32_t android_control_ae_compensation_range[] = {-4, 4};
+ m.addInt32(ANDROID_CONTROL_AE_COMPENSATION_RANGE,
+ ARRAY_SIZE(android_control_ae_compensation_range),
+ android_control_ae_compensation_range);
+
+ camera_metadata_rational_t android_control_ae_compensation_step[] = {{2,1}};
+ m.addRational(ANDROID_CONTROL_AE_COMPENSATION_STEP,
+ ARRAY_SIZE(android_control_ae_compensation_step),
+ android_control_ae_compensation_step);
+
+ int32_t android_control_max_regions[] = {1};
+ m.addInt32(ANDROID_CONTROL_MAX_REGIONS,
+ ARRAY_SIZE(android_control_max_regions),
+ android_control_max_regions);
+
+ /* android.jpeg */
+ int32_t android_jpeg_available_thumbnail_sizes[] = {0, 0, 128, 96};
+ m.addInt32(ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES,
+ ARRAY_SIZE(android_jpeg_available_thumbnail_sizes),
+ android_jpeg_available_thumbnail_sizes);
+
+ int32_t android_jpeg_max_size[] = {13 * 1024 * 1024}; // 13MB
+ m.addInt32(ANDROID_JPEG_MAX_SIZE,
+ ARRAY_SIZE(android_jpeg_max_size),
+ android_jpeg_max_size);
+
+ /* android.lens */
+ float android_lens_info_available_focal_lengths[] = {1.0};
+ m.addFloat(ANDROID_LENS_INFO_AVAILABLE_FOCAL_LENGTHS,
+ ARRAY_SIZE(android_lens_info_available_focal_lengths),
+ android_lens_info_available_focal_lengths);
+
+ /* android.request */
+ int32_t android_request_max_num_output_streams[] = {0, 3, 1};
+ m.addInt32(ANDROID_REQUEST_MAX_NUM_OUTPUT_STREAMS,
+ ARRAY_SIZE(android_request_max_num_output_streams),
+ android_request_max_num_output_streams);
+
+ /* android.scaler */
+ int32_t android_scaler_available_formats[] = {
+ HAL_PIXEL_FORMAT_RAW_SENSOR,
+ HAL_PIXEL_FORMAT_BLOB,
+ HAL_PIXEL_FORMAT_RGBA_8888,
+ HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED,
+ // These are handled by YCbCr_420_888
+ // HAL_PIXEL_FORMAT_YV12,
+ // HAL_PIXEL_FORMAT_YCrCb_420_SP,
+ HAL_PIXEL_FORMAT_YCbCr_420_888};
+ m.addInt32(ANDROID_SCALER_AVAILABLE_FORMATS,
+ ARRAY_SIZE(android_scaler_available_formats),
+ android_scaler_available_formats);
+
+ int64_t android_scaler_available_jpeg_min_durations[] = {1};
+ m.addInt64(ANDROID_SCALER_AVAILABLE_JPEG_MIN_DURATIONS,
+ ARRAY_SIZE(android_scaler_available_jpeg_min_durations),
+ android_scaler_available_jpeg_min_durations);
+
+ int32_t android_scaler_available_jpeg_sizes[] = {640, 480};
+ m.addInt32(ANDROID_SCALER_AVAILABLE_JPEG_SIZES,
+ ARRAY_SIZE(android_scaler_available_jpeg_sizes),
+ android_scaler_available_jpeg_sizes);
+
+ float android_scaler_available_max_digital_zoom[] = {1};
+ m.addFloat(ANDROID_SCALER_AVAILABLE_MAX_DIGITAL_ZOOM,
+ ARRAY_SIZE(android_scaler_available_max_digital_zoom),
+ android_scaler_available_max_digital_zoom);
+
+ int64_t android_scaler_available_processed_min_durations[] = {1};
+ m.addInt64(ANDROID_SCALER_AVAILABLE_PROCESSED_MIN_DURATIONS,
+ ARRAY_SIZE(android_scaler_available_processed_min_durations),
+ android_scaler_available_processed_min_durations);
+
+ int32_t android_scaler_available_processed_sizes[] = {640, 480};
+ m.addInt32(ANDROID_SCALER_AVAILABLE_PROCESSED_SIZES,
+ ARRAY_SIZE(android_scaler_available_processed_sizes),
+ android_scaler_available_processed_sizes);
+
+ int64_t android_scaler_available_raw_min_durations[] = {1};
+ m.addInt64(ANDROID_SCALER_AVAILABLE_RAW_MIN_DURATIONS,
+ ARRAY_SIZE(android_scaler_available_raw_min_durations),
+ android_scaler_available_raw_min_durations);
+
+ int32_t android_scaler_available_raw_sizes[] = {640, 480};
+ m.addInt32(ANDROID_SCALER_AVAILABLE_RAW_SIZES,
+ ARRAY_SIZE(android_scaler_available_raw_sizes),
+ android_scaler_available_raw_sizes);
+
+ /* android.sensor */
+
+ int32_t android_sensor_info_active_array_size[] = {0, 0, 640, 480};
+ m.addInt32(ANDROID_SENSOR_INFO_ACTIVE_ARRAY_SIZE,
+ ARRAY_SIZE(android_sensor_info_active_array_size),
+ android_sensor_info_active_array_size);
+
+ int32_t android_sensor_info_sensitivity_range[] =
+ {100, 1600};
+ m.addInt32(ANDROID_SENSOR_INFO_SENSITIVITY_RANGE,
+ ARRAY_SIZE(android_sensor_info_sensitivity_range),
+ android_sensor_info_sensitivity_range);
+
+ int64_t android_sensor_info_max_frame_duration[] = {30000000000};
+ m.addInt64(ANDROID_SENSOR_INFO_MAX_FRAME_DURATION,
+ ARRAY_SIZE(android_sensor_info_max_frame_duration),
+ android_sensor_info_max_frame_duration);
+
+ float android_sensor_info_physical_size[] = {3.2, 2.4};
+ m.addFloat(ANDROID_SENSOR_INFO_PHYSICAL_SIZE,
+ ARRAY_SIZE(android_sensor_info_physical_size),
+ android_sensor_info_physical_size);
+
+ int32_t android_sensor_info_pixel_array_size[] = {640, 480};
+ m.addInt32(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE,
+ ARRAY_SIZE(android_sensor_info_pixel_array_size),
+ android_sensor_info_pixel_array_size);
+
+ int32_t android_sensor_orientation[] = {0};
+ m.addInt32(ANDROID_SENSOR_ORIENTATION,
+ ARRAY_SIZE(android_sensor_orientation),
+ android_sensor_orientation);
+
+ /* End of static camera characteristics */
+
+ return clone_camera_metadata(m.generate());
+}
+
+int ExampleCamera::initDevice()
+{
+ // Create standard settings templates
+ Metadata preview = Metadata(ANDROID_CONTROL_MODE_OFF,
+ ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW);
+ setTemplate(CAMERA3_TEMPLATE_PREVIEW, preview.generate());
+ Metadata capture = Metadata(ANDROID_CONTROL_MODE_OFF,
+ ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE);
+ setTemplate(CAMERA3_TEMPLATE_STILL_CAPTURE, capture.generate());
+ Metadata record = Metadata(ANDROID_CONTROL_MODE_OFF,
+ ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD);
+ setTemplate(CAMERA3_TEMPLATE_VIDEO_RECORD, record.generate());
+ Metadata snapshot = Metadata(ANDROID_CONTROL_MODE_OFF,
+ ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT);
+ setTemplate(CAMERA3_TEMPLATE_VIDEO_SNAPSHOT, snapshot.generate());
+ Metadata zsl = Metadata(ANDROID_CONTROL_MODE_OFF,
+ ANDROID_CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG);
+ setTemplate(CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG, zsl.generate());
+
+ return 0;
+}
+
+bool ExampleCamera::isValidCaptureSettings(const camera_metadata_t* settings)
+{
+ // TODO: reject settings that cannot be captured
+ return true;
+}
+
+} // namespace default_camera_hal
diff --git a/modules/camera/ExampleCamera.h b/modules/camera/ExampleCamera.h
new file mode 100644
index 0000000..9d6a9c0
--- /dev/null
+++ b/modules/camera/ExampleCamera.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef EXAMPLE_CAMERA_H_
+#define EXAMPLE_CAMERA_H_
+
+#include <system/camera_metadata.h>
+#include "Camera.h"
+
+namespace default_camera_hal {
+// ExampleCamera is an example for a specific camera device. The Camera object
+// contains all logic common between all cameras (e.g. front and back cameras),
+// while a specific camera device (e.g. ExampleCamera) holds all specific
+// metadata and logic about that device.
+class ExampleCamera : public Camera {
+ public:
+ ExampleCamera(int id);
+ ~ExampleCamera();
+
+ private:
+ // Initialize static camera characteristics for individual device
+ camera_metadata_t *initStaticInfo();
+ // Initialize whole device (templates/etc) when opened
+ int initDevice();
+ // Verify settings are valid for a capture with this device
+ bool isValidCaptureSettings(const camera_metadata_t* settings);
+};
+} // namespace default_camera_hal
+
+#endif // CAMERA_H_