1 /*
2 * Copyright (c) 2021-2022 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
26 namespace OHOS {
27 namespace DistributedHardware {
DCameraSinkDataProcess(const std::string & dhId,std::shared_ptr<ICameraChannel> & channel)28 DCameraSinkDataProcess::DCameraSinkDataProcess(const std::string& dhId, std::shared_ptr<ICameraChannel>& channel)
29 : dhId_(dhId), channel_(channel), eventHandler_(nullptr)
30 {
31 DHLOGI("DCameraSinkDataProcess Constructor dhId: %s", GetAnonyString(dhId_).c_str());
32 }
33
~DCameraSinkDataProcess()34 DCameraSinkDataProcess::~DCameraSinkDataProcess()
35 {
36 DHLOGI("DCameraSinkDataProcess delete dhId: %s", GetAnonyString(dhId_).c_str());
37 if ((eventHandler_ != nullptr) && (eventHandler_->GetEventRunner() != nullptr)) {
38 eventHandler_->GetEventRunner()->Stop();
39 }
40 eventThread_.join();
41 eventHandler_ = nullptr;
42 }
43
Init()44 void DCameraSinkDataProcess::Init()
45 {
46 DHLOGI("DCameraSinkDataProcess Init dhId: %s", GetAnonyString(dhId_).c_str());
47 eventThread_ = std::thread(&DCameraSinkDataProcess::StartEventHandler, this);
48 std::unique_lock<std::mutex> lock(eventMutex_);
49 eventCon_.wait(lock, [this] {
50 return eventHandler_ != nullptr;
51 });
52 }
53
StartEventHandler()54 void DCameraSinkDataProcess::StartEventHandler()
55 {
56 auto runner = AppExecFwk::EventRunner::Create(false);
57 {
58 std::lock_guard<std::mutex> lock(eventMutex_);
59 eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(runner);
60 }
61 eventCon_.notify_one();
62 runner->Run();
63 }
64
StartCapture(std::shared_ptr<DCameraCaptureInfo> & captureInfo)65 int32_t DCameraSinkDataProcess::StartCapture(std::shared_ptr<DCameraCaptureInfo>& captureInfo)
66 {
67 DHLOGI("DCameraSinkDataProcess::StartCapture dhId: %s, width: %d, height: %d, format: %d, stream: %d, encode: %d",
68 GetAnonyString(dhId_).c_str(), captureInfo->width_, captureInfo->height_, captureInfo->format_,
69 captureInfo->streamType_, captureInfo->encodeType_);
70 captureInfo_ = captureInfo;
71 if (pipeline_ != nullptr) {
72 DHLOGI("DCameraSinkDataProcess::StartCapture %s pipeline already exits", GetAnonyString(dhId_).c_str());
73 return DCAMERA_OK;
74 }
75
76 if (captureInfo->streamType_ == CONTINUOUS_FRAME) {
77 DHLOGI("DCameraSinkDataProcess::StartCapture %s create data process pipeline", GetAnonyString(dhId_).c_str());
78 pipeline_ = std::make_shared<DCameraPipelineSink>();
79 auto dataProcess = std::shared_ptr<DCameraSinkDataProcess>(shared_from_this());
80 std::shared_ptr<DataProcessListener> listener = std::make_shared<DCameraSinkDataProcessListener>(dataProcess);
81 VideoConfigParams srcParams(VideoCodecType::NO_CODEC,
82 GetPipelineFormat(captureInfo->format_),
83 DCAMERA_PRODUCER_FPS_DEFAULT,
84 captureInfo->width_,
85 captureInfo->height_);
86 VideoConfigParams destParams(GetPipelineCodecType(captureInfo->encodeType_),
87 GetPipelineFormat(captureInfo->format_),
88 DCAMERA_PRODUCER_FPS_DEFAULT,
89 captureInfo->width_,
90 captureInfo->height_);
91 int32_t ret = pipeline_->CreateDataProcessPipeline(PipelineType::VIDEO, srcParams, destParams, listener);
92 if (ret != DCAMERA_OK) {
93 DHLOGE("DCameraSinkDataProcess::StartCapture create data process pipeline failed, dhId: %s, ret: %d",
94 GetAnonyString(dhId_).c_str(), ret);
95 return ret;
96 }
97 }
98 DHLOGI("DCameraSinkDataProcess::StartCapture %s success", GetAnonyString(dhId_).c_str());
99 return DCAMERA_OK;
100 }
101
StopCapture()102 int32_t DCameraSinkDataProcess::StopCapture()
103 {
104 DHLOGI("DCameraSinkDataProcess::StopCapture dhId: %s", GetAnonyString(dhId_).c_str());
105 if (pipeline_ != nullptr) {
106 pipeline_->DestroyDataProcessPipeline();
107 pipeline_ = nullptr;
108 }
109 if (eventHandler_ != nullptr) {
110 DHLOGI("DCameraSinkDataProcess::StopCapture dhId: %s, remove all events", GetAnonyString(dhId_).c_str());
111 eventHandler_->RemoveAllEvents();
112 }
113 return DCAMERA_OK;
114 }
115
FeedStream(std::shared_ptr<DataBuffer> & dataBuffer)116 int32_t DCameraSinkDataProcess::FeedStream(std::shared_ptr<DataBuffer>& dataBuffer)
117 {
118 DCStreamType type = captureInfo_->streamType_;
119 DHLOGD("DCameraSinkDataProcess::FeedStream dhId: %s, stream type: %d", GetAnonyString(dhId_).c_str(), type);
120 switch (type) {
121 case CONTINUOUS_FRAME: {
122 int32_t ret = FeedStreamInner(dataBuffer);
123 if (ret != DCAMERA_OK) {
124 DHLOGE("DCameraSinkDataProcess::FeedStream continuous frame failed, dhId: %s, ret: %d",
125 GetAnonyString(dhId_).c_str(), ret);
126 return ret;
127 }
128 break;
129 }
130 case SNAPSHOT_FRAME: {
131 SendDataAsync(dataBuffer);
132 break;
133 }
134 default: {
135 DHLOGE("DCameraSinkDataProcess::FeedStream %s unknown stream type: %d",
136 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("DCameraSinkDataProcess::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("DCameraSinkDataProcess::FeedStreamInner process data failed, dhId: %s, ret: %d",
174 GetAnonyString(dhId_).c_str(), ret);
175 return ret;
176 }
177 return DCAMERA_OK;
178 }
179
GetPipelineCodecType(DCEncodeType encodeType)180 VideoCodecType DCameraSinkDataProcess::GetPipelineCodecType(DCEncodeType encodeType)
181 {
182 VideoCodecType codecType;
183 switch (encodeType) {
184 case ENCODE_TYPE_H264:
185 codecType = VideoCodecType::CODEC_H264;
186 break;
187 case ENCODE_TYPE_H265:
188 codecType = VideoCodecType::CODEC_H265;
189 break;
190 default:
191 codecType = VideoCodecType::NO_CODEC;
192 break;
193 }
194 return codecType;
195 }
196
GetPipelineFormat(int32_t format)197 Videoformat DCameraSinkDataProcess::GetPipelineFormat(int32_t format)
198 {
199 return Videoformat::NV21;
200 }
201 } // namespace DistributedHardware
202 } // namespace OHOS