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 "VirtualScreen.h"
17 #include "CommandParser.h"
18 #include "CppTimerManager.h"
19 #include "PreviewerEngineLog.h"
20 #include "VirtualScreen.h"
21
22 #define boolean jpegboolean
23 #include "jpeglib.h"
24 #undef boolean
25
26 using namespace std;
27
28 uint32_t VirtualScreen::validFrameCountPerMinute = 0;
29 uint32_t VirtualScreen::invalidFrameCountPerMinute = 0;
30 uint32_t VirtualScreen::sendFrameCountPerMinute = 0;
31 uint32_t VirtualScreen::inputKeyCountPerMinute = 0;
32 uint32_t VirtualScreen::inputMethodCountPerMinute = 0;
33 bool VirtualScreen::isWebSocketListening = false;
34 std::string VirtualScreen::webSocketPort = "";
35
36 std::chrono::system_clock::time_point VirtualScreen::startTime = std::chrono::system_clock::now();
37 std::chrono::system_clock::time_point VirtualScreen::staticCardStartTime = std::chrono::system_clock::now();
38 bool VirtualScreen::isStartCount = true;
39 bool VirtualScreen::isOutOfSeconds = false;
40
VirtualScreen()41 VirtualScreen::VirtualScreen()
42 : isFrameUpdated(false),
43 orignalResolutionWidth(0),
44 orignalResolutionHeight(0),
45 compressionResolutionWidth(0),
46 compressionResolutionHeight(0),
47 screenSocket(nullptr),
48 frameCountTimer(nullptr),
49 isWebSocketConfiged(false),
50 currentRouter(""),
51 jpgScreenBuffer(nullptr),
52 jpgBufferSize(0)
53 {
54 }
55
~VirtualScreen()56 VirtualScreen::~VirtualScreen()
57 {
58 if (screenSocket != nullptr) {
59 screenSocket->DisconnectFromServer();
60 delete screenSocket;
61 screenSocket = nullptr;
62 }
63 }
64
GetCurrentRouter() const65 std::string VirtualScreen::GetCurrentRouter() const
66 {
67 return currentRouter;
68 }
69
SetCurrentRouter(const std::string currentRouterValue)70 void VirtualScreen::SetCurrentRouter(const std::string currentRouterValue)
71 {
72 currentRouter = currentRouterValue;
73 }
74
GetAbilityCurrentRouter() const75 std::string VirtualScreen::GetAbilityCurrentRouter() const
76 {
77 return abilityCurrentRouter;
78 }
79
SetAbilityCurrentRouter(const std::string currentRouterValue)80 void VirtualScreen::SetAbilityCurrentRouter(const std::string currentRouterValue)
81 {
82 abilityCurrentRouter = currentRouterValue;
83 }
84
GetOrignalWidth() const85 int32_t VirtualScreen::GetOrignalWidth() const
86 {
87 return orignalResolutionWidth;
88 }
89
SetOrignalWidth(const int32_t & value)90 void VirtualScreen::SetOrignalWidth(const int32_t& value)
91 {
92 orignalResolutionWidth = value;
93 }
94
GetOrignalHeight() const95 int32_t VirtualScreen::GetOrignalHeight() const
96 {
97 return orignalResolutionHeight;
98 }
99
SetOrignalHeight(const int32_t & value)100 void VirtualScreen::SetOrignalHeight(const int32_t& value)
101 {
102 orignalResolutionHeight = value;
103 }
104
GetCompressionWidth() const105 int32_t VirtualScreen::GetCompressionWidth() const
106 {
107 return compressionResolutionWidth;
108 }
109
SetCompressionWidth(const int32_t & value)110 void VirtualScreen::SetCompressionWidth(const int32_t& value)
111 {
112 compressionResolutionWidth = value;
113 }
114
GetCompressionHeight() const115 int32_t VirtualScreen::GetCompressionHeight() const
116 {
117 return compressionResolutionHeight;
118 }
119
SetCompressionHeight(const int32_t & value)120 void VirtualScreen::SetCompressionHeight(const int32_t& value)
121 {
122 compressionResolutionHeight = value;
123 }
124
InitPipe(string pipeName,string pipePort)125 void VirtualScreen::InitPipe(string pipeName, string pipePort)
126 {
127 webSocketPort = pipePort;
128 isWebSocketConfiged = true;
129 WebSocketServer::GetInstance().SetServerPort(atoi(pipePort.c_str()));
130 WebSocketServer::GetInstance().Run();
131 isWebSocketListening = true;
132 }
133
InitVirtualScreen()134 void VirtualScreen::InitVirtualScreen()
135 {
136 int32_t orignalWidth = CommandParser::GetInstance().GetOrignalResolutionWidth();
137 int32_t orignalHeight = CommandParser::GetInstance().GetOrignalResolutionHeight();
138 int32_t compressionWidth = CommandParser::GetInstance().GetCompressionResolutionWidth();
139 int32_t compressionHeight = CommandParser::GetInstance().GetCompressionResolutionHeight();
140 SetVirtualScreenWidthAndHeight(orignalWidth, orignalHeight, compressionWidth, compressionHeight);
141 }
142
SetVirtualScreenWidthAndHeight(const int32_t & orignalWidth,const int32_t & orignalHeight,const int32_t & compressionWidth,const int32_t & compressionHeight)143 void VirtualScreen::SetVirtualScreenWidthAndHeight(const int32_t& orignalWidth,
144 const int32_t& orignalHeight,
145 const int32_t& compressionWidth,
146 const int32_t& compressionHeight)
147 {
148 VirtualScreen::SetOrignalWidth(orignalWidth);
149 VirtualScreen::SetOrignalHeight(orignalHeight);
150 VirtualScreen::SetCompressionWidth(compressionWidth);
151 VirtualScreen::SetCompressionHeight(compressionHeight);
152 }
153
WidthAndHeightReverse()154 void VirtualScreen::WidthAndHeightReverse()
155 {
156 int32_t temp = 0;
157 temp = orignalResolutionHeight;
158 orignalResolutionHeight = orignalResolutionWidth;
159 orignalResolutionWidth = temp;
160 temp = compressionResolutionHeight;
161 compressionResolutionHeight = compressionResolutionWidth;
162 compressionResolutionWidth = temp;
163 }
164
InitFrameCountTimer()165 void VirtualScreen::InitFrameCountTimer()
166 {
167 if (frameCountTimer.get() != nullptr) {
168 ILOG("VirtualScreen::InitFrameCountTimer timer is already started.");
169 return;
170 }
171
172 frameCountTimer = make_unique<CppTimer>(VirtualScreen::PrintFrameCount);
173 if (frameCountTimer == nullptr) {
174 ELOG("JsApp::InitTimer taskHandleTimer memory allocation failed.");
175 return;
176 }
177 CppTimerManager::GetTimerManager().AddCppTimer(*frameCountTimer);
178 frameCountTimer->Start(frameCountPeriod);
179 }
180
PrintFrameCount()181 void VirtualScreen::PrintFrameCount()
182 {
183 if ((validFrameCountPerMinute | invalidFrameCountPerMinute | sendFrameCountPerMinute |
184 inputKeyCountPerMinute | inputMethodCountPerMinute) == 0) {
185 return;
186 }
187
188 ELOG("ValidFrameCount: %d InvalidFrameCount: %d SendFrameCount: %d inputKeyCount: %d\
189 inputMethodCount: %d", validFrameCountPerMinute, invalidFrameCountPerMinute,
190 sendFrameCountPerMinute, inputKeyCountPerMinute, inputMethodCountPerMinute);
191 validFrameCountPerMinute = 0;
192 invalidFrameCountPerMinute = 0;
193 sendFrameCountPerMinute = 0;
194 inputKeyCountPerMinute = 0;
195 inputMethodCountPerMinute = 0;
196 }
197
198
SetLoadDocFlag(VirtualScreen::LoadDocType flag)199 void VirtualScreen::SetLoadDocFlag(VirtualScreen::LoadDocType flag)
200 {
201 startLoadDoc = flag;
202 }
203
GetLoadDocFlag() const204 VirtualScreen::LoadDocType VirtualScreen::GetLoadDocFlag() const
205 {
206 return startLoadDoc;
207 }
208
GetJpgQualityValue(int32_t width,int32_t height) const209 int VirtualScreen::GetJpgQualityValue(int32_t width, int32_t height) const
210 {
211 long long pixCount = static_cast<long long>(width) * static_cast<long long>(height);
212 if (pixCount <= static_cast<int>(JpgPixCountLevel::LOWCOUNT)) {
213 return static_cast<int>(JpgQualityLevel::HIGHLEVEL);
214 } else if (pixCount > static_cast<int>(JpgPixCountLevel::LOWCOUNT) &&
215 pixCount <= static_cast<int>(JpgPixCountLevel::MIDDLECOUNT)) {
216 return static_cast<int>(JpgQualityLevel::MIDDLELEVEL);
217 } else if (pixCount > static_cast<int>(JpgPixCountLevel::MIDDLECOUNT) &&
218 pixCount <= static_cast<int>(JpgPixCountLevel::HIGHCOUNT)) {
219 return static_cast<int>(JpgQualityLevel::LOWLEVEL);
220 } else {
221 return static_cast<int>(JpgQualityLevel::DEFAULTLEVEL);
222 }
223 }
224
GetFastPreviewMsg() const225 std::string VirtualScreen::GetFastPreviewMsg() const
226 {
227 return fastPreviewMsg;
228 }
229
SetFastPreviewMsg(const std::string msg)230 void VirtualScreen::SetFastPreviewMsg(const std::string msg)
231 {
232 fastPreviewMsg = msg;
233 }
234
SetDropFrameFrequency(const int32_t & value)235 void VirtualScreen::SetDropFrameFrequency(const int32_t& value)
236 {
237 dropFrameFrequency = value;
238 startDropFrameTime = std::chrono::system_clock::now();
239 }
240
JudgeAndDropFrame()241 bool VirtualScreen::JudgeAndDropFrame()
242 {
243 if (dropFrameFrequency <= 0) {
244 return false;
245 }
246 auto endTime = std::chrono::system_clock::now();
247 int64_t timePassed = chrono::duration_cast<chrono::milliseconds>(endTime -
248 startDropFrameTime).count();
249 if (timePassed >= dropFrameFrequency) {
250 startDropFrameTime = std::chrono::system_clock::now();
251 }
252 return timePassed < dropFrameFrequency;
253 }
254
JudgeStaticImage(const int duration)255 bool VirtualScreen::JudgeStaticImage(const int duration)
256 {
257 if (CommandParser::GetInstance().GetScreenMode() == CommandParser::ScreenMode::STATIC) {
258 if (VirtualScreen::isOutOfSeconds) {
259 return false;
260 }
261 if (VirtualScreen::isStartCount) {
262 VirtualScreen::isStartCount = false;
263 VirtualScreen::startTime = std::chrono::system_clock::now();
264 }
265 auto endTime = std::chrono::system_clock::now();
266 int64_t timePassed = chrono::duration_cast<chrono::milliseconds>(endTime -
267 VirtualScreen::startTime).count();
268 if (timePassed > duration) {
269 VirtualScreen::isOutOfSeconds = true;
270 return false;
271 }
272 }
273 return true;
274 }
275
StopSendStaticCardImage(const int duration)276 bool VirtualScreen::StopSendStaticCardImage(const int duration)
277 {
278 if (CommandParser::GetInstance().IsStaticCard()) {
279 static bool first = true;
280 if (first) {
281 first = false;
282 VirtualScreen::staticCardStartTime = std::chrono::system_clock::now();
283 }
284 auto endTime = std::chrono::system_clock::now();
285 int64_t timePassed = chrono::duration_cast<chrono::milliseconds>(endTime -
286 VirtualScreen::staticCardStartTime).count();
287 if (timePassed > duration) {
288 return true;
289 }
290 }
291 return false;
292 }
293
RgbToJpg(unsigned char * data,const int32_t width,const int32_t height)294 void VirtualScreen::RgbToJpg(unsigned char* data, const int32_t width, const int32_t height)
295 {
296 if (width < 1 || height < 1) {
297 FLOG("VirtualScreenImpl::RgbToJpg the width or height is invalid value");
298 }
299 jpeg_compress_struct jpeg = {0};
300 jpeg_error_mgr jerr;
301 jpeg.err = jpeg_std_error(&jerr);
302 jpeg_create_compress(&jpeg);
303 jpeg_mem_dest(&jpeg, &jpgScreenBuffer, &jpgBufferSize);
304 jpeg.image_width = width;
305 jpeg.image_height = height;
306 jpeg.input_components = jpgPix;
307 jpeg.in_color_space = JCS_RGB;
308 jpeg_set_defaults(&jpeg);
309 jpeg_set_quality(&jpeg, GetJpgQualityValue(width, height), TRUE);
310 jpeg_start_compress(&jpeg, TRUE);
311 JSAMPROW rowPointer[1];
312 int rowStride = width * jpgPix;
313 while (jpeg.next_scanline < jpeg.image_height) {
314 rowPointer[0] = &data[jpeg.next_scanline * rowStride];
315 jpeg_write_scanlines(&jpeg, rowPointer, 1);
316 }
317 jpeg_finish_compress(&jpeg);
318 jpeg_destroy_compress(&jpeg);
319 }