blob: 25f6b100d21925416c45ae72a0ecd0da052f0fe3 [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 Pal6152a302023-12-19 12:44:09 +000038using ::aidl::android::companion::virtualcamera::SensorOrientation;
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +010039using ::aidl::android::companion::virtualcamera::SupportedStreamConfiguration;
Biswarup Pal6152a302023-12-19 12:44:09 +000040using ::aidl::android::companion::virtualcamera::VirtualCameraConfiguration;
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +010041using ::aidl::android::hardware::camera::device::CameraMetadata;
42using ::aidl::android::hardware::camera::device::Stream;
43using ::aidl::android::hardware::camera::device::StreamConfiguration;
44using ::aidl::android::hardware::camera::device::StreamType;
45using ::aidl::android::hardware::graphics::common::PixelFormat;
46using ::testing::UnorderedElementsAreArray;
47using metadata_stream_t =
48 camera_metadata_enum_android_scaler_available_stream_configurations_t;
49
50constexpr int kCameraId = 42;
51constexpr int kVgaWidth = 640;
52constexpr int kVgaHeight = 480;
53constexpr int kHdWidth = 1280;
54constexpr int kHdHeight = 720;
Biswarup Pal6152a302023-12-19 12:44:09 +000055constexpr int kMaxFps = 30;
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +010056
57struct AvailableStreamConfiguration {
58 const int width;
59 const int height;
60 const int pixelFormat;
61 const metadata_stream_t streamConfiguration;
62};
63
64bool operator==(const AvailableStreamConfiguration& a,
65 const AvailableStreamConfiguration& b) {
66 return a.width == b.width && a.height == b.height &&
67 a.pixelFormat == b.pixelFormat &&
68 a.streamConfiguration == b.streamConfiguration;
69}
70
71std::ostream& operator<<(std::ostream& os,
72 const AvailableStreamConfiguration& config) {
73 os << config.width << "x" << config.height << " (pixfmt "
74 << config.pixelFormat << ", streamConfiguration "
75 << config.streamConfiguration << ")";
76 return os;
77}
78
79std::vector<AvailableStreamConfiguration> getAvailableStreamConfigurations(
80 const CameraMetadata& metadata) {
81 const camera_metadata_t* const raw =
82 reinterpret_cast<const camera_metadata_t*>(metadata.metadata.data());
83 camera_metadata_ro_entry_t entry;
84 if (find_camera_metadata_ro_entry(
85 raw, ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, &entry) !=
86 NO_ERROR) {
87 return {};
88 }
89
90 std::vector<AvailableStreamConfiguration> res;
91 for (int i = 0; i < entry.count; i += 4) {
92 res.push_back(AvailableStreamConfiguration{
93 .width = entry.data.i32[i + 1],
94 .height = entry.data.i32[i + 2],
95 .pixelFormat = entry.data.i32[i],
96 .streamConfiguration =
97 static_cast<metadata_stream_t>(entry.data.i32[i + 3])});
98 }
99 return res;
100}
101
102struct VirtualCameraConfigTestParam {
Biswarup Pal6152a302023-12-19 12:44:09 +0000103 VirtualCameraConfiguration inputConfig;
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100104 std::vector<AvailableStreamConfiguration> expectedAvailableStreamConfigs;
105};
106
107class VirtualCameraDeviceTest
108 : public testing::TestWithParam<VirtualCameraConfigTestParam> {};
109
110TEST_P(VirtualCameraDeviceTest, cameraCharacteristicsForInputFormat) {
111 const VirtualCameraConfigTestParam& param = GetParam();
112 std::shared_ptr<VirtualCameraDevice> camera =
Biswarup Pal6152a302023-12-19 12:44:09 +0000113 ndk::SharedRefBase::make<VirtualCameraDevice>(kCameraId,
114 param.inputConfig);
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100115
116 CameraMetadata metadata;
117 ASSERT_TRUE(camera->getCameraCharacteristics(&metadata).isOk());
118 EXPECT_THAT(getAvailableStreamConfigurations(metadata),
119 UnorderedElementsAreArray(param.expectedAvailableStreamConfigs));
120
121 // Configuration needs to succeed for every available stream configuration
122 for (const AvailableStreamConfiguration& config :
123 param.expectedAvailableStreamConfigs) {
124 StreamConfiguration configuration{
125 .streams = std::vector<Stream>{Stream{
126 .streamType = StreamType::OUTPUT,
127 .width = config.width,
128 .height = config.height,
129 .format = static_cast<PixelFormat>(config.pixelFormat),
130 }}};
131 bool aidl_ret;
132 ASSERT_TRUE(
133 camera->isStreamCombinationSupported(configuration, &aidl_ret).isOk());
134 EXPECT_TRUE(aidl_ret);
135 }
136}
137
138INSTANTIATE_TEST_SUITE_P(
139 cameraCharacteristicsForInputFormat, VirtualCameraDeviceTest,
140 testing::Values(
141 VirtualCameraConfigTestParam{
Biswarup Pal6152a302023-12-19 12:44:09 +0000142 .inputConfig =
143 VirtualCameraConfiguration{
144 .supportedStreamConfigs = {SupportedStreamConfiguration{
145 .width = kVgaWidth,
146 .height = kVgaHeight,
147 .pixelFormat = Format::YUV_420_888,
148 .maxFps = kMaxFps}},
149 .virtualCameraCallback = nullptr,
150 .sensorOrientation = SensorOrientation::ORIENTATION_0},
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100151 .expectedAvailableStreamConfigs =
152 {AvailableStreamConfiguration{
153 .width = kVgaWidth,
154 .height = kVgaHeight,
155 .pixelFormat = ANDROID_SCALER_AVAILABLE_FORMATS_YCbCr_420_888,
156 .streamConfiguration =
157 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT},
158 AvailableStreamConfiguration{
159 .width = kVgaWidth,
160 .height = kVgaHeight,
161 .pixelFormat =
162 ANDROID_SCALER_AVAILABLE_FORMATS_IMPLEMENTATION_DEFINED,
163 .streamConfiguration =
164 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT},
165 AvailableStreamConfiguration{
166 .width = kVgaWidth,
167 .height = kVgaHeight,
168 .pixelFormat = ANDROID_SCALER_AVAILABLE_FORMATS_BLOB,
169 .streamConfiguration =
170 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT}}},
171 VirtualCameraConfigTestParam{
Biswarup Pal6152a302023-12-19 12:44:09 +0000172 .inputConfig =
173 VirtualCameraConfiguration{
174 .supportedStreamConfigs =
175 {SupportedStreamConfiguration{
176 .width = kVgaWidth,
177 .height = kVgaHeight,
178 .pixelFormat = Format::YUV_420_888,
179 .maxFps = kMaxFps},
180 SupportedStreamConfiguration{
181 .width = kHdWidth,
182 .height = kHdHeight,
183 .pixelFormat = Format::YUV_420_888,
184 .maxFps = kMaxFps}},
185 .virtualCameraCallback = nullptr,
186 .sensorOrientation = SensorOrientation::ORIENTATION_0},
Jan Sebechlebsky3b478c42023-11-23 13:15:56 +0100187 .expectedAvailableStreamConfigs = {
188 AvailableStreamConfiguration{
189 .width = kVgaWidth,
190 .height = kVgaHeight,
191 .pixelFormat = ANDROID_SCALER_AVAILABLE_FORMATS_YCbCr_420_888,
192 .streamConfiguration =
193 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT},
194 AvailableStreamConfiguration{
195 .width = kVgaWidth,
196 .height = kVgaHeight,
197 .pixelFormat =
198 ANDROID_SCALER_AVAILABLE_FORMATS_IMPLEMENTATION_DEFINED,
199 .streamConfiguration =
200 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT},
201 AvailableStreamConfiguration{
202 .width = kVgaWidth,
203 .height = kVgaHeight,
204 .pixelFormat = ANDROID_SCALER_AVAILABLE_FORMATS_BLOB,
205 .streamConfiguration =
206 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT},
207 AvailableStreamConfiguration{
208 .width = kHdWidth,
209 .height = kHdHeight,
210 .pixelFormat = ANDROID_SCALER_AVAILABLE_FORMATS_YCbCr_420_888,
211 .streamConfiguration =
212 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT},
213 AvailableStreamConfiguration{
214 .width = kHdWidth,
215 .height = kHdHeight,
216 .pixelFormat =
217 ANDROID_SCALER_AVAILABLE_FORMATS_IMPLEMENTATION_DEFINED,
218 .streamConfiguration =
219 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT},
220 AvailableStreamConfiguration{
221 .width = kHdWidth,
222 .height = kHdHeight,
223 .pixelFormat = ANDROID_SCALER_AVAILABLE_FORMATS_BLOB,
224 .streamConfiguration =
225 ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS_OUTPUT}}}));
226
227} // namespace
228} // namespace virtualcamera
229} // namespace companion
230} // namespace android