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_sink_data_process.h"
17
18 #include "anonymous_string.h"
19 #include "dcamera_channel_sink_impl.h"
20 #include "dcamera_pipeline_sink.h"
21 #include "dcamera_sink_data_process_listener.h"
22 #include "distributed_camera_constants.h"
23 #include "distributed_camera_errno.h"
24 #include "distributed_hardware_log.h"
25 #include <sys/prctl.h>
26
27 namespace OHOS {
28 namespace DistributedHardware {
DCameraSinkDataProcess(const std::string & dhId,std::shared_ptr<ICameraChannel> & channel)29 DCameraSinkDataProcess::DCameraSinkDataProcess(const std::string& dhId, std::shared_ptr<ICameraChannel>& channel)
30 : dhId_(dhId), channel_(channel), eventHandler_(nullptr)
31 {
32 DHLOGI("DCameraSinkDataProcess Constructor dhId: %s", GetAnonyString(dhId_).c_str());
33 }
34
~DCameraSinkDataProcess()35 DCameraSinkDataProcess::~DCameraSinkDataProcess()
36 {
37 DHLOGI("DCameraSinkDataProcess delete dhId: %s", GetAnonyString(dhId_).c_str());
38 if ((eventHandler_ != nullptr) && (eventHandler_->GetEventRunner() != nullptr)) {
39 eventHandler_->GetEventRunner()->Stop();
40 }
41 eventThread_.join();
42 eventHandler_ = nullptr;
43 }
44
Init()45 void DCameraSinkDataProcess::Init()
46 {
47 DHLOGI("DCameraSinkDataProcess Init dhId: %s", GetAnonyString(dhId_).c_str());
48 eventThread_ = std::thread(&DCameraSinkDataProcess::StartEventHandler, this);
49 std::unique_lock<std::mutex> lock(eventMutex_);
50 eventCon_.wait(lock, [this] {
51 return eventHandler_ != nullptr;
52 });
53 }
54
StartEventHandler()55 void DCameraSinkDataProcess::StartEventHandler()
56 {
57 prctl(PR_SET_NAME, SINK_START_EVENT.c_str());
58 auto runner = AppExecFwk::EventRunner::Create(false);
59 {
60 std::lock_guard<std::mutex> lock(eventMutex_);
61 eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
62 }
63 eventCon_.notify_one();
64 runner->Run();
65 }
66
StartCapture(std::shared_ptr<DCameraCaptureInfo> & captureInfo)67 int32_t DCameraSinkDataProcess::StartCapture(std::shared_ptr<DCameraCaptureInfo>& captureInfo)
68 {
69 DHLOGI("StartCapture dhId: %s, width: %d, height: %d, format: %d, stream: %d, encode: %d",
70 GetAnonyString(dhId_).c_str(), captureInfo->width_, captureInfo->height_, captureInfo->format_,
71 captureInfo->streamType_, captureInfo->encodeType_);
72 captureInfo_ = captureInfo;
73 if (pipeline_ != nullptr) {
74 DHLOGI("StartCapture %s pipeline already exits", GetAnonyString(dhId_).c_str());
75 return DCAMERA_OK;
76 }
77
78 if (captureInfo->streamType_ == CONTINUOUS_FRAME) {
79 DHLOGI("StartCapture %s create data process pipeline", GetAnonyString(dhId_).c_str());
80 pipeline_ = std::make_shared<DCameraPipelineSink>();
81 auto dataProcess = std::shared_ptr<DCameraSinkDataProcess>(shared_from_this());
82 std::shared_ptr<DataProcessListener> listener = std::make_shared<DCameraSinkDataProcessListener>(dataProcess);
83 VideoConfigParams srcParams(VideoCodecType::NO_CODEC,
84 GetPipelineFormat(captureInfo->format_),
85 DCAMERA_PRODUCER_FPS_DEFAULT,
86 captureInfo->width_,
87 captureInfo->height_);
88 VideoConfigParams destParams(GetPipelineCodecType(captureInfo->encodeType_),
89 GetPipelineFormat(captureInfo->format_),
90 DCAMERA_PRODUCER_FPS_DEFAULT,
91 captureInfo->width_,
92 captureInfo->height_);
93 int32_t ret = pipeline_->CreateDataProcessPipeline(PipelineType::VIDEO, srcParams, destParams, listener);
94 if (ret != DCAMERA_OK) {
95 DHLOGE("create data process pipeline failed, dhId: %s, ret: %d",
96 GetAnonyString(dhId_).c_str(), ret);
97 return ret;
98 }
99 }
100 DHLOGI("StartCapture %s success", GetAnonyString(dhId_).c_str());
101 return DCAMERA_OK;
102 }
103
StopCapture()104 int32_t DCameraSinkDataProcess::StopCapture()
105 {
106 DHLOGI("StopCapture dhId: %s", GetAnonyString(dhId_).c_str());
107 if (pipeline_ != nullptr) {
108 pipeline_->DestroyDataProcessPipeline();
109 pipeline_ = nullptr;
110 }
111 if (eventHandler_ != nullptr) {
112 DHLOGI("StopCapture dhId: %s, remove all events", GetAnonyString(dhId_).c_str());
113 eventHandler_->RemoveAllEvents();
114 }
115 return DCAMERA_OK;
116 }
117
FeedStream(std::shared_ptr<DataBuffer> & dataBuffer)118 int32_t DCameraSinkDataProcess::FeedStream(std::shared_ptr<DataBuffer>& dataBuffer)
119 {
120 DCStreamType type = captureInfo_->streamType_;
121 DHLOGD("FeedStream dhId: %s, stream type: %d", GetAnonyString(dhId_).c_str(), type);
122 switch (type) {
123 case CONTINUOUS_FRAME: {
124 int32_t ret = FeedStreamInner(dataBuffer);
125 if (ret != DCAMERA_OK) {
126 DHLOGE("FeedStream continuous frame failed, dhId: %s, ret: %d", GetAnonyString(dhId_).c_str(), ret);
127 return ret;
128 }
129 break;
130 }
131 case SNAPSHOT_FRAME: {
132 SendDataAsync(dataBuffer);
133 break;
134 }
135 default: {
136 DHLOGE("FeedStream %s unknown stream type: %d", GetAnonyString(dhId_).c_str(), type);
137 break;
138 }
139 }
140 return DCAMERA_OK;
141 }
142
SendDataAsync(const std::shared_ptr<DataBuffer> & buffer)143 void DCameraSinkDataProcess::SendDataAsync(const std::shared_ptr<DataBuffer>& buffer)
144 {
145 auto sendFunc = [this, buffer]() mutable {
146 std::shared_ptr<DataBuffer> sendBuffer = buffer;
147 int32_t ret = channel_->SendData(sendBuffer);
148 DHLOGD("SendData type: %d output data ret: %d, dhId: %s, bufferSize: %d", captureInfo_->streamType_, ret,
149 GetAnonyString(dhId_).c_str(), buffer->Size());
150 };
151 if (eventHandler_ != nullptr) {
152 eventHandler_->PostTask(sendFunc);
153 }
154 }
155
OnProcessedVideoBuffer(const std::shared_ptr<DataBuffer> & videoResult)156 void DCameraSinkDataProcess::OnProcessedVideoBuffer(const std::shared_ptr<DataBuffer>& videoResult)
157 {
158 SendDataAsync(videoResult);
159 }
160
OnError(DataProcessErrorType errorType)161 void DCameraSinkDataProcess::OnError(DataProcessErrorType errorType)
162 {
163 DHLOGE("OnError %s data process pipeline error, errorType: %d",
164 GetAnonyString(dhId_).c_str(), errorType);
165 }
166
FeedStreamInner(std::shared_ptr<DataBuffer> & dataBuffer)167 int32_t DCameraSinkDataProcess::FeedStreamInner(std::shared_ptr<DataBuffer>& dataBuffer)
168 {
169 std::vector<std::shared_ptr<DataBuffer>> buffers;
170 buffers.push_back(dataBuffer);
171 int32_t ret = pipeline_->ProcessData(buffers);
172 if (ret != DCAMERA_OK) {
173 DHLOGE("process data failed, dhId: %s, ret: %d", GetAnonyString(dhId_).c_str(), ret);
174 return ret;
175 }
176 return DCAMERA_OK;
177 }
178
GetPipelineCodecType(DCEncodeType encodeType)179 VideoCodecType DCameraSinkDataProcess::GetPipelineCodecType(DCEncodeType encodeType)
180 {
181 VideoCodecType codecType;
182 switch (encodeType) {
183 case ENCODE_TYPE_H264:
184 codecType = VideoCodecType::CODEC_H264;
185 break;
186 case ENCODE_TYPE_H265:
187 codecType = VideoCodecType::CODEC_H265;
188 break;
189 case ENCODE_TYPE_MPEG4_ES:
190 codecType = VideoCodecType::CODEC_MPEG4_ES;
191 break;
192 default:
193 codecType = VideoCodecType::NO_CODEC;
194 break;
195 }
196 return codecType;
197 }
198
GetPipelineFormat(int32_t format)199 Videoformat DCameraSinkDataProcess::GetPipelineFormat(int32_t format)
200 {
201 Videoformat videoFormat;
202 switch (format) {
203 case OHOS_CAMERA_FORMAT_RGBA_8888:
204 videoFormat = Videoformat::RGBA_8888;
205 break;
206 default:
207 videoFormat = Videoformat::NV21;
208 break;
209 }
210 return videoFormat;
211 }
212
GetProperty(const std::string & propertyName,PropertyCarrier & propertyCarrier)213 int32_t DCameraSinkDataProcess::GetProperty(const std::string& propertyName, PropertyCarrier& propertyCarrier)
214 {
215 if (pipeline_ == nullptr) {
216 DHLOGD("GetProperty: pipeline is nullptr.");
217 return DCAMERA_BAD_VALUE;
218 }
219 return pipeline_->GetProperty(propertyName, propertyCarrier);
220 }
221 } // namespace DistributedHardware
222 } // namespace OHOS