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