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