From fcd3b13ca81cfeb10bb209198e14cc8a48d2b895 Mon Sep 17 00:00:00 2001 From: yuanyuanxiang <962914132@qq.com> Date: Wed, 3 Jun 2026 18:53:14 +0200 Subject: [PATCH] Fix: skip detection black-screen on single-monitor capture --- client/ScreenCapture.h | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/client/ScreenCapture.h b/client/ScreenCapture.h index 4ec2471..969d27a 100644 --- a/client/ScreenCapture.h +++ b/client/ScreenCapture.h @@ -150,6 +150,12 @@ public: int m_GOP; // 关键帧间隔 bool m_SendKeyFrame; // 发送关键帧 std::unique_ptr 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,仅发 cursor;x264 走这里也省 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);