xref: /aosp_15_r20/frameworks/av/services/camera/libcameraservice/tests/Camera3StreamSplitterTest.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
1 /*
2  * Copyright (C) 2024 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 #define LOG_TAG "Camera3StreamSplitterTest"
18 // #define LOG_NDEBUG 0
19 
20 #include <android/hardware_buffer.h>
21 #include <com_android_graphics_libgui_flags.h>
22 #include <com_android_internal_camera_flags.h>
23 #include <gui/BufferItemConsumer.h>
24 #include <gui/IGraphicBufferConsumer.h>
25 #include <gui/IGraphicBufferProducer.h>
26 #include <gui/Surface.h>
27 #include <ui/Fence.h>
28 #include <ui/GraphicBuffer.h>
29 #include <ui/GraphicBufferAllocator.h>
30 #include <ui/PixelFormat.h>
31 
32 #include <system/window.h>
33 #include <vndk/window.h>
34 
35 #include <gtest/gtest.h>
36 
37 #include "../device3/Flags.h"
38 
39 #if USE_NEW_STREAM_SPLITTER
40 #include "../device3/Camera3StreamSplitter.h"
41 #else
42 #include "../device3/deprecated/DeprecatedCamera3StreamSplitter.h"
43 #endif  // USE_NEW_STREAM_SPLITTER
44 
45 using namespace android;
46 
47 namespace {
48 
49 uint64_t kConsumerUsage = AHARDWAREBUFFER_USAGE_CAMERA_READ;
50 uint64_t kProducerUsage = AHARDWAREBUFFER_USAGE_CAMERA_READ;
51 size_t kHalMaxBuffers = 3;
52 uint32_t kWidth = 640;
53 uint32_t kHeight = 480;
54 PixelFormat kFormat = HAL_PIXEL_FORMAT_YCBCR_420_888;
55 int64_t kDynamicRangeProfile = 0;
56 
createConsumerAndSurface()57 std::tuple<sp<BufferItemConsumer>, sp<Surface>> createConsumerAndSurface() {
58 #if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
59     sp<BufferItemConsumer> consumer = sp<BufferItemConsumer>::make(kConsumerUsage);
60     return {consumer, consumer->getSurface()};
61 #else
62     sp<IGraphicBufferProducer> producer;
63     sp<IGraphicBufferConsumer> consumer;
64     BufferQueue::createBufferQueue(&producer, &consumer);
65 
66     return {sp<BufferItemConsumer>::make(consumer, kConsumerUsage), sp<Surface>::make(producer)};
67 #endif  // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_CONSUMER_BASE_OWNS_BQ)
68 }
69 
70 class Camera3StreamSplitterTest : public testing::Test {
71   public:
SetUp()72     void SetUp() override {
73 #if USE_NEW_STREAM_SPLITTER
74         mSplitter = sp<Camera3StreamSplitter>::make();
75 #else
76         mSplitter = sp<DeprecatedCamera3StreamSplitter>::make();
77 #endif  // USE_NEW_STREAM_SPLITTER
78     }
79 
80   protected:
81 #if USE_NEW_STREAM_SPLITTER
82     sp<Camera3StreamSplitter> mSplitter;
83 #else
84     sp<DeprecatedCamera3StreamSplitter> mSplitter;
85 #endif  // USE_NEW_STREAM_SPLITTER
86 };
87 
88 class TestSurfaceListener : public SurfaceListener {
89   public:
onBufferReleased()90     virtual void onBufferReleased() override { mNumBuffersReleased++; }
needsReleaseNotify()91     virtual bool needsReleaseNotify() { return true; }
onBufferDetached(int)92     virtual void onBufferDetached(int) override {}
onBuffersDiscarded(const std::vector<sp<GraphicBuffer>> &)93     virtual void onBuffersDiscarded(const std::vector<sp<GraphicBuffer>>&) override {};
94 
95     uint32_t mNumBuffersReleased = 0;
96 };
97 
98 class TestConsumerListener : public BufferItemConsumer::FrameAvailableListener {
99   public:
TestConsumerListener(const wp<BufferItemConsumer> & consumer)100     TestConsumerListener(const wp<BufferItemConsumer>& consumer) : mConsumer(consumer) {}
101 
onFrameAvailable(const BufferItem &)102     virtual void onFrameAvailable(const BufferItem&) {
103         sp<BufferItemConsumer> consumer = mConsumer.promote();
104         EXPECT_NE(nullptr, consumer);
105 
106         BufferItem item;
107         EXPECT_EQ(OK, consumer->acquireBuffer(&item, 0));
108         mNumBuffersAcquired++;
109         EXPECT_EQ(OK, consumer->releaseBuffer(item, Fence::NO_FENCE));
110     }
onFrameReplaced(const BufferItem &)111     virtual void onFrameReplaced(const BufferItem&) {}
onFrameDequeued(const uint64_t)112     virtual void onFrameDequeued(const uint64_t) {}
onFrameCancelled(const uint64_t)113     virtual void onFrameCancelled(const uint64_t) {}
onFrameDetached(const uint64_t)114     virtual void onFrameDetached(const uint64_t) {}
115 
116     wp<BufferItemConsumer> mConsumer;
117     uint32_t mNumBuffersAcquired = 0;
118 };
119 
120 }  // namespace
121 
TEST_F(Camera3StreamSplitterTest,WithoutSurfaces_NoBuffersConsumed)122 TEST_F(Camera3StreamSplitterTest, WithoutSurfaces_NoBuffersConsumed) {
123     sp<Surface> consumer;
124     EXPECT_EQ(OK, mSplitter->connect({}, kConsumerUsage, kProducerUsage, kHalMaxBuffers, kWidth,
125                                      kHeight, kFormat, &consumer, kDynamicRangeProfile));
126 
127     sp<TestSurfaceListener> surfaceListener = sp<TestSurfaceListener>::make();
128     EXPECT_EQ(OK, consumer->connect(NATIVE_WINDOW_API_CAMERA, surfaceListener, false));
129 
130     sp<GraphicBuffer> buffer = new GraphicBuffer(kWidth, kHeight, kFormat, kProducerUsage);
131     EXPECT_EQ(OK, consumer->attachBuffer(buffer->getNativeBuffer()));
132     // TODO: Do this with the surface itself once the API is available.
133     EXPECT_EQ(OK,
134               ANativeWindow_queueBuffer(consumer.get(), buffer->getNativeBuffer(), /*fenceFd*/ -1));
135 
136     EXPECT_EQ(0u, surfaceListener->mNumBuffersReleased);
137 }
138 
TEST_F(Camera3StreamSplitterTest,TestProcessSingleBuffer)139 TEST_F(Camera3StreamSplitterTest, TestProcessSingleBuffer) {
140     //
141     // Set up output consumers:
142     //
143     constexpr auto kSurfaceId1 = 1;
144     auto [bufferItemConsumer1, surface1] = createConsumerAndSurface();
145     sp<TestConsumerListener> consumerListener1 =
146             sp<TestConsumerListener>::make(bufferItemConsumer1);
147     bufferItemConsumer1->setFrameAvailableListener(consumerListener1);
148 
149     constexpr auto kSurfaceId2 = 2;
150     auto [bufferItemConsumer2, surface2] = createConsumerAndSurface();
151     sp<TestConsumerListener> consumerListener2 =
152             sp<TestConsumerListener>::make(bufferItemConsumer2);
153     bufferItemConsumer2->setFrameAvailableListener(consumerListener2);
154 
155     //
156     // Connect it to the splitter, get the input surface, and set it up:
157     //
158     sp<Surface> inputSurface;
159     EXPECT_EQ(OK, mSplitter->connect({{kSurfaceId1, surface1}, {kSurfaceId2, surface2}},
160                                      kConsumerUsage, kProducerUsage, kHalMaxBuffers, kWidth,
161                                      kHeight, kFormat, &inputSurface, kDynamicRangeProfile));
162     sp<TestSurfaceListener> surfaceListener = sp<TestSurfaceListener>::make();
163     EXPECT_EQ(OK, inputSurface->connect(NATIVE_WINDOW_API_CAMERA, surfaceListener, false));
164     // TODO: Do this with the surface itself once the API is available.
165     EXPECT_EQ(OK, inputSurface->getIGraphicBufferProducer()->allowAllocation(false));
166 
167     //
168     // Create a buffer to use:
169     //
170     sp<GraphicBuffer> singleBuffer = new GraphicBuffer(kWidth, kHeight, kFormat, kProducerUsage);
171     EXPECT_NE(nullptr, singleBuffer);
172     mSplitter->attachBufferToOutputs(singleBuffer->getNativeBuffer(), {kSurfaceId1, kSurfaceId2});
173 
174     //
175     // Verify that when we attach the buffer, it's processed appropriately:
176     //
177     EXPECT_EQ(OK, inputSurface->attachBuffer(singleBuffer->getNativeBuffer()));
178     EXPECT_EQ(OK, mSplitter->getOnFrameAvailableResult());
179     // TODO: Do this with the surface itself once the API is available.
180     EXPECT_EQ(OK, ANativeWindow_queueBuffer(inputSurface.get(), singleBuffer->getNativeBuffer(),
181                                             /*fenceFd*/ -1));
182 
183     EXPECT_EQ(1u, consumerListener1->mNumBuffersAcquired);
184     EXPECT_EQ(1u, consumerListener2->mNumBuffersAcquired);
185     EXPECT_EQ(1u, surfaceListener->mNumBuffersReleased);
186 }
187