blob: 027ecb77172aab53167a6a74d256dfe31878782b [file] [log] [blame]
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +01001/*
Biswarup Pal6152a302023-12-19 12:44:09 +00002 * Copyright 2023 The Android Open Source Project
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +01003 *
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#include <memory>
18
19#include "VirtualCameraDevice.h"
20#include "aidl/android/companion/virtualcamera/Format.h"
21#include "aidl/android/companion/virtualcamera/SupportedStreamConfiguration.h"
Biswarup Pal6152a302023-12-19 12:44:09 +000022#include "aidl/android/companion/virtualcamera/VirtualCameraConfiguration.h"
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +010023#include "aidl/android/hardware/camera/device/CameraMetadata.h"
24#include "aidl/android/hardware/camera/device/StreamConfiguration.h"
25#include "android/binder_interface_utils.h"
26#include "gmock/gmock.h"
27#include "gtest/gtest.h"
28#include "log/log_main.h"
29#include "system/camera_metadata.h"
30#include "utils/Errors.h"
31
32namespace android {
33namespace companion {
34namespace virtualcamera {
35namespace {
36
37using ::aidl::android::companion::virtualcamera::Format;
Biswarup Pal112458f2023-12-28 19:50:17 +000038using ::aidl::android::companion::virtualcamera::LensFacing;
Biswarup Pal6152a302023-12-19 12:44:09 +000039using ::aidl::android::companion::virtualcamera::SensorOrientation;
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +010040using ::aidl::android::companion::virtualcamera::SupportedStreamConfiguration;
Biswarup Pal6152a302023-12-19 12:44:09 +000041using ::aidl::android::companion::virtualcamera::VirtualCameraConfiguration;
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +010042using ::aidl::android::hardware::camera::device::CameraMetadata;
43using ::aidl::android::hardware::camera::device::Stream;
44using ::aidl::android::hardware::camera::device::StreamConfiguration;
45using ::aidl::android::hardware::camera::device::StreamType;
46using ::aidl::android::hardware::graphics::common::PixelFormat;
47using ::testing::UnorderedElementsAreArray;
48using metadata_stream_t =
49 camera_metadata_enum_android_scaler_available_stream_configurations_t;
50
51constexpr int kCameraId = 42;
52constexpr int kVgaWidth = 640;
53constexpr int kVgaHeight = 480;
54constexpr int kHdWidth = 1280;
55constexpr int kHdHeight = 720;
Biswarup Pal6152a302023-12-19 12:44:09 +000056constexpr int kMaxFps = 30;
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +010057
58struct AvailableStreamConfiguration {
59 const int width;
60 const int height;
61 const int pixelFormat;
62 const metadata_stream_t streamConfiguration;
63};
64
65bool operator==(const AvailableStreamConfiguration& a,
66 const AvailableStreamConfiguration& b) {
67 return a.width == b.width && a.height == b.height &&
68 a.pixelFormat == b.pixelFormat &&
69 a.streamConfiguration == b.streamConfiguration;
70}
71
72std::ostream& operator<<(std::ostream& os,
73 const AvailableStreamConfiguration& config) {
74 os << config.width << "x" << config.height << " (pixfmt "
75 << config.pixelFormat << ", streamConfiguration "
76 << config.streamConfiguration << ")";
77 return os;
78}
79
80std::vector<AvailableStreamConfiguration> getAvailableStreamConfigurations(
81 const CameraMetadata& metadata) {
82 const camera_metadata_t* const raw =
83 reinterpret_cast<const camera_metadata_t*>(metadata.metadata.data());
84 camera_metadata_ro_entry_t entry;
85 if (find_camera_metadata_ro_entry(
86 raw, ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, &entry) !=
87 NO_ERROR) {
88 return {};
89 }
90
91 std::vector<AvailableStreamConfiguration> res;
92 for (int i = 0; i < entry.count; i += 4) {
93 res.push_back(AvailableStreamConfiguration{
94 .width = entry.data.i32[i + 1],
95 .height = entry.data.i32[i + 2],
96 .pixelFormat = entry.data.i32[i],
97 .streamConfiguration =
98 static_cast<metadata_stream_t>(entry.data.i32[i + 3])});
99 }
100 return res;
101}
102
103struct VirtualCameraConfigTestParam {
Biswarup Pal6152a302023-12-19 12:44:09 +0000104 VirtualCameraConfiguration inputConfig;
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100105 std::vector<AvailableStreamConfiguration> expectedAvailableStreamConfigs;
106};
107
108class VirtualCameraDeviceTest
109 : public testing::TestWithParam<VirtualCameraConfigTestParam> {};
110
111TEST_P(VirtualCameraDeviceTest, cameraCharacteristicsForInputFormat) {
112 const VirtualCameraConfigTestParam& param = GetParam();
113 std::shared_ptr<VirtualCameraDevice> camera =
Biswarup Pal6152a302023-12-19 12:44:09 +0000114 ndk::SharedRefBase::make<VirtualCameraDevice>(kCameraId,
115 param.inputConfig);
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100116
117 CameraMetadata metadata;
118 ASSERT_TRUE(camera->getCameraCharacteristics(&metadata).isOk());
119 EXPECT_THAT(getAvailableStreamConfigurations(metadata),
120 UnorderedElementsAreArray(param.expectedAvailableStreamConfigs));
121
122 // Configuration needs to succeed for every available stream configuration
123 for (const AvailableStreamConfiguration& config :
124 param.expectedAvailableStreamConfigs) {
125 StreamConfiguration configuration{
126 .streams = std::vector<Stream>{Stream{
127 .streamType = StreamType::OUTPUT,
128 .width = config.width,
129 .height = config.height,
130 .format = static_cast<PixelFormat>(config.pixelFormat),
131 }}};
132 bool aidl_ret;
133 ASSERT_TRUE(
134 camera->isStreamCombinationSupported(configuration, &aidl_ret).isOk());
135 EXPECT_TRUE(aidl_ret);
136 }
137}
138
139INSTANTIATE_TEST_SUITE_P(
140 cameraCharacteristicsForInputFormat, VirtualCameraDeviceTest,
141 testing::Values(
142 VirtualCameraConfigTestParam{
Biswarup Pal6152a302023-12-19 12:44:09 +0000143 .inputConfig =
144 VirtualCameraConfiguration{
145 .supportedStreamConfigs = {SupportedStreamConfiguration{
146 .width = kVgaWidth,
147 .height = kVgaHeight,
148 .pixelFormat = Format::YUV_420_888,
149 .maxFps = kMaxFps}},
150 .virtualCameraCallback = nullptr,
Biswarup Pal112458f2023-12-28 19:50:17 +0000151 .sensorOrientation = SensorOrientation::ORIENTATION_0,
152 .lensFacing = LensFacing::FRONT},
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100153 .expectedAvailableStreamConfigs =
154 {AvailableStreamConfiguration{
155 .width = kVgaWidth,
156 .height = kVgaHeight,
157 .pixelFormat = ANDROID_SCALER_AVAILABLE_FORMATS_YCbCr_420_888,
158 .streamConfiguration =
159 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT},
160 AvailableStreamConfiguration{
161 .width = kVgaWidth,
162 .height = kVgaHeight,
163 .pixelFormat =
164 ANDROID_SCALER_AVAILABLE_FORMATS_IMPLEMENTATION_DEFINED,
165 .streamConfiguration =
166 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT},
167 AvailableStreamConfiguration{
168 .width = kVgaWidth,
169 .height = kVgaHeight,
170 .pixelFormat = ANDROID_SCALER_AVAILABLE_FORMATS_BLOB,
171 .streamConfiguration =
172 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT}}},
173 VirtualCameraConfigTestParam{
Biswarup Pal6152a302023-12-19 12:44:09 +0000174 .inputConfig =
175 VirtualCameraConfiguration{
176 .supportedStreamConfigs =
177 {SupportedStreamConfiguration{
178 .width = kVgaWidth,
179 .height = kVgaHeight,
180 .pixelFormat = Format::YUV_420_888,
181 .maxFps = kMaxFps},
182 SupportedStreamConfiguration{
183 .width = kHdWidth,
184 .height = kHdHeight,
185 .pixelFormat = Format::YUV_420_888,
186 .maxFps = kMaxFps}},
187 .virtualCameraCallback = nullptr,
Biswarup Pal112458f2023-12-28 19:50:17 +0000188 .sensorOrientation = SensorOrientation::ORIENTATION_0,
189 .lensFacing = LensFacing::BACK},
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100190 .expectedAvailableStreamConfigs = {
191 AvailableStreamConfiguration{
192 .width = kVgaWidth,
193 .height = kVgaHeight,
194 .pixelFormat = ANDROID_SCALER_AVAILABLE_FORMATS_YCbCr_420_888,
195 .streamConfiguration =
196 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT},
197 AvailableStreamConfiguration{
198 .width = kVgaWidth,
199 .height = kVgaHeight,
200 .pixelFormat =
201 ANDROID_SCALER_AVAILABLE_FORMATS_IMPLEMENTATION_DEFINED,
202 .streamConfiguration =
203 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT},
204 AvailableStreamConfiguration{
205 .width = kVgaWidth,
206 .height = kVgaHeight,
207 .pixelFormat = ANDROID_SCALER_AVAILABLE_FORMATS_BLOB,
208 .streamConfiguration =
209 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT},
210 AvailableStreamConfiguration{
211 .width = kHdWidth,
212 .height = kHdHeight,
213 .pixelFormat = ANDROID_SCALER_AVAILABLE_FORMATS_YCbCr_420_888,
214 .streamConfiguration =
215 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT},
216 AvailableStreamConfiguration{
217 .width = kHdWidth,
218 .height = kHdHeight,
219 .pixelFormat =
220 ANDROID_SCALER_AVAILABLE_FORMATS_IMPLEMENTATION_DEFINED,
221 .streamConfiguration =
222 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT},
223 AvailableStreamConfiguration{
224 .width = kHdWidth,
225 .height = kHdHeight,
226 .pixelFormat = ANDROID_SCALER_AVAILABLE_FORMATS_BLOB,
227 .streamConfiguration =
228 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT}}}));
229
230} // namespace
231} // namespace virtualcamera
232} // namespace companion
233} // namespace android