• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Shenzhen Kaihong Digital Industry Development 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 "wfd_demo.h"
17 #include <cstdint>
18 #include <functional>
19 #include <iostream>
20 #include <mutex>
21 #include <string>
22 #include <vector>
23 #include "extend/magic_enum/magic_enum.hpp"
24 #include "impl/scene/wfd/wfd_def.h"
25 #include "math.h"
26 #include "surface.h"
27 #include "surface_utils.h"
28 #include "transaction/rs_transaction.h"
29 #include "ui/rs_surface_node.h"
30 #include "utils/utils.h"
31 #include "window.h"
32 #include "window_option.h"
33 
34 using namespace OHOS;
35 using namespace OHOS::Sharing;
36 
37 VideoFormat DEFAULT_VIDEO_FORMAT = VideoFormat::VIDEO_1920X1080_30;
38 AudioFormat DEFAULT_AUDIO_FORMAT = AudioFormat::AUDIO_48000_16_2;
39 int32_t DEFAULT_WINDOW_WIDTH = 1920;
40 int32_t DEFAULT_WINDOW_HEIGHT = 1080;
41 std::vector<std::pair<int32_t, int32_t>> position{{0, 0}, {960, 0}, {0, 540}, {960, 540}};
42 
Init(const WfdMode mode)43 bool WfdDemo::Init(const WfdMode mode)
44 {
45     std::cout << "to get wifi display " << std::string(magic_enum::enum_name(mode)).c_str() << '\n';
46     client_ = MiracastFactory::GetInstance(mode);
47     if (!client_) {
48         std::cout << "create wfd client error\n";
49         return false;
50     }
51     client_->SetListener(shared_from_this());
52 
53     // when mode is SINK, init a window to display
54     if (mode == SINK) {
55         InitWindow();
56         WifiDisplayTable_.emplace("Play", std::bind(&WifiDisplay::Play, client_, std::placeholders::_1));
57         WifiDisplayTable_.emplace("Pause", std::bind(&WifiDisplay::Pause, client_, std::placeholders::_1));
58         WifiDisplayTable_.emplace("Close", std::bind(&WifiDisplay::Close, client_, std::placeholders::_1));
59     }
60     return true;
61 }
62 
InitWindow()63 void WfdDemo::InitWindow()
64 {
65     if (!surfaceIds_.empty())
66         return;
67     std::cout << "create window enter\n";
68 
69     for (int i = 0; i < windowNum_; i++) {
70         sptr<Rosen::WindowOption> option = new Rosen::WindowOption();
71         option->SetWindowRect({position[i].first, position[i].second, DEFAULT_WINDOW_WIDTH / sqrt(windowNum_),
72                                DEFAULT_WINDOW_HEIGHT / sqrt(windowNum_)});
73         option->SetWindowType(Rosen::WindowType::WINDOW_TYPE_APP_LAUNCHING);
74         option->SetWindowMode(Rosen::WindowMode::WINDOW_MODE_FULLSCREEN);
75         sptr<Rosen::Window> window = Rosen::Window::Create("wifi display window:" + std::to_string(i), option);
76         auto surfaceNode = window->GetSurfaceNode();
77         surfaceNode->SetFrameGravity(Rosen::Gravity::RESIZE);
78         Rosen::RSTransaction::FlushImplicitTransaction();
79         sptr<Surface> surface = surfaceNode->GetSurface();
80         window->SetRequestedOrientation(Rosen::Orientation::HORIZONTAL);
81         window->Show();
82         auto surfaceId = surface->GetUniqueId();
83         surfaceIds_.push_back(surfaceId);
84         int ret = SurfaceUtils::GetInstance()->Add(surfaceId, surface);
85         if (ret != 0)
86             std::cout << "add failed\n";
87         devicesIsPlaying_.push_back("");
88     }
89 }
90 
SelectMediaFormat()91 void WfdDemo::SelectMediaFormat()
92 {
93     videoAttr_.codecType = CodecType::CODEC_H264;
94     videoAttr_.format = 7;
95     audioAttr_.codecType = CodecType::CODEC_AAC;
96     audioAttr_.format = 43;
97 
98     std::cout << "please input videoFormatId:(default 4)\n";
99     std::cout << "0: VIDEO_640X480_60\n";
100     std::cout << "1: VIDEO_1280X720_25\n";
101     std::cout << "2: VIDEO_1280X720_30\n";
102     std::cout << "4: VIDEO_1920X1080_25\n";
103     std::cout << "5: VIDEO_1920X1080_30\n";
104 
105     std::string input;
106     getline(std::cin, input);
107     if (input != "") {
108         videoAttr_.format = static_cast<VideoFormat>(atoi(input.c_str()) + 2);
109     }
110 
111     std::cout << "please input audioFormatId:\n(default 13)";
112     std::cout << "0: AUDIO_44100_8_1\n";
113     std::cout << "1: AUDIO_44100_8_2\n";
114     std::cout << "2: AUDIO_44100_16_1\n";
115     std::cout << "3: AUDIO_44100_16_2\n";
116     std::cout << "10: AUDIO_48000_8_1\n";
117     std::cout << "11: AUDIO_48000_8_2\n";
118     std::cout << "12: AUDIO_48000_16_1\n";
119     std::cout << "13: AUDIO_48000_16_2\n";
120 
121     getline(std::cin, input);
122     if (input != "") {
123         audioAttr_.format = static_cast<AudioFormat>(atoi(input.c_str()) + 30);
124     }
125 }
126 
AddDevice()127 void WfdDemo::AddDevice() {}
RemoveDevice()128 void WfdDemo::RemoveDevice() {}
129 
OnError(const CastErrorInfo & errorInfo)130 void WfdDemo::OnError(const CastErrorInfo &errorInfo)
131 {
132     std::cout << "on error. deviceId : " << errorInfo.deviceId << ", errorCode : " << errorInfo.errorCode << '\n';
133 }
134 
OnDeviceState(const CastDeviceInfo & deviceInfo)135 void WfdDemo::OnDeviceState(const CastDeviceInfo &deviceInfo)
136 {
137     switch (deviceInfo.state) {
138         case CastDeviceState::CONNECTED: {
139             {
140                 std::unique_lock<std::mutex> lock(mutex_);
141                 for (int item = 0; item < windowNum_; item++) {
142                     if (devicesIsPlaying_[item] == "") {
143                         client_->AppendSurface(deviceInfo.deviceId, surfaceIds_[item]);
144                         client_->SetMediaFormat(deviceInfo.deviceId, videoAttr_, audioAttr_);
145                         client_->Play(deviceInfo.deviceId);
146                         devicesIsPlaying_[item] = deviceInfo.deviceId;
147                         break;
148                     }
149                 }
150                 break;
151             }
152         }
153         case CastDeviceState::DISCONNECTED: {
154             {
155                 std::unique_lock<std::mutex> lock(mutex_);
156                 for (int item = 0; item < windowNum_; item++) {
157                     if (devicesIsPlaying_[item] == deviceInfo.deviceId) {
158                         devicesIsPlaying_[item] = "";
159                     }
160                 }
161                 break;
162             }
163         }
164         default:
165             break;
166     }
167     std::cout << "on OnConnectionChanged : \n";
168     std::cout << "ip : " << deviceInfo.ipAddr.c_str() << '\n';
169     std::cout << "mac : " << deviceInfo.deviceId.c_str() << '\n';
170     std::cout << "state: " << std::string(magic_enum::enum_name(deviceInfo.state)).c_str() << '\n';
171 }
172 
OnDeviceFound(const std::vector<CastDeviceInfo> & deviceInfos)173 void WfdDemo::OnDeviceFound(const std::vector<CastDeviceInfo> &deviceInfos)
174 {
175     for (int deviceNum = 0; deviceNum < deviceInfos.size(); deviceNum++) {
176         std::cout << deviceNum << ". device id : " << deviceInfos[deviceNum].deviceId
177                   << " device name : " << deviceInfos[deviceNum].deviceName << "\n";
178     }
179 }
180 
RunWfdSink()181 void WfdDemo::RunWfdSink()
182 {
183     if (!Init(SINK))
184         return;
185 
186     if (client_->Start() == 0) {
187         std::cout << "wifi display sink service start!\n";
188     }
189     SelectMediaFormat();
190 
191     std::map<std::string, std::string> cmdMap = {{"1", "Start"},      {"2", "Stop"},  {"3", "SelectMediaFormat"},
192                                                  {"4", "Play"},       {"5", "Pause"}, {"6", "Close"},
193                                                  {"12", "ListDevice"}};
194 
195     std::string helpNotice = "select steps:        0-quit;\n"
196                              "1-Start;             2-Stop;\n"
197                              "3-SelectMediaFormat; 4-Play;\n"
198                              "5-Pause;             6-Close;\n"
199                              "12-ListDevice\n";
200 
201     std::string inputCmd;
202     while (1) {
203         std::cout << helpNotice;
204         getline(std::cin, inputCmd);
205         if (inputCmd == "") {
206             continue;
207         } else if (inputCmd == "0") {
208             break;
209         } else {
210             if (cmdMap.count(inputCmd) == 0) {
211                 std::cout << "no cmd: " << inputCmd << ", input agin\n";
212                 continue;
213             } else {
214                 DoCmd(cmdMap[inputCmd]);
215             }
216         }
217     }
218 }
219 
RunWfdSource()220 void WfdDemo::RunWfdSource() {}
221 
DoCmd(std::string cmd)222 void WfdDemo::DoCmd(std::string cmd)
223 {
224     if (!client_)
225         return;
226     if (cmd.find("Start") != std::string::npos) {
227         client_->Start();
228     } else if (cmd.find("Stop") != std::string::npos) {
229         client_->Stop();
230         {
231             std::unique_lock<std::mutex> lock(mutex_);
232             for (int item = 0; item < devicesIsPlaying_.size(); item++)
233                 devicesIsPlaying_[item] = "";
234         }
235     } else if (WifiDisplayTable_.find(cmd) != WifiDisplayTable_.end()) {
236         std::cout << "enter the window number to operate: \n";
237         int32_t winNum = 0;
238         std::string input;
239         getline(std::cin, input);
240         if (input != "") {
241             winNum = static_cast<int32_t>(atoi(input.c_str()));
242             if (winNum >= windowNum_) {
243                 std::cout << "the window not exits\n";
244                 return;
245             }
246         }
247         auto iter = WifiDisplayTable_.find(cmd);
248         auto func = iter->second;
249         func(devicesIsPlaying_[winNum]);
250     } else if (cmd.find("SelectMediaFormat") != std::string::npos) {
251         SelectMediaFormat();
252     } else if (cmd.find("StartDiscover") != std::string::npos) {
253         client_->StartDiscover();
254     } else if (cmd.find("StopDiscover") != std::string::npos) {
255         client_->StopDiscover();
256     } else if (cmd.find("AddDevice") != std::string::npos) {
257         CastDeviceInfo info;
258         client_->AddDevice(info);
259     } else if (cmd.find("RemoveDevice") != std::string::npos) {
260         client_->RemoveDevice("0.0.0.0");
261     } else {
262         std::cout << "operation is invalid\n";
263     }
264 
265     return;
266 }
267 
main()268 int main()
269 {
270     std::cout << "Please select a demo scenario number(default sink): \n";
271     std::cout << "0:wfd sink\n";
272     std::cout << "1:wfd source\n";
273 
274     auto wifiDisplay = std::make_shared<WfdDemo>();
275 
276     std::string mode;
277     (void)getline(std::cin, mode);
278     if (mode == "" || mode == "0") {
279         wifiDisplay->RunWfdSink();
280     } else if (mode == "1") {
281         wifiDisplay->RunWfdSource();
282     } else {
283         std::cout << "no that selection\n";
284         return 0;
285     }
286 
287     std::cout << "wfd test end!\n";
288     return 0;
289 }