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_sink_output.h"
17
18 #include "anonymous_string.h"
19 #include "dcamera_channel_sink_impl.h"
20 #include "dcamera_client.h"
21 #include "dcamera_sink_data_process.h"
22 #include "dcamera_sink_output_channel_listener.h"
23 #include "dcamera_sink_output_result_callback.h"
24 #include "distributed_camera_constants.h"
25 #include "distributed_camera_errno.h"
26 #include "distributed_hardware_log.h"
27
28 namespace OHOS {
29 namespace DistributedHardware {
DCameraSinkOutput(const std::string & dhId,std::shared_ptr<ICameraOperator> & cameraOperator)30 DCameraSinkOutput::DCameraSinkOutput(const std::string& dhId, std::shared_ptr<ICameraOperator>& cameraOperator)
31 : dhId_(dhId), operator_(cameraOperator)
32 {
33 DHLOGI("DCameraSinkOutput Constructor dhId: %{public}s", GetAnonyString(dhId_).c_str());
34 isInit_ = false;
35 }
36
~DCameraSinkOutput()37 DCameraSinkOutput::~DCameraSinkOutput()
38 {
39 if (isInit_) {
40 UnInit();
41 }
42 }
43
Init()44 int32_t DCameraSinkOutput::Init()
45 {
46 CHECK_AND_RETURN_RET_LOG(operator_ == nullptr, DCAMERA_BAD_VALUE, "operator_ is null");
47 DHLOGI("Init dhId: %{public}s", GetAnonyString(dhId_).c_str());
48 auto output = std::shared_ptr<DCameraSinkOutput>(shared_from_this());
49 std::shared_ptr<ResultCallback> resultCallback = std::make_shared<DCameraSinkOutputResultCallback>(output);
50 operator_->SetResultCallback(resultCallback);
51
52 InitInner(CONTINUOUS_FRAME);
53 InitInner(SNAPSHOT_FRAME);
54 isInit_ = true;
55 DHLOGI("Init %{public}s success", GetAnonyString(dhId_).c_str());
56 return DCAMERA_OK;
57 }
58
InitInner(DCStreamType type)59 void DCameraSinkOutput::InitInner(DCStreamType type)
60 {
61 std::shared_ptr<ICameraChannel> channel = std::make_shared<DCameraChannelSinkImpl>();
62 std::shared_ptr<ICameraSinkDataProcess> dataProcess = std::make_shared<DCameraSinkDataProcess>(dhId_, channel);
63 dataProcess->Init();
64 dataProcesses_.emplace(type, dataProcess);
65 channels_.emplace(type, channel);
66 sessionState_.emplace(type, DCAMERA_CHANNEL_STATE_DISCONNECTED);
67 }
68
UnInit()69 int32_t DCameraSinkOutput::UnInit()
70 {
71 DHLOGI("UnInit dhId: %{public}s", GetAnonyString(dhId_).c_str());
72 channels_.clear();
73 dataProcesses_.clear();
74 sessionState_.clear();
75 isInit_ = false;
76 DHLOGI("UnInit %{public}s success", GetAnonyString(dhId_).c_str());
77 return DCAMERA_OK;
78 }
79
OpenChannel(std::shared_ptr<DCameraChannelInfo> & info)80 int32_t DCameraSinkOutput::OpenChannel(std::shared_ptr<DCameraChannelInfo>& info)
81 {
82 DHLOGI("OpenChannel dhId: %{public}s", GetAnonyString(dhId_).c_str());
83 CHECK_AND_RETURN_RET_LOG(info == nullptr, DCAMERA_BAD_VALUE, "OpenChannel info is null");
84 std::map<DCStreamType, DCameraSessionMode> modeMaps;
85 modeMaps.emplace(CONTINUOUS_FRAME, DCAMERA_SESSION_MODE_VIDEO);
86 modeMaps.emplace(SNAPSHOT_FRAME, DCAMERA_SESSION_MODE_JPEG);
87 std::vector<DCameraIndex> indexs;
88 indexs.push_back(DCameraIndex(info->sourceDevId_, dhId_));
89 for (auto iter = info->detail_.begin(); iter != info->detail_.end(); iter++) {
90 if (sessionState_[iter->streamType_] != DCAMERA_CHANNEL_STATE_DISCONNECTED) {
91 DHLOGE("wrong state, sessionState: %{public}d", sessionState_[iter->streamType_]);
92 return DCAMERA_OK;
93 }
94 auto iterCh = channels_.find(iter->streamType_);
95 if (iterCh == channels_.end()) {
96 continue;
97 }
98 auto output = std::shared_ptr<DCameraSinkOutput>(shared_from_this());
99 std::shared_ptr<ICameraChannelListener> channelListener =
100 std::make_shared<DCameraSinkOutputChannelListener>(iter->streamType_, output);
101 int32_t ret = iterCh->second->CreateSession(indexs, iter->dataSessionFlag_, modeMaps[iter->streamType_],
102 channelListener);
103 if (ret != DCAMERA_OK) {
104 DHLOGE("channel create session failed, dhId: %{public}s, ret: %{public}d",
105 GetAnonyString(dhId_).c_str(), ret);
106 return ret;
107 }
108 }
109 return DCAMERA_OK;
110 }
111
CloseChannel()112 int32_t DCameraSinkOutput::CloseChannel()
113 {
114 DHLOGI("CloseChannel dhId: %{public}s", GetAnonyString(dhId_).c_str());
115 auto iterCon = channels_.find(CONTINUOUS_FRAME);
116 if (iterCon != channels_.end()) {
117 int32_t ret = DCAMERA_OK;
118 CHECK_AND_RETURN_RET_LOG(iterCon->second == nullptr, DCAMERA_BAD_VALUE,
119 "CloseChannel continuous channel is null");
120 ret = iterCon->second->ReleaseSession();
121 if (ret != DCAMERA_OK) {
122 DHLOGI("DCameraSinkOutput UnInit release continue session failed, dhId: %{public}s, ret: %{public}d",
123 GetAnonyString(dhId_).c_str(), ret);
124 }
125 sessionState_[CONTINUOUS_FRAME] = DCAMERA_CHANNEL_STATE_DISCONNECTED;
126 }
127
128 auto iterSnap = channels_.find(SNAPSHOT_FRAME);
129 if (iterSnap != channels_.end()) {
130 int32_t ret = DCAMERA_OK;
131 CHECK_AND_RETURN_RET_LOG(iterSnap->second == nullptr, DCAMERA_BAD_VALUE,
132 "CloseChannel snapshot channel is null");
133 ret = iterSnap->second->ReleaseSession();
134 if (ret != DCAMERA_OK) {
135 DHLOGI("DCameraSinkOutput UnInit release snapshot session failed, dhId: %{public}s, ret: %{public}d",
136 GetAnonyString(dhId_).c_str(), ret);
137 }
138 sessionState_[SNAPSHOT_FRAME] = DCAMERA_CHANNEL_STATE_DISCONNECTED;
139 }
140 return DCAMERA_OK;
141 }
142
StartCapture(std::vector<std::shared_ptr<DCameraCaptureInfo>> & captureInfos)143 int32_t DCameraSinkOutput::StartCapture(std::vector<std::shared_ptr<DCameraCaptureInfo>>& captureInfos)
144 {
145 DHLOGI("StartCapture dhId: %{public}s", GetAnonyString(dhId_).c_str());
146 for (auto& info : captureInfos) {
147 if (info == nullptr) {
148 DHLOGE("StartCapture info is null");
149 continue;
150 }
151 if (dataProcesses_.find(info->streamType_) == dataProcesses_.end()) {
152 DHLOGE("has no data process, streamType: %{public}d", info->streamType_);
153 break;
154 }
155 int32_t ret = dataProcesses_[info->streamType_]->StartCapture(info);
156 if (ret != DCAMERA_OK) {
157 DHLOGE("StartCapture failed, dhId: %{public}s, ret: %{public}d", GetAnonyString(dhId_).c_str(), ret);
158 return ret;
159 }
160 }
161 return DCAMERA_OK;
162 }
163
StopCapture()164 int32_t DCameraSinkOutput::StopCapture()
165 {
166 DHLOGI("StopCapture dhId: %{public}s", GetAnonyString(dhId_).c_str());
167 auto iterCon = dataProcesses_.find(CONTINUOUS_FRAME);
168 if (iterCon != dataProcesses_.end()) {
169 DHLOGI("StopCapture %{public}s continuous frame stop capture", GetAnonyString(dhId_).c_str());
170 CHECK_AND_RETURN_RET_LOG(iterCon->second == nullptr, DCAMERA_BAD_VALUE,
171 "StopCapture continuous data process is null");
172 int32_t ret = iterCon->second->StopCapture();
173 if (ret != DCAMERA_OK) {
174 DHLOGE("continuous data process stop capture failed, dhId: %{public}s, ret: %{public}d",
175 GetAnonyString(dhId_).c_str(), ret);
176 }
177 }
178
179 auto iterSnap = dataProcesses_.find(SNAPSHOT_FRAME);
180 if (iterSnap != dataProcesses_.end()) {
181 DHLOGI("StopCapture %{public}s snapshot frame stop capture", GetAnonyString(dhId_).c_str());
182 CHECK_AND_RETURN_RET_LOG(iterSnap->second == nullptr, DCAMERA_BAD_VALUE,
183 "StopCapture snapshot data process is null");
184 int32_t ret = iterSnap->second->StopCapture();
185 if (ret != DCAMERA_OK) {
186 DHLOGE("snapshot data process stop capture failed, dhId: %{public}s, ret: %{public}d",
187 GetAnonyString(dhId_).c_str(), ret);
188 }
189 }
190 DHLOGI("StopCapture %{public}s success", GetAnonyString(dhId_).c_str());
191 return DCAMERA_OK;
192 }
193
OnVideoResult(std::shared_ptr<DataBuffer> & buffer)194 void DCameraSinkOutput::OnVideoResult(std::shared_ptr<DataBuffer>& buffer)
195 {
196 if (sessionState_[CONTINUOUS_FRAME] != DCAMERA_CHANNEL_STATE_CONNECTED) {
197 DHLOGE("OnVideoResult dhId: %{public}s, channel state: %{public}d",
198 GetAnonyString(dhId_).c_str(), sessionState_[CONTINUOUS_FRAME]);
199 return;
200 }
201 if (dataProcesses_.find(CONTINUOUS_FRAME) == dataProcesses_.end()) {
202 DHLOGE("OnVideoResult %{public}s has no continuous data process", GetAnonyString(dhId_).c_str());
203 return;
204 }
205 CHECK_AND_RETURN_LOG(dataProcesses_[CONTINUOUS_FRAME] == nullptr,
206 "OnVideoResult continuous data process is null");
207 dataProcesses_[CONTINUOUS_FRAME]->FeedStream(buffer);
208 }
209
OnPhotoResult(std::shared_ptr<DataBuffer> & buffer)210 void DCameraSinkOutput::OnPhotoResult(std::shared_ptr<DataBuffer>& buffer)
211 {
212 if (dataProcesses_.find(SNAPSHOT_FRAME) == dataProcesses_.end()) {
213 DHLOGE("OnPhotoResult %{public}s has no snapshot data process", GetAnonyString(dhId_).c_str());
214 return;
215 }
216 CHECK_AND_RETURN_LOG(dataProcesses_[SNAPSHOT_FRAME] == nullptr,
217 "OnPhotoResult snapshot data process is null");
218 dataProcesses_[SNAPSHOT_FRAME]->FeedStream(buffer);
219 }
220
OnSessionState(DCStreamType type,int32_t state)221 void DCameraSinkOutput::OnSessionState(DCStreamType type, int32_t state)
222 {
223 DHLOGI("OnSessionState dhId: %{public}s, stream type: %{public}d, state: %{public}d",
224 GetAnonyString(dhId_).c_str(), type, state);
225 sessionState_[type] = state;
226 switch (state) {
227 case DCAMERA_CHANNEL_STATE_CONNECTING: {
228 DHLOGI("channel is connecting, dhId: %{public}s, stream type: %{public}d",
229 GetAnonyString(dhId_).c_str(), type);
230 break;
231 }
232 case DCAMERA_CHANNEL_STATE_CONNECTED: {
233 DHLOGI("channel is connected, dhId: %{public}s, stream type: %{public}d",
234 GetAnonyString(dhId_).c_str(), type);
235 break;
236 }
237 case DCAMERA_CHANNEL_STATE_DISCONNECTED: {
238 DHLOGI("channel is disconnected, dhId: %{public}s, stream type: %{public}d",
239 GetAnonyString(dhId_).c_str(), type);
240 break;
241 }
242 default: {
243 DHLOGE("OnSessionState %{public}s unknown session state", GetAnonyString(dhId_).c_str());
244 break;
245 }
246 }
247 }
248
OnSessionError(DCStreamType type,int32_t eventType,int32_t eventReason,std::string detail)249 void DCameraSinkOutput::OnSessionError(DCStreamType type, int32_t eventType, int32_t eventReason, std::string detail)
250 {
251 DHLOGI("OnSessionError dhId: %{public}s, stream type: %{public}d, eventType: %{public}d, eventReason: "
252 "%{public}d, detail: %{public}s", GetAnonyString(dhId_).c_str(), type, eventType, eventReason, detail.c_str());
253 }
254
OnDataReceived(DCStreamType type,std::vector<std::shared_ptr<DataBuffer>> & dataBuffers)255 void DCameraSinkOutput::OnDataReceived(DCStreamType type, std::vector<std::shared_ptr<DataBuffer>>& dataBuffers)
256 {
257 }
258
GetProperty(const std::string & propertyName,PropertyCarrier & propertyCarrier)259 int32_t DCameraSinkOutput::GetProperty(const std::string& propertyName, PropertyCarrier& propertyCarrier)
260 {
261 if (dataProcesses_[CONTINUOUS_FRAME] == nullptr) {
262 DHLOGD("GetProperty: continuous frame is nullptr.");
263 return DCAMERA_BAD_VALUE;
264 }
265 return dataProcesses_[CONTINUOUS_FRAME]->GetProperty(propertyName, propertyCarrier);
266 }
267 } // namespace DistributedHardware
268 } // namespace OHOS