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