1 /*
2 * Copyright 2020 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 <gmock/gmock.h>
18 #include <gtest/gtest.h>
19 #include <vndk/hardware_buffer.h>
20 #include <android-base/logging.h>
21
22 #include "EventGenerator.h"
23 #include "InputFrame.h"
24 #include "MockEngine.h"
25 #include "OutputConfig.pb.h"
26 #include "PixelFormatUtils.h"
27 #include "PixelStreamManager.h"
28 #include "RunnerComponent.h"
29 #include "StreamEngineInterface.h"
30 #include "StreamManager.h"
31 #include "gmock/gmock-matchers.h"
32 #include "types/Status.h"
33
34 using ::android::automotive::computepipe::runner::RunnerComponentInterface;
35 using ::android::automotive::computepipe::runner::RunnerEvent;
36 using ::android::automotive::computepipe::runner::generator::DefaultEvent;
37 using ::testing::Contains;
38 using ::testing::Not;
39 using ::testing::Return;
40
41 namespace android {
42 namespace automotive {
43 namespace computepipe {
44 namespace runner {
45 namespace stream_manager {
46 namespace {
47
48 MATCHER_P(ContainsDataFromFrame, data, "") {
49 const uint8_t* dataPtr = data->getFramePtr();
50 FrameInfo info = data->getFrameInfo();
51 AHardwareBuffer_Desc desc;
52 AHardwareBuffer_describe(arg, &desc);
53
54 if (desc.width != info.width) {
55 *result_listener << "Width does not match with values " << desc.width << " and "
56 << info.width;
57 return false;
58 }
59
60 if (desc.height != info.height) {
61 *result_listener << "Height does not match with values " << desc.height << " and "
62 << info.height;
63 return false;
64 }
65
66 AHardwareBuffer_Format expectedFormat = PixelFormatToHardwareBufferFormat(info.format);
67 if (expectedFormat != desc.format) {
68 *result_listener << "Format does not match";
69 return false;
70 }
71
72 void* mappedBuffer = nullptr;
73 int err = AHardwareBuffer_lock(arg, AHARDWAREBUFFER_USAGE_CPU_READ_RARELY, -1, nullptr,
74 &mappedBuffer);
75 if (err != 0 || mappedBuffer == nullptr) {
76 *result_listener << "Unable to lock the buffer for reading and comparing";
77 return false;
78 }
79
80 bool dataMatched = true;
81 int bytesPerPixel = numBytesPerPixel(expectedFormat);
82 for (int y = 0; y < info.height; y++) {
83 uint8_t* mappedRow = (uint8_t*)mappedBuffer + y * desc.stride * bytesPerPixel;
84 if (memcmp(mappedRow, dataPtr + y * info.stride,
85 std::min(info.stride, desc.stride * bytesPerPixel))) {
86 *result_listener << "Row " << y << " does not match";
87 dataMatched = false;
88 break;
89 }
90 }
91 AHardwareBuffer_unlock(arg, nullptr);
92 return dataMatched;
93 }
94
TEST(PixelMemHandleTest,SuccessfullyCreatesMemHandleOnFirstAttempt)95 TEST(PixelMemHandleTest, SuccessfullyCreatesMemHandleOnFirstAttempt) {
96 int bufferId = 10;
97 int streamId = 1;
98 uint64_t timestamp = 100;
99 PixelMemHandle memHandle(bufferId, streamId, AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN);
100
101 EXPECT_EQ(memHandle.getBufferId(), bufferId);
102 EXPECT_EQ(memHandle.getStreamId(), streamId);
103 EXPECT_EQ(memHandle.getHardwareBuffer(), nullptr);
104
105 std::vector<uint8_t> data(16 * 16 * 3, 0);
106 InputFrame frame(16, 16, PixelFormat::RGB, 16 * 3, &data[0]);
107 Status status = memHandle.setFrameData(timestamp, frame);
108 EXPECT_EQ(status, Status::SUCCESS);
109 ASSERT_NE(memHandle.getHardwareBuffer(), nullptr);
110
111 AHardwareBuffer_Desc desc;
112 AHardwareBuffer* buffer = memHandle.getHardwareBuffer();
113 AHardwareBuffer_describe(buffer, &desc);
114 EXPECT_EQ(desc.height, 16);
115 EXPECT_EQ(desc.width, 16);
116 EXPECT_EQ(desc.usage,
117 AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN | AHARDWAREBUFFER_USAGE_CPU_WRITE_OFTEN);
118 EXPECT_EQ(desc.format, AHardwareBuffer_Format::AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM);
119
120 EXPECT_THAT(buffer, ContainsDataFromFrame(&frame));
121 }
122
TEST(PixelMemHandleTest,FailsToOverwriteFrameDataWithDifferentImageFormat)123 TEST(PixelMemHandleTest, FailsToOverwriteFrameDataWithDifferentImageFormat) {
124 int bufferId = 10;
125 int streamId = 1;
126 uint64_t timestamp = 100;
127 PixelMemHandle memHandle(bufferId, streamId, AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN);
128
129 EXPECT_EQ(memHandle.getBufferId(), bufferId);
130 EXPECT_EQ(memHandle.getStreamId(), streamId);
131 EXPECT_EQ(memHandle.getHardwareBuffer(), nullptr);
132
133 uint8_t data[16 * 16 * 3] = {0};
134 InputFrame frame(16, 16, PixelFormat::RGB, 16 * 3, &data[0]);
135 Status status = memHandle.setFrameData(timestamp, frame);
136 EXPECT_EQ(status, Status::SUCCESS);
137 ASSERT_NE(memHandle.getHardwareBuffer(), nullptr);
138
139 InputFrame frameWithNewFormat(16, 16, PixelFormat::RGBA, 16 * 4, nullptr);
140 status = memHandle.setFrameData(timestamp, frameWithNewFormat);
141 EXPECT_EQ(status, Status::INVALID_ARGUMENT);
142
143 InputFrame frameWithNewDimensions(8, 8, PixelFormat::RGB, 8 * 3, nullptr);
144 status = memHandle.setFrameData(timestamp, frameWithNewDimensions);
145 EXPECT_EQ(status, Status::INVALID_ARGUMENT);
146 }
147
TEST(PixelMemHandleTest,SuccessfullyOverwritesOldData)148 TEST(PixelMemHandleTest, SuccessfullyOverwritesOldData) {
149 int bufferId = 10;
150 int streamId = 1;
151 uint64_t timestamp = 100;
152 PixelMemHandle memHandle(bufferId, streamId, AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN);
153
154 EXPECT_EQ(memHandle.getBufferId(), bufferId);
155 EXPECT_EQ(memHandle.getStreamId(), streamId);
156 EXPECT_EQ(memHandle.getHardwareBuffer(), nullptr);
157
158 std::vector<uint8_t> data(16 * 16 * 3, 0);
159 InputFrame frame(16, 16, PixelFormat::RGB, 16 * 3, &data[0]);
160 Status status = memHandle.setFrameData(timestamp, frame);
161 EXPECT_EQ(status, Status::SUCCESS);
162 ASSERT_NE(memHandle.getHardwareBuffer(), nullptr);
163 EXPECT_THAT(memHandle.getHardwareBuffer(), ContainsDataFromFrame(&frame));
164
165 std::vector<uint8_t> newData(16 * 16 * 3, 1);
166 uint64_t newTimestamp = 200;
167 InputFrame newFrame(16, 16, PixelFormat::RGB, 16 * 3, &newData[0]);
168 memHandle.setFrameData(newTimestamp, newFrame);
169 EXPECT_THAT(memHandle.getHardwareBuffer(), ContainsDataFromFrame(&newFrame));
170 EXPECT_THAT(memHandle.getTimeStamp(), newTimestamp);
171 }
172
TEST(PixelMemHandleTest,CreatesBuffersOfExpectedFormats)173 TEST(PixelMemHandleTest, CreatesBuffersOfExpectedFormats) {
174 int bufferId = 10;
175 int streamId = 1;
176 uint64_t timestamp = 100;
177
178 std::vector<uint8_t> rgbData(16 * 16 * 3, 10);
179 InputFrame rgbFrame(16, 16, PixelFormat::RGB, 16 * 3, &rgbData[0]);
180 PixelMemHandle rgbHandle(bufferId, streamId, AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN);
181 rgbHandle.setFrameData(timestamp, rgbFrame);
182 EXPECT_THAT(rgbHandle.getHardwareBuffer(), ContainsDataFromFrame(&rgbFrame));
183
184 std::vector<uint8_t> rgbaData(16 * 16 * 4, 20);
185 InputFrame rgbaFrame(16, 16, PixelFormat::RGBA, 16 * 4, &rgbaData[0]);
186 PixelMemHandle rgbaHandle(bufferId, streamId, AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN);
187 rgbaHandle.setFrameData(timestamp, rgbaFrame);
188 EXPECT_THAT(rgbaHandle.getHardwareBuffer(), ContainsDataFromFrame(&rgbaFrame));
189
190 std::vector<uint8_t> yData(16 * 16, 40);
191 InputFrame yFrame(16, 16, PixelFormat::GRAY, 16, &yData[0]);
192 PixelMemHandle yHandle(bufferId, streamId, AHARDWAREBUFFER_USAGE_CPU_READ_OFTEN);
193 yHandle.setFrameData(timestamp, yFrame);
194 EXPECT_THAT(yHandle.getHardwareBuffer(), ContainsDataFromFrame(&yFrame));
195 }
196
CreateStreamManagerAndEngine(int maxInFlightPackets)197 std::pair<std::shared_ptr<MockEngine>, std::unique_ptr<StreamManager>> CreateStreamManagerAndEngine(
198 int maxInFlightPackets) {
199 StreamManagerFactory factory;
200 proto::OutputConfig outputConfig;
201 outputConfig.set_type(proto::PacketType::PIXEL_DATA);
202 outputConfig.set_stream_name("pixel_stream");
203 std::shared_ptr<MockEngine> mockEngine = std::make_shared<MockEngine>();
204 std::unique_ptr<StreamManager> manager =
205 factory.getStreamManager(outputConfig, mockEngine, maxInFlightPackets);
206
207 return std::pair(mockEngine, std::move(manager));
208 }
209
TEST(PixelStreamManagerTest,PacketQueueingProducesACallback)210 TEST(PixelStreamManagerTest, PacketQueueingProducesACallback) {
211 // Create stream manager
212 int maxInFlightPackets = 1;
213 auto [mockEngine, manager] = CreateStreamManagerAndEngine(maxInFlightPackets);
214
215 DefaultEvent e = DefaultEvent::generateEntryEvent(DefaultEvent::Phase::RUN);
216
217 ASSERT_EQ(manager->handleExecutionPhase(e), Status::SUCCESS);
218 std::vector<uint8_t> data(16 * 16 * 3, 100);
219 InputFrame frame(16, 16, PixelFormat::RGB, 16 * 3, &data[0]);
220
221 std::shared_ptr<MemHandle> memHandle;
222 EXPECT_CALL((*mockEngine), dispatchPacket)
223 .WillOnce(testing::DoAll(testing::SaveArg<0>(&memHandle), (Return(Status::SUCCESS))));
224
225 EXPECT_EQ(manager->queuePacket(frame, 0), Status::SUCCESS);
226 sleep(1);
227 ASSERT_NE(memHandle, nullptr);
228 EXPECT_THAT(memHandle->getHardwareBuffer(), ContainsDataFromFrame(&frame));
229 EXPECT_THAT(memHandle->getTimeStamp(), 0);
230 EXPECT_THAT(memHandle->getStreamId(), 0);
231 }
232
TEST(PixelStreamManagerTest,MorePacketsThanMaxInFlightAreNotDispatched)233 TEST(PixelStreamManagerTest, MorePacketsThanMaxInFlightAreNotDispatched) {
234 int maxInFlightPackets = 3;
235 auto [mockEngine, manager] = CreateStreamManagerAndEngine(maxInFlightPackets);
236
237 DefaultEvent e = DefaultEvent::generateEntryEvent(DefaultEvent::Phase::RUN);
238
239 ASSERT_EQ(manager->handleExecutionPhase(e), Status::SUCCESS);
240 std::vector<uint8_t> data(16 * 16 * 3, 100);
241 InputFrame frame(16, 16, PixelFormat::RGB, 16 * 3, &data[0]);
242 std::set<int> activeBufferIds;
243
244 std::shared_ptr<MemHandle> memHandle;
245 EXPECT_CALL((*mockEngine), dispatchPacket)
246 .Times(3)
247 .WillRepeatedly(testing::DoAll(testing::SaveArg<0>(&memHandle), (Return(Status::SUCCESS))));
248
249 EXPECT_EQ(manager->queuePacket(frame, 0), Status::SUCCESS);
250 sleep(1);
251 ASSERT_NE(memHandle, nullptr);
252 EXPECT_THAT(memHandle->getHardwareBuffer(), ContainsDataFromFrame(&frame));
253 EXPECT_THAT(memHandle->getTimeStamp(), 0);
254 EXPECT_THAT(memHandle->getStreamId(), 0);
255 activeBufferIds.insert(memHandle->getBufferId());
256
257 EXPECT_EQ(manager->queuePacket(frame, 10), Status::SUCCESS);
258 sleep(1);
259 ASSERT_NE(memHandle, nullptr);
260 EXPECT_THAT(memHandle->getHardwareBuffer(), ContainsDataFromFrame(&frame));
261 EXPECT_THAT(memHandle->getTimeStamp(), 10);
262 EXPECT_THAT(memHandle->getStreamId(), 0);
263 EXPECT_THAT(activeBufferIds, Not(Contains(memHandle->getBufferId())));
264 activeBufferIds.insert(memHandle->getBufferId());
265
266 EXPECT_EQ(manager->queuePacket(frame, 20), Status::SUCCESS);
267 sleep(1);
268 ASSERT_NE(memHandle, nullptr);
269 EXPECT_THAT(memHandle->getHardwareBuffer(), ContainsDataFromFrame(&frame));
270 EXPECT_THAT(memHandle->getTimeStamp(), 20);
271 EXPECT_THAT(memHandle->getStreamId(), 0);
272 EXPECT_THAT(activeBufferIds, Not(Contains(memHandle->getBufferId())));
273 activeBufferIds.insert(memHandle->getBufferId());
274
275 // No new packet is produced as we have now reached the limit of number of
276 // packets.
277 EXPECT_EQ(manager->queuePacket(frame, 30), Status::SUCCESS);
278 sleep(1);
279 EXPECT_THAT(memHandle->getTimeStamp(), 20);
280 EXPECT_THAT(activeBufferIds, Contains(memHandle->getBufferId()));
281 }
282
TEST(PixelStreamManagerTest,DoneWithPacketCallReleasesAPacket)283 TEST(PixelStreamManagerTest, DoneWithPacketCallReleasesAPacket) {
284 int maxInFlightPackets = 1;
285 auto [mockEngine, manager] = CreateStreamManagerAndEngine(maxInFlightPackets);
286 std::set<int> activeBufferIds;
287
288 DefaultEvent e = DefaultEvent::generateEntryEvent(DefaultEvent::Phase::RUN);
289
290 ASSERT_EQ(manager->handleExecutionPhase(e), Status::SUCCESS);
291 std::vector<uint8_t> data(16 * 16 * 3, 100);
292 InputFrame frame(16, 16, PixelFormat::RGB, 16 * 3, &data[0]);
293
294 std::shared_ptr<MemHandle> memHandle;
295 EXPECT_CALL((*mockEngine), dispatchPacket)
296 .Times(2)
297 .WillRepeatedly(testing::DoAll(testing::SaveArg<0>(&memHandle), (Return(Status::SUCCESS))));
298
299 EXPECT_EQ(manager->queuePacket(frame, 10), Status::SUCCESS);
300 sleep(1);
301 ASSERT_NE(memHandle, nullptr);
302 activeBufferIds.insert(memHandle->getBufferId());
303 EXPECT_THAT(memHandle->getHardwareBuffer(), ContainsDataFromFrame(&frame));
304 EXPECT_THAT(memHandle->getTimeStamp(), 10);
305 EXPECT_THAT(memHandle->getStreamId(), 0);
306
307 // Check that new packet has not been dispatched as the old packet has not been released yet.
308 EXPECT_EQ(manager->queuePacket(frame, 20), Status::SUCCESS);
309 sleep(1);
310 ASSERT_NE(memHandle, nullptr);
311 EXPECT_THAT(memHandle->getTimeStamp(), 10);
312
313 EXPECT_THAT(manager->freePacket(memHandle->getBufferId()), Status::SUCCESS);
314 EXPECT_EQ(manager->queuePacket(frame, 30), Status::SUCCESS);
315 sleep(1);
316 ASSERT_NE(memHandle, nullptr);
317 EXPECT_THAT(memHandle->getTimeStamp(), 30);
318 }
319
TEST(PixelStreamManagerTest,EngineReceivesEndOfStreamCallbackOnStoppage)320 TEST(PixelStreamManagerTest, EngineReceivesEndOfStreamCallbackOnStoppage) {
321 int maxInFlightPackets = 1;
322 auto [mockEngine, manager] = CreateStreamManagerAndEngine(maxInFlightPackets);
323
324 DefaultEvent e = DefaultEvent::generateEntryEvent(DefaultEvent::Phase::RUN);
325
326 ASSERT_EQ(manager->handleExecutionPhase(e), Status::SUCCESS);
327 std::vector<uint8_t> data(16 * 16 * 3, 100);
328 InputFrame frame(16, 16, PixelFormat::RGB, 16 * 3, &data[0]);
329
330 std::shared_ptr<MemHandle> memHandle;
331 EXPECT_CALL((*mockEngine), dispatchPacket)
332 .WillOnce(testing::DoAll(testing::SaveArg<0>(&memHandle), (Return(Status::SUCCESS))));
333
334 EXPECT_EQ(manager->queuePacket(frame, 10), Status::SUCCESS);
335 sleep(1);
336 ASSERT_NE(memHandle, nullptr);
337 EXPECT_THAT(memHandle->getHardwareBuffer(), ContainsDataFromFrame(&frame));
338 EXPECT_THAT(memHandle->getTimeStamp(), 10);
339 EXPECT_THAT(memHandle->getStreamId(), 0);
340 EXPECT_EQ(manager->handleStopImmediatePhase(e), Status::SUCCESS);
341 // handleStopImmediatePhase is non-blocking call, so wait for manager to finish freeing the
342 // packets.
343 sleep(1);
344 }
345
TEST(PixelStreamManagerTest,MultipleFreePacketReleasesPacketAfterClone)346 TEST(PixelStreamManagerTest, MultipleFreePacketReleasesPacketAfterClone) {
347 int maxInFlightPackets = 1;
348 auto [mockEngine, manager] = CreateStreamManagerAndEngine(maxInFlightPackets);
349
350 DefaultEvent e = DefaultEvent::generateEntryEvent(DefaultEvent::Phase::RUN);
351 ASSERT_EQ(manager->handleExecutionPhase(e), Status::SUCCESS);
352 std::vector<uint8_t> data(16 * 16 * 3, 100);
353 InputFrame frame(16, 16, PixelFormat::RGB, 16 * 3, &data[0]);
354
355 std::shared_ptr<MemHandle> memHandle;
356 EXPECT_CALL((*mockEngine), dispatchPacket)
357 .Times(2)
358 .WillRepeatedly(testing::DoAll(testing::SaveArg<0>(&memHandle), (Return(Status::SUCCESS))));
359
360 EXPECT_EQ(manager->queuePacket(frame, 10), Status::SUCCESS);
361 sleep(1);
362 ASSERT_NE(memHandle, nullptr);
363 EXPECT_THAT(memHandle->getHardwareBuffer(), ContainsDataFromFrame(&frame));
364 EXPECT_THAT(memHandle->getTimeStamp(), 10);
365 EXPECT_THAT(memHandle->getStreamId(), 0);
366
367 std::shared_ptr<MemHandle> clonedMemHandle = manager->clonePacket(memHandle);
368 ASSERT_NE(clonedMemHandle, nullptr);
369 EXPECT_THAT(clonedMemHandle->getTimeStamp(), 10);
370
371 // Free packet once.
372 EXPECT_THAT(manager->freePacket(memHandle->getBufferId()), Status::SUCCESS);
373
374 // Check that new packet has not been dispatched as the old packet has not been released yet.
375 EXPECT_EQ(manager->queuePacket(frame, 20), Status::SUCCESS);
376 sleep(1);
377 EXPECT_THAT(memHandle->getTimeStamp(), 10);
378
379 // Free packet second time, this should dispatch new packet.
380 EXPECT_THAT(manager->freePacket(memHandle->getBufferId()), Status::SUCCESS);
381 EXPECT_EQ(manager->queuePacket(frame, 30), Status::SUCCESS);
382 sleep(1);
383 ASSERT_NE(memHandle, nullptr);
384 EXPECT_THAT(memHandle->getTimeStamp(), 30);
385 }
386
387
388 } // namespace
389 } // namespace stream_manager
390 } // namespace runner
391 } // namespace computepipe
392 } // namespace automotive
393 } // namespace android
394