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