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