/* * Copyright (C) 2012 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. */ /* * Contains implementation of a class EmulatedCamera that encapsulates * functionality common to all version 2.0 emulated camera devices. Instances * of this class (for each emulated camera) are created during the construction * of the EmulatedCameraFactory instance. This class serves as an entry point * for all camera API calls that defined by camera2_device_ops_t API. */ #define LOG_NDEBUG 0 #define LOG_TAG "EmulatedCamera2_Camera" #include <cutils/log.h> #include "EmulatedCamera2.h" #include "system/camera_metadata.h" namespace android { /* Constructs EmulatedCamera2 instance. * Param: * cameraId - Zero based camera identifier, which is an index of the camera * instance in camera factory's array. * module - Emulated camera HAL module descriptor. */ EmulatedCamera2::EmulatedCamera2(int cameraId, struct hw_module_t *module) : EmulatedBaseCamera(cameraId, CAMERA_DEVICE_API_VERSION_2_0, &common, module) { common.close = EmulatedCamera2::close; ops = &sDeviceOps; priv = this; mNotifyCb = NULL; mRequestQueueSrc = NULL; mFrameQueueDst = NULL; mVendorTagOps.get_camera_vendor_section_name = EmulatedCamera2::get_camera_vendor_section_name; mVendorTagOps.get_camera_vendor_tag_name = EmulatedCamera2::get_camera_vendor_tag_name; mVendorTagOps.get_camera_vendor_tag_type = EmulatedCamera2::get_camera_vendor_tag_type; mVendorTagOps.parent = this; mStatusPresent = true; } /* Destructs EmulatedCamera2 instance. */ EmulatedCamera2::~EmulatedCamera2() {} /**************************************************************************** * Abstract API ***************************************************************************/ /**************************************************************************** * Public API ***************************************************************************/ status_t EmulatedCamera2::Initialize(const cvd::CameraDefinition & /*props*/) { return NO_ERROR; } /**************************************************************************** * Camera API implementation ***************************************************************************/ status_t EmulatedCamera2::connectCamera(hw_device_t **device) { *device = &common; return NO_ERROR; } status_t EmulatedCamera2::closeCamera() { return NO_ERROR; } status_t EmulatedCamera2::getCameraInfo(struct camera_info *info) { return EmulatedBaseCamera::getCameraInfo(info); } /**************************************************************************** * Camera Device API implementation. * These methods are called from the camera API callback routines. ***************************************************************************/ /** Request input queue */ int EmulatedCamera2::requestQueueNotify() { return INVALID_OPERATION; } /** Count of requests in flight */ int EmulatedCamera2::getInProgressCount() { return INVALID_OPERATION; } /** Cancel all captures in flight */ int EmulatedCamera2::flushCapturesInProgress() { return INVALID_OPERATION; } /** Construct a default request for a given use case */ int EmulatedCamera2::constructDefaultRequest(int /*request_template*/, camera_metadata_t ** /*request*/) { return INVALID_OPERATION; } /** Output stream creation and management */ int EmulatedCamera2::allocateStream(uint32_t /*width*/, uint32_t /*height*/, int /*format*/, const camera2_stream_ops_t * /*stream_ops*/, uint32_t * /*stream_id*/, uint32_t * /*format_actual*/, uint32_t * /*usage*/, uint32_t * /*max_buffers*/) { return INVALID_OPERATION; } int EmulatedCamera2::registerStreamBuffers(uint32_t /*stream_id*/, int /*num_buffers*/, buffer_handle_t * /*buffers*/) { return INVALID_OPERATION; } int EmulatedCamera2::releaseStream(uint32_t /*stream_id*/) { return INVALID_OPERATION; } /** Reprocessing input stream management */ int EmulatedCamera2::allocateReprocessStream( uint32_t /*width*/, uint32_t /*height*/, uint32_t /*format*/, const camera2_stream_in_ops_t * /*reprocess_stream_ops*/, uint32_t * /*stream_id*/, uint32_t * /*consumer_usage*/, uint32_t * /*max_buffers*/) { return INVALID_OPERATION; } int EmulatedCamera2::allocateReprocessStreamFromStream( uint32_t /*output_stream_id*/, const camera2_stream_in_ops_t * /*reprocess_stream_ops*/, uint32_t * /*stream_id*/) { return INVALID_OPERATION; } int EmulatedCamera2::releaseReprocessStream(uint32_t /*stream_id*/) { return INVALID_OPERATION; } /** 3A triggering */ int EmulatedCamera2::triggerAction(uint32_t /*trigger_id*/, int /*ext1*/, int /*ext2*/) { return INVALID_OPERATION; } /** Custom tag query methods */ const char *EmulatedCamera2::getVendorSectionName(uint32_t /*tag*/) { return NULL; } const char *EmulatedCamera2::getVendorTagName(uint32_t /*tag*/) { return NULL; } int EmulatedCamera2::getVendorTagType(uint32_t /*tag*/) { return -1; } /** Debug methods */ int EmulatedCamera2::dump(int /*fd*/) { return INVALID_OPERATION; } /**************************************************************************** * Private API. ***************************************************************************/ /**************************************************************************** * Camera API callbacks as defined by camera2_device_ops structure. See * hardware/libhardware/include/hardware/camera2.h for information on each * of these callbacks. Implemented in this class, these callbacks simply * dispatch the call into an instance of EmulatedCamera2 class defined by the * 'camera_device2' parameter, or set a member value in the same. ***************************************************************************/ EmulatedCamera2 *getInstance(const camera2_device_t *d) { const EmulatedCamera2 *cec = static_cast<const EmulatedCamera2 *>(d); return const_cast<EmulatedCamera2 *>(cec); } int EmulatedCamera2::set_request_queue_src_ops( const camera2_device_t *d, const camera2_request_queue_src_ops *queue_src_ops) { EmulatedCamera2 *ec = getInstance(d); ec->mRequestQueueSrc = queue_src_ops; return NO_ERROR; } int EmulatedCamera2::notify_request_queue_not_empty(const camera2_device_t *d) { EmulatedCamera2 *ec = getInstance(d); return ec->requestQueueNotify(); } int EmulatedCamera2::set_frame_queue_dst_ops( const camera2_device_t *d, const camera2_frame_queue_dst_ops *queue_dst_ops) { EmulatedCamera2 *ec = getInstance(d); ec->mFrameQueueDst = queue_dst_ops; return NO_ERROR; } int EmulatedCamera2::get_in_progress_count(const camera2_device_t *d) { EmulatedCamera2 *ec = getInstance(d); return ec->getInProgressCount(); } int EmulatedCamera2::flush_captures_in_progress(const camera2_device_t *d) { EmulatedCamera2 *ec = getInstance(d); return ec->flushCapturesInProgress(); } int EmulatedCamera2::construct_default_request(const camera2_device_t *d, int request_template, camera_metadata_t **request) { EmulatedCamera2 *ec = getInstance(d); return ec->constructDefaultRequest(request_template, request); } int EmulatedCamera2::allocate_stream(const camera2_device_t *d, uint32_t width, uint32_t height, int format, const camera2_stream_ops_t *stream_ops, uint32_t *stream_id, uint32_t *format_actual, uint32_t *usage, uint32_t *max_buffers) { EmulatedCamera2 *ec = getInstance(d); return ec->allocateStream(width, height, format, stream_ops, stream_id, format_actual, usage, max_buffers); } int EmulatedCamera2::register_stream_buffers(const camera2_device_t *d, uint32_t stream_id, int num_buffers, buffer_handle_t *buffers) { EmulatedCamera2 *ec = getInstance(d); return ec->registerStreamBuffers(stream_id, num_buffers, buffers); } int EmulatedCamera2::release_stream(const camera2_device_t *d, uint32_t stream_id) { EmulatedCamera2 *ec = getInstance(d); return ec->releaseStream(stream_id); } int EmulatedCamera2::allocate_reprocess_stream( const camera2_device_t *d, uint32_t width, uint32_t height, uint32_t format, const camera2_stream_in_ops_t *reprocess_stream_ops, uint32_t *stream_id, uint32_t *consumer_usage, uint32_t *max_buffers) { EmulatedCamera2 *ec = getInstance(d); return ec->allocateReprocessStream(width, height, format, reprocess_stream_ops, stream_id, consumer_usage, max_buffers); } int EmulatedCamera2::allocate_reprocess_stream_from_stream( const camera2_device_t *d, uint32_t output_stream_id, const camera2_stream_in_ops_t *reprocess_stream_ops, uint32_t *stream_id) { EmulatedCamera2 *ec = getInstance(d); return ec->allocateReprocessStreamFromStream(output_stream_id, reprocess_stream_ops, stream_id); } int EmulatedCamera2::release_reprocess_stream(const camera2_device_t *d, uint32_t stream_id) { EmulatedCamera2 *ec = getInstance(d); return ec->releaseReprocessStream(stream_id); } int EmulatedCamera2::trigger_action(const camera2_device_t *d, uint32_t trigger_id, int ext1, int ext2) { EmulatedCamera2 *ec = getInstance(d); return ec->triggerAction(trigger_id, ext1, ext2); } int EmulatedCamera2::set_notify_callback(const camera2_device_t *d, camera2_notify_callback notify_cb, void *user) { EmulatedCamera2 *ec = getInstance(d); Mutex::Autolock l(ec->mMutex); ec->mNotifyCb = notify_cb; ec->mNotifyUserPtr = user; return NO_ERROR; } int EmulatedCamera2::get_instance_metadata( const struct camera2_device *d, camera_metadata **instance_metadata) { EmulatedCamera2 *ec = getInstance(d); if (!ec) { return INVALID_OPERATION; } *instance_metadata = ec->mCameraInfo; return NO_ERROR; } int EmulatedCamera2::get_metadata_vendor_tag_ops(const camera2_device_t *d, vendor_tag_query_ops_t **ops) { EmulatedCamera2 *ec = getInstance(d); *ops = static_cast<vendor_tag_query_ops_t *>(&ec->mVendorTagOps); return NO_ERROR; } const char *EmulatedCamera2::get_camera_vendor_section_name( const vendor_tag_query_ops_t *v, uint32_t tag) { EmulatedCamera2 *ec = static_cast<const TagOps *>(v)->parent; return ec->getVendorSectionName(tag); } const char *EmulatedCamera2::get_camera_vendor_tag_name( const vendor_tag_query_ops_t *v, uint32_t tag) { EmulatedCamera2 *ec = static_cast<const TagOps *>(v)->parent; return ec->getVendorTagName(tag); } int EmulatedCamera2::get_camera_vendor_tag_type(const vendor_tag_query_ops_t *v, uint32_t tag) { EmulatedCamera2 *ec = static_cast<const TagOps *>(v)->parent; return ec->getVendorTagType(tag); } int EmulatedCamera2::dump(const camera2_device_t *d, int fd) { EmulatedCamera2 *ec = getInstance(d); return ec->dump(fd); } int EmulatedCamera2::close(struct hw_device_t *device) { EmulatedCamera2 *ec = static_cast<EmulatedCamera2 *>( reinterpret_cast<camera2_device_t *>(device)); if (ec == NULL) { ALOGE("%s: Unexpected NULL camera2 device", __FUNCTION__); return -EINVAL; } return ec->closeCamera(); } void EmulatedCamera2::sendNotification(int32_t msgType, int32_t ext1, int32_t ext2, int32_t ext3) { camera2_notify_callback notifyCb; { Mutex::Autolock l(mMutex); notifyCb = mNotifyCb; } if (notifyCb != NULL) { notifyCb(msgType, ext1, ext2, ext3, mNotifyUserPtr); } } camera2_device_ops_t EmulatedCamera2::sDeviceOps = { EmulatedCamera2::set_request_queue_src_ops, EmulatedCamera2::notify_request_queue_not_empty, EmulatedCamera2::set_frame_queue_dst_ops, EmulatedCamera2::get_in_progress_count, EmulatedCamera2::flush_captures_in_progress, EmulatedCamera2::construct_default_request, EmulatedCamera2::allocate_stream, EmulatedCamera2::register_stream_buffers, EmulatedCamera2::release_stream, EmulatedCamera2::allocate_reprocess_stream, EmulatedCamera2::allocate_reprocess_stream_from_stream, EmulatedCamera2::release_reprocess_stream, EmulatedCamera2::trigger_action, EmulatedCamera2::set_notify_callback, EmulatedCamera2::get_metadata_vendor_tag_ops, EmulatedCamera2::dump, #ifdef CAMERA_DEVICE_API_VERSION_2_1 EmulatedCamera2::get_instance_metadata, #endif }; }; /* namespace android */