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