xref: /aosp_15_r20/external/v4l2_codec2/tests/c2_comp_intf/C2VEACompIntf_test.cpp (revision 0ec5a0ec62797f775085659156625e7f1bdb369f)
1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 //#define LOG_NDEBUG 0
6 #define LOG_TAG "C2VDEACompIntf_test"
7 
8 #include <C2CompIntfTest.h>
9 
10 #include <inttypes.h>
11 #include <stdio.h>
12 #include <limits>
13 
14 #include <C2PlatformSupport.h>
15 #include <SimpleC2Interface.h>
16 #include <gtest/gtest.h>
17 #include <utils/Log.h>
18 
19 #include <v4l2_codec2/components/V4L2EncodeComponent.h>
20 #include <v4l2_codec2/components/V4L2EncodeInterface.h>
21 
22 namespace android {
23 
24 constexpr const char* testCompName = "c2.v4l2.avc.encoder";
25 constexpr c2_node_id_t testCompNodeId = 12345;
26 
27 constexpr const char* MEDIA_MIMETYPE_VIDEO_RAW = "video/raw";
28 constexpr const char* MEDIA_MIMETYPE_VIDEO_AVC = "video/avc";
29 
30 constexpr C2Allocator::id_t kInputAllocators[] = {C2PlatformAllocatorStore::GRALLOC};
31 constexpr C2Allocator::id_t kOutputAllocators[] = {C2PlatformAllocatorStore::BLOB};
32 constexpr C2BlockPool::local_id_t kDefaultOutputBlockPool = C2BlockPool::BASIC_LINEAR;
33 
34 class C2VEACompIntfTest: public C2CompIntfTest {
35 protected:
C2VEACompIntfTest()36     C2VEACompIntfTest() {
37         mReflector = std::make_shared<C2ReflectorHelper>();
38         auto componentInterface = std::make_shared<EncodeInterface>(testCompName, mReflector);
39         mIntf = std::shared_ptr<C2ComponentInterface>(new SimpleInterface<EncodeInterface>(
40                 testCompName, testCompNodeId, componentInterface));
41     }
~C2VEACompIntfTest()42     ~C2VEACompIntfTest() override {
43     }
44 };
45 
46 #define TRACED_FAILURE(func)                            \
47     do {                                                \
48         SCOPED_TRACE(#func);                            \
49         func;                                           \
50         if (::testing::Test::HasFatalFailure()) return; \
51     } while (false)
52 
TEST_F(C2VEACompIntfTest,CreateInstance)53 TEST_F(C2VEACompIntfTest, CreateInstance) {
54     auto name = mIntf->getName();
55     auto id = mIntf->getId();
56     printf("name = %s\n", name.c_str());
57     printf("node_id = %u\n", id);
58     EXPECT_STREQ(name.c_str(), testCompName);
59     EXPECT_EQ(id, testCompNodeId);
60 }
61 
TEST_F(C2VEACompIntfTest,TestInputFormat)62 TEST_F(C2VEACompIntfTest, TestInputFormat) {
63     C2StreamBufferTypeSetting::input expected(0u, C2BufferData::GRAPHIC);
64     C2StreamBufferTypeSetting::input invalid(0u, C2BufferData::LINEAR);
65     TRACED_FAILURE(testReadOnlyParam(&expected, &invalid));
66 }
67 
TEST_F(C2VEACompIntfTest,TestOutputFormat)68 TEST_F(C2VEACompIntfTest, TestOutputFormat) {
69     C2StreamBufferTypeSetting::output expected(0u, C2BufferData::LINEAR);
70     C2StreamBufferTypeSetting::output invalid(0u, C2BufferData::GRAPHIC);
71     TRACED_FAILURE(testReadOnlyParam(&expected, &invalid));
72 }
73 
TEST_F(C2VEACompIntfTest,TestInputPortMime)74 TEST_F(C2VEACompIntfTest, TestInputPortMime) {
75     std::shared_ptr<C2PortMediaTypeSetting::input> expected(
76             AllocSharedString<C2PortMediaTypeSetting::input>(MEDIA_MIMETYPE_VIDEO_RAW));
77     std::shared_ptr<C2PortMediaTypeSetting::input> invalid(
78             AllocSharedString<C2PortMediaTypeSetting::input>(MEDIA_MIMETYPE_VIDEO_AVC));
79     TRACED_FAILURE(testReadOnlyParamOnHeap(expected.get(), invalid.get()));
80 }
81 
TEST_F(C2VEACompIntfTest,TestOutputPortMime)82 TEST_F(C2VEACompIntfTest, TestOutputPortMime) {
83     std::shared_ptr<C2PortMediaTypeSetting::output> expected(
84             AllocSharedString<C2PortMediaTypeSetting::output>(MEDIA_MIMETYPE_VIDEO_AVC));
85     std::shared_ptr<C2PortMediaTypeSetting::output> invalid(
86             AllocSharedString<C2PortMediaTypeSetting::output>(MEDIA_MIMETYPE_VIDEO_RAW));
87     TRACED_FAILURE(testReadOnlyParamOnHeap(expected.get(), invalid.get()));
88 }
89 
TEST_F(C2VEACompIntfTest,TestProfileLevel)90 TEST_F(C2VEACompIntfTest, TestProfileLevel) {
91     // Configure input size, framerate, and bitrate to values which are capable of the lowest
92     // profile and level. (176x144, 15fps, 64000bps)
93     C2StreamPictureSizeInfo::input videoSize(0u, 176, 144);
94     C2StreamFrameRateInfo::output frameRate(0u, 15.);
95     C2StreamBitrateInfo::output bitrate(0u, 64000);
96 
97     // Configure and check if value is configured.
98     TRACED_FAILURE(testWritableParam(&videoSize));
99     TRACED_FAILURE(testWritableParam(&frameRate));
100     TRACED_FAILURE(testWritableParam(&bitrate));
101 
102     // Iterate all possible profile and level combination
103     TRACED_FAILURE(testWritableProfileLevelParam<C2StreamProfileLevelInfo::output>());
104 }
105 
TEST_F(C2VEACompIntfTest,TestVideoSize)106 TEST_F(C2VEACompIntfTest, TestVideoSize) {
107     C2StreamPictureSizeInfo::input videoSize;
108     videoSize.setStream(0);  // only support single stream
109     std::vector<C2FieldSupportedValuesQuery> widthC2FSV = {
110             {C2ParamField(&videoSize, &C2StreamPictureSizeInfo::width),
111              C2FieldSupportedValuesQuery::CURRENT},
112     };
113     ASSERT_EQ(C2_OK, mIntf->querySupportedValues_vb(widthC2FSV, C2_DONT_BLOCK));
114     std::vector<C2FieldSupportedValuesQuery> heightC2FSV = {
115             {C2ParamField(&videoSize, &C2StreamPictureSizeInfo::height),
116              C2FieldSupportedValuesQuery::CURRENT},
117     };
118     ASSERT_EQ(C2_OK, mIntf->querySupportedValues_vb(heightC2FSV, C2_DONT_BLOCK));
119 
120     // Configure input size may take more time since the profile level setter also depends on it.
121     // Just limit the test range to 1080p and step up to 16 to make test run faster.
122     ASSERT_EQ(1u, widthC2FSV.size());
123     ASSERT_EQ(C2_OK, widthC2FSV[0].status);
124     ASSERT_EQ(C2FieldSupportedValues::RANGE, widthC2FSV[0].values.type);
125     auto& widthFSVRange = widthC2FSV[0].values.range;
126     int32_t widthMin = widthFSVRange.min.i32;
127     int32_t widthMax = std::min(widthFSVRange.max.i32, 1920);
128     int32_t widthStep = std::max(widthFSVRange.step.i32, 16);
129 
130     ASSERT_EQ(1u, heightC2FSV.size());
131     ASSERT_EQ(C2_OK, heightC2FSV[0].status);
132     ASSERT_EQ(C2FieldSupportedValues::RANGE, heightC2FSV[0].values.type);
133     auto& heightFSVRange = heightC2FSV[0].values.range;
134     int32_t heightMin = heightFSVRange.min.i32;
135     int32_t heightMax = std::min(heightFSVRange.max.i32, 1080);
136     int32_t heightStep = std::max(heightFSVRange.step.i32, 16);
137 
138     // test updating valid and invalid values
139     TRACED_FAILURE(testWritableVideoSizeParam<C2StreamPictureSizeInfo::input>(
140             widthMin, widthMax, widthStep, heightMin, heightMax, heightStep));
141 }
142 
TEST_F(C2VEACompIntfTest,TestBitrate)143 TEST_F(C2VEACompIntfTest, TestBitrate) {
144     C2StreamBitrateInfo::output bitrate;
145     std::vector<C2FieldSupportedValuesQuery> valueC2FSV = {
146             {C2ParamField(&bitrate, &C2StreamBitrateInfo::value),
147              C2FieldSupportedValuesQuery::CURRENT},
148     };
149     ASSERT_EQ(C2_OK, mIntf->querySupportedValues_vb(valueC2FSV, C2_DONT_BLOCK));
150     ASSERT_EQ(1u, valueC2FSV.size());
151     ASSERT_EQ(C2_OK, valueC2FSV[0].status);
152     ASSERT_EQ(C2FieldSupportedValues::RANGE, valueC2FSV[0].values.type);
153     auto& valueFSVRange = valueC2FSV[0].values.range;
154     uint32_t bitrateMin = valueFSVRange.min.u32;
155     uint32_t bitrateMax = valueFSVRange.max.u32;
156     uint32_t bitrateStep = valueFSVRange.step.u32;
157     bitrate.value = bitrateMin;
158     TRACED_FAILURE(testWritableParam(&bitrate));
159     bitrate.value = bitrateMax;
160     TRACED_FAILURE(testWritableParam(&bitrate));
161     // Choose the value which is half steps from bitrateMin than bitrateMax.
162     uint32_t steps = (bitrateMax - bitrateMin) / bitrateStep;
163     bitrate.value = bitrateMin + steps / 2 * bitrateStep;
164     TRACED_FAILURE(testWritableParam(&bitrate));
165     // TODO: Add invalid value test after validate possible values in C2InterfaceHelper is
166     //       implemented.
167 }
168 
TEST_F(C2VEACompIntfTest,TestFrameRate)169 TEST_F(C2VEACompIntfTest, TestFrameRate) {
170     C2StreamFrameRateInfo::output frameRate;
171     frameRate.setStream(0);  // only support single stream
172     std::vector<C2Param*> stackParams{&frameRate};
173     ASSERT_EQ(C2_OK, mIntf->query_vb(stackParams, {}, C2_DONT_BLOCK, nullptr));
174 
175     float defaultFrameRate = frameRate.value;
176     frameRate.value = defaultFrameRate / 2;
177     TRACED_FAILURE(testWritableParam(&frameRate));
178     frameRate.value = defaultFrameRate;
179     TRACED_FAILURE(testWritableParam(&frameRate));
180     // TODO: Add invalid value test after validate possible values in C2InterfaceHelper is
181     //       implemented.
182 }
183 
TEST_F(C2VEACompIntfTest,TestIntraRefreshPeriod)184 TEST_F(C2VEACompIntfTest, TestIntraRefreshPeriod) {
185     C2StreamIntraRefreshTuning::output period(0u, C2Config::INTRA_REFRESH_ARBITRARY, 30.);
186     TRACED_FAILURE(testWritableParam(&period));
187     period.mode = C2Config::INTRA_REFRESH_DISABLED;
188     period.period = 0;
189     TRACED_FAILURE(testWritableParam(&period));
190 }
191 
TEST_F(C2VEACompIntfTest,TestRequestKeyFrame)192 TEST_F(C2VEACompIntfTest, TestRequestKeyFrame) {
193     C2StreamRequestSyncFrameTuning::output request(0u, C2_TRUE);
194     TRACED_FAILURE(testWritableParam(&request));
195     request.value = C2_FALSE;
196     TRACED_FAILURE(testWritableParam(&request));
197 }
198 
TEST_F(C2VEACompIntfTest,TestKeyFramePeriodUs)199 TEST_F(C2VEACompIntfTest, TestKeyFramePeriodUs) {
200     C2StreamSyncFrameIntervalTuning::output period(0u, 500000);
201     TRACED_FAILURE(testWritableParam(&period));
202     period.value = 1500000;
203     TRACED_FAILURE(testWritableParam(&period));
204 }
205 
TEST_F(C2VEACompIntfTest,TestInputAllocatorIds)206 TEST_F(C2VEACompIntfTest, TestInputAllocatorIds) {
207     std::shared_ptr<C2PortAllocatorsTuning::input> expected(
208             C2PortAllocatorsTuning::input::AllocShared(kInputAllocators));
209     std::shared_ptr<C2PortAllocatorsTuning::input> invalid(
210             C2PortAllocatorsTuning::input::AllocShared(kOutputAllocators));
211     TRACED_FAILURE(testReadOnlyParamOnHeap(expected.get(), invalid.get()));
212 }
213 
TEST_F(C2VEACompIntfTest,TestOutputAllocatorIds)214 TEST_F(C2VEACompIntfTest, TestOutputAllocatorIds) {
215     std::shared_ptr<C2PortAllocatorsTuning::output> expected(
216             C2PortAllocatorsTuning::output::AllocShared(kOutputAllocators));
217     std::shared_ptr<C2PortAllocatorsTuning::output> invalid(
218             C2PortAllocatorsTuning::output::AllocShared(kInputAllocators));
219     TRACED_FAILURE(testReadOnlyParamOnHeap(expected.get(), invalid.get()));
220 }
221 
TEST_F(C2VEACompIntfTest,TestOutputBlockPoolIds)222 TEST_F(C2VEACompIntfTest, TestOutputBlockPoolIds) {
223     std::vector<std::unique_ptr<C2Param>> heapParams;
224     C2Param::Index index = C2PortBlockPoolsTuning::output::PARAM_TYPE;
225 
226     // Query the param and check the default value.
227     ASSERT_EQ(C2_OK, mIntf->query_vb({}, {index}, C2_DONT_BLOCK, &heapParams));
228     ASSERT_EQ(1u, heapParams.size());
229     C2BlockPool::local_id_t value =
230             reinterpret_cast<C2PortBlockPoolsTuning*>(heapParams[0].get())->m.values[0];
231     ASSERT_EQ(kDefaultOutputBlockPool, value);
232 
233     // Configure the param.
234     C2BlockPool::local_id_t configBlockPools[] = {C2BlockPool::PLATFORM_START + 1};
235     std::shared_ptr<C2PortBlockPoolsTuning::output> newParam(
236             C2PortBlockPoolsTuning::output::AllocShared(configBlockPools));
237 
238     std::vector<C2Param*> params{newParam.get()};
239     std::vector<std::unique_ptr<C2SettingResult>> failures;
240     ASSERT_EQ(C2_OK, mIntf->config_vb(params, C2_DONT_BLOCK, &failures));
241     EXPECT_EQ(0u, failures.size());
242 
243     // Query the param again and check the value is as configured
244     heapParams.clear();
245     ASSERT_EQ(C2_OK, mIntf->query_vb({}, {index}, C2_DONT_BLOCK, &heapParams));
246     ASSERT_EQ(1u, heapParams.size());
247     value = ((C2PortBlockPoolsTuning*)heapParams[0].get())->m.values[0];
248     ASSERT_EQ(configBlockPools[0], value);
249 }
250 
TEST_F(C2VEACompIntfTest,TestUnsupportedParam)251 TEST_F(C2VEACompIntfTest, TestUnsupportedParam) {
252     C2ComponentTimeStretchTuning unsupportedParam;
253     std::vector<C2Param*> stackParams{&unsupportedParam};
254     ASSERT_EQ(C2_BAD_INDEX, mIntf->query_vb(stackParams, {}, C2_DONT_BLOCK, nullptr));
255     EXPECT_EQ(0u, unsupportedParam.size());  // invalidated
256 }
257 
TEST_F(C2VEACompIntfTest,TestAvcLevelDependency)258 TEST_F(C2VEACompIntfTest, TestAvcLevelDependency) {
259     C2StreamProfileLevelInfo::output info;
260     info.setStream(0);
261 
262     // Read out the default profile and level.
263     std::vector<C2Param*> stackParams{&info};
264     ASSERT_EQ(C2_OK, mIntf->query_vb(stackParams, {}, C2_DONT_BLOCK, nullptr));
265 
266     // The default profile should be the lowest one component could support, and we would expect
267     // either BASELINE or MAIN is supported. In addition, profiles higher than HIGH will have
268     // different bitrate limit for levels, we don't want to make this test too complicated.
269     ASSERT_LT(info.profile, PROFILE_AVC_HIGH);
270 
271     // Set AVC level to 1.2.
272     // Configure input size, framerate, and bitrate to values which are capable of level 1.2.
273     C2StreamPictureSizeInfo::input videoSize(0u, 320, 240);
274     C2StreamFrameRateInfo::output frameRate(0u, 15.);
275     C2StreamBitrateInfo::output bitrate(0u, 384000);
276     info.level = LEVEL_AVC_1_2;
277 
278     std::vector<C2Param*> params{&videoSize, &frameRate, &bitrate, &info};
279     std::vector<std::unique_ptr<C2SettingResult>> failures;
280     ASSERT_EQ(C2_OK, mIntf->config_vb(params, C2_DONT_BLOCK, &failures));
281     EXPECT_EQ(0u, failures.size());
282 
283     // Check AVC level is 1.2.
284     std::vector<std::unique_ptr<C2Param>> heapParams;
285     C2Param::Index index = C2StreamProfileLevelInfo::output::PARAM_TYPE;
286     ASSERT_EQ(C2_OK, mIntf->query_vb({}, {index}, C2_DONT_BLOCK, &heapParams));
287     ASSERT_EQ(1u, heapParams.size());
288     EXPECT_EQ(((C2StreamProfileLevelInfo*)heapParams[0].get())->level, LEVEL_AVC_1_2);
289 
290     // Configure input size, framerate, and bitrate to values which are capable of level 4.0.
291     videoSize.width = 2048;
292     videoSize.height = 1024;
293     frameRate.value = 30;
294     bitrate.value = 20000000;
295 
296     failures.clear();
297     ASSERT_EQ(C2_OK, mIntf->config_vb(params, C2_DONT_BLOCK, &failures));
298     EXPECT_EQ(0u, failures.size());
299 
300     // Check AVC level is adjusted to 4.0.
301     heapParams.clear();
302     ASSERT_EQ(C2_OK, mIntf->query_vb({}, {index}, C2_DONT_BLOCK, &heapParams));
303     ASSERT_EQ(1u, heapParams.size());
304     EXPECT_EQ(((C2StreamProfileLevelInfo*)heapParams[0].get())->level, LEVEL_AVC_4);
305 }
306 
TEST_F(C2VEACompIntfTest,TestBug114332827)307 TEST_F(C2VEACompIntfTest, TestBug114332827) {
308     // Use at least PROFILE_AVC_MAIN for 1080p input video and up. b/114332827
309 
310     // Config input video size to 1080p.
311     C2StreamPictureSizeInfo::input videoSize(0u, 1920, 1080);
312 
313     std::vector<C2Param*> params{&videoSize};
314     std::vector<std::unique_ptr<C2SettingResult>> failures;
315     ASSERT_EQ(C2_OK, mIntf->config_vb(params, C2_DONT_BLOCK, &failures));
316     EXPECT_EQ(0u, failures.size());
317 
318     // Query video size back to check it is 1080p.
319     std::vector<std::unique_ptr<C2Param>> heapParams;
320     C2Param::Index index = C2StreamPictureSizeInfo::input::PARAM_TYPE;
321     ASSERT_EQ(C2_OK, mIntf->query_vb({}, {index}, C2_DONT_BLOCK, &heapParams));
322     ASSERT_EQ(1u, heapParams.size());
323     EXPECT_EQ(1920u, ((C2StreamPictureSizeInfo*)heapParams[0].get())->width);
324     EXPECT_EQ(1080u, ((C2StreamPictureSizeInfo*)heapParams[0].get())->height);
325 
326     // Check profile should be PROFILE_AVC_MAIN or higher.
327     heapParams.clear();
328     index = C2StreamProfileLevelInfo::output::PARAM_TYPE;
329     ASSERT_EQ(C2_OK, mIntf->query_vb({}, {index}, C2_DONT_BLOCK, &heapParams));
330     ASSERT_EQ(1u, heapParams.size());
331     EXPECT_GE(((C2StreamProfileLevelInfo*)heapParams[0].get())->profile, PROFILE_AVC_MAIN);
332 }
333 
TEST_F(C2VEACompIntfTest,ParamReflector)334 TEST_F(C2VEACompIntfTest, ParamReflector) {
335     dumpParamDescriptions();
336 }
337 }  // namespace android
338