* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "VirtualScreen.h"
#include "CommandParser.h"
#include "CppTimerManager.h"
#include "PreviewerEngineLog.h"
#include "VirtualScreen.h"
#define boolean jpegboolean
#include "jpeglib.h"
#undef boolean
uint32_t VirtualScreen::validFrameCountPerMinute = 0;
uint32_t VirtualScreen::invalidFrameCountPerMinute = 0;
uint32_t VirtualScreen::sendFrameCountPerMinute = 0;
uint32_t VirtualScreen::inputKeyCountPerMinute = 0;
uint32_t VirtualScreen::inputMethodCountPerMinute = 0;
bool VirtualScreen::isWebSocketListening = false;
std::string VirtualScreen::webSocketPort = "";
std::chrono::system_clock::time_point VirtualScreen::startTime = std::chrono::system_clock::now();
std::chrono::system_clock::time_point VirtualScreen::staticCardStartTime = std::chrono::system_clock::now();
bool VirtualScreen::isStartCount = true;
bool VirtualScreen::isOutOfSeconds = false;
VirtualScreen::VirtualScreen()
: isFrameUpdated(false),
orignalResolutionWidth(0),
orignalResolutionHeight(0),
compressionResolutionWidth(0),
compressionResolutionHeight(0),
screenSocket(nullptr),
frameCountTimer(nullptr),
isWebSocketConfiged(false),
currentRouter(""),
jpgScreenBuffer(nullptr),
jpgBufferSize(0)
{
}
VirtualScreen::~VirtualScreen()
{
if (screenSocket != nullptr) {
screenSocket->DisconnectFromServer();
delete screenSocket;
screenSocket = nullptr;
}
}
std::string VirtualScreen::GetCurrentRouter() const
{
return currentRouter;
}
void VirtualScreen::SetCurrentRouter(const std::string currentRouterValue)
{
currentRouter = currentRouterValue;
}
std::string VirtualScreen::GetAbilityCurrentRouter() const
{
return abilityCurrentRouter;
}
void VirtualScreen::SetAbilityCurrentRouter(const std::string currentRouterValue)
{
abilityCurrentRouter = currentRouterValue;
}
int32_t VirtualScreen::GetOrignalWidth() const
{
return orignalResolutionWidth;
}
void VirtualScreen::SetOrignalWidth(const int32_t& value)
{
orignalResolutionWidth = value;
}
int32_t VirtualScreen::GetOrignalHeight() const
{
return orignalResolutionHeight;
}
void VirtualScreen::SetOrignalHeight(const int32_t& value)
{
orignalResolutionHeight = value;
}
int32_t VirtualScreen::GetCompressionWidth() const
{
return compressionResolutionWidth;
}
void VirtualScreen::SetCompressionWidth(const int32_t& value)
{
compressionResolutionWidth = value;
}
int32_t VirtualScreen::GetCompressionHeight() const
{
return compressionResolutionHeight;
}
void VirtualScreen::SetCompressionHeight(const int32_t& value)
{
compressionResolutionHeight = value;
}
void VirtualScreen::InitPipe(std::string pipeName, std::string pipePort)
{
webSocketPort = pipePort;
isWebSocketConfiged = true;
WebSocketServer::GetInstance().SetServerPort(atoi(pipePort.c_str()));
WebSocketServer::GetInstance().SetSid(CommandParser::GetInstance().GetSid());
WebSocketServer::GetInstance().Run();
isWebSocketListening = true;
}
void VirtualScreen::InitVirtualScreen()
{
int32_t orignalWidth = CommandParser::GetInstance().GetOrignalResolutionWidth();
int32_t orignalHeight = CommandParser::GetInstance().GetOrignalResolutionHeight();
int32_t compressionWidth = CommandParser::GetInstance().GetCompressionResolutionWidth();
int32_t compressionHeight = CommandParser::GetInstance().GetCompressionResolutionHeight();
SetVirtualScreenWidthAndHeight(orignalWidth, orignalHeight, compressionWidth, compressionHeight);
}
void VirtualScreen::SetVirtualScreenWidthAndHeight(const int32_t& orignalWidth,
const int32_t& orignalHeight,
const int32_t& compressionWidth,
const int32_t& compressionHeight)
{
VirtualScreen::SetOrignalWidth(orignalWidth);
VirtualScreen::SetOrignalHeight(orignalHeight);
VirtualScreen::SetCompressionWidth(compressionWidth);
VirtualScreen::SetCompressionHeight(compressionHeight);
}
void VirtualScreen::WidthAndHeightReverse()
{
int32_t temp = 0;
temp = orignalResolutionHeight;
orignalResolutionHeight = orignalResolutionWidth;
orignalResolutionWidth = temp;
temp = compressionResolutionHeight;
compressionResolutionHeight = compressionResolutionWidth;
compressionResolutionWidth = temp;
}
void VirtualScreen::InitFrameCountTimer()
{
if (frameCountTimer.get() != nullptr) {
ILOG("VirtualScreen::InitFrameCountTimer timer is already started.");
return;
}
frameCountTimer = std::make_unique<CppTimer>(VirtualScreen::PrintFrameCount);
if (frameCountTimer == nullptr) {
ELOG("JsApp::InitTimer taskHandleTimer memory allocation failed.");
return;
}
CppTimerManager::GetTimerManager().AddCppTimer(*frameCountTimer);
frameCountTimer->Start(frameCountPeriod);
}
void VirtualScreen::PrintFrameCount()
{
if ((validFrameCountPerMinute | invalidFrameCountPerMinute | sendFrameCountPerMinute |
inputKeyCountPerMinute | inputMethodCountPerMinute) == 0) {
return;
}
ELOG("ValidFrameCount: %d InvalidFrameCount: %d SendFrameCount: %d inputKeyCount: %d\
inputMethodCount: %d", validFrameCountPerMinute, invalidFrameCountPerMinute,
sendFrameCountPerMinute, inputKeyCountPerMinute, inputMethodCountPerMinute);
validFrameCountPerMinute = 0;
invalidFrameCountPerMinute = 0;
sendFrameCountPerMinute = 0;
inputKeyCountPerMinute = 0;
inputMethodCountPerMinute = 0;
}
void VirtualScreen::SetLoadDocFlag(VirtualScreen::LoadDocType flag)
{
startLoadDoc = flag;
}
VirtualScreen::LoadDocType VirtualScreen::GetLoadDocFlag() const
{
return startLoadDoc;
}
int VirtualScreen::GetJpgQualityValue(int32_t width, int32_t height) const
{
long long pixCount = static_cast<long long>(width) * static_cast<long long>(height);
if (pixCount <= static_cast<int>(JpgPixCountLevel::LOWCOUNT)) {
return static_cast<int>(JpgQualityLevel::HIGHLEVEL);
} else if (pixCount > static_cast<int>(JpgPixCountLevel::LOWCOUNT) &&
pixCount <= static_cast<int>(JpgPixCountLevel::MIDDLECOUNT)) {
return static_cast<int>(JpgQualityLevel::MIDDLELEVEL);
} else if (pixCount > static_cast<int>(JpgPixCountLevel::MIDDLECOUNT) &&
pixCount <= static_cast<int>(JpgPixCountLevel::HIGHCOUNT)) {
return static_cast<int>(JpgQualityLevel::LOWLEVEL);
} else {
return static_cast<int>(JpgQualityLevel::DEFAULTLEVEL);
}
}
std::string VirtualScreen::GetFastPreviewMsg() const
{
return fastPreviewMsg;
}
void VirtualScreen::SetFastPreviewMsg(const std::string msg)
{
fastPreviewMsg = msg;
}
void VirtualScreen::SetDropFrameFrequency(const int32_t& value)
{
dropFrameFrequency = value;
startDropFrameTime = std::chrono::system_clock::now();
}
bool VirtualScreen::JudgeAndDropFrame()
{
if (dropFrameFrequency <= 0) {
return false;
}
auto endTime = std::chrono::system_clock::now();
int64_t timePassed = std::chrono::duration_cast<std::chrono::milliseconds>(endTime -
startDropFrameTime).count();
if (timePassed >= dropFrameFrequency) {
startDropFrameTime = std::chrono::system_clock::now();
}
return timePassed < dropFrameFrequency;
}
bool VirtualScreen::JudgeStaticImage(const int duration)
{
if (CommandParser::GetInstance().GetScreenMode() == CommandParser::ScreenMode::STATIC) {
if (VirtualScreen::isOutOfSeconds) {
return false;
}
if (VirtualScreen::isStartCount) {
VirtualScreen::isStartCount = false;
VirtualScreen::startTime = std::chrono::system_clock::now();
}
auto endTime = std::chrono::system_clock::now();
int64_t timePassed = std::chrono::duration_cast<std::chrono::milliseconds>(endTime -
VirtualScreen::startTime).count();
if (timePassed > duration) {
VirtualScreen::isOutOfSeconds = true;
return false;
}
}
return true;
}
bool VirtualScreen::StopSendStaticCardImage(const int duration)
{
if (CommandParser::GetInstance().IsStaticCard()) {
static bool first = true;
if (first) {
first = false;
VirtualScreen::staticCardStartTime = std::chrono::system_clock::now();
}
auto endTime = std::chrono::system_clock::now();
int64_t timePassed = std::chrono::duration_cast<std::chrono::milliseconds>(endTime -
VirtualScreen::staticCardStartTime).count();
if (timePassed > duration) {
return true;
}
}
return false;
}
void VirtualScreen::RgbToJpg(unsigned char* data, const int32_t width, const int32_t height)
{
if (width < 1 || height < 1) {
FLOG("VirtualScreenImpl::RgbToJpg the width or height is invalid value");
}
jpeg_compress_struct jpeg = {0};
jpeg_error_mgr jerr;
jpeg.err = jpeg_std_error(&jerr);
jpeg_create_compress(&jpeg);
jpeg_mem_dest(&jpeg, &jpgScreenBuffer, &jpgBufferSize);
jpeg.image_width = width;
jpeg.image_height = height;
jpeg.input_components = jpgPix;
jpeg.in_color_space = JCS_RGB;
jpeg_set_defaults(&jpeg);
jpeg_set_quality(&jpeg, GetJpgQualityValue(width, height), TRUE);
jpeg_start_compress(&jpeg, TRUE);
JSAMPROW rowPointer[1];
int rowStride = width * jpgPix;
while (jpeg.next_scanline < jpeg.image_height) {
rowPointer[0] = &data[jpeg.next_scanline * rowStride];
jpeg_write_scanlines(&jpeg, rowPointer, 1);
}
jpeg_finish_compress(&jpeg);
jpeg_destroy_compress(&jpeg);
}
void VirtualScreen::SetFoldable(const bool value)
{
foldable = value;
}
bool VirtualScreen::GetFoldable() const
{
return foldable;
}
void VirtualScreen::SetFoldStatus(const std::string& value)
{
foldStatus = value;
}
std::string VirtualScreen::GetFoldStatus() const
{
return foldStatus;
}
void VirtualScreen::SetFoldResolution(int32_t changedFoldWidth, int32_t changedFoldHeight)
{
foldWidth = changedFoldWidth;
foldHeight = changedFoldHeight;
}
int32_t VirtualScreen::GetFoldWidth() const
{
return foldWidth;
}
int32_t VirtualScreen::GetFoldHeight() const
{
return foldHeight;
}
void VirtualScreen::SetCurrentResolution(int32_t width, int32_t height)
{
currentWidth = width;
currentHeight = height;
}
int32_t VirtualScreen::GetCurrentWidth() const
{
return currentWidth;
}
int32_t VirtualScreen::GetCurrentHeight() const
{
return currentHeight;
}
void VirtualScreen::InitFlushEmptyTime() {}
void VirtualScreen::InitResolution()
{
CommandInfo commandInfo;
CommandParser::GetInstance().GetCommandInfo(commandInfo);
SetOrignalWidth(commandInfo.orignalResolutionWidth);
SetOrignalHeight(commandInfo.orignalResolutionHeight);
SetCompressionWidth(commandInfo.compressionResolutionWidth);
SetCompressionHeight(commandInfo.compressionResolutionHeight);
SetCurrentResolution(commandInfo.orignalResolutionWidth, commandInfo.orignalResolutionHeight);
}