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 &param)
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