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 "dcamera_pipeline_source.h"
17
18 #include "distributed_hardware_log.h"
19
20 #include "decode_data_process.h"
21 #include "fps_controller_process.h"
22
23 namespace OHOS {
24 namespace DistributedHardware {
25 const std::string DCameraPipelineSource::PIPELINE_OWNER = "Source";
26
~DCameraPipelineSource()27 DCameraPipelineSource::~DCameraPipelineSource()
28 {
29 if (isProcess_) {
30 DHLOGD("~DCameraPipelineSource : Destroy source data process pipeline.");
31 DestroyDataProcessPipeline();
32 }
33 }
34
CreateDataProcessPipeline(PipelineType piplineType,const VideoConfigParams & sourceConfig,const VideoConfigParams & targetConfig,const std::shared_ptr<DataProcessListener> & listener)35 int32_t DCameraPipelineSource::CreateDataProcessPipeline(PipelineType piplineType,
36 const VideoConfigParams& sourceConfig, const VideoConfigParams& targetConfig,
37 const std::shared_ptr<DataProcessListener>& listener)
38 {
39 DHLOGD("Create source data process pipeline.");
40 switch (piplineType) {
41 case PipelineType::VIDEO:
42 if (!(IsInRange(sourceConfig) && IsInRange(targetConfig))) {
43 DHLOGE("Source config or target config of source pipeline are invalid.");
44 return DCAMERA_BAD_VALUE;
45 }
46 break;
47 default:
48 DHLOGE("JPEG or other pipeline type are not supported in source pipeline.");
49 return DCAMERA_NOT_FOUND;
50 }
51 if (listener == nullptr) {
52 DHLOGE("The process listener of source pipeline is empty.");
53 return DCAMERA_BAD_VALUE;
54 }
55
56 if (pipelineHead_ != nullptr) {
57 DHLOGD("The source pipeline already exists.");
58 return DCAMERA_OK;
59 }
60
61 InitDCameraPipEvent();
62 int32_t err = InitDCameraPipNodes(sourceConfig, targetConfig);
63 if (err != DCAMERA_OK) {
64 DestroyDataProcessPipeline();
65 return err;
66 }
67 piplineType_ = piplineType;
68 processListener_ = listener;
69 isProcess_ = true;
70 return DCAMERA_OK;
71 }
72
IsInRange(const VideoConfigParams & curConfig)73 bool DCameraPipelineSource::IsInRange(const VideoConfigParams& curConfig)
74 {
75 return (curConfig.GetFrameRate() <= MAX_FRAME_RATE || curConfig.GetWidth() >= MIN_VIDEO_WIDTH ||
76 curConfig.GetWidth() <= MAX_VIDEO_WIDTH || curConfig.GetHeight() >= MIN_VIDEO_HEIGHT ||
77 curConfig.GetHeight() <= MAX_VIDEO_HEIGHT);
78 }
79
InitDCameraPipEvent()80 void DCameraPipelineSource::InitDCameraPipEvent()
81 {
82 DHLOGD("Init source DCamera pipeline event to asynchronously process data.");
83 eventBusSource_ = std::make_shared<EventBus>();
84 DCameraPipelineEvent pipelineEvent(*this, std::make_shared<PipelineConfig>());
85 eventBusSource_->AddHandler<DCameraPipelineEvent>(pipelineEvent.GetType(), *this);
86 }
87
InitDCameraPipNodes(const VideoConfigParams & sourceConfig,const VideoConfigParams & targetConfig)88 int32_t DCameraPipelineSource::InitDCameraPipNodes(const VideoConfigParams& sourceConfig,
89 const VideoConfigParams& targetConfig)
90 {
91 DHLOGD("Init source DCamera pipeline Nodes.");
92 if (piplineType_ == PipelineType::PHOTO_JPEG) {
93 DHLOGE("JPEG data process is not supported.");
94 return DCAMERA_NOT_FOUND;
95 }
96 if (eventBusSource_ == nullptr) {
97 DHLOGE("eventBusSource is nullptr.");
98 return DCAMERA_BAD_VALUE;
99 }
100 pipNodeRanks_.push_back(std::make_shared<DecodeDataProcess>(sourceConfig, targetConfig,
101 eventBusSource_, shared_from_this()));
102 if (pipNodeRanks_.size() == 0) {
103 DHLOGD("Creating an empty source pipeline.");
104 pipelineHead_ = nullptr;
105 return DCAMERA_BAD_VALUE;
106 }
107 for (size_t i = 0; i < pipNodeRanks_.size(); i++) {
108 pipNodeRanks_[i]->SetNodeRank(i);
109 int32_t err = pipNodeRanks_[i]->InitNode();
110 if (err != DCAMERA_OK) {
111 DHLOGE("Init source DCamera pipeline Node [%d] failed.", i);
112 return DCAMERA_INIT_ERR;
113 }
114 if (i == 0) {
115 continue;
116 }
117 err = pipNodeRanks_[i - 1]->SetNextNode(pipNodeRanks_[i]);
118 if (err != DCAMERA_OK) {
119 DHLOGE("Set the next node of Node [%d] failed in source pipeline.", i - 1);
120 return DCAMERA_INIT_ERR;
121 }
122 }
123 DHLOGD("All nodes have been linked in source pipeline.");
124 pipelineHead_ = pipNodeRanks_[0];
125 return DCAMERA_OK;
126 }
127
ProcessData(std::vector<std::shared_ptr<DataBuffer>> & dataBuffers)128 int32_t DCameraPipelineSource::ProcessData(std::vector<std::shared_ptr<DataBuffer>>& dataBuffers)
129 {
130 DHLOGD("Process data buffers in source pipeline.");
131 if (piplineType_ == PipelineType::PHOTO_JPEG) {
132 DHLOGE("JPEG data process is not supported in source pipeline.");
133 return DCAMERA_NOT_FOUND;
134 }
135 if (pipelineHead_ == nullptr) {
136 DHLOGE("The current source pipeline node is empty. Processing failed.");
137 return DCAMERA_INIT_ERR;
138 }
139 if (dataBuffers.empty()) {
140 DHLOGE("Source Pipeline Input data buffers is empty.");
141 return DCAMERA_BAD_VALUE;
142 }
143 if (!isProcess_) {
144 DHLOGE("Source Pipeline node occurred error or start destroy.");
145 return DCAMERA_DISABLE_PROCESS;
146 }
147
148 DHLOGD("Send asynchronous event to process data in source pipeline.");
149 std::shared_ptr<PipelineConfig> pipConfigSource = std::make_shared<PipelineConfig>(piplineType_,
150 PIPELINE_OWNER, dataBuffers);
151 DCameraPipelineEvent dCamPipelineEvent(*this, pipConfigSource);
152 if (eventBusSource_ == nullptr) {
153 DHLOGE("eventBusSource_ is nullptr.");
154 return DCAMERA_BAD_VALUE;
155 }
156 eventBusSource_->PostEvent<DCameraPipelineEvent>(dCamPipelineEvent, POSTMODE::POST_ASYNC);
157 return DCAMERA_OK;
158 }
159
DestroyDataProcessPipeline()160 void DCameraPipelineSource::DestroyDataProcessPipeline()
161 {
162 DHLOGD("Destroy source data process pipeline start.");
163 isProcess_ = false;
164 if (pipelineHead_ != nullptr) {
165 pipelineHead_->ReleaseProcessNode();
166 pipelineHead_ = nullptr;
167 }
168 eventBusSource_ = nullptr;
169 processListener_ = nullptr;
170 pipNodeRanks_.clear();
171 piplineType_ = PipelineType::VIDEO;
172 DHLOGD("Destroy source data process pipeline end.");
173 }
174
OnEvent(DCameraPipelineEvent & ev)175 void DCameraPipelineSource::OnEvent(DCameraPipelineEvent& ev)
176 {
177 DHLOGD("Receive asynchronous event then start process data in source pipeline.");
178 std::shared_ptr<PipelineConfig> pipelineConfig = ev.GetPipelineConfig();
179 std::vector<std::shared_ptr<DataBuffer>> inputBuffers = pipelineConfig->GetDataBuffers();
180 if (inputBuffers.empty()) {
181 DHLOGE("Receiving process data buffers is empty in source pipeline.");
182 OnError(ERROR_PIPELINE_EVENTBUS);
183 return;
184 }
185 pipelineHead_->ProcessData(inputBuffers);
186 }
187
OnError(DataProcessErrorType errorType)188 void DCameraPipelineSource::OnError(DataProcessErrorType errorType)
189 {
190 DHLOGE("A runtime error occurred in the source pipeline.");
191 isProcess_ = false;
192 if (processListener_ == nullptr) {
193 DHLOGE("The process listener of source pipeline is empty.");
194 return;
195 }
196 processListener_->OnError(errorType);
197 }
198
OnProcessedVideoBuffer(const std::shared_ptr<DataBuffer> & videoResult)199 void DCameraPipelineSource::OnProcessedVideoBuffer(const std::shared_ptr<DataBuffer>& videoResult)
200 {
201 DHLOGD("Source pipeline output the processed video buffer.");
202 if (processListener_ == nullptr) {
203 DHLOGE("The process listener of source pipeline is empty.");
204 return;
205 }
206 processListener_->OnProcessedVideoBuffer(videoResult);
207 }
208 }
209 }