• 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 "offline_pipeline.h"
17 #include "buffer_manager.h"
18 #include "ibuffer_pool.h"
19 #include <vector>
20 
21 namespace OHOS::Camera {
OfflinePipeline()22 OfflinePipeline::OfflinePipeline() {}
23 
~OfflinePipeline()24 OfflinePipeline::~OfflinePipeline()
25 {
26     StopProcess();
27     bufferCache_.clear();
28 }
29 
StartProcess()30 RetCode OfflinePipeline::StartProcess()
31 {
32     running_ = true;
33     processThread_ = new std::thread([this]() {
34         prctl(PR_SET_NAME, "offlinepipeline");
35         std::unique_lock<std::mutex> l(queueLock_);
36         while (running_) {
37             cv_.wait(l, [this] { return !(running_.load() && bufferCache_.empty()); });
38             HandleBuffers();
39         }
40     });
41     if (processThread_ == nullptr) {
42         return RC_ERROR;
43     }
44     return RC_OK;
45 }
46 
StopProcess()47 RetCode OfflinePipeline::StopProcess()
48 {
49     if (processThread_ == nullptr) {
50         CAMERA_LOGE("cannot stop.");
51         return RC_ERROR;
52     }
53 
54     {
55         std::unique_lock<std::mutex> l(queueLock_);
56         if (running_.load() == false) {
57             return RC_OK;
58         }
59         running_ = false;
60     }
61 
62     cv_.notify_one();
63     processThread_->join();
64     delete processThread_;
65     processThread_ = nullptr;
66     return RC_OK;
67 }
68 
BindOfflineStreamCallback(std::function<void (std::shared_ptr<IBuffer> &)> & callback)69 void OfflinePipeline::BindOfflineStreamCallback(std::function<void(std::shared_ptr<IBuffer>&)>& callback)
70 {
71     std::lock_guard<std::mutex> l(cbLock_);
72     callback_ = callback;
73 
74     return;
75 }
76 
SwitchToOfflineMode()77 void OfflinePipeline::SwitchToOfflineMode()
78 {
79     offlineMode_ = true;
80 }
81 
CancelCapture(int32_t captureId)82 RetCode OfflinePipeline::CancelCapture(int32_t captureId)
83 {
84     CAMERA_LOGE("cancel capture begin");
85     if (bufferCache_.empty()) {
86         CAMERA_LOGE("cancel capture failed, capture id = %{public}d doesn't exist", captureId);
87         return RC_OK;
88     }
89 
90     std::vector<std::shared_ptr<IBuffer>> cache;
91     {
92         std::unique_lock<std::mutex> l(queueLock_);
93         auto it = std::find_if(bufferCache_.begin(), bufferCache_.end(),
94             [&captureId](const std::vector<std::shared_ptr<IBuffer>>& c) {
95                 for (auto b : c) {
96                     if (b->GetCaptureId() == captureId) {
97                         return true;
98                     }
99                 }
100                 return false;
101             });
102         if (it == bufferCache_.end()) {
103             CAMERA_LOGE("cancel capture failed, capture id = %{public}d doesn't exist", captureId);
104             return RC_OK;
105         }
106         cache = *it;
107         bufferCache_.erase(it);
108     }
109     for (auto it : cache) {
110         it->SetBufferStatus(CAMERA_BUFFER_STATUS_DROP);
111     }
112     DeliverCancelCache(cache);
113     CAMERA_LOGE("cancel capture end");
114     return RC_OK;
115 }
116 
FlushOfflineStream()117 RetCode OfflinePipeline::FlushOfflineStream()
118 {
119     if (!offlineMode_.load()) {
120         CAMERA_LOGE("can't flush in online mode");
121         return RC_ERROR;
122     }
123 
124     if (!bufferCache_.empty()) {
125         std::unique_lock<std::mutex> l(queueLock_);
126         while (!bufferCache_.empty()) {
127             auto cache = bufferCache_.front();
128             bufferCache_.pop_front();
129 
130             for (auto it : cache) {
131                 it->SetBufferStatus(CAMERA_BUFFER_STATUS_DROP);
132             }
133             DeliverCancelCache(cache);
134         }
135     }
136 
137     return RC_OK;
138 }
139 
ReceiveCache(std::vector<std::shared_ptr<IBuffer>> & buffers)140 void OfflinePipeline::ReceiveCache(std::vector<std::shared_ptr<IBuffer>>& buffers)
141 {
142     if (!buffers.empty() && buffers[0]->GetBufferStatus() != CAMERA_BUFFER_STATUS_OK) {
143         DeliverCancelCache(buffers);
144         return;
145     }
146 
147     std::unique_lock<std::mutex> l(queueLock_);
148     bufferCache_.emplace_back(buffers);
149     cv_.notify_one();
150 
151     return;
152 }
153 
HandleBuffers()154 void OfflinePipeline::HandleBuffers()
155 {
156     if (running_ == false) {
157         return;
158     }
159 
160     std::vector<std::shared_ptr<IBuffer>> cache = {};
161     cache = bufferCache_.front();
162     bufferCache_.pop_front();
163     if (cache.empty()) {
164         return;
165     }
166 
167     ProcessCache(cache);
168     return;
169 }
170 
ProcessCache(std::vector<std::shared_ptr<IBuffer>> & buffers)171 void OfflinePipeline::ProcessCache(std::vector<std::shared_ptr<IBuffer>>& buffers)
172 {
173     DeliverCache(buffers);
174     return;
175 }
DeliverCacheCheck(std::vector<std::shared_ptr<IBuffer>> & buffers)176 void OfflinePipeline::DeliverCacheCheck(std::vector<std::shared_ptr<IBuffer>>& buffers)
177 {
178     for (auto it : buffers) {
179         if (it == nullptr) {
180             continue;
181         }
182         auto bufferManager = BufferManager::GetInstance();
183         if (bufferManager == nullptr) {
184             CAMERA_LOGE("can't get buffer manager");
185             continue;
186         }
187         auto bufferPool = bufferManager->GetBufferPool(it->GetPoolId());
188         if (bufferPool == nullptr) {
189             CAMERA_LOGE("can't get buffer pool");
190             return;
191         }
192         bufferPool->ReturnBuffer(it);
193     }
194 }
DeliverCache(std::vector<std::shared_ptr<IBuffer>> & buffers)195 void OfflinePipeline::DeliverCache(std::vector<std::shared_ptr<IBuffer>>& buffers)
196 {
197     DeliverCacheCheck(buffers);
198     if (offlineMode_.load()) {
199         std::shared_ptr<IBuffer> nullBuffer = nullptr;
200         DeliverOfflineBuffer(nullBuffer);
201     }
202     return;
203 }
204 
DeliverCancelCache(std::vector<std::shared_ptr<IBuffer>> & buffers)205 void OfflinePipeline::DeliverCancelCache(std::vector<std::shared_ptr<IBuffer>>& buffers)
206 {
207     DeliverCache(buffers);
208     return;
209 }
210 
DeliverOfflineBuffer(std::shared_ptr<IBuffer> & buffer)211 void OfflinePipeline::DeliverOfflineBuffer(std::shared_ptr<IBuffer>& buffer)
212 {
213     if (!offlineMode_.load()) {
214         CAMERA_LOGE("cannot deliver buffer in online mode");
215         return;
216     }
217 
218     if (callback_ == nullptr) {
219         CAMERA_LOGE("cannot deliver offline buffer, callback_ is null");
220         return;
221     }
222 
223     callback_(buffer);
224 
225     return;
226 }
227 
CacheQueueDry()228 bool OfflinePipeline::CacheQueueDry()
229 {
230     std::unique_lock<std::mutex> l(queueLock_);
231     return bufferCache_.empty();
232 }
233 
CheckOwnerOfCaptureId(int32_t captureId)234 bool OfflinePipeline::CheckOwnerOfCaptureId(int32_t captureId)
235 {
236     std::unique_lock<std::mutex> l(queueLock_);
237     for (auto it : bufferCache_) {
238         for (auto buffer : it) {
239             if (captureId == buffer->GetCaptureId()) {
240                 return true;
241             }
242         }
243     }
244     return false;
245 }
246 } // namespace OHOS::Camera
247