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