• 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 "stream_base.h"
17 #include "buffer_adapter.h"
18 #include "buffer_manager.h"
19 #include "watchdog.h"
20 
21 namespace OHOS::Camera {
22 std::map<VdiStreamIntent, std::string> IStream::g_availableStreamType = {
23     {PREVIEW, STREAM_INTENT_TO_STRING(PREVIEW)},
24     {VIDEO, STREAM_INTENT_TO_STRING(VIDEO)},
25     {STILL_CAPTURE, STREAM_INTENT_TO_STRING(STILL_CAPTURE)},
26     {POST_VIEW, STREAM_INTENT_TO_STRING(POST_VIEW)},
27     {ANALYZE, STREAM_INTENT_TO_STRING(ANALYZE)},
28     {CUSTOM, STREAM_INTENT_TO_STRING(CUSTOM)},
29 };
30 
StreamBase(const int32_t id,const VdiStreamIntent type,std::shared_ptr<IPipelineCore> & p,std::shared_ptr<CaptureMessageOperator> & m)31 StreamBase::StreamBase(const int32_t id,
32                        const VdiStreamIntent type,
33                        std::shared_ptr<IPipelineCore>& p,
34                        std::shared_ptr<CaptureMessageOperator>& m) : calltimes_(0)
35 {
36     streamId_ = id;
37     streamType_ = static_cast<int32_t>(type);
38     pipelineCore_ = p;
39     messenger_ = m;
40 }
41 
~StreamBase()42 StreamBase::~StreamBase()
43 {
44     if (state_ == STREAM_STATE_BUSY) {
45         StopStream();
46     }
47 
48     if (hostStreamMgr_ != nullptr) {
49         hostStreamMgr_->DestroyHostStream({streamId_});
50     }
51 
52     if (pipeline_ != nullptr) {
53         pipeline_->DestroyPipeline({streamId_});
54     }
55 }
56 
ConfigStream(StreamConfiguration & config)57 RetCode StreamBase::ConfigStream(StreamConfiguration& config)
58 {
59     std::unique_lock<std::mutex> l(smLock_);
60     if (state_ != STREAM_STATE_IDLE) {
61         return RC_ERROR;
62     }
63 
64     streamConfig_ = config;
65     streamConfig_.usage = GetUsage();
66     if (tunnel_ != nullptr) {
67         streamConfig_.tunnelMode = true;
68     }
69     streamConfig_.bufferCount = GetBufferCount();
70     streamConfig_.maxBatchCaptureCount = 1;
71     streamConfig_.maxCaptureCount = 1;
72     // get device cappability to override configuration
73     return RC_OK;
74 }
75 
CommitStream()76 RetCode StreamBase::CommitStream()
77 {
78     std::unique_lock<std::mutex> l(smLock_);
79     CHECK_IF_NOT_EQUAL_RETURN_VALUE(state_, STREAM_STATE_IDLE, RC_ERROR);
80 
81     CHECK_IF_PTR_NULL_RETURN_VALUE(pipelineCore_, RC_ERROR);
82 
83     pipeline_ = pipelineCore_->GetStreamPipelineCore();
84     CHECK_IF_PTR_NULL_RETURN_VALUE(pipeline_, RC_ERROR);
85 
86     hostStreamMgr_ = pipelineCore_->GetHostStreamMgr();
87     CHECK_IF_PTR_NULL_RETURN_VALUE(hostStreamMgr_, RC_ERROR);
88 
89     HostStreamInfo info;
90     info.type_ = static_cast<VdiStreamIntent>(streamType_);
91     info.streamId_ = streamId_;
92     info.width_ = streamConfig_.width;
93     info.height_ = streamConfig_.height;
94     info.format_ = streamConfig_.format;
95     info.usage_ = streamConfig_.usage;
96     info.encodeType_ = streamConfig_.encodeType;
97 
98     if (streamConfig_.tunnelMode) {
99         BufferManager* mgr = BufferManager::GetInstance();
100         CHECK_IF_PTR_NULL_RETURN_VALUE(mgr, RC_ERROR);
101 
102         if (bufferPool_ == nullptr) {
103             poolId_ = mgr->GenerateBufferPoolId();
104             CHECK_IF_EQUAL_RETURN_VALUE(poolId_, 0, RC_ERROR);
105             bufferPool_ = mgr->GetBufferPool(poolId_);
106             CHECK_IF_PTR_NULL_RETURN_VALUE(bufferPool_, RC_ERROR);
107         }
108         info.bufferPoolId_ = poolId_;
109         info.bufferCount_ = GetBufferCount();
110         RetCode rc = bufferPool_->Init(streamConfig_.width, streamConfig_.height, streamConfig_.usage,
111                                        streamConfig_.format, GetBufferCount(), CAMERA_BUFFER_SOURCE_TYPE_EXTERNAL);
112 
113         CHECK_IF_NOT_EQUAL_RETURN_VALUE(rc, RC_OK, RC_ERROR);
114     }
115     RetCode rc = hostStreamMgr_->CreateHostStream(info, [this](auto buffer) { HandleResult(buffer); });
116     if (rc != RC_OK) {
117         CAMERA_LOGE("commit stream [id:%{public}d] to pipeline failed.", streamId_);
118         return RC_ERROR;
119     }
120     CAMERA_LOGI("commit a stream to pipeline id[%{public}d], w[%{public}d], h[%{public}d], poolId[%{public}llu], \
121         encodeType = %{public}d", info.streamId_, info.width_, info.height_, info.bufferPoolId_, info.encodeType_);
122     state_ = STREAM_STATE_ACTIVE;
123     return RC_OK;
124 }
125 
StartStream()126 RetCode StreamBase::StartStream()
127 {
128     CHECK_IF_PTR_NULL_RETURN_VALUE(pipeline_, RC_ERROR);
129 
130     int origin = calltimes_.fetch_add(1);
131     if (origin != 0) {
132         // already called, no reenter
133         CAMERA_LOGE("Now will not start, current start %{public}d times", calltimes_.load());
134         return RC_ERROR;
135     }
136 
137     std::unique_lock<std::mutex> l(smLock_);
138     if (state_ != STREAM_STATE_ACTIVE) {
139         return RC_ERROR;
140     }
141 
142     CAMERA_LOGI("start stream [id:%{public}d] begin", streamId_);
143     tunnel_->NotifyStart();
144 
145     RetCode rc = pipeline_->Prepare({streamId_});
146     if (rc != RC_OK) {
147         CAMERA_LOGE("pipeline [id:%{public}d] prepare failed", streamId_);
148         return rc;
149     }
150 
151     state_ = STREAM_STATE_BUSY;
152     std::string threadName =
153         g_availableStreamType[static_cast<VdiStreamIntent>(streamType_)] + "#" + std::to_string(streamId_);
154     handler_ = std::make_unique<std::thread>([this, &threadName] {
155         prctl(PR_SET_NAME, threadName.c_str());
156         while (state_ == STREAM_STATE_BUSY) {
157             tunnel_->DumpStats(3); // set output interval to 30 second
158             HandleRequest();
159         }
160     });
161     if (handler_ == nullptr) {
162         state_ = STREAM_STATE_ACTIVE;
163         return RC_ERROR;
164     }
165 
166     rc = pipeline_->Start({streamId_});
167     if (rc != RC_OK) {
168         CAMERA_LOGE("pipeline [%{public}d] start failed", streamId_);
169         return RC_ERROR;
170     }
171     CAMERA_LOGI("start stream [id:%{public}d] end", streamId_);
172 
173     return RC_OK;
174 }
175 
StopStream()176 RetCode StreamBase::StopStream()
177 {
178     CHECK_IF_PTR_NULL_RETURN_VALUE(pipeline_, RC_ERROR);
179     std::unique_lock<std::mutex> l(smLock_);
180 
181     CAMERA_LOGI("stop stream [id:%{public}d] begin", streamId_);
182     CHECK_IF_EQUAL_RETURN_VALUE(state_, STREAM_STATE_IDLE, RC_OK);
183 
184     state_ = STREAM_STATE_IDLE;
185     tunnel_->NotifyStop();
186     cv_.notify_all();
187 
188     if (handler_ != nullptr && handler_->joinable()) {
189         handler_->join();
190         handler_ = nullptr;
191     }
192 
193     if (!waitingList_.empty()) {
194         auto request = waitingList_.front();
195         if (request != nullptr && request->IsContinous()) {
196             request->Cancel();
197         }
198     }
199     {
200         std::unique_lock<std::mutex> l(wtLock_);
201         waitingList_.clear();
202     }
203 
204     RetCode rc = pipeline_->Flush({streamId_});
205     CHECK_IF_NOT_EQUAL_RETURN_VALUE(rc, RC_OK, RC_ERROR);
206     tunnel_->WaitForAllBufferReturned();
207     rc = pipeline_->Stop({streamId_});
208     CHECK_IF_NOT_EQUAL_RETURN_VALUE(rc, RC_OK, RC_ERROR);
209 
210     if (lastRequest_ != nullptr && lastRequest_->IsContinous() && !inTransitList_.empty() && messenger_ != nullptr) {
211         std::shared_ptr<ICaptureMessage> endMessage =
212             std::make_shared<CaptureEndedMessage>(streamId_, lastRequest_->GetCaptureId(),
213             lastRequest_->GetEndTime(), lastRequest_->GetOwnerCount(), tunnel_->GetFrameCount());
214         CAMERA_LOGV("end of stream [%{public}d], ready to send end message", streamId_);
215         messenger_->SendMessage(endMessage);
216     }
217     CAMERA_LOGI("stop stream [id:%{public}d] end", streamId_);
218     isFirstRequest = true;
219     inTransitList_.clear();
220     tunnel_->CleanBuffers();
221     bufferPool_->ClearBuffers();
222     return RC_OK;
223 }
224 
AddRequest(std::shared_ptr<CaptureRequest> & request)225 RetCode StreamBase::AddRequest(std::shared_ptr<CaptureRequest>& request)
226 {
227     CHECK_IF_PTR_NULL_RETURN_VALUE(request, RC_ERROR);
228     request->AddOwner(shared_from_this());
229 
230     request->SetFirstRequest(false);
231     if (isFirstRequest) {
232         RetCode rc = StartStream();
233         if (rc != RC_OK) {
234             CAMERA_LOGE("start stream [id:%{public}d] failed", streamId_);
235             return RC_ERROR;
236         }
237         request->SetFirstRequest(true);
238         isFirstRequest = false;
239     }
240 
241     {
242         std::unique_lock<std::mutex> l(wtLock_);
243         waitingList_.emplace_back(request);
244         cv_.notify_one();
245     }
246 
247     return RC_OK;
248 }
249 
CancelRequest(const std::shared_ptr<CaptureRequest> & request)250 RetCode StreamBase::CancelRequest(const std::shared_ptr<CaptureRequest>& request)
251 {
252     CHECK_IF_PTR_NULL_RETURN_VALUE(request, RC_ERROR);
253     CHECK_IF_PTR_NULL_RETURN_VALUE(messenger_, RC_ERROR);
254     {
255         // We don't care if this request is continious-capture or single-capture, just erase it.
256         // And those requests in inTransitList_ removed in HandleResult.
257         std::unique_lock<std::mutex> wl(wtLock_);
258         auto it = std::find(waitingList_.begin(), waitingList_.end(), request);
259         if (it != waitingList_.end()) {
260             waitingList_.erase(it);
261             CAMERA_LOGI("stream [id:%{public}d], cancel request(capture id:%{public}d) success",
262                 streamId_, request->GetCaptureId());
263         }
264     }
265 
266     if (request->IsContinous()) {
267         // may be this is the last request
268         std::unique_lock<std::mutex> tl(tsLock_);
269         auto it = std::find(inTransitList_.begin(), inTransitList_.end(), request);
270         if (it == inTransitList_.end()) {
271             std::shared_ptr<ICaptureMessage> endMessage =
272                 std::make_shared<CaptureEndedMessage>(streamId_, request->GetCaptureId(), request->GetEndTime(),
273                                                       request->GetOwnerCount(), tunnel_->GetFrameCount());
274             CAMERA_LOGV("end of stream [%{public}d], ready to send end message", streamId_);
275             messenger_->SendMessage(endMessage);
276             pipeline_->CancelCapture({streamId_});
277         }
278     }
279     return RC_OK;
280 }
281 
HandleRequest()282 void StreamBase::HandleRequest()
283 {
284     if (waitingList_.empty()) {
285         std::unique_lock<std::mutex> l(wtLock_);
286         if (waitingList_.empty()) {
287             cv_.wait(l, [this] { return !(state_ == STREAM_STATE_BUSY && waitingList_.empty()); });
288         }
289     }
290     if (state_ != STREAM_STATE_BUSY) {
291         return;
292     }
293 
294     std::shared_ptr<CaptureRequest> request = nullptr;
295     {
296         // keep a copy of continious-capture in waitingList_, unless it's going to be canceled.
297         std::unique_lock<std::mutex> l(wtLock_);
298         if (waitingList_.empty()) {
299             return;
300         }
301         request = waitingList_.front();
302         CHECK_IF_PTR_NULL_RETURN_VOID(request);
303         CAMERA_LOGE("HandleRequest streamId = [%{public}d] and needCancel = [%{public}d]",
304             streamId_, request->NeedCancel() ? 1 : 0);
305         if (!request->IsContinous()) {
306             waitingList_.pop_front();
307         }
308     }
309     if (request == nullptr) {
310         CAMERA_LOGE("fatal error, stream [%{public}d] request list is not empty, but can't get one", streamId_);
311         return;
312     }
313 
314     if (request->NeedCancel()) {
315         return;
316     }
317 
318     request->Process(streamId_);
319 
320     return;
321 }
322 
Capture(const std::shared_ptr<CaptureRequest> & request)323 RetCode StreamBase::Capture(const std::shared_ptr<CaptureRequest>& request)
324 {
325     CHECK_IF_PTR_NULL_RETURN_VALUE(request, RC_ERROR);
326     CHECK_IF_PTR_NULL_RETURN_VALUE(pipeline_, RC_ERROR);
327 
328     RetCode rc = RC_ERROR;
329     if (request->IsFirstOne() && !request->IsContinous()) {
330         uint32_t n = GetBufferCount();
331         for (uint32_t i = 0; i < n; i++) {
332             DeliverBuffer();
333         }
334     } else {
335         do {
336             rc = DeliverBuffer();
337             {
338                 std::unique_lock<std::mutex> l(wtLock_);
339                 if (waitingList_.empty()) {
340                     CAMERA_LOGI("Capture stream [id:%{public}d] stop deliver buffer.", streamId_);
341                     break;
342                 }
343             }
344         } while (rc != RC_OK && state_ == STREAM_STATE_BUSY);
345     }
346 
347     rc = pipeline_->Config({streamId_}, request->GetCaptureSetting());
348     if (rc != RC_OK) {
349         CAMERA_LOGE("stream [id:%{public}d] config pipeline failed.", streamId_);
350         return RC_ERROR;
351     }
352 
353     rc = pipeline_->Capture({streamId_}, request->GetCaptureId());
354     if (rc != RC_OK) {
355         CAMERA_LOGE("stream [id:%{public}d] take a capture failed.", streamId_);
356         return RC_ERROR;
357     }
358 
359     {
360         std::unique_lock<std::mutex> l(tsLock_);
361         inTransitList_.emplace_back(request);
362     }
363 
364     if (request->IsFirstOne()) {
365         if (messenger_ == nullptr) {
366             CAMERA_LOGE("stream [id:%{public}d] can't send message, messenger_ is null", streamId_);
367             return RC_ERROR;
368         }
369         std::shared_ptr<ICaptureMessage> startMessage = std::make_shared<CaptureStartedMessage>(
370             streamId_, request->GetCaptureId(), request->GetBeginTime(), request->GetOwnerCount());
371         messenger_->SendMessage(startMessage);
372         request->SetFirstRequest(false);
373     }
374 
375     return RC_OK;
376 }
377 
DeliverBuffer()378 RetCode StreamBase::DeliverBuffer()
379 {
380     CHECK_IF_PTR_NULL_RETURN_VALUE(tunnel_, RC_ERROR);
381     CHECK_IF_PTR_NULL_RETURN_VALUE(bufferPool_, RC_ERROR);
382 
383     std::shared_ptr<IBuffer> buffer = tunnel_->GetBuffer();
384     CHECK_IF_PTR_NULL_RETURN_VALUE(buffer, RC_ERROR);
385 
386     buffer->SetEncodeType(streamConfig_.encodeType);
387     buffer->SetStreamId(streamId_);
388     bufferPool_->AddBuffer(buffer);
389     CAMERA_LOGI("stream [id:%{public}d] enqueue buffer index:%{public}d", streamId_, buffer->GetIndex());
390     return RC_OK;
391 }
392 
HandleResult(std::shared_ptr<IBuffer> & buffer)393 void StreamBase::HandleResult(std::shared_ptr<IBuffer>& buffer)
394 {
395     CHECK_IF_PTR_NULL_RETURN_VOID(buffer);
396     if (buffer->GetBufferStatus() == CAMERA_BUFFER_STATUS_INVALID) {
397         CAMERA_LOGI("stream [id:%{public}d], this buffer(index:%{public}d) has nothing to do with request.", streamId_,
398                     buffer->GetIndex());
399         ReceiveBuffer(buffer);
400         return;
401     }
402 
403     if (buffer->GetStreamId() != streamId_) {
404         CAMERA_LOGE("fatal error, stream [%{public}d] reveived a wrong buffer, index:%{public}d. \
405             this buffer belongs to stream:%{public}d", streamId_, buffer->GetIndex(), buffer->GetStreamId());
406         return;
407     }
408 
409     int32_t captureId = buffer->GetCaptureId();
410     std::shared_ptr<CaptureRequest> request = nullptr;
411     {
412         std::unique_lock<std::mutex> l(tsLock_);
413         for (auto& r : inTransitList_) {
414             if (r == nullptr) {
415                 continue;
416             }
417             if (r->GetCaptureId() == captureId) {
418                 request = r;
419                 break;
420             }
421         }
422     }
423     if (request == nullptr) {
424         CAMERA_LOGI("stream [id:%{public}d], this buffer(index:%{public}d) has nothing to do with request.",
425             streamId_, buffer->GetIndex());
426         buffer->SetBufferStatus(CAMERA_BUFFER_STATUS_INVALID);
427         ReceiveBuffer(buffer);
428         return;
429     }
430     request->AttachBuffer(buffer);
431     // To synchronize multiple stream, bottom-layer device stream need be synchronized first.
432     request->OnResult(streamId_);
433     lastRequest_ = request;
434 }
435 
OnFrame(const std::shared_ptr<CaptureRequest> & request)436 RetCode StreamBase::OnFrame(const std::shared_ptr<CaptureRequest>& request)
437 {
438     CHECK_IF_PTR_NULL_RETURN_VALUE(request, RC_ERROR);
439     CHECK_IF_PTR_NULL_RETURN_VALUE(pipeline_, RC_ERROR);
440     CHECK_IF_PTR_NULL_RETURN_VALUE(messenger_, RC_ERROR);
441     auto buffer = request->GetAttachedBuffer();
442     CameraBufferStatus status = buffer->GetBufferStatus();
443     if (status != CAMERA_BUFFER_STATUS_OK) {
444         if (status != CAMERA_BUFFER_STATUS_DROP) {
445             std::shared_ptr<ICaptureMessage> errorMessage =
446                 std::make_shared<CaptureErrorMessage>(streamId_, request->GetCaptureId(), request->GetEndTime(),
447                                                       request->GetOwnerCount(), static_cast<VdiStreamError>(status));
448             messenger_->SendMessage(errorMessage);
449         } else {
450             CAMERA_LOGE("stream [id:%{public}d] drop buffer index:%{public}d, status:%{public}d",
451                 streamId_, buffer->GetIndex(), buffer->GetBufferStatus());
452             ReceiveBuffer(buffer);
453             return RC_OK;
454         }
455     }
456     if (request->NeedShutterCallback()) {
457         std::shared_ptr<ICaptureMessage> shutterMessage = std::make_shared<FrameShutterMessage>(
458             streamId_, request->GetCaptureId(), request->GetEndTime(), request->GetOwnerCount());
459         messenger_->SendMessage(shutterMessage);
460     }
461     bool isEnded = !request->IsContinous() || request->NeedCancel();
462     {
463         // inTransitList_ may has multiple copies of continious-capture request, we just need erase one of them.
464         std::unique_lock<std::mutex> l(tsLock_);
465         for (auto it = inTransitList_.begin(); it != inTransitList_.end(); it++) {
466             if ((*it) == request) {
467                 inTransitList_.erase(it);
468                 break;
469             }
470         }
471         if (isEnded) {
472             // if this is the last request of capture, send CaptureEndedMessage.
473             auto it = std::find(inTransitList_.begin(), inTransitList_.end(), request);
474             if (it == inTransitList_.end()) {
475                 std::shared_ptr<ICaptureMessage> endMessage =
476                     std::make_shared<CaptureEndedMessage>(streamId_, request->GetCaptureId(), request->GetEndTime(),
477                                                           request->GetOwnerCount(), tunnel_->GetFrameCount());
478                 CAMERA_LOGV("end of stream [%d], capture id = %d", streamId_, request->GetCaptureId());
479                 messenger_->SendMessage(endMessage);
480                 pipeline_->CancelCapture({streamId_});
481             }
482         }
483     }
484     CAMERA_LOGI("stream = [%{public}d] OnFrame and NeedCancel = [%{public}d]",
485         buffer->GetStreamId(), request->NeedCancel() ? 1 : 0);
486     if (request->NeedCancel()) {
487         buffer->SetBufferStatus(CAMERA_BUFFER_STATUS_DROP);
488     } else {
489         buffer->SetBufferStatus(CAMERA_BUFFER_STATUS_OK);
490     }
491     ReceiveBuffer(buffer);
492     return RC_OK;
493 }
494 
ReceiveBuffer(std::shared_ptr<IBuffer> & buffer)495 RetCode StreamBase::ReceiveBuffer(std::shared_ptr<IBuffer>& buffer)
496 {
497     CHECK_IF_PTR_NULL_RETURN_VALUE(buffer, RC_ERROR);
498     CHECK_IF_PTR_NULL_RETURN_VALUE(tunnel_, RC_ERROR);
499     CHECK_IF_PTR_NULL_RETURN_VALUE(bufferPool_, RC_ERROR);
500 
501     CAMERA_LOGI("stream [id:%{public}d] dequeue buffer index:%{public}d, status:%{public}d",
502         streamId_, buffer->GetIndex(), buffer->GetBufferStatus());
503     bufferPool_->ReturnBuffer(buffer);
504     tunnel_->PutBuffer(buffer);
505     return RC_OK;
506 }
507 
GetFrameCount() const508 uint64_t StreamBase::GetFrameCount() const
509 {
510     CHECK_IF_PTR_NULL_RETURN_VALUE(tunnel_, 0);
511     return tunnel_->GetFrameCount();
512 }
513 
AttachStreamTunnel(std::shared_ptr<StreamTunnel> & tunnel)514 RetCode StreamBase::AttachStreamTunnel(std::shared_ptr<StreamTunnel>& tunnel)
515 {
516     std::unique_lock<std::mutex> l(smLock_);
517     if (state_ == STREAM_STATE_BUSY || state_ == STREAM_STATE_OFFLINE) {
518         return RC_ERROR;
519     }
520 
521     tunnel_ = tunnel;
522     CHECK_IF_PTR_NULL_RETURN_VALUE(tunnel_, RC_ERROR);
523     tunnel_->SetBufferCount(GetBufferCount());
524     TunnelConfig config = {(uint32_t)streamConfig_.width, (uint32_t)streamConfig_.height,
525         (uint32_t)streamConfig_.format, streamConfig_.usage};
526     tunnel_->Config(config);
527     tunnel_->SetStreamId(streamId_);
528     streamConfig_.tunnelMode = true;
529     return RC_OK;
530 }
531 
DetachStreamTunnel()532 RetCode StreamBase::DetachStreamTunnel()
533 {
534     std::unique_lock<std::mutex> l(smLock_);
535     if (state_ == STREAM_STATE_BUSY || state_ == STREAM_STATE_OFFLINE) {
536         return RC_ERROR;
537     }
538 
539     tunnel_.reset();
540     streamConfig_.tunnelMode = false;
541 
542     state_ = STREAM_STATE_IDLE;
543     return RC_OK;
544 }
545 
ChangeToOfflineStream(std::shared_ptr<OfflineStream> offlineStream)546 RetCode StreamBase::ChangeToOfflineStream(std::shared_ptr<OfflineStream> offlineStream)
547 {
548     (void)offlineStream;
549     return RC_OK;
550 }
551 
GetUsage()552 uint64_t StreamBase::GetUsage()
553 {
554     return CAMERA_USAGE_SW_WRITE_OFTEN | CAMERA_USAGE_SW_READ_OFTEN | CAMERA_USAGE_MEM_DMA;
555 }
556 
GetBufferCount()557 uint32_t StreamBase::GetBufferCount()
558 {
559     return 3; // 3: buffer count
560 }
561 
GetStreamAttribute() const562 StreamConfiguration StreamBase::GetStreamAttribute() const
563 {
564     return streamConfig_;
565 }
566 
GetStreamId() const567 int32_t StreamBase::GetStreamId() const
568 {
569     return streamId_;
570 }
571 
IsRunning() const572 bool StreamBase::IsRunning() const
573 {
574     return state_ == STREAM_STATE_BUSY;
575 }
576 
GetTunnelMode() const577 bool StreamBase::GetTunnelMode() const
578 {
579     return streamConfig_.tunnelMode;
580 }
581 
DumpStatsInfo() const582 void StreamBase::DumpStatsInfo() const
583 {
584     if (tunnel_ != nullptr) {
585         tunnel_->DumpStats();
586     }
587 }
588 
ReleaseStreamBufferPool()589 void StreamBase::ReleaseStreamBufferPool()
590 {
591     BufferManager* mgr = BufferManager::GetInstance();
592     if (mgr != nullptr) {
593         mgr->EraseBufferPoolMapById(poolId_);
594     }
595     bufferPool_ = nullptr;
596 }
597 } // namespace OHOS::Camera
598