17c804472Sopenharmony_ci/* 27c804472Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 37c804472Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 47c804472Sopenharmony_ci * you may not use this file except in compliance with the License. 57c804472Sopenharmony_ci * You may obtain a copy of the License at 67c804472Sopenharmony_ci * 77c804472Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 87c804472Sopenharmony_ci * 97c804472Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 107c804472Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 117c804472Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 127c804472Sopenharmony_ci * See the License for the specific language governing permissions and 137c804472Sopenharmony_ci * limitations under the License. 147c804472Sopenharmony_ci */ 157c804472Sopenharmony_ci 167c804472Sopenharmony_ci#include "VirtualScreenImpl.h" 177c804472Sopenharmony_ci 187c804472Sopenharmony_ci#include <cinttypes> 197c804472Sopenharmony_ci#define boolean jpegboolean 207c804472Sopenharmony_ci#include "jpeglib.h" 217c804472Sopenharmony_ci#undef boolean 227c804472Sopenharmony_ci 237c804472Sopenharmony_ci#include "CommandLineInterface.h" 247c804472Sopenharmony_ci#include "CommandParser.h" 257c804472Sopenharmony_ci#include "PreviewerEngineLog.h" 267c804472Sopenharmony_ci#include "TraceTool.h" 277c804472Sopenharmony_ci#include <sstream> 287c804472Sopenharmony_ci 297c804472Sopenharmony_ciVirtualScreenImpl& VirtualScreenImpl::GetInstance() 307c804472Sopenharmony_ci{ 317c804472Sopenharmony_ci static VirtualScreenImpl virtualScreen; 327c804472Sopenharmony_ci return virtualScreen; 337c804472Sopenharmony_ci} 347c804472Sopenharmony_ci 357c804472Sopenharmony_civoid VirtualScreenImpl::SendBufferOnTimer() 367c804472Sopenharmony_ci{ 377c804472Sopenharmony_ci GetInstance().SetLoadDocFlag(VirtualScreen::LoadDocType::NORMAL); 387c804472Sopenharmony_ci if (GetInstance().loadDocTempBuffer == nullptr) { 397c804472Sopenharmony_ci PrintLoadDocFinishedLog("onRender timeout,no buffer to send"); 407c804472Sopenharmony_ci return; 417c804472Sopenharmony_ci } 427c804472Sopenharmony_ci VirtualScreen::isStartCount = true; 437c804472Sopenharmony_ci { 447c804472Sopenharmony_ci std::lock_guard<std::mutex> guard(WebSocketServer::GetInstance().mutex); 457c804472Sopenharmony_ci if (GetInstance().loadDocCopyBuffer != nullptr) { 467c804472Sopenharmony_ci delete [] GetInstance().loadDocCopyBuffer; 477c804472Sopenharmony_ci GetInstance().loadDocCopyBuffer = nullptr; 487c804472Sopenharmony_ci } 497c804472Sopenharmony_ci GetInstance().loadDocCopyBuffer = new(std::nothrow) uint8_t[GetInstance().lengthTemp]; 507c804472Sopenharmony_ci if (!GetInstance().loadDocCopyBuffer) { 517c804472Sopenharmony_ci ELOG("Memory allocation failed : loadDocCopyBuffer."); 527c804472Sopenharmony_ci return; 537c804472Sopenharmony_ci } 547c804472Sopenharmony_ci std::copy(GetInstance().loadDocTempBuffer, 557c804472Sopenharmony_ci GetInstance().loadDocTempBuffer + GetInstance().lengthTemp, 567c804472Sopenharmony_ci GetInstance().loadDocCopyBuffer); 577c804472Sopenharmony_ci } 587c804472Sopenharmony_ci VirtualScreenImpl::GetInstance().protocolVersion = 597c804472Sopenharmony_ci static_cast<uint16_t>(VirtualScreen::ProtocolVersion::LOADDOC); 607c804472Sopenharmony_ci GetInstance().bufferSize = GetInstance().lengthTemp + GetInstance().headSize; 617c804472Sopenharmony_ci GetInstance().wholeBuffer = new(std::nothrow) uint8_t[LWS_PRE + GetInstance().bufferSize]; 627c804472Sopenharmony_ci if (!GetInstance().wholeBuffer) { 637c804472Sopenharmony_ci ELOG("Memory allocation failed : wholeBuffer."); 647c804472Sopenharmony_ci return; 657c804472Sopenharmony_ci } 667c804472Sopenharmony_ci GetInstance().screenBuffer = GetInstance().wholeBuffer + LWS_PRE; 677c804472Sopenharmony_ci GetInstance().SendPixmap(GetInstance().loadDocCopyBuffer, GetInstance().lengthTemp, 687c804472Sopenharmony_ci GetInstance().widthTemp, GetInstance().heightTemp); 697c804472Sopenharmony_ci} 707c804472Sopenharmony_ci 717c804472Sopenharmony_civoid VirtualScreenImpl::PrintLoadDocFinishedLog(const std::string& logStr) 727c804472Sopenharmony_ci{ 737c804472Sopenharmony_ci ILOG("loadDoc: LoadDocFlag2:finished %s, onRenderTime:%" PRIu64 ", flushEmptyTime:%" PRIu64 ", \ 747c804472Sopenharmony_ci onRenderTimeStamp:%" PRIu64 " flushEmptyTimeStamp:%" PRIu64 "", logStr.c_str(), 757c804472Sopenharmony_ci GetInstance().onRenderTime, GetInstance().flushEmptyTime, 767c804472Sopenharmony_ci GetInstance().timeStampTemp, GetInstance().flushEmptyTimeStamp); 777c804472Sopenharmony_ci} 787c804472Sopenharmony_ci 797c804472Sopenharmony_cibool VirtualScreenImpl::FlushEmptyFunc(std::chrono::system_clock::time_point endTime, int64_t timePassed) 807c804472Sopenharmony_ci{ 817c804472Sopenharmony_ci if (GetInstance().onRenderTime > GetInstance().flushEmptyTime) { 827c804472Sopenharmony_ci if (GetInstance().timeStampTemp < GetInstance().flushEmptyTimeStamp) { 837c804472Sopenharmony_ci SendBufferOnTimer(); // 有收到结束标记,且flushEmpty后有继续出图 847c804472Sopenharmony_ci PrintLoadDocFinishedLog("flushEmpty normal, onRender normal"); 857c804472Sopenharmony_ci return true; 867c804472Sopenharmony_ci } 877c804472Sopenharmony_ci } else { 887c804472Sopenharmony_ci // flushEmpty后没有继续出图,计时100ms,如果仍没有onRender,发送上一次的的onRender buffer 897c804472Sopenharmony_ci int64_t timePassed2 = std::chrono::duration_cast<std::chrono::milliseconds>(endTime - 907c804472Sopenharmony_ci GetInstance().flushEmptyTime).count(); 917c804472Sopenharmony_ci if (timePassed2 > TIMEOUT_ONRENDER_DURATION_MS) { 927c804472Sopenharmony_ci if (GetInstance().timeStampTemp < GetInstance().flushEmptyTimeStamp) { 937c804472Sopenharmony_ci SendBufferOnTimer(); 947c804472Sopenharmony_ci PrintLoadDocFinishedLog("flushEmpty normal, onRender timeout"); 957c804472Sopenharmony_ci return true; 967c804472Sopenharmony_ci } 977c804472Sopenharmony_ci } 987c804472Sopenharmony_ci } 997c804472Sopenharmony_ci if (timePassed >= TIMEOUT_NINE_S) { // 有结束点,无出图 1007c804472Sopenharmony_ci PrintLoadDocFinishedLog("flushEmpty normal, onRender timeout"); 1017c804472Sopenharmony_ci return true; // 有收到结束标记,且超过最大时限还没有出图则结束 1027c804472Sopenharmony_ci } 1037c804472Sopenharmony_ci return false; 1047c804472Sopenharmony_ci} 1057c804472Sopenharmony_ci 1067c804472Sopenharmony_cibool VirtualScreenImpl::NoFlushEmptyFunc(int64_t timePassed) 1077c804472Sopenharmony_ci{ 1087c804472Sopenharmony_ci if (timePassed >= SEND_IMG_DURATION_MS && 1097c804472Sopenharmony_ci GetInstance().onRenderTime != std::chrono::system_clock::time_point::min()) { 1107c804472Sopenharmony_ci SendBufferOnTimer(); // 没有收到结束标记,300ms内有出图选取最后一张图 1117c804472Sopenharmony_ci PrintLoadDocFinishedLog("async load, flushEmpty timeout, onRender normal"); 1127c804472Sopenharmony_ci return true; 1137c804472Sopenharmony_ci } 1147c804472Sopenharmony_ci if (timePassed >= TIMEOUT_NINE_S) { 1157c804472Sopenharmony_ci SendBufferOnTimer(); 1167c804472Sopenharmony_ci PrintLoadDocFinishedLog("flushEmpty timeout, onRender unknown"); 1177c804472Sopenharmony_ci return true; // 没有收到结束标记,且超过最大时限还没有出图则结束 1187c804472Sopenharmony_ci } 1197c804472Sopenharmony_ci return false; 1207c804472Sopenharmony_ci} 1217c804472Sopenharmony_ci 1227c804472Sopenharmony_ci 1237c804472Sopenharmony_civoid VirtualScreenImpl::StartTimer() 1247c804472Sopenharmony_ci{ 1257c804472Sopenharmony_ci while (true) { 1267c804472Sopenharmony_ci auto endTime = std::chrono::system_clock::now(); 1277c804472Sopenharmony_ci int64_t timePassed = std::chrono::duration_cast<std::chrono::milliseconds>(endTime - 1287c804472Sopenharmony_ci VirtualScreenImpl::GetInstance().startTime).count(); 1297c804472Sopenharmony_ci bool ret = false; 1307c804472Sopenharmony_ci if (GetInstance().isFlushEmpty) { 1317c804472Sopenharmony_ci ret = FlushEmptyFunc(endTime, timePassed); 1327c804472Sopenharmony_ci } else { 1337c804472Sopenharmony_ci ret = NoFlushEmptyFunc(timePassed); 1347c804472Sopenharmony_ci } 1357c804472Sopenharmony_ci if (ret) { 1367c804472Sopenharmony_ci return; 1377c804472Sopenharmony_ci } 1387c804472Sopenharmony_ci } 1397c804472Sopenharmony_ci} 1407c804472Sopenharmony_ci 1417c804472Sopenharmony_cibool VirtualScreenImpl::LoadDocCallback(const void* data, const size_t length, const int32_t width, 1427c804472Sopenharmony_ci const int32_t height, const uint64_t timeStamp) 1437c804472Sopenharmony_ci{ 1447c804472Sopenharmony_ci if (timeStamp < GetInstance().loadDocTimeStamp) { 1457c804472Sopenharmony_ci return false; 1467c804472Sopenharmony_ci } 1477c804472Sopenharmony_ci if (GetInstance().GetLoadDocFlag() == VirtualScreen::LoadDocType::FINISHED) { 1487c804472Sopenharmony_ci { 1497c804472Sopenharmony_ci std::lock_guard<std::mutex> guard(WebSocketServer::GetInstance().mutex); 1507c804472Sopenharmony_ci if (GetInstance().loadDocTempBuffer != nullptr) { 1517c804472Sopenharmony_ci delete [] GetInstance().loadDocTempBuffer; 1527c804472Sopenharmony_ci GetInstance().loadDocTempBuffer = nullptr; 1537c804472Sopenharmony_ci } 1547c804472Sopenharmony_ci GetInstance().lengthTemp = length; 1557c804472Sopenharmony_ci GetInstance().widthTemp = width; 1567c804472Sopenharmony_ci GetInstance().heightTemp = height; 1577c804472Sopenharmony_ci GetInstance().timeStampTemp = timeStamp; 1587c804472Sopenharmony_ci if (length <= 0) { 1597c804472Sopenharmony_ci return false; 1607c804472Sopenharmony_ci } 1617c804472Sopenharmony_ci GetInstance().loadDocTempBuffer = new(std::nothrow) uint8_t[length]; 1627c804472Sopenharmony_ci if (!GetInstance().loadDocTempBuffer) { 1637c804472Sopenharmony_ci ELOG("Memory allocation failed : loadDocTempBuffer."); 1647c804472Sopenharmony_ci return false; 1657c804472Sopenharmony_ci } 1667c804472Sopenharmony_ci uint8_t* dataPtr = reinterpret_cast<uint8_t*>(const_cast<void*>(data)); 1677c804472Sopenharmony_ci std::copy(dataPtr, dataPtr + length, GetInstance().loadDocTempBuffer); 1687c804472Sopenharmony_ci GetInstance().onRenderTime = std::chrono::system_clock::now(); 1697c804472Sopenharmony_ci } 1707c804472Sopenharmony_ci if (VirtualScreen::isStartCount) { 1717c804472Sopenharmony_ci VirtualScreen::isStartCount = false; 1727c804472Sopenharmony_ci VirtualScreen::startTime = std::chrono::system_clock::now(); 1737c804472Sopenharmony_ci std::thread timerThread(std::ref(VirtualScreenImpl::StartTimer)); 1747c804472Sopenharmony_ci timerThread.detach(); 1757c804472Sopenharmony_ci } 1767c804472Sopenharmony_ci return false; 1777c804472Sopenharmony_ci } 1787c804472Sopenharmony_ci return true; 1797c804472Sopenharmony_ci} 1807c804472Sopenharmony_ci 1817c804472Sopenharmony_cibool VirtualScreenImpl::Callback(const void* data, const size_t length, 1827c804472Sopenharmony_ci const int32_t width, const int32_t height, const uint64_t timeStamp) 1837c804472Sopenharmony_ci{ 1847c804472Sopenharmony_ci if (VirtualScreenImpl::GetInstance().StopSendStaticCardImage(STOP_SEND_CARD_DURATION_MS)) { 1857c804472Sopenharmony_ci return false; // 静态卡片 1867c804472Sopenharmony_ci } 1877c804472Sopenharmony_ci if (VirtualScreenImpl::GetInstance().GetLoadDocFlag() < VirtualScreen::LoadDocType::FINISHED) { 1887c804472Sopenharmony_ci return false; 1897c804472Sopenharmony_ci } 1907c804472Sopenharmony_ci if (VirtualScreenImpl::GetInstance().JudgeAndDropFrame()) { 1917c804472Sopenharmony_ci return false; // 丢帧* 1927c804472Sopenharmony_ci } 1937c804472Sopenharmony_ci bool staticRet = VirtualScreen::JudgeStaticImage(SEND_IMG_DURATION_MS); 1947c804472Sopenharmony_ci if (!staticRet) { 1957c804472Sopenharmony_ci return false; // 平行世界 1967c804472Sopenharmony_ci } 1977c804472Sopenharmony_ci if (!LoadDocCallback(data, length, width, height, timeStamp)) { 1987c804472Sopenharmony_ci return false; // 组件预览 1997c804472Sopenharmony_ci } 2007c804472Sopenharmony_ci 2017c804472Sopenharmony_ci GetInstance().bufferSize = length + GetInstance().headSize; 2027c804472Sopenharmony_ci GetInstance().wholeBuffer = new(std::nothrow) uint8_t[LWS_PRE + GetInstance().bufferSize]; 2037c804472Sopenharmony_ci if (!GetInstance().wholeBuffer) { 2047c804472Sopenharmony_ci ELOG("Memory allocation failed : wholeBuffer."); 2057c804472Sopenharmony_ci return false; 2067c804472Sopenharmony_ci } 2077c804472Sopenharmony_ci GetInstance().screenBuffer = GetInstance().wholeBuffer + LWS_PRE; 2087c804472Sopenharmony_ci 2097c804472Sopenharmony_ci return GetInstance().SendPixmap(data, length, width, height); 2107c804472Sopenharmony_ci} 2117c804472Sopenharmony_ci 2127c804472Sopenharmony_cibool VirtualScreenImpl::FlushEmptyCallback(const uint64_t timeStamp) 2137c804472Sopenharmony_ci{ 2147c804472Sopenharmony_ci if (timeStamp < GetInstance().loadDocTimeStamp) { 2157c804472Sopenharmony_ci return false; 2167c804472Sopenharmony_ci } 2177c804472Sopenharmony_ci ILOG("loadDoc: flushEmptyTimeStamp:%" PRIu64 ", loadDocTimeStamp:%" PRIu64 "", 2187c804472Sopenharmony_ci timeStamp, GetInstance().loadDocTimeStamp); 2197c804472Sopenharmony_ci GetInstance().isFlushEmpty = true; 2207c804472Sopenharmony_ci GetInstance().flushEmptyTime = std::chrono::system_clock::now(); 2217c804472Sopenharmony_ci GetInstance().flushEmptyTimeStamp = timeStamp; 2227c804472Sopenharmony_ci return true; 2237c804472Sopenharmony_ci} 2247c804472Sopenharmony_ci 2257c804472Sopenharmony_civoid VirtualScreenImpl::InitFlushEmptyTime() 2267c804472Sopenharmony_ci{ 2277c804472Sopenharmony_ci GetInstance().isFlushEmpty = false; 2287c804472Sopenharmony_ci GetInstance().flushEmptyTime = std::chrono::system_clock::time_point::min(); 2297c804472Sopenharmony_ci GetInstance().onRenderTime = std::chrono::system_clock::time_point::min(); 2307c804472Sopenharmony_ci GetInstance().flushEmptyTimeStamp = 0; 2317c804472Sopenharmony_ci struct timespec ts; 2327c804472Sopenharmony_ci clock_gettime(CLOCK_MONOTONIC, &ts); 2337c804472Sopenharmony_ci loadDocTimeStamp = ts.tv_sec * SEC_TO_NANOSEC + ts.tv_nsec; 2347c804472Sopenharmony_ci ILOG("loadDoc: loadDocTimeStamp:%" PRIu64 "", loadDocTimeStamp); 2357c804472Sopenharmony_ci} 2367c804472Sopenharmony_ci 2377c804472Sopenharmony_cibool VirtualScreenImpl::PageCallback(const std::string currentRouterPath) 2387c804472Sopenharmony_ci{ 2397c804472Sopenharmony_ci std::string currentRouter = currentRouterPath.substr(0, currentRouterPath.size() - 3); 2407c804472Sopenharmony_ci ILOG("PageCallback currentPage is : %s", currentRouter.c_str()); 2417c804472Sopenharmony_ci GetInstance().SetCurrentRouter(currentRouter); 2427c804472Sopenharmony_ci Json2::Value val; 2437c804472Sopenharmony_ci CommandLineInterface::GetInstance().CreatCommandToSendData("CurrentRouter", val, "get"); 2447c804472Sopenharmony_ci return true; 2457c804472Sopenharmony_ci} 2467c804472Sopenharmony_ci 2477c804472Sopenharmony_cibool VirtualScreenImpl::LoadContentCallback(const std::string currentRouterPath) 2487c804472Sopenharmony_ci{ 2497c804472Sopenharmony_ci ILOG("LoadContentCallback currentPage is : %s", currentRouterPath.c_str()); 2507c804472Sopenharmony_ci GetInstance().SetAbilityCurrentRouter(currentRouterPath); 2517c804472Sopenharmony_ci Json2::Value val; 2527c804472Sopenharmony_ci CommandLineInterface::GetInstance().CreatCommandToSendData("LoadContent", val, "get"); 2537c804472Sopenharmony_ci return true; 2547c804472Sopenharmony_ci} 2557c804472Sopenharmony_ci 2567c804472Sopenharmony_civoid VirtualScreenImpl::FastPreviewCallback(const std::string& jsonStr) 2577c804472Sopenharmony_ci{ 2587c804472Sopenharmony_ci GetInstance().SetFastPreviewMsg(jsonStr); 2597c804472Sopenharmony_ci Json2::Value val; 2607c804472Sopenharmony_ci CommandLineInterface::GetInstance().CreatCommandToSendData("FastPreviewMsg", val, "get"); 2617c804472Sopenharmony_ci} 2627c804472Sopenharmony_ci 2637c804472Sopenharmony_civoid VirtualScreenImpl::InitAll(std::string pipeName, std::string pipePort) 2647c804472Sopenharmony_ci{ 2657c804472Sopenharmony_ci VirtualScreen::InitPipe(pipeName, pipePort); 2667c804472Sopenharmony_ci} 2677c804472Sopenharmony_ci 2687c804472Sopenharmony_ciVirtualScreenImpl::VirtualScreenImpl() 2697c804472Sopenharmony_ci : isFirstSend(true), 2707c804472Sopenharmony_ci isFirstRender(true), 2717c804472Sopenharmony_ci writed(0), 2727c804472Sopenharmony_ci wholeBuffer(nullptr), 2737c804472Sopenharmony_ci screenBuffer(nullptr), 2747c804472Sopenharmony_ci bufferSize(0), 2757c804472Sopenharmony_ci currentPos(0) 2767c804472Sopenharmony_ci{ 2777c804472Sopenharmony_ci} 2787c804472Sopenharmony_ci 2797c804472Sopenharmony_ciVirtualScreenImpl::~VirtualScreenImpl() 2807c804472Sopenharmony_ci{ 2817c804472Sopenharmony_ci FreeJpgMemory(); 2827c804472Sopenharmony_ci if (WebSocketServer::GetInstance().firstImageBuffer) { 2837c804472Sopenharmony_ci delete [] WebSocketServer::GetInstance().firstImageBuffer; 2847c804472Sopenharmony_ci WebSocketServer::GetInstance().firstImageBuffer = nullptr; 2857c804472Sopenharmony_ci } 2867c804472Sopenharmony_ci if (VirtualScreenImpl::GetInstance().loadDocTempBuffer != nullptr) { 2877c804472Sopenharmony_ci delete [] VirtualScreenImpl::GetInstance().loadDocTempBuffer; 2887c804472Sopenharmony_ci VirtualScreenImpl::GetInstance().loadDocTempBuffer = nullptr; 2897c804472Sopenharmony_ci } 2907c804472Sopenharmony_ci if (VirtualScreenImpl::GetInstance().loadDocCopyBuffer != nullptr) { 2917c804472Sopenharmony_ci delete [] VirtualScreenImpl::GetInstance().loadDocCopyBuffer; 2927c804472Sopenharmony_ci VirtualScreenImpl::GetInstance().loadDocCopyBuffer = nullptr; 2937c804472Sopenharmony_ci } 2947c804472Sopenharmony_ci} 2957c804472Sopenharmony_ci 2967c804472Sopenharmony_civoid VirtualScreenImpl::Send(const void* data, int32_t retWidth, int32_t retHeight) 2977c804472Sopenharmony_ci{ 2987c804472Sopenharmony_ci if (CommandParser::GetInstance().GetScreenMode() == CommandParser::ScreenMode::STATIC 2997c804472Sopenharmony_ci && VirtualScreen::isOutOfSeconds) { 3007c804472Sopenharmony_ci return; 3017c804472Sopenharmony_ci } 3027c804472Sopenharmony_ci 3037c804472Sopenharmony_ci if (retWidth < 1 || retHeight < 1) { 3047c804472Sopenharmony_ci FLOG("VirtualScreenImpl::RgbToJpg the retWidth or height is invalid value"); 3057c804472Sopenharmony_ci return; 3067c804472Sopenharmony_ci } 3077c804472Sopenharmony_ci unsigned char* dataTemp = new(std::nothrow) unsigned char[retWidth * retHeight * jpgPix]; 3087c804472Sopenharmony_ci if (!dataTemp) { 3097c804472Sopenharmony_ci ELOG("Memory allocation failed : dataTemp."); 3107c804472Sopenharmony_ci return; 3117c804472Sopenharmony_ci } 3127c804472Sopenharmony_ci for (int i = 0; i < retHeight; i++) { 3137c804472Sopenharmony_ci for (int j = 0; j < retWidth; j++) { 3147c804472Sopenharmony_ci int inputBasePos = i * retWidth * pixelSize + j * pixelSize; 3157c804472Sopenharmony_ci int nowBasePos = i * retWidth * jpgPix + j * jpgPix; 3167c804472Sopenharmony_ci dataTemp[nowBasePos + redPos] = *((char*)data + inputBasePos + redPos); 3177c804472Sopenharmony_ci dataTemp[nowBasePos + greenPos] = *((char*)data + inputBasePos + greenPos); 3187c804472Sopenharmony_ci dataTemp[nowBasePos + bluePos] = *((char*)data + inputBasePos + bluePos); 3197c804472Sopenharmony_ci } 3207c804472Sopenharmony_ci } 3217c804472Sopenharmony_ci VirtualScreen::RgbToJpg(dataTemp, retWidth, retHeight); 3227c804472Sopenharmony_ci delete [] dataTemp; 3237c804472Sopenharmony_ci if (jpgBufferSize > bufferSize - headSize) { 3247c804472Sopenharmony_ci FLOG("VirtualScreenImpl::Send length must < %d", bufferSize - headSize); 3257c804472Sopenharmony_ci return; 3267c804472Sopenharmony_ci } 3277c804472Sopenharmony_ci 3287c804472Sopenharmony_ci std::copy(jpgScreenBuffer, jpgScreenBuffer + jpgBufferSize, screenBuffer + headSize); 3297c804472Sopenharmony_ci writed = WebSocketServer::GetInstance().WriteData(screenBuffer, headSize + jpgBufferSize); 3307c804472Sopenharmony_ci std::lock_guard<std::mutex> guard(WebSocketServer::GetInstance().mutex); 3317c804472Sopenharmony_ci if (WebSocketServer::GetInstance().firstImageBuffer) { 3327c804472Sopenharmony_ci delete [] WebSocketServer::GetInstance().firstImageBuffer; 3337c804472Sopenharmony_ci WebSocketServer::GetInstance().firstImageBuffer = nullptr; 3347c804472Sopenharmony_ci } 3357c804472Sopenharmony_ci WebSocketServer::GetInstance().firstImageBuffer = new(std::nothrow) uint8_t[LWS_PRE + bufferSize]; 3367c804472Sopenharmony_ci if (!WebSocketServer::GetInstance().firstImageBuffer) { 3377c804472Sopenharmony_ci ELOG("Memory allocation failed : firstImageBuffer."); 3387c804472Sopenharmony_ci return; 3397c804472Sopenharmony_ci } 3407c804472Sopenharmony_ci WebSocketServer::GetInstance().firstImagebufferSize = headSize + jpgBufferSize; 3417c804472Sopenharmony_ci std::copy(screenBuffer, 3427c804472Sopenharmony_ci screenBuffer + headSize + jpgBufferSize, 3437c804472Sopenharmony_ci WebSocketServer::GetInstance().firstImageBuffer + LWS_PRE); 3447c804472Sopenharmony_ci 3457c804472Sopenharmony_ci FreeJpgMemory(); 3467c804472Sopenharmony_ci} 3477c804472Sopenharmony_ci 3487c804472Sopenharmony_cibool VirtualScreenImpl::SendPixmap(const void* data, size_t length, int32_t retWidth, int32_t retHeight) 3497c804472Sopenharmony_ci{ 3507c804472Sopenharmony_ci if (data == nullptr) { 3517c804472Sopenharmony_ci ELOG("render callback data is null."); 3527c804472Sopenharmony_ci invalidFrameCountPerMinute++; 3537c804472Sopenharmony_ci return false; 3547c804472Sopenharmony_ci } 3557c804472Sopenharmony_ci 3567c804472Sopenharmony_ci if (!isWebSocketConfiged) { 3577c804472Sopenharmony_ci ELOG("image socket is not ready"); 3587c804472Sopenharmony_ci return false; 3597c804472Sopenharmony_ci } 3607c804472Sopenharmony_ci 3617c804472Sopenharmony_ci if (isFirstRender) { 3627c804472Sopenharmony_ci ILOG("Get first render buffer"); 3637c804472Sopenharmony_ci TraceTool::GetInstance().HandleTrace("Get first render buffer"); 3647c804472Sopenharmony_ci isFirstRender = false; 3657c804472Sopenharmony_ci } 3667c804472Sopenharmony_ci 3677c804472Sopenharmony_ci isFrameUpdated = true; 3687c804472Sopenharmony_ci currentPos = 0; 3697c804472Sopenharmony_ci 3707c804472Sopenharmony_ci WriteBuffer(headStart); 3717c804472Sopenharmony_ci WriteBuffer(retWidth); 3727c804472Sopenharmony_ci WriteBuffer(retHeight); 3737c804472Sopenharmony_ci WriteBuffer(retWidth); 3747c804472Sopenharmony_ci WriteBuffer(retHeight); 3757c804472Sopenharmony_ci if (!CommandParser::GetInstance().IsRegionRefresh()) { 3767c804472Sopenharmony_ci for (size_t i = 0; i < headReservedSize / sizeof(int32_t); i++) { 3777c804472Sopenharmony_ci WriteBuffer(static_cast<uint32_t>(0)); 3787c804472Sopenharmony_ci } 3797c804472Sopenharmony_ci } else { 3807c804472Sopenharmony_ci uint16_t x1 = 0; 3817c804472Sopenharmony_ci uint16_t y1 = 0; 3827c804472Sopenharmony_ci uint16_t width = static_cast<uint16_t>(retWidth); 3837c804472Sopenharmony_ci uint16_t height = static_cast<uint16_t>(retHeight); 3847c804472Sopenharmony_ci WriteBuffer(protocolVersion); 3857c804472Sopenharmony_ci WriteBuffer(x1); 3867c804472Sopenharmony_ci WriteBuffer(y1); 3877c804472Sopenharmony_ci WriteBuffer(width); 3887c804472Sopenharmony_ci WriteBuffer(height); 3897c804472Sopenharmony_ci for (size_t i = 0; i < 10 / sizeof(uint16_t); i++) { // fill 10bytes for header 3907c804472Sopenharmony_ci WriteBuffer(static_cast<uint16_t>(0)); 3917c804472Sopenharmony_ci } 3927c804472Sopenharmony_ci } 3937c804472Sopenharmony_ci Send(data, retWidth, retHeight); 3947c804472Sopenharmony_ci if (isFirstSend) { 3957c804472Sopenharmony_ci ILOG("Send first buffer finish"); 3967c804472Sopenharmony_ci TraceTool::GetInstance().HandleTrace("Send first buffer finish"); 3977c804472Sopenharmony_ci isFirstSend = false; 3987c804472Sopenharmony_ci } 3997c804472Sopenharmony_ci 4007c804472Sopenharmony_ci validFrameCountPerMinute++; 4017c804472Sopenharmony_ci sendFrameCountPerMinute++; 4027c804472Sopenharmony_ci return writed == length; 4037c804472Sopenharmony_ci} 4047c804472Sopenharmony_ci 4057c804472Sopenharmony_civoid VirtualScreenImpl::FreeJpgMemory() 4067c804472Sopenharmony_ci{ 4077c804472Sopenharmony_ci if (wholeBuffer != nullptr) { 4087c804472Sopenharmony_ci delete [] wholeBuffer; 4097c804472Sopenharmony_ci wholeBuffer = nullptr; 4107c804472Sopenharmony_ci screenBuffer = nullptr; 4117c804472Sopenharmony_ci } 4127c804472Sopenharmony_ci if (jpgScreenBuffer != nullptr) { 4137c804472Sopenharmony_ci free(jpgScreenBuffer); 4147c804472Sopenharmony_ci jpgScreenBuffer = NULL; 4157c804472Sopenharmony_ci jpgBufferSize = 0; 4167c804472Sopenharmony_ci } 4177c804472Sopenharmony_ci if (loadDocCopyBuffer != nullptr) { 4187c804472Sopenharmony_ci delete [] loadDocCopyBuffer; 4197c804472Sopenharmony_ci loadDocCopyBuffer = nullptr; 4207c804472Sopenharmony_ci } 4217c804472Sopenharmony_ci if (loadDocTempBuffer != nullptr) { 4227c804472Sopenharmony_ci delete [] loadDocTempBuffer; 4237c804472Sopenharmony_ci loadDocTempBuffer = nullptr; 4247c804472Sopenharmony_ci } 4257c804472Sopenharmony_ci} 4267c804472Sopenharmony_ci 4277c804472Sopenharmony_ciScreenInfo VirtualScreenImpl::GetScreenInfo() 4287c804472Sopenharmony_ci{ 4297c804472Sopenharmony_ci ScreenInfo info; 4307c804472Sopenharmony_ci info.orignalResolutionWidth = GetOrignalWidth(); 4317c804472Sopenharmony_ci info.orignalResolutionHeight = GetOrignalHeight(); 4327c804472Sopenharmony_ci info.compressionResolutionWidth = GetCompressionWidth(); 4337c804472Sopenharmony_ci info.compressionResolutionHeight = GetCompressionHeight(); 4347c804472Sopenharmony_ci info.foldStatus = GetFoldStatus(); 4357c804472Sopenharmony_ci info.foldable = GetFoldable(); 4367c804472Sopenharmony_ci info.foldWidth = GetFoldWidth(); 4377c804472Sopenharmony_ci info.foldHeight = GetFoldHeight(); 4387c804472Sopenharmony_ci return info; 4397c804472Sopenharmony_ci} 4407c804472Sopenharmony_ci 4417c804472Sopenharmony_civoid VirtualScreenImpl::InitFoldParams() 4427c804472Sopenharmony_ci{ 4437c804472Sopenharmony_ci CommandParser& parser = CommandParser::GetInstance(); 4447c804472Sopenharmony_ci FoldInfo info; 4457c804472Sopenharmony_ci parser.GetFoldInfo(info); 4467c804472Sopenharmony_ci if (parser.IsSet("foldable")) { 4477c804472Sopenharmony_ci SetFoldable(info.foldable); 4487c804472Sopenharmony_ci } 4497c804472Sopenharmony_ci if (parser.IsSet("foldStatus")) { 4507c804472Sopenharmony_ci SetFoldStatus(info.foldStatus); 4517c804472Sopenharmony_ci } 4527c804472Sopenharmony_ci if (parser.IsSet("fr")) { 4537c804472Sopenharmony_ci SetFoldResolution(info.foldResolutionWidth, info.foldResolutionHeight); 4547c804472Sopenharmony_ci } 4557c804472Sopenharmony_ci}