You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
325 lines
11 KiB
325 lines
11 KiB
/*
|
|
* Copyright (C) 2015 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.
|
|
*/
|
|
|
|
//#define LOG_NDEBUG 0
|
|
#define LOG_TAG "UsbCameraDevice"
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <log/log.h>
|
|
|
|
#define ATRACE_TAG (ATRACE_TAG_CAMERA | ATRACE_TAG_HAL)
|
|
#include <utils/Trace.h>
|
|
|
|
#include <system/camera_metadata.h>
|
|
|
|
#include "Camera.h"
|
|
#include "UsbCamera.h"
|
|
|
|
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
|
|
|
|
namespace usb_camera_hal {
|
|
|
|
UsbCamera::UsbCamera(int id) : Camera(id) {
|
|
}
|
|
|
|
UsbCamera::~UsbCamera() {
|
|
}
|
|
|
|
int UsbCamera::initStaticInfo() {
|
|
/*
|
|
* Setup static camera info. This will have to customized per camera
|
|
* device.
|
|
* TODO: this is just some sample code, need tailor for USB cameras.
|
|
*/
|
|
if (mStaticInfo != NULL) {
|
|
free_camera_metadata(mStaticInfo);
|
|
}
|
|
|
|
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[] = {/*AE*/ 1,/*AWB*/ 1,/*AF*/ 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_RAW16,
|
|
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 */
|
|
|
|
mStaticInfo = clone_camera_metadata(m.get());
|
|
|
|
return 0;
|
|
}
|
|
|
|
int UsbCamera::openDevice() {
|
|
// TODO: implement usb camera device open sequence: open device nodes etc.
|
|
|
|
return 0;
|
|
}
|
|
|
|
int UsbCamera::closeDevice() {
|
|
// TODO: implement usb camera device close sequence: close device nodes etc.
|
|
|
|
return 0;
|
|
}
|
|
|
|
int UsbCamera::processCaptureBuffer(const camera3_stream_buffer_t *in,
|
|
camera3_stream_buffer_t *out) {
|
|
if (in->acquire_fence != -1) {
|
|
int res = sync_wait(in->acquire_fence, CAMERA_SYNC_TIMEOUT_MS);
|
|
if (res == -ETIME) {
|
|
ALOGE("%s:%d: Timeout waiting on buffer acquire fence",
|
|
__func__, mId);
|
|
return res;
|
|
} else if (res) {
|
|
ALOGE("%s:%d: Error waiting on buffer acquire fence: %s(%d)",
|
|
__func__, mId, strerror(-res), res);
|
|
return res;
|
|
}
|
|
}
|
|
|
|
out->stream = in->stream;
|
|
out->buffer = in->buffer;
|
|
out->status = CAMERA3_BUFFER_STATUS_OK;
|
|
// TODO: use driver-backed release fences
|
|
out->acquire_fence = -1;
|
|
out->release_fence = -1;
|
|
|
|
// TODO: lock and software-paint buffer
|
|
return 0;
|
|
}
|
|
|
|
int UsbCamera::initDevice() {
|
|
int res;
|
|
Metadata base;
|
|
|
|
// Create standard settings templates from copies of base metadata
|
|
res = base.add1UInt8(ANDROID_CONTROL_MODE, ANDROID_CONTROL_MODE_OFF);
|
|
if (res)
|
|
return res;
|
|
|
|
// Use base settings to create all other templates and set them. This is just some samples,
|
|
// More initialization may be needed.
|
|
res = initPreviewTemplate(base);
|
|
if (res)
|
|
return res;
|
|
res = initStillTemplate(base);
|
|
if (res)
|
|
return res;
|
|
res = initRecordTemplate(base);
|
|
if (res)
|
|
return res;
|
|
res = initSnapshotTemplate(base);
|
|
if (res)
|
|
return res;
|
|
res = initZslTemplate(base);
|
|
if (res)
|
|
return res;
|
|
res = initManualTemplate(base);
|
|
if (res)
|
|
return res;
|
|
|
|
return 0;
|
|
}
|
|
|
|
int UsbCamera::initPreviewTemplate(Metadata m) {
|
|
// Setup default preview controls
|
|
int res = m.add1UInt8(ANDROID_CONTROL_CAPTURE_INTENT,
|
|
ANDROID_CONTROL_CAPTURE_INTENT_PREVIEW);
|
|
|
|
if (res)
|
|
return res;
|
|
// TODO: set fast auto-focus, auto-whitebalance, auto-exposure, auto flash
|
|
return setTemplate(CAMERA3_TEMPLATE_PREVIEW, m.get());
|
|
}
|
|
|
|
int UsbCamera::initStillTemplate(Metadata m) {
|
|
int res = m.add1UInt8(ANDROID_CONTROL_CAPTURE_INTENT,
|
|
ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE);
|
|
// Setup default still capture controls
|
|
if (res)
|
|
return res;
|
|
// TODO: set fast auto-focus, auto-whitebalance, auto-exposure, auto flash
|
|
return setTemplate(CAMERA3_TEMPLATE_STILL_CAPTURE, m.get());
|
|
}
|
|
|
|
int UsbCamera::initRecordTemplate(Metadata m) {
|
|
int res = m.add1UInt8(ANDROID_CONTROL_CAPTURE_INTENT,
|
|
ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_RECORD);
|
|
// Setup default video record controls
|
|
if (res)
|
|
return res;
|
|
// TODO: set slow auto-focus, auto-whitebalance, auto-exposure, flash off
|
|
return setTemplate(CAMERA3_TEMPLATE_VIDEO_RECORD, m.get());
|
|
}
|
|
|
|
int UsbCamera::initSnapshotTemplate(Metadata m) {
|
|
int res = m.add1UInt8(ANDROID_CONTROL_CAPTURE_INTENT,
|
|
ANDROID_CONTROL_CAPTURE_INTENT_VIDEO_SNAPSHOT);
|
|
// Setup default video snapshot controls
|
|
if (res)
|
|
return res;
|
|
// TODO: set slow auto-focus, auto-whitebalance, auto-exposure, flash off
|
|
return setTemplate(CAMERA3_TEMPLATE_VIDEO_SNAPSHOT, m.get());
|
|
}
|
|
|
|
int UsbCamera::initZslTemplate(Metadata m) {
|
|
int res = m.add1UInt8(ANDROID_CONTROL_CAPTURE_INTENT,
|
|
ANDROID_CONTROL_CAPTURE_INTENT_ZERO_SHUTTER_LAG);
|
|
// Setup default zero shutter lag controls
|
|
if (res)
|
|
return res;
|
|
// TODO: set reprocessing parameters for zsl input queue
|
|
return setTemplate(CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG, m.get());
|
|
}
|
|
|
|
int UsbCamera::initManualTemplate(Metadata m) {
|
|
int res = m.add1UInt8(ANDROID_CONTROL_CAPTURE_INTENT,
|
|
ANDROID_CONTROL_CAPTURE_INTENT_MANUAL);
|
|
// Setup manual controls
|
|
if (res)
|
|
return res;
|
|
// TODO: set reprocessing parameters for zsl input queue
|
|
return setTemplate(CAMERA3_TEMPLATE_MANUAL, m.get());
|
|
}
|
|
|
|
bool UsbCamera::isValidCaptureSettings(const camera_metadata_t* /*settings*/) {
|
|
// TODO: reject settings that cannot be captured
|
|
return true;
|
|
}
|
|
|
|
} // namespace usb_camera_hal
|