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