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