• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "buffer_manager_utest.h"
17 #include <chrono>
18 #include <iostream>
19 #include <sys/wait.h>
20 #include <unistd.h>
21 #include "buffer_adapter.h"
22 #include "buffer_allocator_utils.h"
23 #include "buffer_manager.h"
24 #include "buffer_tracking.h"
25 #include "image_buffer.h"
26 #include "securec.h"
27 
28 using namespace OHOS;
29 using namespace OHOS::CameraUtest;
30 using namespace testing::ext;
31 
32 namespace {
33     const int FRAME_INTERVAL_US = 33000; // 33ms
34     const int FRAME_RUN_TIME_S = 3;      // 3s
35 }
36 
SetUpTestCase(void)37 void BufferManagerTest::SetUpTestCase(void)
38 {
39     std::cout << "Camera::BufferManager SetUpTestCase" << std::endl;
40 }
41 
TearDownTestCase(void)42 void BufferManagerTest::TearDownTestCase(void)
43 {
44     std::cout << "Camera::BufferManager TearDownTestCase" << std::endl;
45 }
46 
SetUp(void)47 void BufferManagerTest::SetUp(void)
48 {
49     std::cout << "Camera::BufferManager SetUp" << std::endl;
50 }
51 
TearDown(void)52 void BufferManagerTest::TearDown(void)
53 {
54     std::cout << "Camera::BufferManager TearDown.." << std::endl;
55 }
56 
57 HWTEST_F(BufferManagerTest, TestBufferQueueLoop, TestSize.Level0)
58 {
59     bool running = true;
60 #ifdef CAMERA_BUILT_ON_OHOS_LITE
61     std::shared_ptr<OHOS::Surface> consumer =
62         std::shared_ptr<OHOS::Surface>(OHOS::Surface::CreateSurface());
__anon003b7ddb0202null63     std::thread consumerThread([&consumer, &running] {
64         while (running) {
65             OHOS::SurfaceBuffer* buffer = consumer->AcquireBuffer();
66             if (buffer != nullptr) {
67                 consumer->ReleaseBuffer(buffer);
68                 std::cout << "receive a buffer ..." << std::endl;
69             }
70         }
71     });
72     std::shared_ptr<OHOS::Surface> producer = consumer;
73 #else
74     OHOS::sptr<OHOS::Surface> consumer = Surface::CreateSurfaceAsConsumer();
75     sptr<IBufferConsumerListener> listener = new TestBufferConsumerListener();
76     consumer->RegisterConsumerListener(listener);
77 
78     auto producer = consumer->GetProducer();
79     EXPECT_EQ(false, producer == nullptr);
__anon003b7ddb0302null80     std::thread consumerThread([&consumer, &running] {
81         int32_t flushFence = 0;
82         int64_t timestamp = 0;
83         Rect damage;
84         while (running) {
85             sptr<SurfaceBuffer> buffer = nullptr;
86             consumer->AcquireBuffer(buffer, flushFence, timestamp, damage);
87             if (buffer != nullptr) {
88                 SurfaceError ret = consumer->ReleaseBuffer(buffer, -1);
89                 if (ret == SURFACE_ERROR_OK) {
90                     std::cout << "receive a buffer ..." << std::endl;
91                 }
92             }
93         }
94     });
95 #endif
96 
97     // HDI impl start from here
98     auto stream = std::make_shared<BufferManagerTest::Stream>();
99     stream->Init(producer);
100     stream->StartStream();
101 
102     BufferManagerTest::Pipeline pipeline;
103     pipeline.AddStream(stream);
104 
__anon003b7ddb0402null105     std::thread enqueueThread([&stream, &running] {
106         while (running == true) {
107             stream->EnqueueBufferNonBlock();
108         }
109     });
110     pipeline.StartStream();
111 
112     std::this_thread::sleep_for(std::chrono::seconds(10));
113     running = false;
114     enqueueThread.join();
115     pipeline.StopStream();
116     stream->StopStream();
117 
118     running = false;
119     consumerThread.join();
120 }
121 
122 HWTEST_F(BufferManagerTest, TestGetBufferPool, TestSize.Level0)
123 {
124     Camera::BufferManager* manager = Camera::BufferManager::GetInstance();
125     EXPECT_EQ(true, manager != nullptr);
126 
127     int64_t bufferPoolId = manager->GenerateBufferPoolId();
128     EXPECT_EQ(true, bufferPoolId != 0);
129 
130     std::shared_ptr<IBufferPool> bufferPool1 = nullptr;
__anon003b7ddb0502null131     std::thread user1([&manager, &bufferPool1, &bufferPoolId] { bufferPool1 = manager->GetBufferPool(bufferPoolId); });
132 
133     std::shared_ptr<IBufferPool> bufferPool2 = nullptr;
__anon003b7ddb0602null134     std::thread user2([&manager, &bufferPool2, &bufferPoolId] { bufferPool2 = manager->GetBufferPool(bufferPoolId); });
135 
136     user1.join();
137     user2.join();
138 
139     EXPECT_EQ(true, bufferPool1 != nullptr);
140     EXPECT_EQ(true, bufferPool1 == bufferPool2);
141 
142     int64_t bufferPoolId2 = manager->GenerateBufferPoolId();
143     EXPECT_EQ(true, bufferPoolId != 0);
144     std::shared_ptr<IBufferPool> bufferPool3 = manager->GetBufferPool(bufferPoolId2);
145     EXPECT_EQ(true, bufferPool1 != bufferPool3);
146 
147     std::shared_ptr<IBufferPool> nullbufferPool = manager->GetBufferPool(1);
148     EXPECT_EQ(true, nullbufferPool == nullptr);
149 }
150 
151 HWTEST_F(BufferManagerTest, TestHeapBuffer, TestSize.Level0)
152 {
153     Camera::BufferManager* manager = Camera::BufferManager::GetInstance();
154     EXPECT_EQ(true, manager != nullptr);
155 
156     int64_t bufferPoolId = manager->GenerateBufferPoolId();
157     EXPECT_EQ(true, bufferPoolId != 0);
158 
159     std::shared_ptr<IBuffer> buffer;
160     {
161         std::shared_ptr<IBufferPool> bufferPool = manager->GetBufferPool(bufferPoolId);
162         EXPECT_EQ(true, bufferPool != nullptr);
163 
164         RetCode rc = bufferPool->Init(2, 1, CAMERA_USAGE_SW_WRITE_OFTEN, CAMERA_FORMAT_YCBCR_422_P, 1,
165                                       CAMERA_BUFFER_SOURCE_TYPE_HEAP);
166         EXPECT_EQ(true, rc == RC_OK);
167 
168         buffer = bufferPool->AcquireBuffer();
169         EXPECT_EQ(true, buffer != nullptr);
170         EXPECT_EQ(true, buffer->GetVirAddress() != nullptr);
171         EXPECT_EQ(true, buffer->GetWidth() == 2);
172         EXPECT_EQ(true, buffer->GetHeight() == 1);
173         EXPECT_EQ(true, buffer->GetUsage() == CAMERA_USAGE_SW_WRITE_OFTEN);
174         EXPECT_EQ(true, buffer->GetFormat() == CAMERA_FORMAT_YCBCR_422_P);
175         EXPECT_EQ(true, buffer->GetSize() == 4);
176 
177         char src[4] = {'t', 'e', 's', 't'};
178         char* dest = reinterpret_cast<char*>(buffer->GetVirAddress());
179         EXPECT_EQ(true, dest != nullptr);
180         (void)memcpy_s(dest, sizeof(char) * 4, src, sizeof(char) * 4);
181         EXPECT_EQ(true, 0 == ::memcmp(src, dest, 4));
182 
183         EXPECT_EQ(true, RC_OK == bufferPool->ReturnBuffer(buffer));
184     }
185     EXPECT_EQ(true, buffer->GetVirAddress() == nullptr);
186 }
187 
188 #ifndef CAMERA_BUILT_ON_OHOS_LITE
189 HWTEST_F(BufferManagerTest, TestGrallocBuffer, TestSize.Level0)
190 {
191     Camera::BufferManager* manager = Camera::BufferManager::GetInstance();
192     EXPECT_EQ(true, manager != nullptr);
193 
194     uint32_t formatTest[] = {CAMERA_FORMAT_YCBCR_420_SP, CAMERA_FORMAT_YCRCB_420_SP,
195                              CAMERA_FORMAT_YCBCR_420_P, CAMERA_FORMAT_YCRCB_420_P};
196     for (auto f : formatTest) {
197         int64_t bufferPoolId = manager->GenerateBufferPoolId();
198         EXPECT_EQ(true, bufferPoolId != 0);
199 
200         std::shared_ptr<IBufferPool> bufferPool = manager->GetBufferPool(bufferPoolId);
201         EXPECT_EQ(true, bufferPool != nullptr);
202 
203         RetCode rc = RC_ERROR;
204         rc = bufferPool->Init(1280, 720,
205                               CAMERA_USAGE_SW_WRITE_OFTEN | CAMERA_USAGE_SW_READ_OFTEN | CAMERA_USAGE_MEM_DMA, f, 3,
206                               CAMERA_BUFFER_SOURCE_TYPE_HEAP);
207         EXPECT_EQ(true, rc == RC_OK);
208     }
209 }
210 #endif
211 
212 HWTEST_F(BufferManagerTest, TestInternalBufferLoop, TestSize.Level0)
213 {
214     Camera::BufferManager* manager = Camera::BufferManager::GetInstance();
215     EXPECT_EQ(true, manager != nullptr);
216     int64_t bufferPoolId = manager->GenerateBufferPoolId();
217     EXPECT_EQ(true, bufferPoolId != 0);
218     std::shared_ptr<IBufferPool> bufferPool = manager->GetBufferPool(bufferPoolId);
219     EXPECT_EQ(true, bufferPool != nullptr);
220     int count = 5;
221     RetCode rc = bufferPool->Init(1280, 720, CAMERA_USAGE_SW_WRITE_OFTEN, CAMERA_FORMAT_YCBCR_422_P, count,
222                                   CAMERA_BUFFER_SOURCE_TYPE_HEAP);
223     EXPECT_EQ(true, rc == RC_OK);
224     std::vector<std::shared_ptr<IBuffer>> bufferVector;
225     for (int i = 0; i < count; i++) {
226         auto buffer = bufferPool->AcquireBuffer();
227         if (buffer != nullptr) {
228             bufferVector.emplace_back(buffer);
229         }
230     }
231     EXPECT_EQ(true, 5 == bufferVector.size());
232     EXPECT_EQ(true, bufferPool->AcquireBuffer() == nullptr);
233     auto begin = std::chrono::system_clock::now();
234     auto nullBuffer = bufferPool->AcquireBuffer(1);
235     auto end = std::chrono::system_clock::now();
236     auto timeElapsed = std::chrono::duration_cast<std::chrono::microseconds>(end - begin);
237     std::cout << "timeElapsed = " << timeElapsed.count() << std::endl;
238     EXPECT_EQ(true,
239               timeElapsed >= std::chrono::microseconds(1000000) && timeElapsed < std::chrono::microseconds(1100000));
240     EXPECT_EQ(true, nullBuffer == nullptr);
241     int32_t id = bufferVector[1]->GetIndex();
242     EXPECT_EQ(true, bufferPool->ReturnBuffer(bufferVector[1]) == RC_OK);
243     begin = std::chrono::system_clock::now();
244     nullBuffer = bufferPool->AcquireBuffer(1);
245     end = std::chrono::system_clock::now();
246     timeElapsed = std::chrono::duration_cast<std::chrono::microseconds>(end - begin);
247     EXPECT_EQ(true, timeElapsed < std::chrono::microseconds(1000000));
248     EXPECT_EQ(true, id == nullBuffer->GetIndex());
249     id = bufferVector[3]->GetIndex();
__anon003b7ddb0702null250     std::thread task([&bufferPool, &bufferVector] {
251         std::this_thread::sleep_for(std::chrono::seconds(5));
252         bufferPool->ReturnBuffer(bufferVector[3]);
253     });
254     begin = std::chrono::system_clock::now();
255     auto lastBuffer = bufferPool->AcquireBuffer(-1);
256     end = std::chrono::system_clock::now();
257     task.join();
258     timeElapsed = std::chrono::duration_cast<std::chrono::microseconds>(end - begin);
259     EXPECT_EQ(true, timeElapsed <= std::chrono::microseconds(5000000 + 10000) &&
260                         timeElapsed >= std::chrono::microseconds(5000000 - 10000));
261     EXPECT_EQ(true, lastBuffer != nullptr);
262     EXPECT_EQ(true, id == lastBuffer->GetIndex());
263 }
264 
265 HWTEST_F(BufferManagerTest, TestExternalBufferLoop, TestSize.Level0)
266 {
267     Camera::BufferManager* manager = Camera::BufferManager::GetInstance();
268     EXPECT_EQ(true, manager != nullptr);
269     int64_t bufferPoolId = manager->GenerateBufferPoolId();
270     EXPECT_EQ(true, bufferPoolId != 0);
271     std::shared_ptr<IBufferPool> bufferPool = manager->GetBufferPool(bufferPoolId);
272     EXPECT_EQ(true, bufferPool != nullptr);
273     int count = 5;
274     RetCode rc = bufferPool->Init(1280, 720, CAMERA_USAGE_SW_WRITE_OFTEN, CAMERA_FORMAT_YCBCR_422_P, count,
275                                   CAMERA_BUFFER_SOURCE_TYPE_EXTERNAL);
276     EXPECT_EQ(true, rc == RC_OK);
277     std::list<std::shared_ptr<IBuffer>> idleList;
278     std::list<std::shared_ptr<IBuffer>> busyList;
279     for (int i = 0; i < count; i++) {
280         std::shared_ptr<IBuffer> buffer = std::make_shared<ImageBuffer>();
281         buffer->SetIndex(i);
282         busyList.emplace_back(buffer);
283         bufferPool->AddBuffer(buffer);
284         std::cout << "Add buffer : " << i << std::endl;
285     }
286     bool running = true;
287     std::mutex lock;
288     int realFrameCount = 0;
__anon003b7ddb0802null289     std::thread dispatchBufferTask([&running, &idleList, &busyList, &bufferPool, &lock, &realFrameCount] {
290         while (running) {
291             std::lock_guard<std::mutex> l(lock);
292             if (idleList.empty()) {
293                 continue;
294             }
295             auto it = idleList.begin();
296             if (RC_OK == bufferPool->AddBuffer(*it)) {
297                 busyList.splice(busyList.begin(), idleList, it);
298                 std::cout << "Enq buffer : " << (*it)->GetIndex() << std::endl;
299                 realFrameCount++;
300             }
301         }
302     });
303     std::list<std::shared_ptr<IBuffer>> inuseBufferList;
__anon003b7ddb0902null304     std::thread acquireBufferTask([&running, &bufferPool, &lock, &inuseBufferList] {
305         while (running) {
306             auto buffer = bufferPool->AcquireBuffer(2);
307             if (buffer != nullptr) {
308                 std::lock_guard<std::mutex> l(lock);
309                 inuseBufferList.emplace_back(buffer);
310             }
311         }
312     });
__anon003b7ddb0a02null313     std::thread returnBufferTask([&running, &lock, &inuseBufferList, &bufferPool, &busyList, &idleList] {
314         while (running) {
315             std::this_thread::sleep_for(std::chrono::microseconds(FRAME_INTERVAL_US));
316             {
317                 std::lock_guard<std::mutex> l(lock);
318                 if (inuseBufferList.empty()) {
319                     continue;
320                 }
321                 auto it = inuseBufferList.begin();
322                 bufferPool->ReturnBuffer(*it);
323                 auto retBufferIt = std::find(busyList.begin(), busyList.end(), *it);
324                 if (retBufferIt != busyList.end()) {
325                     idleList.splice(idleList.end(), busyList, retBufferIt);
326                     std::cout << "Deq buffer : " << (*retBufferIt)->GetIndex() << std::endl;
327                 }
328                 inuseBufferList.erase(it);
329             }
330         }
331     });
332     std::this_thread::sleep_for(std::chrono::seconds(3));
333     running = false;
334     dispatchBufferTask.join();
335     acquireBufferTask.join();
336     returnBufferTask.join();
337     int expectFrameCount = FRAME_RUN_TIME_S * 1000 * 1000 / FRAME_INTERVAL_US;
338     std::cout << "expectFrameCount = " << expectFrameCount << ", realFrameCount = " << realFrameCount << std::endl;
339     EXPECT_EQ(true, realFrameCount >= expectFrameCount / 2 && realFrameCount <= expectFrameCount + 5);
340 }
341 
342 HWTEST_F(BufferManagerTest, TestTrackingBufferLoop, TestSize.Level0)
343 {
344 #ifdef CAMERA_BUILT_ON_OHOS_LITE
345     std::shared_ptr<OHOS::Surface> producer = nullptr;
346 #else
347     sptr<OHOS::IBufferProducer> producer = nullptr;
348 #endif
349     // HDI impl start from here
350     bool running = true;
351     auto stream = std::make_shared<Stream>();
352     stream->Init(producer);
353     stream->StartStream();
354 
355     Pipeline pipeline;
356     pipeline.AddStream(stream);
357 
__anon003b7ddb0b02null358     std::thread enqueueThread([&stream, &running] {
359         while (running == true) {
360             stream->EnqueueBufferNonBlock();
361         }
362     });
363     pipeline.StartStream();
364 
365     std::this_thread::sleep_for(std::chrono::seconds(3));
366     int32_t emptyCheck1 = BufferTracking::IsNodeEmpty(0, "SourceNode");
367     int32_t emptyCheck2 = BufferTracking::IsNodeEmpty(0, "SourceNode", "SinkNode");
368     BufferTraceGraph graph{};
369     BufferTracking::DumpBufferTrace(0, graph);
370     running = false;
371     enqueueThread.join();
372     pipeline.StopStream();
373     stream->StopStream();
374     EXPECT_EQ(true, emptyCheck1 == NODE_IS_NOT_EMPTY);
375     EXPECT_EQ(true, emptyCheck2 == NODE_IS_NOT_EMPTY);
376     EXPECT_EQ(true, graph.size() == 10);
377     EXPECT_EQ(true, graph.front().first == "SourceNode");
378     EXPECT_EQ(true, graph.front().second.size() == 3);
379     EXPECT_EQ(true, graph.back().first == "SinkNode");
380     EXPECT_EQ(true, graph.back().second.size() < 2);
381     for (auto it = graph.begin(); it != graph.end(); it++) {
382         std::cout << "node [" << it->first << "] has buffer {";
383         for (auto& b : it->second) {
384             std::cout << static_cast<uint32_t>(b.GetFrameNumber()) << ", ";
385         }
386         std::cout << "}" << std::endl;
387     }
388 }
389 
390 namespace OHOS::CameraUtest {
391 #ifdef CAMERA_BUILT_ON_OHOS_LITE
Init(std::shared_ptr<OHOS::Surface> & producer)392 bool BufferManagerTest::Stream::Init(std::shared_ptr<OHOS::Surface>& producer)
393 {
394     Camera::BufferManager* manager = Camera::BufferManager::GetInstance();
395     if (manager == nullptr) {
396         return false;
397     }
398     bufferPoolId_ = manager->GenerateBufferPoolId();
399     if (bufferPoolId_ == 0) {
400         return false;
401     }
402     bufferPool_ = manager->GetBufferPool(bufferPoolId_);
403     if (bufferPool_ == nullptr) {
404         return false;
405     }
406     RetCode rc = RC_ERROR;
407     if (producer == nullptr) {
408         rc = bufferPool_->Init(width_, height_, usage_, format_, queueSize_, CAMERA_BUFFER_SOURCE_TYPE_HEAP);
409         std::cout << "init inner buffer loop" << std::endl;
410     }
411     if (producer_ != nullptr) {
412         producer_->SetQueueSize(queueSize_);
413         if (producer_->GetQueueSize() != queueSize_) {
414             return false;
415         }
416         producer_->SetWidthAndHeight(width_, height_);
417         producer_->SetFormat(BufferAdapter::CameraFormatToPixelFormat(format_));
418         producer_->SetStrideAlignment(8); // 8:value of strideAlignment
419         rc = bufferPool_->Init(width_, height_, usage_, format_, queueSize_, CAMERA_BUFFER_SOURCE_TYPE_EXTERNAL);
420         std::cout << "init external buffer loop" << std::endl;
421     }
422     if (rc != RC_OK) {
423         return false;
424     }
425 
426     return true;
427 }
428 #else
429 bool BufferManagerTest::Stream::Init(sptr<IBufferProducer>& producer)
430 {
431     Camera::BufferManager* manager = Camera::BufferManager::GetInstance();
432     if (manager == nullptr) {
433         return false;
434     }
435     bufferPoolId_ = manager->GenerateBufferPoolId();
436     if (bufferPoolId_ == 0) {
437         return false;
438     }
439     bufferPool_ = manager->GetBufferPool(bufferPoolId_);
440     if (bufferPool_ == nullptr) {
441         return false;
442     }
443     RetCode rc = RC_ERROR;
444     if (producer == nullptr) {
445         rc = bufferPool_->Init(width_, height_, usage_, format_, queueSize_, CAMERA_BUFFER_SOURCE_TYPE_HEAP);
446         std::cout << "init inner buffer loop" << std::endl;
447     }
448     if (producer != nullptr) {
449         producer_ = Surface::CreateSurfaceAsProducer(producer);
450         producer_->SetQueueSize(queueSize_);
451         if (producer_->GetQueueSize() != queueSize_) {
452             return false;
453         }
454 
455         requestConfig_.width = static_cast<int32_t>(width_);
456         requestConfig_.height = static_cast<int32_t>(height_);
457         requestConfig_.strideAlignment = 8; // 8:value of strideAlignment
458         requestConfig_.format = static_cast<int32_t>(BufferAdapter::CameraFormatToPixelFormat(format_));
459         requestConfig_.usage = static_cast<int32_t>(BufferAdapter::CameraUsageToGrallocUsage(usage_));
460         requestConfig_.timeout = 0;
461         flushConfig_.damage.x = 0;
462         flushConfig_.damage.y = 0;
463         flushConfig_.damage.w = width_;
464         flushConfig_.damage.h = height_;
465         flushConfig_.timestamp = 0;
466         rc = bufferPool_->Init(width_, height_, usage_, format_, queueSize_, CAMERA_BUFFER_SOURCE_TYPE_EXTERNAL);
467         std::cout << "init external buffer loop" << std::endl;
468     }
469     if (rc != RC_OK) {
470         return false;
471     }
472 
473     return true;
474 }
475 #endif
476 
StartInnerStream() const477 void BufferManagerTest::Stream::StartInnerStream() const
478 {
479     if (producer_ != nullptr) {
480         return;
481     }
482     std::cout << "start inner buffer loop" << std::endl;
483     return;
484 }
485 
StartExternalStream()486 void BufferManagerTest::Stream::StartExternalStream()
487 {
488     if (producer_ == nullptr) {
489         return;
490     }
491 
492     for (uint32_t indexOfSize = 0; indexOfSize < queueSize_; indexOfSize++) {
493 #ifdef CAMERA_BUILT_ON_OHOS_LITE
494     OHOS::SurfaceBuffer *sb = nullptr;
495     sb = producer_->RequestBuffer();
496 #else
497         sptr<SurfaceBuffer> sb = nullptr;
498         SurfaceError ret = producer_->RequestBuffer(sb, releaseFence_, requestConfig_);
499         if (ret != SURFACE_ERROR_OK) {
500             continue;
501         }
502 #endif
503         if (sb == nullptr) {
504             continue;
505         }
506         std::cout << "request a buffer ..." << std::endl;
507 
508         std::shared_ptr<IBuffer> cameraBuffer = std::make_shared<ImageBuffer>(CAMERA_BUFFER_SOURCE_TYPE_EXTERNAL);
509 #ifdef CAMERA_BUILT_ON_OHOS_LITE
510         RetCode rc = BufferAdapter::SurfaceBufferToCameraBuffer(sb, producer_, cameraBuffer);
511 #else
512         RetCode rc = BufferAdapter::SurfaceBufferToCameraBuffer(sb, cameraBuffer);
513 #endif
514         if (rc != RC_OK) {
515             continue;
516         }
517 
518         {
519             std::lock_guard<std::mutex> l(lock_);
520             bufferVec_.emplace_back(std::make_pair(sb, cameraBuffer));
521         }
522 
523         if (bufferPool_ == nullptr) {
524             continue;
525         }
526         bufferPool_->AddBuffer(cameraBuffer);
527         std::cout << "Add buffer ..." << std::endl;
528     }
529 
530     std::cout << "start external buffer loop" << std::endl;
531 
532     return;
533 }
534 
StartStream()535 void BufferManagerTest::Stream::StartStream()
536 {
537     if (producer_ == nullptr) {
538         StartInnerStream();
539         return;
540     }
541 
542     if (producer_ != nullptr) {
543         StartExternalStream();
544         return;
545     }
546 
547     return;
548 }
549 
EnqueueBufferNonBlock()550 void BufferManagerTest::Stream::EnqueueBufferNonBlock()
551 {
552     if (producer_ == nullptr) {
553         return;
554     }
555 
556 #ifdef CAMERA_BUILT_ON_OHOS_LITE
557     OHOS::SurfaceBuffer *sb = nullptr;
558     sb = producer_->RequestBuffer();
559 #else
560     sptr<SurfaceBuffer> sb = nullptr;
561     SurfaceError ret = producer_->RequestBuffer(sb, releaseFence_, requestConfig_);
562     if (ret != SURFACE_ERROR_OK) {
563         return;
564     }
565 #endif
566     if (sb == nullptr) {
567         return;
568     }
569 
570     std::cout << "find buffer begin ..." << std::endl;
571     std::shared_ptr<IBuffer> buffer = nullptr;
572     {
573         std::lock_guard<std::mutex> l(lock_);
574         for (auto& it : bufferVec_) {
575             if (it.first == sb) {
576                 buffer = it.second;
577                 break;
578             }
579         }
580     }
581     if (buffer == nullptr) {
582         return;
583     }
584     std::cout << "find buffer end ..." << std::endl;
585     bufferPool_->AddBuffer(buffer);
586     std::cout << "enqueue buffer ..." << std::endl;
587 
588     return;
589 }
590 
DequeueBuffer(std::shared_ptr<IBuffer> & buffer)591 void BufferManagerTest::Stream::DequeueBuffer(std::shared_ptr<IBuffer>& buffer)
592 {
593     if (buffer == nullptr) {
594         return;
595     }
596 
597     if (bufferPool_ == nullptr) {
598         return;
599     }
600 
601     std::cout << "ready to dequeue buffer ..." << std::endl;
602     bufferPool_->ReturnBuffer(buffer);
603 
604     if (producer_ != nullptr) {
605 #ifdef CAMERA_BUILT_ON_OHOS_LITE
606         SurfaceBuffer* surfaceBuffer = nullptr;
607 #else
608         sptr<SurfaceBuffer> surfaceBuffer = nullptr;
609 #endif
610         {
611             std::lock_guard<std::mutex> l(lock_);
612             for (auto& it : bufferVec_) {
613                 if (it.second == buffer) {
614                     surfaceBuffer = it.first;
615                     break;
616                 }
617             }
618         }
619 
620         if (surfaceBuffer == nullptr) {
621             return;
622         }
623 
624 #ifdef CAMERA_BUILT_ON_OHOS_LITE
625         int32_t ret = producer_->FlushBuffer(surfaceBuffer);
626         if (ret != 0) {
627             std::cout << "flush buffer failed ..." << std::endl;
628         }
629 #else
630         SurfaceError ret = producer_->FlushBuffer(surfaceBuffer, -1, flushConfig_);
631         if (ret != SURFACE_ERROR_OK) {
632             std::cout << "flush buffer failed ..." << std::endl;
633         }
634 #endif
635     }
636 
637     std::cout << "dequeue buffer ..." << std::endl;
638 
639     return;
640 }
641 
StopStream()642 void BufferManagerTest::Stream::StopStream()
643 {
644     return;
645 }
646 
GetBufferPool() const647 std::shared_ptr<IBufferPool> BufferManagerTest::Stream::GetBufferPool() const
648 {
649     return bufferPool_;
650 }
651 
AddStream(std::shared_ptr<Stream> & stream)652 bool BufferManagerTest::Pipeline::AddStream(std::shared_ptr<Stream>& stream)
653 {
654     std::lock_guard<std::mutex> l(streamLock_);
655     localStream_ = std::make_shared<LocalStream>();
656     if (localStream_ == nullptr) {
657         return false;
658     }
659     localStream_->stream = stream;
660     return true;
661 }
662 
StartStream()663 void BufferManagerTest::Pipeline::StartStream()
664 {
665     running = true;
666     CollectBuffers();
667     BuildPipeline();
668     DeliverBuffer();
669 
670     BufferTracking::StartTracking();
671     return;
672 }
673 
BuildPipeline()674 bool BufferManagerTest::Pipeline::BuildPipeline()
675 {
676     BufferTracking::AddTrackingStreamBegin(0, localStream_->stream->GetPoolId());
677     sourceNode_ = std::make_shared<SourceNode>("SourceNode");
678     if (sourceNode_ == nullptr) {
679         return false;
680     }
681     BufferTracking::AddTrackingNode(0, sourceNode_->GetName());
682     std::shared_ptr<Node> tmpNode = sourceNode_;
683     for (int i = 1; i < 9; i++) { // 9: numbers of node
684         std::string name = "node";
685         name += std::to_string(i);
686         auto n = std::make_shared<Node>(name);
687         tmpNode->Connect(n);
688         tmpNode = n;
689         BufferTracking::AddTrackingNode(0, tmpNode->GetName());
690     }
691 
692     auto sinkNode = std::make_shared<SinkNode>(std::string("SinkNode"));
693     if (sinkNode == nullptr) {
694         return false;
695     }
696     sinkNode->BindCallback([this](std::shared_ptr<IBuffer>& buffer) { localStream_->stream->DequeueBuffer(buffer); });
697     std::shared_ptr<Node> node = sinkNode;
698     tmpNode->Connect(node);
699     BufferTracking::AddTrackingNode(0, sinkNode->GetName());
700     BufferTracking::AddTrackingStreamEnd(0);
701 
702     return true;
703 }
704 
CollectBuffers()705 void BufferManagerTest::Pipeline::CollectBuffers()
706 {
707     collectThread_ = new std::thread([this] {
708         while (running == true) {
709             auto bufferPool = localStream_->stream->GetBufferPool();
710             if (bufferPool == nullptr) {
711                 continue;
712             }
713             auto buffer = bufferPool->AcquireBuffer(3); // 3:Minimum number of buffer rotation
714             if (buffer == nullptr) {
715                 continue;
716             }
717 
718             std::lock_guard<std::mutex> deviceL(localStream_->deviceLock);
719             localStream_->deviceBufferList.emplace_back(buffer);
720         }
721     });
722 
723     return;
724 }
725 
DeliverBuffer(std::shared_ptr<IBuffer> & buffer)726 void BufferManagerTest::Pipeline::DeliverBuffer(std::shared_ptr<IBuffer>& buffer)
727 {
728     buffer->SetFrameNumber(frameNumber_++);
729     std::cout << "deliver buffer : " << static_cast<uint64_t>(frameNumber_) << std::endl;
730     sourceNode_->Receive(buffer);
731     return;
732 }
733 
DeliverBuffer()734 void BufferManagerTest::Pipeline::DeliverBuffer()
735 {
736     localStream_->deliverThread = new std::thread([this] {
737         while (running == true) {
738             std::this_thread::sleep_for(std::chrono::microseconds(FRAME_INTERVAL_US));
739             std::shared_ptr<IBuffer> buffer = nullptr;
740             {
741                 std::cout << "load device buffer ..." << std::endl;
742                 std::lock_guard<std::mutex> l(localStream_->deviceLock);
743                 if (localStream_->deviceBufferList.empty()) {
744                     continue;
745                 }
746                 buffer = localStream_->deviceBufferList.front();
747                 localStream_->deviceBufferList.pop_front();
748             }
749             DeliverBuffer(buffer);
750         }
751     });
752 
753     return;
754 }
755 
StopStream()756 void BufferManagerTest::Pipeline::StopStream()
757 {
758     running = false;
759     collectThread_->join();
760 
761     localStream_->deliverThread->join();
762 
763     BufferTracking::DeleteTrackingStream(0);
764     BufferTracking::StopTracking();
765     return;
766 }
767 
Connect(std::shared_ptr<Node> & nextNode)768 void BufferManagerTest::Node::Connect(std::shared_ptr<Node>& nextNode)
769 {
770     nextNode_ = nextNode;
771     return;
772 }
773 
Deliver(std::shared_ptr<IBuffer> & buffer)774 void BufferManagerTest::Node::Deliver(std::shared_ptr<IBuffer>& buffer)
775 {
776     if (nextNode_ == nullptr) {
777         return;
778     }
779     nextNode_->Receive(buffer);
780     return;
781 }
782 
Receive(std::shared_ptr<IBuffer> & buffer)783 void BufferManagerTest::Node::Receive(std::shared_ptr<IBuffer>& buffer)
784 {
785     std::cout << "report buffer location to node: " << name_ << std::endl;
786     PIPELINE_REPORT_BUFFER_LOCATION(0, buffer->GetFrameNumber(), name_);
787     Process(buffer);
788     return;
789 }
790 
GetName() const791 std::string BufferManagerTest::Node::GetName() const
792 {
793     return name_;
794 }
795 
Process(std::shared_ptr<IBuffer> & buffer)796 void BufferManagerTest::Node::Process(std::shared_ptr<IBuffer>& buffer)
797 {
798     std::this_thread::sleep_for(std::chrono::microseconds(5000)); // 5000:microsecond
799     Deliver(buffer);
800     return;
801 }
802 
BindCallback(const std::function<void (std::shared_ptr<IBuffer> &)> & func)803 void BufferManagerTest::SinkNode::BindCallback(const std::function<void(std::shared_ptr<IBuffer>&)>& func)
804 {
805     callback_ = func;
806     return;
807 }
808 
Deliver(std::shared_ptr<IBuffer> & buffer)809 void BufferManagerTest::SinkNode::Deliver(std::shared_ptr<IBuffer>& buffer)
810 {
811     if (callback_ == nullptr) {
812         return;
813     }
814     callback_(buffer);
815     return;
816 }
817 
Process(std::shared_ptr<IBuffer> & buffer)818 void BufferManagerTest::SourceNode::Process(std::shared_ptr<IBuffer>& buffer)
819 {
820     if (cacheSize_ > 0) {
821         cache_.emplace_back(buffer);
822         cacheSize_--;
823         return;
824     }
825 
826     if (cache_.empty()) {
827         Deliver(buffer);
828         return;
829     }
830 
831     auto b = cache_.front();
832     cache_.pop_front();
833     cache_.emplace_back(buffer);
834     Deliver(b);
835 
836     return;
837 }
838 } // namespace OHOS::CameraUtest
839 
840