fix: 启动黑屏 - 静止桌面响应KeyFrameReq + 首帧强制IDR + 入会主动请求关键帧

This commit is contained in:
dev-team 2026-10-23 13:12:27 +08:00
parent 68b2ddc59a
commit 04c02d9ced
2 changed files with 9 additions and 4 deletions

View File

@ -236,7 +236,8 @@ impl NvencEncoder {
/// 编码当前 GPU 纹理内容,返回 Annex B H.264 码流。
fn encode(&mut self, force_idr: bool, ts_ms: u64) -> Result<Vec<u8>> {
let ty = if force_idr {
// 首帧强制 IDR:解码端从任意时刻接入,没有 IDR 无法解出后续 P 帧
let ty = if force_idr || self.frame_count == 0 {
NVencPicType::IDR
} else {
NVencPicType::P
@ -441,12 +442,14 @@ pub fn run(tx: Sender<Option<Vec<u8>>>, keyreq: Arc<AtomicBool>, congestion: Arc
}
Ok(false) => {
// 桌面静止:低频重发(丢包后恢复 + 会话保活)。
// NVENC 重编当前 GPU 帧(输出极小 P 帧);软编重发最后一帧副本。
// 关键:KeyFrameReq 在桌面静止时也必须响应 —— 此前只在新帧路径
// 消费该标志,桌面完全静止时解码端请求 IDR 永远得不到响应 → 黑屏。
let force_key = keyreq.swap(false, Ordering::Relaxed);
if last_sent.elapsed() > Duration::from_millis(500) {
match &mut encoder {
EncoderKind::Nvenc(enc) => {
// 重编当前 GPU 帧(内容未变,输出极小 P 帧)
let r = enc.encode(false, start.elapsed().as_millis() as u64);
// 重编当前 GPU 帧(内容未变,输出极小;force_key 时为 IDR)
let r = enc.encode(force_key, start.elapsed().as_millis() as u64);
match r {
Ok(payload) => emit!(payload),
Err(e) => {

View File

@ -360,6 +360,8 @@ fn session(
let push = |tx: &tokio::sync::mpsc::UnboundedSender<Vec<u8>>, m: ControlMsg| {
let _ = tx.send(common::encode_control(&m));
};
// 入会立即请求 IDR:避免从 GOP 中间接入收到裸 P 帧解码失败导致启动黑屏
push(&msg_tx, ControlMsg::KeyFrameReq);
let mut window = Window::new(
"mvp-remote v0.7-LowLatency (Esc 退出)",