1 /*
2 * Copyright (c) 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/av_sender_engine_adapter.h"
17
18 #include "dscreen_errcode.h"
19 #include "dscreen_log.h"
20 #include "dscreen_util.h"
21 #include "dscreen_hidumper.h"
22 #include "hitrace_meter.h"
23 #include "dscreen_hitrace.h"
24
25 namespace OHOS {
26 namespace DistributedHardware {
Initialize(IAVEngineProvider * providerPtr,const std::string & peerDevId)27 int32_t AVTransSenderAdapter::Initialize(IAVEngineProvider *providerPtr, const std::string &peerDevId)
28 {
29 DHLOGI("Initialize enter");
30 if (initialized_.load()) {
31 return DH_SUCCESS;
32 }
33 if (providerPtr == nullptr) {
34 DHLOGE("av transport sender engine provider ptr is null");
35 return ERR_DH_AV_TRANS_NULL_VALUE;
36 }
37 senderEngine_ = providerPtr->CreateAVSenderEngine(peerDevId);
38 if (senderEngine_ == nullptr) {
39 DHLOGE("create av transport sender engine is null");
40 return ERR_DH_AV_TRANS_NULL_VALUE;
41 }
42 senderEngine_->RegisterSenderCallback(shared_from_this());
43 initialized_ = true;
44 return DH_SUCCESS;
45 }
46
Release()47 int32_t AVTransSenderAdapter::Release()
48 {
49 DHLOGI("Release enter");
50 if (senderEngine_ != nullptr) {
51 StartTrace(DSCREEN_HITRACE_LABEL, DSCREEN_SOURCE_CLOSE_SESSION_START);
52 StartTrace(DSCREEN_HITRACE_LABEL, DSCREEN_SOURCE_RELEASE_SESSION_START);
53 int32_t ret = senderEngine_->Release();
54 FinishTrace(DSCREEN_HITRACE_LABEL);
55 FinishTrace(DSCREEN_HITRACE_LABEL);
56 if (ret != DH_AVT_SUCCESS) {
57 DHLOGE("release av transport sender engine failed");
58 }
59 senderEngine_ = nullptr;
60 }
61 initialized_ = false;
62 chnCreateSuccess_ = false;
63 transStartSuccess_ = false;
64 return DH_SUCCESS;
65 }
66
Start()67 int32_t AVTransSenderAdapter::Start()
68 {
69 DHLOGI("Start enter");
70 if (transStartSuccess_.load()) {
71 DHLOGI("av transport sender channel already created");
72 return DH_SUCCESS;
73 }
74 if (senderEngine_ == nullptr) {
75 DHLOGE("av transport sender engine is null");
76 return ERR_DH_AV_TRANS_NULL_VALUE;
77 }
78 int32_t ret = senderEngine_->Start();
79 if (ret != DH_AVT_SUCCESS) {
80 DHLOGE("start av transport sender engine failed, ret:%{public}" PRId32, ret);
81 return ERR_DH_AV_TRANS_START_FAILED;
82 }
83 DHLOGI("Start Success");
84 return DH_SUCCESS;
85 }
86
Stop()87 int32_t AVTransSenderAdapter::Stop()
88 {
89 DHLOGI("Stop enter");
90 if (senderEngine_ == nullptr) {
91 DHLOGE("av transport sender engine is null");
92 return ERR_DH_AV_TRANS_NULL_VALUE;
93 }
94 int32_t ret = senderEngine_->Stop();
95 if (ret != DH_AVT_SUCCESS) {
96 DHLOGE("stop av transport sender engine failed, ret:%{public}" PRId32, ret);
97 return ERR_DH_AV_TRANS_STOP_FAILED;
98 }
99 DHLOGI("Stop Success");
100 transStartSuccess_ = false;
101 return DH_SUCCESS;
102 }
103
CreateControlChannel(const std::string & peerDevId)104 int32_t AVTransSenderAdapter::CreateControlChannel(const std::string& peerDevId)
105 {
106 DHLOGI("CreateControlChannel enter, peerDevId:%{public}s", GetAnonyString(peerDevId).c_str());
107 if (chnCreateSuccess_.load()) {
108 DHLOGI("av transport sender channel already created");
109 return DH_SUCCESS;
110 }
111 if (senderEngine_ == nullptr) {
112 DHLOGE("av transport sender engine is null");
113 return ERR_DH_AV_TRANS_NULL_VALUE;
114 }
115 std::vector<std::string> dstDevIds = {peerDevId};
116 StartTrace(DSCREEN_HITRACE_LABEL, DSCREEN_SOURCE_OPEN_SESSION_START);
117 int32_t ret = senderEngine_->CreateControlChannel(dstDevIds, ChannelAttribute{TransStrategy::LOW_LATANCY_STRATEGY});
118 FinishTrace(DSCREEN_HITRACE_LABEL);
119 if (ret != DH_AVT_SUCCESS) {
120 DHLOGE("create av transport sender channel failed, ret:%{public}" PRId32, ret);
121 return ERR_DH_AV_TRANS_CREATE_CHANNEL_FAILED;
122 }
123 ret = WaitForChannelCreated();
124 if (ret != DH_SUCCESS) {
125 DHLOGE("wait for create av transport sender channel failed, ret:%{public}" PRId32, ret);
126 return ERR_DH_AV_TRANS_CREATE_CHANNEL_FAILED;
127 }
128 DHLOGI("CreateControlChannel Success, peerDevId:%{public}s", GetAnonyString(peerDevId).c_str());
129 return DH_SUCCESS;
130 }
131
SetParameter(const AVTransTag & tag,const std::string & param)132 int32_t AVTransSenderAdapter::SetParameter(const AVTransTag &tag, const std::string ¶m)
133 {
134 DHLOGI("AVTransSenderAdapter::SetParameter enter");
135 if (senderEngine_ == nullptr) {
136 DHLOGE("av transport sender engine is null");
137 return ERR_DH_AV_TRANS_NULL_VALUE;
138 }
139 int32_t ret = senderEngine_->SetParameter(tag, param);
140 if (ret != DH_AVT_SUCCESS) {
141 DHLOGE("set av transport sender parameter failed, ret:%{public}" PRId32, ret);
142 return ERR_DH_AV_TRANS_SETUP_FAILED;
143 }
144 return DH_SUCCESS;
145 }
146
PushData(const VideoData & video)147 int32_t AVTransSenderAdapter::PushData(const VideoData &video)
148 {
149 if (senderEngine_ == nullptr) {
150 DHLOGE("av transport sender engine is null");
151 return ERR_DH_AV_TRANS_NULL_VALUE;
152 }
153 auto transBuffer = std::make_shared<AVTransBuffer>(MetaType::VIDEO);
154 auto bufferData = transBuffer->WrapBufferData(video.data, video.size, video.size);
155 auto bufferMata = transBuffer->GetBufferMeta();
156 bufferMata->SetMetaItem(AVTransTag::BUFFER_DATA_TYPE, std::to_string(static_cast<uint32_t>(MetaType::VIDEO)));
157 bufferMata->SetMetaItem(AVTransTag::VIDEO_WIDTH, std::to_string(video.width));
158 bufferMata->SetMetaItem(AVTransTag::VIDEO_HEIGHT, std::to_string(video.height));
159 bufferMata->SetMetaItem(AVTransTag::VIDEO_PIXEL_FORMAT, video.format);
160 bufferMata->SetMetaItem(AVTransTag::PRE_TIMESTAMP, std::to_string(video.timestamp));
161 #ifdef DUMP_DSCREEN_FILE
162 if (DscreenHidumper::GetInstance().GetFlagStatus()) {
163 senderEngine_->StartDumpMediaData();
164 } else {
165 senderEngine_->StopDumpMediaData();
166 }
167 if (DscreenHidumper::GetInstance().GetTransReDumpFlag()) {
168 senderEngine_->ReStartDumpMediaData();
169 DscreenHidumper::GetInstance().SetTransReDumpFlagFalse();
170 }
171 #endif
172 StartTrace(DSCREEN_HITRACE_LABEL, DSCREEN_START_ENCODER_START);
173 int32_t ret = senderEngine_->PushData(transBuffer);
174 FinishTrace(DSCREEN_HITRACE_LABEL);
175 if (ret != DH_AVT_SUCCESS) {
176 DHLOGE("feed data to av transport sender failed, ret:%{public}" PRId32, ret);
177 return ERR_DH_AV_TRANS_FEED_DATA_FAILED;
178 }
179 return DH_SUCCESS;
180 }
181
SendMessageToRemote(const std::shared_ptr<AVTransMessage> & message)182 int32_t AVTransSenderAdapter::SendMessageToRemote(const std::shared_ptr<AVTransMessage> &message)
183 {
184 DHLOGI("AVTransSenderAdapter::SendMessageToRemote enter");
185 if (senderEngine_ == nullptr) {
186 DHLOGE("av transport sender engine is null");
187 return ERR_DH_AV_TRANS_NULL_VALUE;
188 }
189 int32_t ret = senderEngine_->SendMessage(message);
190 if (ret != DH_AVT_SUCCESS) {
191 DHLOGE("send meassage to remote receiver engine failed, ret:%{public}" PRId32, ret);
192 return ERR_DH_AV_TRANS_SEND_MSG_FAILED;
193 }
194 return DH_SUCCESS;
195 }
196
RegisterAdapterCallback(const std::shared_ptr<AVSenderAdapterCallback> & callback)197 int32_t AVTransSenderAdapter::RegisterAdapterCallback(const std::shared_ptr<AVSenderAdapterCallback> &callback)
198 {
199 if (callback == nullptr) {
200 return ERR_DH_AV_TRANS_NULL_VALUE;
201 }
202 adapterCallback_ = callback;
203 return DH_SUCCESS;
204 }
205
WaitForChannelCreated()206 int32_t AVTransSenderAdapter::WaitForChannelCreated()
207 {
208 std::unique_lock<std::mutex> lock(chnCreatedMtx_);
209 auto status = chnCreatedCondVar_.wait_for(lock, std::chrono::milliseconds(WAIT_TIMEOUT_MS),
210 [this]() { return chnCreateSuccess_.load(); });
211 if (!status) {
212 DHLOGE("wait for av transport sender channel created timeout");
213 return ERR_DH_AV_TRANS_TIMEOUT;
214 }
215 if (!chnCreateSuccess_.load()) {
216 DHLOGE("create av transport sender channel failed");
217 return ERR_DH_AV_TRANS_CREATE_CHANNEL_FAILED;
218 }
219 return DH_SUCCESS;
220 }
221
WaitForAVTransStarted()222 int32_t AVTransSenderAdapter::WaitForAVTransStarted()
223 {
224 std::unique_lock<std::mutex> lock(transStartedMtx_);
225 auto status = transStartedCondVar_.wait_for(lock, std::chrono::milliseconds(WAIT_TIMEOUT_MS),
226 [this]() { return transStartSuccess_.load(); });
227 if (!status) {
228 DHLOGE("wait for av transport sender started timeout");
229 return ERR_DH_AV_TRANS_TIMEOUT;
230 }
231 if (!transStartSuccess_.load()) {
232 DHLOGE("start av transport sender engine failed");
233 return ERR_DH_AV_TRANS_START_FAILED;
234 }
235 return DH_SUCCESS;
236 }
237
OnSenderEvent(const AVTransEvent & event)238 int32_t AVTransSenderAdapter::OnSenderEvent(const AVTransEvent& event)
239 {
240 DHLOGI("OnSenderEvent enter. event type:%{public}" PRId32, event.type);
241 switch (event.type) {
242 case EventType::EVENT_CHANNEL_OPEN_FAIL:
243 case EventType::EVENT_CHANNEL_OPENED: {
244 chnCreateSuccess_ = (event.type == EventType::EVENT_CHANNEL_OPENED);
245 chnCreatedCondVar_.notify_one();
246 break;
247 }
248 case EventType::EVENT_CHANNEL_CLOSED: {
249 chnCreateSuccess_ = false;
250 if (adapterCallback_ != nullptr) {
251 adapterCallback_->OnEngineEvent(DScreenEventType::TRANS_CHANNEL_CLOSED, event.peerDevId);
252 }
253 break;
254 }
255 case EventType::EVENT_START_FAIL:
256 case EventType::EVENT_START_SUCCESS: {
257 transStartSuccess_ = (event.type == EventType::EVENT_START_SUCCESS);
258 transStartedCondVar_.notify_one();
259 break;
260 }
261 case EventType::EVENT_ENGINE_ERROR:
262 case EventType::EVENT_REMOTE_ERROR:
263 if (adapterCallback_ != nullptr) {
264 adapterCallback_->OnEngineEvent(DScreenEventType::ENGINE_ERROR, event.content);
265 }
266 break;
267 default:
268 DHLOGE("Invalid event type.");
269 }
270 return DH_AVT_SUCCESS;
271 }
272
OnMessageReceived(const std::shared_ptr<AVTransMessage> & message)273 int32_t AVTransSenderAdapter::OnMessageReceived(const std::shared_ptr<AVTransMessage> &message)
274 {
275 if (adapterCallback_ != nullptr) {
276 adapterCallback_->OnEngineMessage(message);
277 }
278 return DH_AVT_SUCCESS;
279 }
280 } // namespace DistributedHardware
281 } // namespace OHOS