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