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 {
183 std::unique_lock<std::mutex> l(wtLock_);
184 CHECK_IF_EQUAL_RETURN_VALUE(state_, STREAM_STATE_IDLE, RC_OK);
185
186 state_ = STREAM_STATE_IDLE;
187 tunnel_->NotifyStop();
188 cv_.notify_all();
189 }
190
191 if (handler_ != nullptr && handler_->joinable()) {
192 handler_->join();
193 handler_ = nullptr;
194 }
195
196 if (!waitingList_.empty()) {
197 auto request = waitingList_.front();
198 if (request != nullptr && request->IsContinous()) {
199 request->Cancel();
200 }
201 }
202 {
203 std::unique_lock<std::mutex> l(wtLock_);
204 waitingList_.clear();
205 }
206
207 RetCode rc = pipeline_->Flush({streamId_});
208 CHECK_IF_NOT_EQUAL_RETURN_VALUE(rc, RC_OK, RC_ERROR);
209 tunnel_->WaitForAllBufferReturned();
210 rc = pipeline_->Stop({streamId_});
211 CHECK_IF_NOT_EQUAL_RETURN_VALUE(rc, RC_OK, RC_ERROR);
212
213 if (lastRequest_ != nullptr && lastRequest_->IsContinous() && !inTransitList_.empty() && messenger_ != nullptr) {
214 std::shared_ptr<ICaptureMessage> endMessage =
215 std::make_shared<CaptureEndedMessage>(streamId_, lastRequest_->GetCaptureId(),
216 lastRequest_->GetEndTime(), lastRequest_->GetOwnerCount(), tunnel_->GetFrameCount());
217 CAMERA_LOGV("end of stream [%{public}d], ready to send end message", streamId_);
218 messenger_->SendMessage(endMessage);
219 }
220 CAMERA_LOGI("stop stream [id:%{public}d] end", streamId_);
221 isFirstRequest = true;
222 inTransitList_.clear();
223 tunnel_->CleanBuffers();
224 bufferPool_->ClearBuffers();
225 return RC_OK;
226 }
227
AddRequest(std::shared_ptr<CaptureRequest> & request)228 RetCode StreamBase::AddRequest(std::shared_ptr<CaptureRequest>& request)
229 {
230 CHECK_IF_PTR_NULL_RETURN_VALUE(request, RC_ERROR);
231 request->AddOwner(shared_from_this());
232
233 if (isFirstRequest) {
234 RetCode rc = StartStream();
235 if (rc != RC_OK) {
236 CAMERA_LOGE("start stream [id:%{public}d] failed", streamId_);
237 return RC_ERROR;
238 }
239 request->SetFirstRequest(true);
240 isFirstRequest = false;
241 }
242
243 {
244 std::unique_lock<std::mutex> l(wtLock_);
245 waitingList_.emplace_back(request);
246 cv_.notify_one();
247 }
248
249 return RC_OK;
250 }
251
CancelRequest(const std::shared_ptr<CaptureRequest> & request)252 RetCode StreamBase::CancelRequest(const std::shared_ptr<CaptureRequest>& request)
253 {
254 CHECK_IF_PTR_NULL_RETURN_VALUE(request, RC_ERROR);
255 CHECK_IF_PTR_NULL_RETURN_VALUE(messenger_, RC_ERROR);
256 {
257 // We don't care if this request is continious-capture or single-capture, just erase it.
258 // And those requests in inTransitList_ removed in HandleResult.
259 std::unique_lock<std::mutex> wl(wtLock_);
260 auto it = std::find(waitingList_.begin(), waitingList_.end(), request);
261 if (it != waitingList_.end()) {
262 waitingList_.erase(it);
263 CAMERA_LOGI("stream [id:%{public}d], cancel request(capture id:%{public}d) success",
264 streamId_, request->GetCaptureId());
265 }
266 }
267
268 if (request->IsContinous()) {
269 // may be this is the last request
270 std::unique_lock<std::mutex> tl(tsLock_);
271 auto it = std::find(inTransitList_.begin(), inTransitList_.end(), request);
272 if (it == inTransitList_.end()) {
273 std::shared_ptr<ICaptureMessage> endMessage =
274 std::make_shared<CaptureEndedMessage>(streamId_, request->GetCaptureId(), request->GetEndTime(),
275 request->GetOwnerCount(), tunnel_->GetFrameCount());
276 CAMERA_LOGV("end of stream [%{public}d], ready to send end message", streamId_);
277 messenger_->SendMessage(endMessage);
278 pipeline_->CancelCapture({streamId_});
279 }
280 }
281 return RC_OK;
282 }
283
HandleRequest()284 void StreamBase::HandleRequest()
285 {
286 if (waitingList_.empty()) {
287 std::unique_lock<std::mutex> l(wtLock_);
288 if (waitingList_.empty()) {
289 cv_.wait(l, [this] { return !(state_ == STREAM_STATE_BUSY && waitingList_.empty()); });
290 }
291 }
292 if (state_ != STREAM_STATE_BUSY) {
293 return;
294 }
295
296 std::shared_ptr<CaptureRequest> request = nullptr;
297 {
298 // keep a copy of continious-capture in waitingList_, unless it's going to be canceled.
299 std::unique_lock<std::mutex> l(wtLock_);
300 if (waitingList_.empty()) {
301 return;
302 }
303 request = waitingList_.front();
304 CHECK_IF_PTR_NULL_RETURN_VOID(request);
305 CAMERA_LOGI("HandleRequest streamId = [%{public}d] and needCancel = [%{public}d]",
306 streamId_, request->NeedCancel() ? 1 : 0);
307 if (!request->IsContinous()) {
308 waitingList_.pop_front();
309 }
310 }
311 if (request == nullptr) {
312 CAMERA_LOGE("fatal error, stream [%{public}d] request list is not empty, but can't get one", streamId_);
313 return;
314 }
315
316 if (request->NeedCancel()) {
317 return;
318 }
319
320 request->Process(streamId_);
321
322 return;
323 }
324
Capture(const std::shared_ptr<CaptureRequest> & request)325 RetCode StreamBase::Capture(const std::shared_ptr<CaptureRequest>& request)
326 {
327 CHECK_IF_PTR_NULL_RETURN_VALUE(request, RC_ERROR);
328 CHECK_IF_PTR_NULL_RETURN_VALUE(pipeline_, RC_ERROR);
329
330 RetCode rc = RC_ERROR;
331 if (request->IsFirstOne() && !request->IsContinous()) {
332 uint32_t n = GetBufferCount();
333 for (uint32_t i = 0; i < n; i++) {
334 DeliverStreamBuffer();
335 }
336 } else {
337 do {
338 rc = DeliverStreamBuffer();
339 {
340 std::unique_lock<std::mutex> l(wtLock_);
341 if (waitingList_.empty()) {
342 CAMERA_LOGI("Capture stream [id:%{public}d] stop deliver buffer.", streamId_);
343 break;
344 }
345 }
346 } while (rc != RC_OK && state_ == STREAM_STATE_BUSY);
347 }
348
349 rc = pipeline_->Config({streamId_}, request->GetCaptureSetting());
350 if (rc != RC_OK) {
351 CAMERA_LOGE("stream [id:%{public}d] config pipeline failed.", streamId_);
352 return RC_ERROR;
353 }
354
355 rc = pipeline_->Capture({streamId_}, request->GetCaptureId());
356 if (rc != RC_OK) {
357 CAMERA_LOGE("stream [id:%{public}d] take a capture failed.", streamId_);
358 return RC_ERROR;
359 }
360
361 {
362 std::unique_lock<std::mutex> l(tsLock_);
363 inTransitList_.emplace_back(request);
364 }
365
366 if (request->IsFirstOne()) {
367 if (messenger_ == nullptr) {
368 CAMERA_LOGE("stream [id:%{public}d] can't send message, messenger_ is null", streamId_);
369 return RC_ERROR;
370 }
371 std::shared_ptr<ICaptureMessage> startMessage = std::make_shared<CaptureStartedMessage>(
372 streamId_, request->GetCaptureId(), request->GetBeginTime(), request->GetOwnerCount());
373 messenger_->SendMessage(startMessage);
374 request->SetFirstRequest(false);
375 }
376
377 return RC_OK;
378 }
379
DeliverStreamBuffer()380 RetCode StreamBase::DeliverStreamBuffer()
381 {
382 CHECK_IF_PTR_NULL_RETURN_VALUE(tunnel_, RC_ERROR);
383 CHECK_IF_PTR_NULL_RETURN_VALUE(bufferPool_, RC_ERROR);
384
385 std::shared_ptr<IBuffer> buffer = tunnel_->GetBuffer();
386 CHECK_IF_PTR_NULL_RETURN_VALUE(buffer, RC_ERROR);
387
388 buffer->SetEncodeType(streamConfig_.encodeType);
389 buffer->SetStreamId(streamId_);
390 bufferPool_->AddBuffer(buffer);
391 CAMERA_LOGI("stream [id:%{public}d] enqueue buffer index:%{public}d, size:%{public}d",
392 streamId_, buffer->GetIndex(), buffer->GetSize());
393 return RC_OK;
394 }
395
HandleResult(std::shared_ptr<IBuffer> & buffer)396 void StreamBase::HandleResult(std::shared_ptr<IBuffer>& buffer)
397 {
398 CHECK_IF_PTR_NULL_RETURN_VOID(buffer);
399 if (buffer->GetBufferStatus() == CAMERA_BUFFER_STATUS_INVALID) {
400 CAMERA_LOGI("stream [id:%{public}d], this buffer(index:%{public}d) has nothing to do with request.", streamId_,
401 buffer->GetIndex());
402 ReceiveBuffer(buffer);
403 return;
404 }
405
406 if (buffer->GetStreamId() != streamId_) {
407 CAMERA_LOGE("fatal error, stream [%{public}d] reveived a wrong buffer, index:%{public}d. \
408 this buffer belongs to stream:%{public}d", streamId_, buffer->GetIndex(), buffer->GetStreamId());
409 return;
410 }
411
412 int32_t captureId = buffer->GetCaptureId();
413 std::shared_ptr<CaptureRequest> request = nullptr;
414 {
415 std::unique_lock<std::mutex> l(tsLock_);
416 for (auto& r : inTransitList_) {
417 if (r == nullptr) {
418 continue;
419 }
420 if (r->GetCaptureId() == captureId) {
421 request = r;
422 break;
423 }
424 }
425 }
426 if (request == nullptr) {
427 CAMERA_LOGI("stream [id:%{public}d], this buffer(index:%{public}d) has nothing to do with request.",
428 streamId_, buffer->GetIndex());
429 buffer->SetBufferStatus(CAMERA_BUFFER_STATUS_INVALID);
430 ReceiveBuffer(buffer);
431 return;
432 }
433 request->AttachBuffer(buffer);
434 // To synchronize multiple stream, bottom-layer device stream need be synchronized first.
435 request->OnResult(streamId_);
436 lastRequest_ = request;
437 }
438
OnFrame(const std::shared_ptr<CaptureRequest> & request)439 RetCode StreamBase::OnFrame(const std::shared_ptr<CaptureRequest>& request)
440 {
441 CHECK_IF_PTR_NULL_RETURN_VALUE(request, RC_ERROR);
442 CHECK_IF_PTR_NULL_RETURN_VALUE(pipeline_, RC_ERROR);
443 CHECK_IF_PTR_NULL_RETURN_VALUE(messenger_, RC_ERROR);
444 auto buffer = request->GetAttachedBuffer();
445 CameraBufferStatus status = buffer->GetBufferStatus();
446 if (status != CAMERA_BUFFER_STATUS_OK) {
447 if (status != CAMERA_BUFFER_STATUS_DROP) {
448 std::shared_ptr<ICaptureMessage> errorMessage =
449 std::make_shared<CaptureErrorMessage>(streamId_, request->GetCaptureId(), request->GetEndTime(),
450 request->GetOwnerCount(), static_cast<VdiStreamError>(status));
451 messenger_->SendMessage(errorMessage);
452 } else {
453 CAMERA_LOGE("stream [id:%{public}d] drop buffer index:%{public}d, status:%{public}d",
454 streamId_, buffer->GetIndex(), buffer->GetBufferStatus());
455 ReceiveBuffer(buffer);
456 return RC_OK;
457 }
458 }
459 if (request->NeedShutterCallback()) {
460 std::shared_ptr<ICaptureMessage> shutterMessage = std::make_shared<FrameShutterMessage>(
461 streamId_, request->GetCaptureId(), request->GetEndTime(), request->GetOwnerCount());
462 messenger_->SendMessage(shutterMessage);
463 }
464 bool isEnded = !request->IsContinous() || request->NeedCancel();
465 {
466 // inTransitList_ may has multiple copies of continious-capture request, we just need erase one of them.
467 std::unique_lock<std::mutex> l(tsLock_);
468 for (auto it = inTransitList_.begin(); it != inTransitList_.end(); it++) {
469 if ((*it) == request) {
470 inTransitList_.erase(it);
471 break;
472 }
473 }
474 if (isEnded) {
475 // if this is the last request of capture, send CaptureEndedMessage.
476 auto it = std::find(inTransitList_.begin(), inTransitList_.end(), request);
477 if (it == inTransitList_.end()) {
478 std::shared_ptr<ICaptureMessage> endMessage =
479 std::make_shared<CaptureEndedMessage>(streamId_, request->GetCaptureId(), request->GetEndTime(),
480 request->GetOwnerCount(), tunnel_->GetFrameCount());
481 CAMERA_LOGV("end of stream [%d], capture id = %d", streamId_, request->GetCaptureId());
482 messenger_->SendMessage(endMessage);
483 pipeline_->CancelCapture({streamId_});
484 }
485 }
486 }
487 CAMERA_LOGI("stream = [%{public}d] OnFrame and NeedCancel = [%{public}d]",
488 buffer->GetStreamId(), request->NeedCancel() ? 1 : 0);
489 request->NeedCancel() ? buffer->SetBufferStatus(CAMERA_BUFFER_STATUS_DROP) :
490 buffer->SetBufferStatus(CAMERA_BUFFER_STATUS_OK);
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