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