1/*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef CAMERA_DEMO_TEST_H
17#define CAMERA_DEMO_TEST_H
18
19#include <list>
20#include <memory>
21#include <mutex>
22#include <string>
23#include <thread>
24#include <vector>
25#include <gtest/gtest.h>
26#include "display_format.h"
27#include "ibuffer.h"
28#include "ibuffer_pool.h"
29#include "surface.h"
30#include "ibuffer_consumer_listener.h"
31
32namespace OHOS::CameraUtest {
33using namespace OHOS::Camera;
34
35class BufferManagerTest : public testing::Test {
36public:
37    static void SetUpTestCase(void);
38    static void TearDownTestCase(void);
39
40    void SetUp(void);
41    void TearDown(void);
42
43public:
44    class Stream {
45    public:
46        Stream() = default;
47        ~Stream() = default;
48#ifdef CAMERA_BUILT_ON_OHOS_LITE
49        bool Init(std::shared_ptr<OHOS::Surface>& producer);
50#else
51        bool Init(OHOS::sptr<OHOS::IBufferProducer>& producer);
52#endif
53        void StartStream();
54        void StopStream();
55        void EnqueueBufferNonBlock();
56        void DequeueBuffer(std::shared_ptr<IBuffer>& buffer);
57        std::shared_ptr<IBufferPool> GetBufferPool() const;
58        int64_t GetPoolId() const
59        {
60            return bufferPoolId_;
61        }
62
63    private:
64        void StartInnerStream() const;
65        void StartExternalStream();
66
67    private:
68        std::mutex lock_;
69#ifdef CAMERA_BUILT_ON_OHOS_LITE
70        std::shared_ptr<OHOS::Surface> producer_ = nullptr;
71#else
72        OHOS::sptr<OHOS::Surface> producer_ = nullptr;
73#endif
74
75        uint32_t width_ = 1920;
76        uint32_t height_ = 1080;
77        uint32_t queueSize_ = 7;
78        uint64_t usage_ = CAMERA_USAGE_SW_WRITE_OFTEN | CAMERA_USAGE_SW_READ_OFTEN | CAMERA_USAGE_MEM_DMA;
79        uint32_t format_ = CAMERA_FORMAT_YCBCR_420_SP;
80        int64_t bufferPoolId_ = -1;
81
82        std::shared_ptr<IBufferPool> bufferPool_ = nullptr;
83
84#ifdef CAMERA_BUILT_ON_OHOS_LITE
85        std::vector<std::pair<OHOS::SurfaceBuffer*, std::shared_ptr<IBuffer>>> bufferVec_ = {};
86#else
87        std::vector<std::pair<OHOS::sptr<OHOS::SurfaceBuffer>, std::shared_ptr<IBuffer>>> bufferVec_ = {};
88        int32_t releaseFence_ = 0;
89        OHOS::BufferRequestConfig requestConfig_ = {};
90        OHOS::BufferFlushConfig flushConfig_ = {};
91#endif
92    };
93
94#ifndef CAMERA_BUILT_ON_OHOS_LITE
95    class TestBufferConsumerListener : public IBufferConsumerListener {
96        public:
97            TestBufferConsumerListener()
98            {
99            }
100
101            ~TestBufferConsumerListener()
102            {
103            }
104
105            void OnBufferAvailable()
106            {
107            }
108    };
109#endif
110
111    class Node {
112    public:
113        explicit Node(const std::string name) : name_(name) {}
114        virtual ~Node() = default;
115
116        virtual void Connect(std::shared_ptr<Node>& nextNode);
117        virtual void Deliver(std::shared_ptr<IBuffer>& buffer);
118        virtual void Receive(std::shared_ptr<IBuffer>& buffer);
119        virtual void Process(std::shared_ptr<IBuffer>& buffer);
120        virtual std::string GetName() const;
121
122    private:
123        std::string name_ = "";
124        std::shared_ptr<Node> nextNode_ = nullptr;
125
126    private:
127        Node() = default;
128    };
129
130    class SinkNode : public Node {
131    public:
132        explicit SinkNode(const std::string& name) : Node(name) {}
133        ~SinkNode() override {}
134        void Deliver(std::shared_ptr<IBuffer>& buffer) override;
135        void BindCallback(const std::function<void(std::shared_ptr<IBuffer>&)>& func);
136
137    private:
138        std::function<void(std::shared_ptr<IBuffer>&)> callback_ = nullptr;
139    };
140
141    class SourceNode : public Node {
142    public:
143        explicit SourceNode(const std::string name) : Node(name) {}
144        void Process(std::shared_ptr<IBuffer>& buffer) override;
145        ~SourceNode() override {}
146    private:
147        int cacheSize_ = 3;
148        std::list<std::shared_ptr<IBuffer>> cache_ = {};
149    };
150
151    class Pipeline {
152    public:
153        Pipeline() = default;
154        ~Pipeline() = default;
155
156        bool AddStream(const std::shared_ptr<Stream>& stream);
157        void StartStream();
158        void StopStream();
159
160    private:
161        void CollectBuffers();
162        void DeliverBuffer();
163        void DeliverBuffer(std::shared_ptr<IBuffer>& buffer);
164        bool BuildPipeline();
165
166    private:
167        bool running = true;
168        std::mutex streamLock_;
169        std::thread* collectThread_ = nullptr;
170        std::shared_ptr<Node> sourceNode_ = nullptr;
171        uint64_t frameNumber_ = 0;
172
173        struct LocalStream {
174            std::mutex deviceLock;
175            std::shared_ptr<Stream> stream = nullptr;
176            std::thread* deliverThread = nullptr;
177            std::list<std::shared_ptr<IBuffer>> deviceBufferList = {};
178        };
179        std::shared_ptr<LocalStream> localStream_ = nullptr;
180    };
181};
182} // namespace OHOS::CameraUtest
183#endif // CAMERA_DEMO_TEST_H
184