• 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  *     http://www.apache.org/licenses/LICENSE-2.0
7  * Unless required by applicable law or agreed to in writing, software
8  * distributed under the License is distributed on an "AS IS" BASIS,
9  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10  * See the License for the specific language governing permissions and
11  * limitations under the License.
12  */
13 
14 #include "buffer_manager.h"
15 #include "stream_pipeline_strategy.h"
16 
17 namespace OHOS::Camera {
StreamPipelineStrategy(const std::shared_ptr<HostStreamMgr> & streamMgr,const std::shared_ptr<PipelineSpec> & spec)18 StreamPipelineStrategy::StreamPipelineStrategy(const std::shared_ptr<HostStreamMgr>& streamMgr,
19     const std::shared_ptr<PipelineSpec>& spec) :
20     hostStreamMgr_(streamMgr),
21     pipelineSpec_(spec)
22 {
23 }
24 
GeneratePipelineSpec(const int32_t & mode)25 std::shared_ptr<PipelineSpec> StreamPipelineStrategy::GeneratePipelineSpec(const int32_t& mode)
26 {
27     PipelineSpec pipe {};
28     if (SelectPipelineSpec(mode, pipe) != RC_OK) {
29         return nullptr;
30     }
31     if (CombineSpecs(pipe) != RC_OK) {
32         return nullptr;
33     }
34     return pipelineSpec_;
35 }
36 
ConstructKeyStrIndex(const int32_t & mode)37 std::string StreamPipelineStrategy::ConstructKeyStrIndex(const int32_t& mode)
38 {
39     std::string keyStr;
40     std::string sceneStr= CheckIdExsit(mode, G_SCENE_TABLE_PTR, G_SCENE_TABLE_SIZE);
41     if (sceneStr.empty()) {
42         CAMERA_LOGE("scene:%{public}d not supported!\n", mode);
43         return keyStr;
44     }
45     keyStr += sceneStr;
46     std::vector<int32_t> streamTypeSet;
47     hostStreamMgr_->GetStreamTypes(streamTypeSet);
48     for (const auto& it : streamTypeSet) {
49         std::string streamStr = CheckIdExsit(it, G_STREAM_TABLE_PTR, G_STREAM_TABLE_SIZE);
50         if (streamStr.empty()) {
51             CAMERA_LOGI("stream type:%{public}d not support!\n", it);
52         }
53         keyStr += "_" + streamStr;
54     }
55     return keyStr;
56 }
57 
SetUpBasicOutPortFormat(const PipelineSpec & pipe,const PortInfo & info,PortFormat & format)58 RetCode StreamPipelineStrategy::SetUpBasicOutPortFormat(const PipelineSpec& pipe,
59     const PortInfo& info, PortFormat& format)
60 {
61     auto peerNode = std::find_if(pipe.nodeSpecSet_.begin(), pipe.nodeSpecSet_.end(),
62         [info](const NodeSpec& n) {
63             return info.peerPortNodeName_ == n.name_;
64         });
65     if (peerNode == pipe.nodeSpecSet_.end()) {
66         CAMERA_LOGI("config fail! node name:%{public}s not next node", info.peerPortNodeName_.c_str());
67         return RC_ERROR;
68     }
69     auto peerPort = std::find_if(peerNode->portSpecSet_.begin(), peerNode->portSpecSet_.end(),
70         [info] (const PortSpec& p) {
71             return info.peerPortName_ == p.info_.name_;
72         });
73     if (peerPort == peerNode->portSpecSet_.end()) {
74         CAMERA_LOGI("config fail! port name:%{public}s not exsit", info.name_.c_str());
75         return RC_ERROR;
76     }
77 
78     format = peerPort->format_;
79     return RC_OK;
80 }
81 
SetUpBasicInPortFormat(const NodeSpec & nodeSpec,PortFormat & format)82 RetCode StreamPipelineStrategy::SetUpBasicInPortFormat(const NodeSpec& nodeSpec, PortFormat& format)
83 {
84     auto outPort = std::find_if(nodeSpec.portSpecSet_.begin(), nodeSpec.portSpecSet_.end(),
85         [] (const PortSpec& p) {
86             return p.info_.name_ == "out0";
87         });
88     if (outPort == nodeSpec.portSpecSet_.end()) {
89         CAMERA_LOGI("config fail! node name:%{public}s  out0 not exsit", nodeSpec.name_.c_str());
90         return RC_ERROR;
91     }
92     format = (*outPort).format_;
93     return RC_OK;
94 }
SetPortFormat(G_PIPELINE_SPEC_DATA_TYPE & pipeSpecPtr,std::optional<int32_t> typeId,int j,int k,HostStreamInfo hostStreamInfo)95 PortFormat StreamPipelineStrategy::SetPortFormat(G_PIPELINE_SPEC_DATA_TYPE &pipeSpecPtr,
96                                                  std::optional<int32_t> typeId,
97                                                  int j,
98                                                  int k,
99                                                  HostStreamInfo hostStreamInfo)
100 {
101     struct PortFormat f {
102         .w_ = hostStreamInfo.width_,
103         .h_ = hostStreamInfo.height_,
104         .streamId_ = hostStreamInfo.streamId_,
105         .format_ = hostStreamInfo.format_,
106         .usage_ = hostStreamInfo.usage_,
107         .needAllocation_ = pipeSpecPtr->nodeSpec[j].portSpec[k].need_allocation,
108         .bufferCount_ = hostStreamInfo.bufferCount_
109     };
110     (void)typeId;
111     CAMERA_LOGI("buffercount = %{public}d", f.bufferCount_);
112     return f;
113 }
114 
InitPipeSpecPtr(G_PIPELINE_SPEC_DATA_TYPE & pipeSpecPtr,std::string keyStr)115 void StreamPipelineStrategy::InitPipeSpecPtr(G_PIPELINE_SPEC_DATA_TYPE &pipeSpecPtr, std::string keyStr)
116 {
117     for (int i = 0; i < G_PIPELINE_SPECS_SIZE; i++) {
118         if (G_PIPELINE_SPECS_TABLE[i].name == keyStr) {
119             pipeSpecPtr = &G_PIPELINE_SPECS_TABLE[i];
120             break;
121         }
122     }
123 }
124 
SelectPipelineSpec(const int32_t & mode,PipelineSpec & pipe)125 RetCode StreamPipelineStrategy::SelectPipelineSpec(const int32_t& mode, PipelineSpec& pipe)
126 {
127     std::string keyStr = ConstructKeyStrIndex(mode);
128     G_PIPELINE_SPEC_DATA_TYPE pipeSpecPtr = nullptr;
129     InitPipeSpecPtr(pipeSpecPtr, keyStr);
130     if (pipeSpecPtr == nullptr) {
131         CAMERA_LOGE("target pipeline spec:%{public}s not exsit!i\n ", keyStr.c_str());
132         return RC_ERROR;
133     }
134 
135     for (int j = pipeSpecPtr->nodeSpecSize - 1; j >= 0; j--) {
136         struct NodeSpec nodeSpec {
137             .name_ = pipeSpecPtr->nodeSpec[j].name,
138             .status_ = std::string(pipeSpecPtr->nodeSpec[j].status),
139             .type_ = std::string(pipeSpecPtr->nodeSpec[j].stream_type)
140         };
141         for (int k = pipeSpecPtr->nodeSpec[j].portSpecSize - 1; k >= 0; k--) {
142             struct PortInfo info {
143                 .name_ = std::string(pipeSpecPtr->nodeSpec[j].portSpec[k].name),
144                 .peerPortName_ = std::string(pipeSpecPtr->nodeSpec[j].portSpec[k].peer_port_name),
145                 .peerPortNodeName_ = std::string(pipeSpecPtr->nodeSpec[j].portSpec[k].peer_port_node_name)
146             };
147             CAMERA_LOGV("read node %{public}s", info.peerPortNodeName_.c_str());
148 
149             std::optional<int32_t> typeId = GetTypeId(std::string(pipeSpecPtr->nodeSpec[j].stream_type),
150                 G_STREAM_TABLE_PTR, G_STREAM_TABLE_SIZE);
151             struct PortFormat format {};
152             int32_t streamId = -1;
153             if (typeId) {
154                 streamId = hostStreamMgr_->DesignateStreamIdForType(typeId.value());
155                 HostStreamInfo hostStreamInfo = hostStreamMgr_->GetStreamInfo(streamId);
156                 PortFormat f = SetPortFormat(pipeSpecPtr, typeId, j, k, hostStreamInfo);
157                 if (!f.needAllocation_) {
158                     f.bufferPoolId_ =
159                         static_cast<int64_t>(hostStreamInfo.bufferPoolId_);
160                 }
161                 format = f;
162                 nodeSpec.streamId_ = hostStreamInfo.streamId_;
163             } else if (pipeSpecPtr->nodeSpec[j].portSpec[k].direction == 1) {
164                 if (SetUpBasicOutPortFormat(pipe, info, format) != RC_OK) {
165                     return RC_ERROR;
166                 }
167             } else {
168                 if (SetUpBasicInPortFormat(nodeSpec, format) != RC_OK) {
169                     return RC_ERROR;
170                 }
171             }
172             struct PortSpec portSpec {
173                 .direction_ = pipeSpecPtr->nodeSpec[j].portSpec[k].direction,
174                 .info_ = info,
175                 .format_ = format,
176             };
177             nodeSpec.portSpecSet_.push_back(portSpec);
178         }
179         pipe.nodeSpecSet_.push_back(nodeSpec);
180     }
181     return RC_OK;
182 }
183 
PrintConnection(const NodeSpec & n)184 void StreamPipelineStrategy::PrintConnection(const NodeSpec& n)
185 {
186     if (n.portSpecSet_.size() == 1 && n.portSpecSet_[0].direction_ == 0) {
187         return;
188     }
189 
190     for (const auto& it : n.portSpecSet_) {
191         if (it.direction_ == 1) {
192             CAMERA_LOGI("(%{public}s)(name:%{public}s w:%{public}d h:%{public}d format:%{public}d usage:%{public}llu \
193                         bufferpoolid:%{public}llu) connect to (%{public}s)(name:%{public}s) \n",
194                         n.name_.c_str(), it.info_.name_.c_str(), it.format_.w_, it.format_.h_, it.format_.format_,
195                         it.format_.usage_, it.format_.bufferPoolId_,
196                         it.info_.peerPortNodeName_.c_str(), it.info_.peerPortName_.c_str());
197             auto nextNode = std::find_if(pipelineSpec_->nodeSpecSet_.begin(),
198                 pipelineSpec_->nodeSpecSet_.end(),
199                 [it](const NodeSpec& n) {
200                     return n.name_ == it.info_.peerPortNodeName_;
201                 });
202             if (nextNode != pipelineSpec_->nodeSpecSet_.end()) {
203                 PrintConnection(*nextNode);
204             }
205         }
206     }
207 }
208 
CombineSpecs(PipelineSpec & pipe)209 RetCode StreamPipelineStrategy::CombineSpecs(PipelineSpec& pipe)
210 {
211     CHECK_IF_PTR_NULL_RETURN_VALUE(pipelineSpec_, RC_ERROR);
212     CAMERA_LOGI("pipe.size = %{public}d,nodeSpecSet_.size = %{public}d", pipe.nodeSpecSet_.size(),
213         pipelineSpec_->nodeSpecSet_.size());
214     for (auto it = pipe.nodeSpecSet_.rbegin(); it != pipe.nodeSpecSet_.rend(); it++) {
215         auto node = std::find_if(pipelineSpec_->nodeSpecSet_.begin(), pipelineSpec_->nodeSpecSet_.end(),
216             [it](const NodeSpec& n) {
217                 return n.name_ == (*it).name_;
218             });
219         if (node == pipelineSpec_->nodeSpecSet_.end()) {
220             CAMERA_LOGI("add node:%{public}s\n", (*it).name_.c_str());
221             pipelineSpec_->nodeSpecSet_.push_back(*it);
222         } else {
223             if (*node != *it) {
224                 CAMERA_LOGI("change node:%{public}s\n", (*it).name_.c_str());
225                 std::swap((*node).portSpecSet_, (*it).portSpecSet_);
226             }
227         }
228     }
229     CAMERA_LOGI("------------------------Connection Dump Begin-------------\n");
230     PrintConnection(pipelineSpec_->nodeSpecSet_[0]);
231     CAMERA_LOGI("------------------------Connection Dump End-------------\n");
232     return RC_OK;
233 }
234 
Destroy(const int & streamId)235 RetCode StreamPipelineStrategy::Destroy(const int& streamId)
236 {
237     CHECK_IF_PTR_NULL_RETURN_VALUE(pipelineSpec_, RC_ERROR);
238     (void)streamId;
239     pipelineSpec_->nodeSpecSet_.clear();
240     return RC_OK;
241 }
242 
Create(const std::shared_ptr<HostStreamMgr> & streamMgr)243 std::unique_ptr<StreamPipelineStrategy> StreamPipelineStrategy::Create(const std::shared_ptr<HostStreamMgr>& streamMgr)
244 {
245     std::shared_ptr<PipelineSpec> p = std::make_shared<PipelineSpec>();
246     return std::make_unique<StreamPipelineStrategy>(streamMgr, p);
247 }
248 
CheckPipelineSpecExist(const int32_t mode,const std::vector<int32_t> & types)249 RetCode StreamPipelineStrategy::CheckPipelineSpecExist(const int32_t mode, const std::vector<int32_t>& types)
250 {
251     std::string sceneStr= CheckIdExsit(mode, G_SCENE_TABLE_PTR, G_SCENE_TABLE_SIZE);
252     if (sceneStr.empty()) {
253         return RC_ERROR;
254     }
255 
256     std::string keyStr = "";
257     keyStr += sceneStr;
258     for (const auto it : types) {
259         std::string streamStr = CheckIdExsit(it, G_STREAM_TABLE_PTR, G_STREAM_TABLE_SIZE);
260         if (streamStr.empty()) {
261             return RC_ERROR;
262         }
263         keyStr += "_" + streamStr;
264     }
265 
266     for (int i = 0; i < G_PIPELINE_SPECS_SIZE; i++) {
267         if (G_PIPELINE_SPECS_TABLE[i].name == keyStr) {
268             return RC_OK;
269         }
270     }
271 
272     return RC_ERROR;
273 }
274 }
275