Compare commits
2 Commits
2765d95950
...
91d4c0a523
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
91d4c0a523 | ||
|
|
abafd673a2 |
@@ -153,7 +153,7 @@ CScreenManager::CScreenManager(IOCPClient* ClientObject, int n, void* user, BOOL
|
|||||||
m_ScreenSettings.FullScreen = cfg.GetInt("settings", "FullScreen", priv);
|
m_ScreenSettings.FullScreen = cfg.GetInt("settings", "FullScreen", priv);
|
||||||
m_ScreenSettings.RemoteCursor = cfg.GetInt("settings", "RemoteCursor", 0);
|
m_ScreenSettings.RemoteCursor = cfg.GetInt("settings", "RemoteCursor", 0);
|
||||||
m_ScreenSettings.ScrollDetectInterval = cfg.GetInt("settings", "ScrollDetectInterval", 2); // 默认每2帧
|
m_ScreenSettings.ScrollDetectInterval = cfg.GetInt("settings", "ScrollDetectInterval", 2); // 默认每2帧
|
||||||
m_ScreenSettings.QualityLevel = cfg.GetInt("settings", "QualityLevel", quality);
|
m_ScreenSettings.QualityLevel = quality;
|
||||||
m_ScreenSettings.CpuSpeedup = cfg.GetInt("settings", "CpuSpeedup", 0);
|
m_ScreenSettings.CpuSpeedup = cfg.GetInt("settings", "CpuSpeedup", 0);
|
||||||
m_ScreenSettings.AudioEnabled = cfg.GetInt("settings", "AudioEnabled", 0); // 默认禁用音频
|
m_ScreenSettings.AudioEnabled = cfg.GetInt("settings", "AudioEnabled", 0); // 默认禁用音频
|
||||||
m_ScreenSettings.EncodeLevel = cfg.GetInt("settings", "EncodeLevel", LEVEL_H264_SOFT);
|
m_ScreenSettings.EncodeLevel = cfg.GetInt("settings", "EncodeLevel", LEVEL_H264_SOFT);
|
||||||
@@ -556,6 +556,10 @@ void CScreenManager::InitScreenSpy()
|
|||||||
m_isGDI = TRUE;
|
m_isGDI = TRUE;
|
||||||
m_ScreenSpyObject = new CScreenSpy(32, algo, DXGI == USING_VIRTUAL, DEFAULT_GOP, all, m_ScreenSettings.EncodeLevel, rect, switchScreen, m_hTargetWnd, m_bDynamicForeground);
|
m_ScreenSpyObject = new CScreenSpy(32, algo, DXGI == USING_VIRTUAL, DEFAULT_GOP, all, m_ScreenSettings.EncodeLevel, rect, switchScreen, m_hTargetWnd, m_bDynamicForeground);
|
||||||
}
|
}
|
||||||
|
// 用已保存的质量配置初始化码率,避免 CMD_QUALITY_LEVEL 到达时 0→3000 触发不必要重启
|
||||||
|
if (m_ScreenSpyObject && level >= 0 && level < QUALITY_COUNT) {
|
||||||
|
m_ScreenSpyObject->SetBitRate(m_QualityProfiles[level].bitRate);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL IsRunningAsSystem()
|
BOOL IsRunningAsSystem()
|
||||||
|
|||||||
@@ -145,10 +145,19 @@ CScreenSpy::~CScreenSpy()
|
|||||||
|
|
||||||
LPBYTE CScreenSpy::GetFirstScreenData(ULONG* ulFirstScreenLength)
|
LPBYTE CScreenSpy::GetFirstScreenData(ULONG* ulFirstScreenLength)
|
||||||
{
|
{
|
||||||
|
if (m_hTargetWnd && IsIconic(m_hTargetWnd)) {
|
||||||
|
*ulFirstScreenLength = 0;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
ScanScreen(m_hFullMemDC, m_hDeskTopDC, m_ulFullWidth, m_ulFullHeight);
|
ScanScreen(m_hFullMemDC, m_hDeskTopDC, m_ulFullWidth, m_ulFullHeight);
|
||||||
m_RectBuffer[0] = TOKEN_FIRSTSCREEN;
|
m_RectBuffer[0] = TOKEN_FIRSTSCREEN;
|
||||||
LPBYTE bmp = scaleBitmap(m_BmpZoomBuffer, (LPBYTE)m_BitmapData_Full);
|
LPBYTE bmp = scaleBitmap(m_BmpZoomBuffer, (LPBYTE)m_BitmapData_Full);
|
||||||
memcpy(m_FirstBuffer, bmp, m_BitmapInfor_Send->bmiHeader.biSizeImage);
|
memcpy(m_FirstBuffer, bmp, m_BitmapInfor_Send->bmiHeader.biSizeImage);
|
||||||
|
// H264/AV1:不发原始位图,IDR 到达后服务端自行解锁;节省每次切窗口的流量峰值
|
||||||
|
if (m_bAlgorithm == ALGORITHM_H264) {
|
||||||
|
*ulFirstScreenLength = 0;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
memcpy(1 + m_RectBuffer, bmp, m_BitmapInfor_Send->bmiHeader.biSizeImage);
|
memcpy(1 + m_RectBuffer, bmp, m_BitmapInfor_Send->bmiHeader.biSizeImage);
|
||||||
if (m_bAlgorithm == ALGORITHM_GRAY) {
|
if (m_bAlgorithm == ALGORITHM_GRAY) {
|
||||||
ToGray(1 + m_RectBuffer, 1 + m_RectBuffer, m_BitmapInfor_Send->bmiHeader.biSizeImage);
|
ToGray(1 + m_RectBuffer, 1 + m_RectBuffer, m_BitmapInfor_Send->bmiHeader.biSizeImage);
|
||||||
|
|||||||
@@ -856,11 +856,12 @@ BOOL CScreenSpyDlg::OnInitDialog()
|
|||||||
BYTE cmd[4] = { CMD_QUALITY_LEVEL, (BYTE)m_AdaptiveQuality.currentLevel, 0 };
|
BYTE cmd[4] = { CMD_QUALITY_LEVEL, (BYTE)m_AdaptiveQuality.currentLevel, 0 };
|
||||||
m_ContextObject->Send2Client(cmd, sizeof(cmd));
|
m_ContextObject->Send2Client(cmd, sizeof(cmd));
|
||||||
|
|
||||||
// 始终发送 CMD_SCREEN_SIZE,让客户端同步分辨率策略
|
// 仅在自适应模式且有缓存宽度时同步分辨率,固定等级分辨率由 profile 决定无需重发
|
||||||
// maxWidth=0 表示使用默认分辨率(1080p 限制)
|
if (m_Settings.QualityLevel == QUALITY_ADAPTIVE && m_AdaptiveQuality.currentMaxWidth > 0) {
|
||||||
BYTE sizeCmd[16] = { CMD_SCREEN_SIZE, 2 }; // strategy=2 表示自适应质量
|
BYTE sizeCmd[16] = { CMD_SCREEN_SIZE, 2 }; // strategy=2 = 自适应质量
|
||||||
memcpy(sizeCmd + 2, &m_AdaptiveQuality.currentMaxWidth, sizeof(int));
|
memcpy(sizeCmd + 2, &m_AdaptiveQuality.currentMaxWidth, sizeof(int));
|
||||||
m_ContextObject->Send2Client(sizeCmd, 10);
|
m_ContextObject->Send2Client(sizeCmd, 10);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SendNext();
|
SendNext();
|
||||||
@@ -1478,6 +1479,11 @@ VOID CScreenSpyDlg::DrawNextScreenDiff(bool keyFrame)
|
|||||||
if (!m_bHide) {
|
if (!m_bHide) {
|
||||||
if (Decode((LPBYTE)NextScreenData, NextScreenLength)) {
|
if (Decode((LPBYTE)NextScreenData, NextScreenLength)) {
|
||||||
bChange = TRUE;
|
bChange = TRUE;
|
||||||
|
// 解码成功即代表 IDR 参考帧已建立(编码器首帧强制 IDR),解除门控。
|
||||||
|
// 不依赖 IsAnyKeyframe:某些硬编输出格式或解码器首帧 EAGAIN 延迟会导致
|
||||||
|
// 关键帧检测误判,进而让 m_bIsFirst 永久为 TRUE("请等待"卡死)。
|
||||||
|
if (m_bIsFirst)
|
||||||
|
m_bIsFirst = FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Broadcast video frame to web clients (only for Web session dialogs)
|
// Broadcast video frame to web clients (only for Web session dialogs)
|
||||||
|
|||||||
Reference in New Issue
Block a user