• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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