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