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