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 "2.0/include/dscreen.h"
17
18 #include "avcodec_info.h"
19 #include "avcodec_list.h"
20 #include "2.0/include/av_sender_engine_adapter.h"
21 #include "distributed_hardware_fwk_kit.h"
22 #include "histreamer_query_tool.h"
23
24 #include "dscreen_constants.h"
25 #include "dscreen_errcode.h"
26 #include "dscreen_fwkkit.h"
27 #include "dscreen_hisysevent.h"
28 #include "dscreen_json_util.h"
29 #include "dscreen_log.h"
30 #include "dscreen_util.h"
31 #include "common/include/screen_manager_adapter.h"
32
33 namespace OHOS {
34 namespace DistributedHardware {
35 namespace V2_0 {
36 /* <<ecoder, decoder>, codec> */
37 static const std::map<std::pair<std::string, std::string>, std::string> CODECS_MAP = {
38 {{"HdiCodecAdapter.OMX.rk.video_encoder.hevc", "HdiCodecAdapter.OMX.rk.video_decoder.hevc"}, CODEC_NAME_H265},
39 {{"HdiCodecAdapter.OMX.hisi.video.encoder.hevc", "HdiCodecAdapter.OMX.hisi.video.decoder.hevc"}, CODEC_NAME_H265},
40 {{"HdiCodecAdapter.OMX.rk.video_encoder.avc", "HdiCodecAdapter.OMX.rk.video_decoder.avc"}, CODEC_NAME_H264},
41 {{"HdiCodecAdapter.OMX.hisi.video.encoder.avc", "HdiCodecAdapter.OMX.hisi.video.decoder.avc"}, CODEC_NAME_H264},
42 };
43
DScreen(const std::string & devId,const std::string & dhId,std::shared_ptr<IDScreenCallback> dscreenCallback)44 DScreen::DScreen(const std::string &devId, const std::string &dhId,
45 std::shared_ptr<IDScreenCallback> dscreenCallback)
46 {
47 DHLOGD("DScreen construct, devId: %s, dhId: %s", GetAnonyString(devId).c_str(),
48 GetAnonyString(dhId).c_str());
49 devId_ = devId;
50 dhId_ = dhId;
51 dscreenCallback_ = dscreenCallback;
52 SetState(DISABLED);
53 taskThreadRunning_ = true;
54 taskQueueThread_ = std::thread(&DScreen::TaskThreadLoop, this);
55 }
56
~DScreen()57 DScreen::~DScreen()
58 {
59 DHLOGD("DScreen deconstruct, devId: %s, dhId: %s", GetAnonyString(devId_).c_str(),
60 GetAnonyString(dhId_).c_str());
61 taskThreadRunning_ = false;
62 taskQueueCond_.notify_all();
63 if (taskQueueThread_.joinable()) {
64 taskQueueThread_.join();
65 }
66 StopSenderEngine();
67 ScreenMgrAdapter::GetInstance().RemoveVirtualScreen(screenId_);
68 videoParam_ = nullptr;
69 senderAdapter_ = nullptr;
70 DHLOGD("DScreen deconstruct end.");
71 }
72
AddTask(const std::shared_ptr<Task> & task)73 int32_t DScreen::AddTask(const std::shared_ptr<Task> &task)
74 {
75 DHLOGI("DScreen::AddTask, devId: %s, dhId: %s", GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str());
76 if (task == nullptr) {
77 DHLOGE("AddTask, task is invalid.");
78 return ERR_DH_SCREEN_SA_DSCREEN_TASK_NOT_VALID;
79 }
80 DHLOGI("AddTask, task type: %" PRId32, task->GetTaskType());
81 {
82 std::lock_guard<std::mutex> lock(taskQueueMtx_);
83 taskQueue_.push(task);
84 }
85 taskQueueCond_.notify_all();
86 return DH_SUCCESS;
87 }
88
HandleTask(const std::shared_ptr<Task> & task)89 void DScreen::HandleTask(const std::shared_ptr<Task> &task)
90 {
91 int32_t taskType = task->GetTaskType();
92 DHLOGI("HandleTask, devId: %s, dhId: %s, task type: %" PRId32, GetAnonyString(devId_).c_str(),
93 GetAnonyString(dhId_).c_str(), taskType);
94 switch (taskType) {
95 case TaskType::TASK_ENABLE:
96 HandleEnable(task->GetTaskParam(), task->GetTaskId());
97 break;
98 case TaskType::TASK_DISABLE:
99 HandleDisable(task->GetTaskId());
100 break;
101 case TaskType::TASK_CONNECT:
102 HandleConnect();
103 break;
104 case TaskType::TASK_DISCONNECT:
105 HandleDisconnect();
106 break;
107 default:
108 DHLOGD("task type unkown.");
109 }
110 }
111
HandleEnable(const std::string & param,const std::string & taskId)112 void DScreen::HandleEnable(const std::string ¶m, const std::string &taskId)
113 {
114 DHLOGI("HandleEnable, devId: %s, dhId: %s", GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str());
115 if (dscreenCallback_ == nullptr) {
116 DHLOGE("DScreen::HandleEnable, dscreenCallback_ is nullptr");
117 return;
118 }
119 if ((curState_ == ENABLED) || (curState_ == ENABLING) || (curState_ == CONNECTING) || (curState_ == CONNECTED)) {
120 dscreenCallback_->OnRegResult(shared_from_this(), taskId, DH_SUCCESS, "dscreen enable success.");
121 return;
122 }
123 SetState(ENABLING);
124
125 json attrJson = json::parse(param, nullptr, false);
126 if (!CheckJsonData(attrJson)) {
127 DHLOGE("HandleEnable, check json data failed.");
128 dscreenCallback_->OnRegResult(shared_from_this(), taskId, ERR_DH_SCREEN_SA_ENABLE_FAILED,
129 "enable param json is invalid.");
130 ReportRegisterFail(DSCREEN_REGISTER_FAIL, ERR_DH_SCREEN_SA_ENABLE_FAILED, GetAnonyString(devId_).c_str(),
131 GetAnonyString(dhId_).c_str(), "check json data failed.");
132 SetState(DISABLED);
133 return;
134 }
135 if (videoParam_ == nullptr) {
136 videoParam_ = std::make_shared<VideoParam>();
137 }
138 int32_t ret = NegotiateCodecType(attrJson[KEY_HISTREAMER_VIDEO_DECODER]);
139 if (ret != DH_SUCCESS) {
140 DHLOGE("HandleEnable, negotiate codec type failed.");
141 dscreenCallback_->OnRegResult(shared_from_this(), taskId, ERR_DH_SCREEN_SA_ENABLE_FAILED,
142 "negotiate codec type failed.");
143 ReportRegisterFail(DSCREEN_REGISTER_FAIL, ERR_DH_SCREEN_SA_ENABLE_FAILED, GetAnonyString(devId_).c_str(),
144 GetAnonyString(dhId_).c_str(), "negotiate codec type failed.");
145 return;
146 }
147 videoParam_->SetScreenWidth(attrJson[KEY_SCREEN_WIDTH].get<uint32_t>());
148 videoParam_->SetScreenHeight(attrJson[KEY_SCREEN_HEIGHT].get<uint32_t>());
149 uint64_t screenId = ScreenMgrAdapter::GetInstance().CreateVirtualScreen(devId_, dhId_, videoParam_);
150 if (screenId == SCREEN_ID_INVALID) {
151 DHLOGE("HandleEnable, create virtual screen failed.");
152 dscreenCallback_->OnRegResult(shared_from_this(), taskId, ERR_DH_SCREEN_SA_ENABLE_FAILED,
153 "create virtual screen failed.");
154 ReportRegisterFail(DSCREEN_REGISTER_FAIL, ERR_DH_SCREEN_SA_ENABLE_FAILED, GetAnonyString(devId_).c_str(),
155 GetAnonyString(dhId_).c_str(), "create virtual screen failed.");
156 return;
157 }
158
159 screenId_ = screenId;
160 SetState(ENABLED);
161 dscreenCallback_->OnRegResult(shared_from_this(), taskId, DH_SUCCESS, "dscreen enable success.");
162 ReportRegisterScreenEvent(DSCREEN_REGISTER, GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str(),
163 "dscreen enable success.");
164 }
165
HandleDisable(const std::string & taskId)166 void DScreen::HandleDisable(const std::string &taskId)
167 {
168 DHLOGI("HandleDisable, devId: %s, dhId: %s", GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str());
169 if (dscreenCallback_ == nullptr) {
170 DHLOGE("DScreen::HandleDisable, dscreenCallback_ is nullptr");
171 return;
172 }
173 SetState(DISABLING);
174 int32_t ret = ScreenMgrAdapter::GetInstance().RemoveVirtualScreen(screenId_);
175 if (ret != DH_SUCCESS) {
176 DHLOGE("HandleDisable, remove virtual screen failed.");
177 dscreenCallback_->OnUnregResult(shared_from_this(), taskId, ERR_DH_SCREEN_SA_DISABLE_FAILED,
178 "remove virtual screen failed.");
179 ReportUnRegisterFail(DSCREEN_UNREGISTER_FAIL, ERR_DH_SCREEN_SA_DISABLE_FAILED, GetAnonyString(devId_).c_str(),
180 GetAnonyString(dhId_).c_str(), "remove virtual screen failed.");
181 return;
182 }
183 SetState(DISABLED);
184 dscreenCallback_->OnUnregResult(shared_from_this(), taskId, DH_SUCCESS, "");
185 ReportUnRegisterScreenEvent(DSCREEN_UNREGISTER, GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str(),
186 "dscreen disable success.");
187 }
188
HandleConnect()189 void DScreen::HandleConnect()
190 {
191 DHLOGI("HandleConnect, devId: %s, dhId: %s", GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str());
192 if (GetState() != ENABLED) {
193 DHLOGE("GetState is not ENABLED, HandleConnect failed.");
194 return;
195 }
196 SetState(CONNECTING);
197 int32_t ret = StartSenderEngine();
198 if (ret != DH_SUCCESS) {
199 SetState(ENABLED);
200 ScreenMgrAdapter::GetInstance().RemoveScreenFromGroup(screenId_);
201 DHLOGE("HandleConnect, start av transport sender engine failed.");
202 return;
203 }
204 ret = ConfigSurface();
205 if (ret != DH_SUCCESS) {
206 SetState(ENABLED);
207 ScreenMgrAdapter::GetInstance().RemoveScreenFromGroup(screenId_);
208 DHLOGE("HandleConnect, config image surface failed.");
209 return;
210 }
211 SetState(CONNECTED);
212 ReportScreenMirrorEvent(DSCREEN_PROJECT_START, GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str(),
213 "dscreen connect success");
214 }
215
HandleDisconnect()216 void DScreen::HandleDisconnect()
217 {
218 DHLOGD("HandleDisconnect, devId: %s, dhId: %s", GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str());
219 if (curState_ != CONNECTED) {
220 DHLOGE("dscreen is not connected, cannot disconnect");
221 return;
222 }
223 SetState(DISCONNECTING);
224 int32_t ret = StopSenderEngine();
225 if (ret != DH_SUCCESS) {
226 SetState(CONNECTED);
227 DHLOGE("dScreen Stop failed.");
228 return;
229 }
230 SetState(ENABLED);
231 RemoveSurface();
232 ReportScreenMirrorEvent(DSCREEN_PROJECT_END, GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str(),
233 "dscreen disconnect success");
234 }
235
ConfigSurface()236 int32_t DScreen::ConfigSurface()
237 {
238 DHLOGD("ConfigSurface, devId: %s, dhId: %s", GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str());
239 consumerSurface_ = Surface::CreateSurfaceAsConsumer();
240 if (consumerSurface_ == nullptr) {
241 DHLOGE("Create consumer surface failed.");
242 return ERR_DH_SCREEN_CODEC_SURFACE_ERROR;
243 }
244 sptr<IBufferProducer> producer = consumerSurface_->GetProducer();
245 if (producer == nullptr) {
246 DHLOGE("Get preducer surface failed.");
247 return ERR_DH_SCREEN_CODEC_SURFACE_ERROR;
248 }
249 sptr<OHOS::Surface> producerSurface = Surface::CreateSurfaceAsProducer(producer);
250 if (producerSurface == nullptr) {
251 DHLOGE("Create preducer surface failed.");
252 return ERR_DH_SCREEN_CODEC_SURFACE_ERROR;
253 }
254 if (consumerBufferListener_ == nullptr) {
255 consumerBufferListener_ = new ConsumBufferListener(shared_from_this());
256 }
257 consumerSurface_->RegisterConsumerListener(consumerBufferListener_);
258 ScreenMgrAdapter::GetInstance().SetImageSurface(screenId_, producerSurface);
259 DHLOGI("ConfigSurface success.");
260 return DH_SUCCESS;
261 }
262
RemoveSurface()263 int32_t DScreen::RemoveSurface()
264 {
265 if (consumerSurface_ == nullptr) {
266 DHLOGE("consumerSurface_ is nullptr.");
267 return ERR_DH_AV_TRANS_NULL_VALUE;
268 }
269 consumerSurface_->UnregisterConsumerListener();
270
271 consumerSurface_ = nullptr;
272 DHLOGI("RemoveSurface success.");
273 return DH_SUCCESS;
274 }
275
OnBufferAvailable()276 void ConsumBufferListener::OnBufferAvailable()
277 {
278 DHLOGI("OnBufferAvailable enter.");
279 if (dScreen_ == nullptr) {
280 DHLOGE("dScreen is nullptr, cannot consume surface buffer.");
281 return;
282 }
283 if (dScreen_->GetState() != CONNECTED) {
284 DHLOGD("screen is not connected, no need consume surface buffer.");
285 return;
286 }
287 dScreen_->ConsumeSurface();
288 }
289
ConsumeSurface()290 void DScreen::ConsumeSurface()
291 {
292 DHLOGI("ConsumeSurface enter.");
293 if (senderAdapter_ == nullptr) {
294 DHLOGE("av transport sender adapter is null.");
295 return;
296 }
297 if (consumerSurface_ == nullptr) {
298 DHLOGE("consumerSurface_ is nullptr, cannot consume surface buffer.");
299 return;
300 }
301 sptr<SurfaceBuffer> surfaceBuffer = nullptr;
302 syncFence_ = SyncFence::INVALID_FENCE;
303 int64_t timestamp = 0;
304 OHOS::Rect damage = {0, 0, 0, 0};
305 SurfaceError surfaceErr = consumerSurface_->AcquireBuffer(surfaceBuffer, syncFence_, timestamp, damage);
306 if (surfaceErr != SURFACE_ERROR_OK) {
307 DHLOGE("consumerSurface_ acquire buffer failed, errcode: %d", surfaceErr);
308 consumerSurface_->ReleaseBuffer(surfaceBuffer, -1);
309 return;
310 }
311 int32_t retcode = syncFence_->Wait(SURFACE_SYNC_FENCE_TIMEOUT);
312 if (retcode == -ETIME) {
313 DHLOGE("%s: Sync fence wait timeout, retcode is %." PRId32, retcode);
314 consumerSurface_->ReleaseBuffer(surfaceBuffer, -1);
315 return;
316 }
317 uint32_t surBufSize = surfaceBuffer->GetSize();
318 auto surBufAddr = static_cast<uint8_t*>(surfaceBuffer->GetVirAddr());
319 uint32_t videoWidth = videoParam_->GetVideoWidth();
320 uint32_t videoHeight = videoParam_->GetVideoHeight();
321 VideoData data = { surBufAddr, surBufSize, videoWidth, videoHeight, timestamp, VIDEO_FORMAT_RGBA8888 };
322 int32_t ret = senderAdapter_->PushData(data);
323 if (ret != DH_SUCCESS) {
324 DHLOGE("feed buffer to av transport sender failed.");
325 }
326 consumerSurface_->ReleaseBuffer(surfaceBuffer, -1);
327 DHLOGI("ConsumeSurface success. timestamp=%lld", (long long)timestamp);
328 }
329
InitSenderEngine(IAVEngineProvider * providerPtr,const std::string & peerDevId)330 int32_t DScreen::InitSenderEngine(IAVEngineProvider *providerPtr, const std::string &peerDevId)
331 {
332 DHLOGI("InitSenderEngine enter.");
333 if (senderAdapter_ == nullptr) {
334 senderAdapter_ = std::make_shared<AVTransSenderAdapter>();
335 }
336 int32_t ret = senderAdapter_->Initialize(providerPtr, peerDevId);
337 if (ret != DH_SUCCESS) {
338 DHLOGE("initialize av sender adapter failed.");
339 return ERR_DH_AV_TRANS_INIT_FAILED;
340 }
341 return senderAdapter_->RegisterAdapterCallback(shared_from_this());
342 }
343
StartSenderEngine()344 int32_t DScreen::StartSenderEngine()
345 {
346 DHLOGI("StartSenderEngine, devId: %s, dhId: %s", GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str());
347 if (senderAdapter_ == nullptr) {
348 DHLOGE("av transport sender adapter is null.");
349 return ERR_DH_AV_TRANS_NULL_VALUE;
350 }
351 int32_t ret = senderAdapter_->CreateControlChannel(devId_);
352 if (ret != DH_SUCCESS) {
353 DHLOGE("create av sender control channel failed.");
354 return ERR_DH_AV_TRANS_CREATE_CHANNEL_FAILED;
355 }
356 ret = SetUp();
357 if (ret != DH_SUCCESS) {
358 DHLOGE("set up av sender engine failed.");
359 return ERR_DH_AV_TRANS_SETUP_FAILED;
360 }
361 ret = senderAdapter_->Start();
362 if (ret != DH_SUCCESS) {
363 DHLOGE("start av sender engine failed.");
364 return ERR_DH_AV_TRANS_START_FAILED;
365 }
366 return DH_SUCCESS;
367 }
368
StopSenderEngine()369 int32_t DScreen::StopSenderEngine()
370 {
371 DHLOGI("StopSenderEngine, devId: %s, dhId: %s", GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str());
372 if (senderAdapter_ == nullptr) {
373 DHLOGE("av transport sender adapter is null.");
374 return ERR_DH_AV_TRANS_NULL_VALUE;
375 }
376
377 json paramJson;
378 paramJson[KEY_DEV_ID] = devId_;
379 paramJson[KEY_DH_ID] = dhId_;
380
381 auto avMessage = std::make_shared<AVTransMessage>(DScreenMsgType::STOP_MIRROR, paramJson.dump(), devId_);
382 senderAdapter_->SendMessageToRemote(avMessage);
383
384 int32_t ret = senderAdapter_->Stop();
385 if (ret != DH_SUCCESS) {
386 DHLOGE("stop av sender adapter failed.");
387 return ERR_DH_AV_TRANS_STOP_FAILED;
388 }
389 ret = senderAdapter_->Release();
390 if (ret != DH_SUCCESS) {
391 DHLOGE("release av sender adapter failed.");
392 return ERR_DH_AV_TRANS_STOP_FAILED;
393 }
394 return DH_SUCCESS;
395 }
396
ChooseParameter(std::string & codecType,std::string & pixelFormat)397 void DScreen::ChooseParameter(std::string &codecType, std::string &pixelFormat)
398 {
399 if (videoParam_->GetCodecType() == VIDEO_CODEC_TYPE_VIDEO_H265) {
400 codecType = MIME_VIDEO_H265;
401 } else if (videoParam_->GetCodecType() == VIDEO_CODEC_TYPE_VIDEO_H264) {
402 codecType = MIME_VIDEO_H264;
403 } else {
404 codecType = MIME_VIDEO_RAW;
405 }
406 if (videoParam_->GetVideoFormat() == VIDEO_DATA_FORMAT_YUVI420) {
407 pixelFormat = VIDEO_FORMAT_YUVI420;
408 } else if (videoParam_->GetVideoFormat() == VIDEO_DATA_FORMAT_NV12) {
409 pixelFormat = VIDEO_FORMAT_NV12;
410 } else if (videoParam_->GetVideoFormat() == VIDEO_DATA_FORMAT_NV21) {
411 pixelFormat = VIDEO_FORMAT_NV21;
412 } else {
413 pixelFormat = VIDEO_FORMAT_RGBA8888;
414 }
415 senderAdapter_->SetParameter(AVTransTag::VIDEO_CODEC_TYPE, codecType);
416 senderAdapter_->SetParameter(AVTransTag::VIDEO_PIXEL_FORMAT, pixelFormat);
417 senderAdapter_->SetParameter(AVTransTag::VIDEO_WIDTH, std::to_string(videoParam_->GetVideoWidth()));
418 senderAdapter_->SetParameter(AVTransTag::VIDEO_HEIGHT, std::to_string(videoParam_->GetVideoHeight()));
419 senderAdapter_->SetParameter(AVTransTag::VIDEO_FRAME_RATE, std::to_string(videoParam_->GetFps()));
420 senderAdapter_->SetParameter(AVTransTag::VIDEO_BIT_RATE, std::to_string(BIT_RATE));
421 }
422
SetUp()423 int32_t DScreen::SetUp()
424 {
425 DHLOGI("SetUp, devId: %s, dhId: %s", GetAnonyString(devId_).c_str(), GetAnonyString(dhId_).c_str());
426 if (senderAdapter_ == nullptr) {
427 DHLOGE("av transport sender adapter is null.");
428 return ERR_DH_AV_TRANS_NULL_VALUE;
429 }
430 if (videoParam_ == nullptr) {
431 DHLOGE("videoParam is nullptr.");
432 return ERR_DH_SCREEN_SA_VALUE_NOT_INIT;
433 }
434 auto mapRelation = ScreenMgrAdapter::GetInstance().GetMapRelation(screenId_);
435 if (mapRelation == nullptr) {
436 DHLOGE("get map relation failed.");
437 return ERR_DH_AV_TRANS_SETUP_FAILED;
438 }
439 DisplayRect displayRect = mapRelation->GetDisplayRect();
440 videoParam_->SetVideoWidth(displayRect.width);
441 videoParam_->SetVideoHeight(displayRect.height);
442
443 json paramJson;
444 paramJson[KEY_DH_ID] = dhId_;
445 paramJson[KEY_SCREEN_ID] = screenId_;
446 paramJson[KEY_VIDEO_PARAM] = *videoParam_;
447 paramJson[KEY_MAPRELATION] = *mapRelation;
448
449 auto avMessage = std::make_shared<AVTransMessage>(DScreenMsgType::START_MIRROR, paramJson.dump(), devId_);
450 int32_t ret = senderAdapter_->SendMessageToRemote(avMessage);
451 if (ret != DH_SUCCESS) {
452 DHLOGE("send message to remote engine failed.");
453 return ret;
454 }
455
456 ret = WaitForSinkStarted();
457 if (ret != DH_SUCCESS) {
458 DHLOGE("send message to start remote device engine failed.");
459 return ret;
460 }
461
462 std::string codecType;
463 std::string pixelFormat;
464 ChooseParameter(codecType, pixelFormat);
465 return senderAdapter_->SetParameter(AVTransTag::ENGINE_READY, OWNER_NAME_D_SCREEN);
466 }
467
WaitForSinkStarted()468 int32_t DScreen::WaitForSinkStarted()
469 {
470 std::unique_lock<std::mutex> lock(waitSinkMtx_);
471 auto status = waitSinkCondVar_.wait_for(lock, std::chrono::milliseconds(WAIT_TIMEOUT_MS));
472 if (status == std::cv_status::timeout) {
473 DHLOGE("wait for sink device engine start timeout");
474 return ERR_DH_AV_TRANS_TIMEOUT;
475 }
476 if (!sinkStartSuccess_.load()) {
477 DHLOGE("start sink device engine failed");
478 return ERR_DH_AV_TRANS_SINK_START_FAILED;
479 }
480 return DH_SUCCESS;
481 }
482
NegotiateCodecType(const std::string & rmtDecoderStr)483 int32_t DScreen::NegotiateCodecType(const std::string &rmtDecoderStr)
484 {
485 DHLOGI("Start NegotiateCodecType, remote decoder: %s", rmtDecoderStr.c_str());
486 json rmtDecoderJson = json::parse(rmtDecoderStr, nullptr, false);
487 if (rmtDecoderJson.is_discarded()) {
488 DHLOGE("remote Decoder Json is invalid.");
489 return ERR_DH_SCREEN_SA_DSCREEN_NEGOTIATE_CODEC_FAIL;
490 }
491
492 std::vector<VideoDecoder> rmtVideoDecoders;
493 FromJson<VideoDecoder>(VIDEO_DECODERS, rmtDecoderJson, rmtVideoDecoders);
494
495 std::shared_ptr<DistributedHardwareFwkKit> dhFwkKit = DScreenFwkKit::GetInstance().GetDHFwkKit();
496 if (dhFwkKit == nullptr) {
497 DHLOGE("Get DhFwkKit return null");
498 return ERR_DH_SCREEN_SA_DSCREEN_NEGOTIATE_CODEC_FAIL;
499 }
500 std::string localVideoEncodersJsonStr =
501 dhFwkKit->QueryLocalSysSpec(QueryLocalSysSpecType::HISTREAMER_VIDEO_ENCODER);
502 if (localVideoEncodersJsonStr.empty()) {
503 DHLOGE("Query local Codec info failed");
504 return ERR_DH_SCREEN_SA_DSCREEN_NEGOTIATE_CODEC_FAIL;
505 }
506 DHLOGI("DScreen Negotiate QueryVideoEncoderAbility info: %s", localVideoEncodersJsonStr.c_str());
507
508 json localVideoEncodersJson = json::parse(localVideoEncodersJsonStr, nullptr, false);
509 if (localVideoEncodersJson.is_discarded()) {
510 DHLOGE("localVideoEncodersJson is invalid.");
511 return ERR_DH_SCREEN_SA_DSCREEN_NEGOTIATE_CODEC_FAIL;
512 }
513
514 std::vector<VideoEncoder> localVideoEncoders;
515 FromJson<VideoEncoder>(VIDEO_ENCODERS, localVideoEncodersJson, localVideoEncoders);
516
517 return ChooseCodecType(localVideoEncoders, rmtVideoDecoders);
518 }
519
ChooseCodecType(const std::vector<VideoEncoder> & localVideoEncoders,const std::vector<VideoDecoder> & rmtVideoDecoders)520 int32_t DScreen::ChooseCodecType(const std::vector<VideoEncoder> &localVideoEncoders,
521 const std::vector<VideoDecoder> &rmtVideoDecoders)
522 {
523 std::vector<std::string> codecTypeCandidates;
524 for (const auto &rmtDec : rmtVideoDecoders) {
525 for (const auto &locEnc : localVideoEncoders) {
526 std::pair<std::string, std::string> comb = {locEnc.name, rmtDec.name};
527 if (CODECS_MAP.find(comb) != CODECS_MAP.end()) {
528 std::string codec = CODECS_MAP.at(comb);
529 DHLOGI("Find match comb, local encoder: %s, remote decoder: %s, codec: %s",
530 locEnc.name.c_str(), rmtDec.name.c_str(), codec.c_str());
531 codecTypeCandidates.push_back(codec);
532 }
533 }
534 }
535 if (std::find(codecTypeCandidates.begin(), codecTypeCandidates.end(),
536 CODEC_NAME_H265) != codecTypeCandidates.end()) {
537 videoParam_->SetCodecType(VIDEO_CODEC_TYPE_VIDEO_H265);
538 videoParam_->SetVideoFormat(VIDEO_DATA_FORMAT_NV12);
539 } else if (std::find(codecTypeCandidates.begin(), codecTypeCandidates.end(),
540 CODEC_NAME_H264) != codecTypeCandidates.end()) {
541 videoParam_->SetCodecType(VIDEO_CODEC_TYPE_VIDEO_H264);
542 videoParam_->SetVideoFormat(VIDEO_DATA_FORMAT_NV12);
543 } else {
544 DHLOGI("codec type not support.");
545 return ERR_DH_SCREEN_SA_DSCREEN_NEGOTIATE_CODEC_FAIL;
546 }
547 return DH_SUCCESS;
548 }
549
550
TaskThreadLoop()551 void DScreen::TaskThreadLoop()
552 {
553 DHLOGI("DScreen taskThread start. devId: %s, dhId: %s", GetAnonyString(devId_).c_str(),
554 GetAnonyString(dhId_).c_str());
555 while (taskThreadRunning_) {
556 std::shared_ptr<Task> task;
557 {
558 std::unique_lock<std::mutex> lock(taskQueueMtx_);
559 taskQueueCond_.wait_for(lock, std::chrono::seconds(TASK_WAIT_SECONDS),
560 [this]() { return !taskQueue_.empty(); });
561 if (taskQueue_.empty()) {
562 continue;
563 }
564 task = taskQueue_.front();
565 taskQueue_.pop();
566 }
567 if (task == nullptr) {
568 DHLOGD("task is null.");
569 continue;
570 }
571 DHLOGD("run task, task queue size: %zu", taskQueue_.size());
572 HandleTask(task);
573 }
574 }
575
CheckJsonData(const json & attrJson)576 bool DScreen::CheckJsonData(const json &attrJson)
577 {
578 if (attrJson.is_discarded()) {
579 DHLOGE("enable param json is invalid.");
580 return false;
581 }
582 if (!IsUInt32(attrJson, KEY_SCREEN_WIDTH) || !IsUInt32(attrJson, KEY_SCREEN_HEIGHT) ||
583 !attrJson.contains(KEY_CODECTYPE)) {
584 DHLOGE("enable param is invalid.");
585 return false;
586 }
587 return true;
588 }
589
OnEngineEvent(DScreenEventType event,const std::string & content)590 void DScreen::OnEngineEvent(DScreenEventType event, const std::string &content)
591 {
592 (void)content;
593 if (event == DScreenEventType::ENGINE_ERROR) {
594 StopSenderEngine();
595 } else if (event == DScreenEventType::TRANS_CHANNEL_CLOSED) {
596 HandleDisconnect();
597 }
598 }
599
OnEngineMessage(const std::shared_ptr<AVTransMessage> & message)600 void DScreen::OnEngineMessage(const std::shared_ptr<AVTransMessage> &message)
601 {
602 if (message == nullptr) {
603 DHLOGE("received engine message is null.");
604 return;
605 }
606 DHLOGI("On sink device engine message received, message type =%d.", message->type_);
607 if ((message->type_ == DScreenMsgType::START_MIRROR_SUCCESS) ||
608 (message->type_ == DScreenMsgType::START_MIRROR_FAIL)) {
609 sinkStartSuccess_ = (message->type_ == DScreenMsgType::START_MIRROR_SUCCESS);
610 waitSinkCondVar_.notify_one();
611 }
612 }
613
GetVideoParam()614 std::shared_ptr<VideoParam> DScreen::GetVideoParam()
615 {
616 return videoParam_;
617 }
618
SetState(DScreenState state)619 void DScreen::SetState(DScreenState state)
620 {
621 std::lock_guard<std::mutex> lock(stateMtx_);
622 curState_ = state;
623 }
624
GetState() const625 DScreenState DScreen::GetState() const
626 {
627 return curState_;
628 }
629
GetScreenId() const630 uint64_t DScreen::GetScreenId() const
631 {
632 return screenId_;
633 }
634
GetDHId() const635 std::string DScreen::GetDHId() const
636 {
637 return dhId_;
638 }
639
GetDevId() const640 std::string DScreen::GetDevId() const
641 {
642 return devId_;
643 }
644 } // namespace V2_0
645 } // namespace DistributedHardware
646 } // namespace OHOS