1 /*
2 * Copyright (c) 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 "screen_sink_trans.h"
17
18 #include "dscreen_errcode.h"
19 #include "dscreen_hisysevent.h"
20 #include "dscreen_hitrace.h"
21 #include "dscreen_log.h"
22 #include "image_sink_processor.h"
23 #include "screen_data_channel_impl.h"
24
25 namespace OHOS {
26 namespace DistributedHardware {
SetUp(const VideoParam & localParam,const VideoParam & remoteParam,const std::string & peerDevId)27 int32_t ScreenSinkTrans::SetUp(const VideoParam &localParam, const VideoParam &remoteParam,
28 const std::string &peerDevId)
29 {
30 DHLOGI("%s: SetUp.", LOG_TAG);
31 int32_t ret = CheckTransParam(localParam, remoteParam, peerDevId);
32 if (ret != DH_SUCCESS) {
33 DHLOGE("%s: SetUp failed param error ret: %d.", LOG_TAG, ret);
34 return ret;
35 }
36
37 ret = InitScreenTrans(localParam, remoteParam, peerDevId);
38 if (ret != DH_SUCCESS) {
39 DHLOGE("%s: SetUp failed ret: %d.", LOG_TAG, ret);
40 return ret;
41 }
42
43 DHLOGI("%s: SetUp success.", LOG_TAG);
44 return DH_SUCCESS;
45 }
46
Release()47 int32_t ScreenSinkTrans::Release()
48 {
49 DHLOGI("%s: Release.", LOG_TAG);
50 if (imageProcessor_ == nullptr || screenChannel_ == nullptr) {
51 DHLOGE("%s: Processor or channel is null, Setup first.", LOG_TAG);
52 return ERR_DH_SCREEN_TRANS_NULL_VALUE;
53 }
54
55 int32_t ret = imageProcessor_->ReleaseImageProcessor();
56 if (ret != DH_SUCCESS) {
57 DHLOGD("%s: Release image processor failed ret: %d.", LOG_TAG, ret);
58 }
59 imageProcessor_ = nullptr;
60
61 StartTrace(DSCREEN_HITRACE_LABEL, DSCREEN_SINK_RELEASE_SESSION_START);
62 ret = screenChannel_->ReleaseSession();
63 FinishTrace(DSCREEN_HITRACE_LABEL);
64 if (ret != DH_SUCCESS) {
65 DHLOGD("%s: Release channel session failed ret: %d.", LOG_TAG, ret);
66 }
67 screenChannel_ = nullptr;
68
69 DHLOGI("%s: Release success.", LOG_TAG);
70 return DH_SUCCESS;
71 }
72
Start()73 int32_t ScreenSinkTrans::Start()
74 {
75 DHLOGI("%s: Start.", LOG_TAG);
76 if (imageProcessor_ == nullptr || screenChannel_ == nullptr) {
77 DHLOGE("%s: Processor or channel is null, Setup first.", LOG_TAG);
78 return ERR_DH_SCREEN_TRANS_NULL_VALUE;
79 }
80
81 int32_t ret = imageProcessor_->StartImageProcessor();
82 if (ret != DH_SUCCESS) {
83 DHLOGE("%s: Start image processor failed ret: %d.", LOG_TAG, ret);
84 return ret;
85 }
86
87 DHLOGI("%s: Start success.", LOG_TAG);
88 return DH_SUCCESS;
89 }
90
Stop()91 int32_t ScreenSinkTrans::Stop()
92 {
93 DHLOGI("%s: Stop.", LOG_TAG);
94 if (imageProcessor_ == nullptr || screenChannel_ == nullptr) {
95 DHLOGE("%s: Processor or channel is null, Setup first.", LOG_TAG);
96 return ERR_DH_SCREEN_TRANS_NULL_VALUE;
97 }
98
99 bool stopStatus = true;
100 int32_t ret = imageProcessor_->StopImageProcessor();
101 if (ret != DH_SUCCESS) {
102 DHLOGD("%s: Stop image processor failed ret: %d.", LOG_TAG, ret);
103 stopStatus = false;
104 }
105
106 StartTrace(DSCREEN_HITRACE_LABEL, DSCREEN_SINK_CLOSE_SESSION_START);
107 ret = screenChannel_->CloseSession();
108 FinishTrace(DSCREEN_HITRACE_LABEL);
109 if (ret != DH_SUCCESS && ret != ERR_DH_SCREEN_TRANS_SESSION_NOT_OPEN) {
110 DHLOGD("%s: Close Session failed ret: %d.", LOG_TAG, ret);
111 stopStatus = false;
112 }
113
114 if (!stopStatus) {
115 DHLOGE("%s: Stop sink trans failed.", LOG_TAG);
116 return ERR_DH_SCREEN_TRANS_ERROR;
117 }
118
119 DHLOGI("%s: Stop success.", LOG_TAG);
120 return DH_SUCCESS;
121 }
122
RegisterStateCallback(const std::shared_ptr<IScreenSinkTransCallback> & callback)123 int32_t ScreenSinkTrans::RegisterStateCallback(const std::shared_ptr<IScreenSinkTransCallback> &callback)
124 {
125 DHLOGI("%s:RegisterStateCallback.", LOG_TAG);
126 if (callback == nullptr) {
127 DHLOGE("%s: Trans callback is null.", LOG_TAG);
128 return ERR_DH_SCREEN_TRANS_NULL_VALUE;
129 }
130 transCallback_ = callback;
131
132 return DH_SUCCESS;
133 }
134
SetImageSurface(const sptr<Surface> & surface)135 int32_t ScreenSinkTrans::SetImageSurface(const sptr<Surface> &surface)
136 {
137 if (surface == nullptr) {
138 DHLOGE("%s: Image surface is null.", LOG_TAG);
139 return ERR_DH_SCREEN_TRANS_NULL_VALUE;
140 }
141 decoderSurface_ = surface;
142
143 return DH_SUCCESS;
144 }
145
CheckVideoParam(const VideoParam & param)146 int32_t ScreenSinkTrans::CheckVideoParam(const VideoParam ¶m)
147 {
148 if ((param.GetCodecType() != VIDEO_CODEC_TYPE_VIDEO_H264) &&
149 (param.GetCodecType() != VIDEO_CODEC_TYPE_VIDEO_H265) &&
150 (param.GetCodecType() != VIDEO_CODEC_TYPE_VIDEO_MPEG4)) {
151 DHLOGE("%s: Invalid codec type.", LOG_TAG);
152 return ERR_DH_SCREEN_TRANS_ILLEGAL_PARAM;
153 }
154
155 if ((param.GetVideoFormat() != VIDEO_DATA_FORMAT_YUVI420) &&
156 (param.GetVideoFormat() != VIDEO_DATA_FORMAT_NV12) &&
157 (param.GetVideoFormat() != VIDEO_DATA_FORMAT_NV21) &&
158 (param.GetVideoFormat() != VIDEO_DATA_FORMAT_RGBA8888)) {
159 DHLOGE("%s: Invalid video data format.", LOG_TAG);
160 return ERR_DH_SCREEN_TRANS_ILLEGAL_PARAM;
161 }
162
163 if ((param.GetVideoWidth() > DSCREEN_MAX_VIDEO_DATA_WIDTH) ||
164 (param.GetVideoHeight() > DSCREEN_MAX_VIDEO_DATA_HEIGHT)) {
165 DHLOGE("%s: Invalid video data size.", LOG_TAG);
166 return ERR_DH_SCREEN_TRANS_ILLEGAL_PARAM;
167 }
168
169 if ((param.GetScreenWidth() > DSCREEN_MAX_SCREEN_DATA_WIDTH) ||
170 (param.GetScreenHeight() > DSCREEN_MAX_SCREEN_DATA_HEIGHT)) {
171 DHLOGE("%s: Invalid screen data size.", LOG_TAG);
172 return ERR_DH_SCREEN_TRANS_ILLEGAL_PARAM;
173 }
174
175 return DH_SUCCESS;
176 }
177
CheckTransParam(const VideoParam & localParam,const VideoParam & remoteParam,const std::string & peerDevId)178 int32_t ScreenSinkTrans::CheckTransParam(const VideoParam &localParam, const VideoParam &remoteParam,
179 const std::string &peerDevId)
180 {
181 if (peerDevId.empty()) {
182 DHLOGE("%s: Remote device id is null.", LOG_TAG);
183 return ERR_DH_SCREEN_TRANS_NULL_VALUE;
184 }
185
186 int32_t ret = CheckVideoParam(localParam);
187 if (ret != DH_SUCCESS) {
188 DHLOGE("%s: check localParam param failed.", LOG_TAG);
189 return ret;
190 }
191
192 ret = CheckVideoParam(remoteParam);
193 if (ret != DH_SUCCESS) {
194 DHLOGE("%s: check remoteParam param failed.", LOG_TAG);
195 return ret;
196 }
197
198 DHLOGI("%s: Local: codecType(%u), videoFormat(%u), videoSize(%ux%u), screenSize(%ux%u).", LOG_TAG,
199 localParam.GetCodecType(), localParam.GetVideoFormat(), localParam.GetVideoWidth(),
200 localParam.GetVideoHeight(), localParam.GetScreenWidth(), localParam.GetScreenHeight());
201 DHLOGI("%s: Remote: codecType(%u), videoFormat(%u), videoSize(%ux%u), screenSize(%ux%u).", LOG_TAG,
202 remoteParam.GetCodecType(), remoteParam.GetVideoFormat(), remoteParam.GetVideoWidth(),
203 remoteParam.GetVideoHeight(), remoteParam.GetScreenWidth(), remoteParam.GetScreenHeight());
204 return DH_SUCCESS;
205 }
206
InitScreenTrans(const VideoParam & localParam,const VideoParam & remoteParam,const std::string & peerDevId)207 int32_t ScreenSinkTrans::InitScreenTrans(const VideoParam &localParam, const VideoParam &remoteParam,
208 const std::string &peerDevId)
209 {
210 screenChannel_ = std::make_shared<ScreenDataChannelImpl>(peerDevId);
211
212 int32_t ret = RegisterChannelListener();
213 if (ret != DH_SUCCESS) {
214 DHLOGE("%s: Register channel listener failed.", LOG_TAG);
215 screenChannel_ = nullptr;
216 return ret;
217 }
218
219 imageProcessor_ = std::make_shared<ImageSinkProcessor>();
220
221 ret = RegisterProcessorListener(localParam, remoteParam, peerDevId);
222 if (ret != DH_SUCCESS) {
223 DHLOGE("%s: Register processor listener failed.", LOG_TAG);
224 screenChannel_ = nullptr;
225 imageProcessor_ = nullptr;
226 return ret;
227 }
228
229 return DH_SUCCESS;
230 }
231
RegisterChannelListener()232 int32_t ScreenSinkTrans::RegisterChannelListener()
233 {
234 DHLOGI("%s: RegisterChannelListener.", LOG_TAG);
235 std::shared_ptr<IScreenChannelListener> listener = shared_from_this();
236 if (listener == nullptr) {
237 DHLOGE("%s: Channel Listener is null.", LOG_TAG);
238 return ERR_DH_SCREEN_TRANS_NULL_VALUE;
239 }
240
241 int32_t ret = screenChannel_->CreateSession(listener);
242 if (ret != DH_SUCCESS) {
243 DHLOGE("%s: Register channel listenner failed ret: %d.", LOG_TAG, ret);
244 ReportOptFail(DSCREEN_OPT_FAIL, ret, "dscreen sink Create session failed.");
245 return ret;
246 }
247
248 return DH_SUCCESS;
249 }
250
RegisterProcessorListener(const VideoParam & localParam,const VideoParam & remoteParam,const std::string & peerDevId)251 int32_t ScreenSinkTrans::RegisterProcessorListener(const VideoParam &localParam, const VideoParam &remoteParam,
252 const std::string &peerDevId)
253 {
254 DHLOGI("%s: RegisterProcessorListener.", LOG_TAG);
255 std::shared_ptr<IImageSinkProcessorListener> listener = shared_from_this();
256 if (listener == nullptr) {
257 DHLOGE("%s: Channel listener to null.", LOG_TAG);
258 return ERR_DH_SCREEN_TRANS_NULL_VALUE;
259 }
260
261 int32_t ret = imageProcessor_->ConfigureImageProcessor(localParam, remoteParam, listener);
262 if (ret != DH_SUCCESS) {
263 DHLOGE("%s: Config image processor failed ret: %d.", LOG_TAG, ret);
264 ReportOptFail(DSCREEN_OPT_FAIL, ret, "Config image processor failed.");
265 return ret;
266 }
267
268 ret = imageProcessor_->SetImageSurface(decoderSurface_);
269 if (ret != DH_SUCCESS) {
270 DHLOGE("%s: Set image surface failed ret: %d.", LOG_TAG, ret);
271 return ret;
272 }
273 return DH_SUCCESS;
274 }
275
OnSessionOpened()276 void ScreenSinkTrans::OnSessionOpened()
277 {
278 DHLOGI("%s: OnChannelSessionOpened.", LOG_TAG);
279 }
280
OnSessionClosed()281 void ScreenSinkTrans::OnSessionClosed()
282 {
283 DHLOGI("%s:OnChannelSessionClosed.", LOG_TAG);
284 std::shared_ptr<IScreenSinkTransCallback> callback = transCallback_.lock();
285 if (callback == nullptr) {
286 DHLOGE("%s: Trans callback is null.", LOG_TAG);
287 return;
288 }
289 callback->OnError(ERR_DH_SCREEN_TRANS_SESSION_CLOSED, "OnChannelSessionClosed");
290 }
291
OnDataReceived(const std::shared_ptr<DataBuffer> & data)292 void ScreenSinkTrans::OnDataReceived(const std::shared_ptr<DataBuffer> &data)
293 {
294 DHLOGD("%s: OnChannelDataReceived.", LOG_TAG);
295 int32_t ret = imageProcessor_->ProcessImage(data);
296 if (ret != DH_SUCCESS) {
297 DHLOGE("%s: send data to image processor failed ret: %d.", LOG_TAG, ret);
298 }
299 }
300
OnProcessorStateNotify(int32_t state)301 void ScreenSinkTrans::OnProcessorStateNotify(int32_t state)
302 {
303 DHLOGI("%s: OnProcessorStateNotify.", LOG_TAG);
304 std::shared_ptr<IScreenSinkTransCallback> callback = transCallback_.lock();
305 if (callback == nullptr) {
306 DHLOGE("%s: Trans callback is null.", LOG_TAG);
307 return;
308 }
309 callback->OnError(state, "OnProcessorStateNotify");
310 }
311 } // namespace DistributedHardware
312 } // namespace OHOS