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