• 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 "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 }