diff options
author | Eino-Ville Talvala <etalvala@google.com> | 2012-03-22 13:11:05 -0700 |
---|---|---|
committer | Eino-Ville Talvala <etalvala@google.com> | 2012-04-11 11:23:31 -0700 |
commit | fed0c0244b569e0bae4280af145a94ef3b1a1468 (patch) | |
tree | ecfe0c5b13cdfccbede81d79fbab4060a8b00731 | |
parent | c65a2fe3925f46b4d4301cef97b308dbc3e22da9 (diff) | |
download | hardware_libhardware-fed0c0244b569e0bae4280af145a94ef3b1a1468.zip hardware_libhardware-fed0c0244b569e0bae4280af145a94ef3b1a1468.tar.gz hardware_libhardware-fed0c0244b569e0bae4280af145a94ef3b1a1468.tar.bz2 |
Revise camera HAL 2, and add unit test skeleton.
- Add missing method in stream_ops (set_buffers_geometry)
- Remove extra method in stream_ops (set_swap_interval)
- Document metadata queue protocol
- Change metadata queue methods to be set/get through function calls
only, instead of a struct member in the HAL device ops.
- Change vendor extension tag query methods to be retrieved by a get
call, instead of a struct member in the HAL device ops.
- Add basic gtest unit test skeleton, which currently just returns
static info from all camera devices.
Change-Id: I94117097b0243023ad60638070cc7f0cefec18e6
-rw-r--r-- | include/hardware/camera2.h | 71 | ||||
-rw-r--r-- | tests/camera2/Android.mk | 27 | ||||
-rw-r--r-- | tests/camera2/camera2.cpp | 123 |
3 files changed, 202 insertions, 19 deletions
diff --git a/include/hardware/camera2.h b/include/hardware/camera2.h index 48f5c35..36f2a9e 100644 --- a/include/hardware/camera2.h +++ b/include/hardware/camera2.h @@ -41,6 +41,8 @@ __BEGIN_DECLS +struct camera2_device; + /** * Output image stream queue management */ @@ -53,6 +55,8 @@ typedef struct camera2_stream_ops { int (*cancel_buffer)(struct camera2_stream_ops* w, buffer_handle_t* buffer); int (*set_buffer_count)(struct camera2_stream_ops* w, int count); + int (*set_buffers_geometry)(struct camera2_stream_ops* pw, + int w, int h, int format); int (*set_crop)(struct camera2_stream_ops *w, int left, int top, int right, int bottom); // Timestamps are measured in nanoseconds, and must be comparable @@ -62,7 +66,6 @@ typedef struct camera2_stream_ops { // The timestamp must be the time at the start of image exposure. int (*set_timestamp)(struct camera2_stream_ops *w, int64_t timestamp); int (*set_usage)(struct camera2_stream_ops* w, int usage); - int (*set_swap_interval)(struct camera2_stream_ops *w, int interval); int (*get_min_undequeued_buffer_count)(const struct camera2_stream_ops *w, int *count); int (*lock_buffer)(struct camera2_stream_ops* w, @@ -72,6 +75,32 @@ typedef struct camera2_stream_ops { /** * Metadata queue management, used for requests sent to HAL module, and for * frames produced by the HAL. + * + * Queue protocol: + * + * The source holds the queue and its contents. At start, the queue is empty. + * + * 1. When the first metadata buffer is placed into the queue, the source must + * signal the destination by calling notify_queue_not_empty(). + * + * 2. After receiving notify_queue_not_empty, the destination must call + * dequeue() once it's ready to handle the next buffer. + * + * 3. Once the destination has processed a buffer, it should try to dequeue + * another buffer. If there are no more buffers available, dequeue() will + * return NULL. In this case, when a buffer becomes available, the source + * must call notify_queue_not_empty() again. If the destination receives a + * NULL return from dequeue, it does not need to query the queue again until + * a notify_queue_not_empty() call is received from the source. + * + * 4. If the destination calls buffer_count() and receives 0, this does not mean + * that the source will provide a notify_queue_not_empty() call. The source + * must only provide such a call after the destination has received a NULL + * from dequeue, or on initial startup. + * + * 5. The dequeue() call in response to notify_queue_not_empty() may be on the + * same thread as the notify_queue_not_empty() call. The source must not + * deadlock in that case. */ typedef struct camera2_metadata_queue_src_ops { @@ -99,6 +128,7 @@ typedef struct camera2_metadata_queue_dst_ops { * Notify destination that the queue is no longer empty */ int (*notify_queue_not_empty)(struct camera2_metadata_queue_dst_ops *); + } camera2_metadata_queue_dst_ops_t; /* Defined in camera_metadata.h */ @@ -153,32 +183,33 @@ enum { CAMERA2_MSG_ERROR_SERVER_FAULT = 0x0003 }; - -struct camera2_device; typedef struct camera2_device_ops { /** * Input request queue methods */ - int (*set_request_queue_ops)(struct camera2_device *, - camera2_metadata_queue_src_ops *request_queue_src_ops); + int (*set_request_queue_src_ops)(struct camera2_device *, + camera2_metadata_queue_src_ops *queue_src_ops); - camera2_metadata_queue_dst_ops_t *request_queue_dst_ops; + int (*get_request_queue_dst_ops)(struct camera2_device *, + camera2_metadata_queue_dst_ops **queue_dst_ops); /** * Input reprocessing queue methods */ int (*set_reprocess_queue_ops)(struct camera2_device *, - camera2_metadata_queue_src_ops *reprocess_queue_src_ops); + camera2_metadata_queue_src_ops *queue_src_ops); - camera2_metadata_queue_dst_ops_t *reprocess_queue_dst_ops; + int (*get_reprocess_queue_dst_ops)(struct camera2_device *, + camera2_metadata_queue_dst_ops **queue_dst_ops); /** * Output frame queue methods */ - int (*set_frame_queue_ops)(struct camera2_device *, - camera2_metadata_queue_dst_ops *frame_queue_dst_ops); + int (*set_frame_queue_dst_ops)(struct camera2_device *, + camera2_metadata_queue_dst_ops *queue_dst_ops); - camera2_metadata_queue_src_ops_t *frame_queue_src_ops; + int (*get_frame_queue_src_ops)(struct camera2_device *, + camera2_metadata_queue_src_ops **queue_dst_ops); /** * Pass in notification methods @@ -209,7 +240,8 @@ typedef struct camera2_device_ops { /** * Operations on the input reprocessing stream */ - camera2_stream_ops_t *reprocess_stream_ops; + int (*get_reprocess_stream_ops)(struct camera2_device *, + camera2_stream_ops_t **stream_ops); /** * Get the number of streams that can be simultaneously allocated. @@ -231,7 +263,7 @@ typedef struct camera2_device_ops { uint32_t stream_slot, uint32_t width, uint32_t height, - int format, + uint32_t format, camera2_stream_ops_t *camera2_stream_ops); /** @@ -244,6 +276,13 @@ typedef struct camera2_device_ops { uint32_t stream_slot); /** + * Get methods to query for vendor extension metadata tag infomation. May + * set ops to NULL if no vendor extension tags are defined. + */ + int (*get_metadata_vendor_tag_ops)(struct camera2_device*, + vendor_tag_query_ops_t **ops); + + /** * Release the camera hardware. Requests that are in flight will be * canceled. No further buffers will be pushed into any allocated pipelines * once this call returns. @@ -251,12 +290,6 @@ typedef struct camera2_device_ops { void (*release)(struct camera2_device *); /** - * Methods to query for vendor extension metadata tag infomation. May be NULL - * if no vendor extension tags are defined. - */ - vendor_tag_query_ops *camera_metadata_vendor_tag_ops; - - /** * Dump state of the camera hardware */ int (*dump)(struct camera2_device *, int fd); diff --git a/tests/camera2/Android.mk b/tests/camera2/Android.mk new file mode 100644 index 0000000..340ec30 --- /dev/null +++ b/tests/camera2/Android.mk @@ -0,0 +1,27 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES:= \ + camera2.cpp + +LOCAL_SHARED_LIBRARIES := \ + libutils \ + libstlport \ + libhardware \ + libcamera_metadata + +LOCAL_STATIC_LIBRARIES := \ + libgtest \ + libgtest_main + +LOCAL_C_INCLUDES += \ + bionic \ + bionic/libstdc++/include \ + external/gtest/include \ + external/stlport/stlport \ + system/media/camera/include \ + +LOCAL_MODULE:= camera2_hal_tests +LOCAL_MODULE_TAGS := tests + +include $(BUILD_EXECUTABLE) diff --git a/tests/camera2/camera2.cpp b/tests/camera2/camera2.cpp new file mode 100644 index 0000000..d13d7cd --- /dev/null +++ b/tests/camera2/camera2.cpp @@ -0,0 +1,123 @@ +/* + * 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. + */ + +#include <system/camera_metadata.h> +#include <hardware/camera2.h> +#include <gtest/gtest.h> +#include <iostream> + +class Camera2Test: public testing::Test { + public: + static void SetUpTestCase() { + int res; + + hw_module_t *module = NULL; + res = hw_get_module(CAMERA_HARDWARE_MODULE_ID, + (const hw_module_t **)&module); + + ASSERT_EQ(0, res) + << "Failure opening camera hardware module: " << res; + ASSERT_TRUE(NULL != module) + << "No camera module was set by hw_get_module"; + + std::cout << " Camera module name: " << module->name << std::endl; + std::cout << " Camera module author: " << module->author << std::endl; + std::cout << " Camera module API version: 0x" << std::hex + << module->module_api_version << std::endl; + std::cout << " Camera module HAL API version: 0x" << std::hex + << module->hal_api_version << std::endl; + + int16_t version2_0 = CAMERA_MODULE_API_VERSION_2_0; + ASSERT_EQ(version2_0, module->module_api_version) + << "Camera module version is 0x" + << std::hex << module->module_api_version + << ", not 2.0. (0x" + << std::hex << CAMERA_MODULE_API_VERSION_2_0 << ")"; + + sCameraModule = reinterpret_cast<camera_module_t*>(module); + + sNumCameras = sCameraModule->get_number_of_cameras(); + ASSERT_LT(0, sNumCameras) << "No camera devices available!"; + + std::cout << " Camera device count: " << sNumCameras << std::endl; + sCameraSupportsHal2 = new bool[sNumCameras]; + + for (int i = 0; i < sNumCameras; i++) { + camera_info info; + res = sCameraModule->get_camera_info(i, &info); + ASSERT_EQ(0, res) + << "Failure getting camera info for camera " << i; + std::cout << " Camera device: " << std::dec + << i << std::endl;; + std::cout << " Facing: " << std::dec + << info.facing << std::endl; + std::cout << " Orientation: " << std::dec + << info.orientation << std::endl; + std::cout << " Version: 0x" << std::hex << + info.device_version << std::endl; + if (info.device_version >= CAMERA_DEVICE_API_VERSION_2_0) { + sCameraSupportsHal2[i] = true; + ASSERT_TRUE(NULL != info.static_camera_characteristics); + std::cout << " Static camera metadata:" << std::endl; + dump_camera_metadata(info.static_camera_characteristics, 0, 1); + } else { + sCameraSupportsHal2[i] = false; + } + } + } + + static const camera_module_t *getCameraModule() { + return sCameraModule; + } + + static const camera2_device_t *openCameraDevice(int id) { + if (NULL == sCameraSupportsHal2) return NULL; + if (id >= sNumCameras) return NULL; + if (!sCameraSupportsHal2[id]) return NULL; + + hw_device_t *device = NULL; + const camera_module_t *cam_module = getCameraModule(); + char camId[10]; + int res; + + snprintf(camId, 10, "%d", id); + res = cam_module->common.methods->open( + (const hw_module_t*)cam_module, + camId, + &device); + if (res < 0 || cam_module == NULL) { + return NULL; + } + camera2_device_t *cam_device = + reinterpret_cast<camera2_device_t*>(device); + return cam_device; + } + + private: + + static camera_module_t *sCameraModule; + static int sNumCameras; + static bool *sCameraSupportsHal2; +}; + +camera_module_t *Camera2Test::sCameraModule = NULL; +int Camera2Test::sNumCameras = 0; +bool *Camera2Test::sCameraSupportsHal2 = NULL; + + +TEST_F(Camera2Test, Basic) { + ASSERT_TRUE(NULL != getCameraModule()); +} |