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