From c5426b0fbc60dbca90c68d0e32090ca49055e6ab Mon Sep 17 00:00:00 2001 From: 21pages Date: Mon, 18 Nov 2024 23:03:27 +0800 Subject: [PATCH] Fix hevc decode error "Could not find ref with POC" (#9960) 1. Dropping frames can cause this error, reset encoder when this happens. 2. There are some logic error for clear video queue, because video queue message is not cleared. This need to be fixed. Signed-off-by: 21pages --- Cargo.lock | 4 ++-- libs/scrap/src/common/hwcodec.rs | 3 ++- src/client.rs | 18 ++++++++++++++++++ src/client/io_loop.rs | 8 ++++++-- 4 files changed, 28 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5930b8721..b8a427f72 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1683,7 +1683,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" dependencies = [ - "libloading 0.8.4", + "libloading 0.7.4", ] [[package]] @@ -3051,7 +3051,7 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hwcodec" version = "0.7.0" -source = "git+https://github.com/rustdesk-org/hwcodec#8bbd05bb300ad07cc345356ad85570f9ea99fbfa" +source = "git+https://github.com/rustdesk-org/hwcodec#da7dab48df19edb5a7138ff9e01bf9f148b523da" dependencies = [ "bindgen 0.59.2", "cc", diff --git a/libs/scrap/src/common/hwcodec.rs b/libs/scrap/src/common/hwcodec.rs index a0e730c91..2a83afacc 100644 --- a/libs/scrap/src/common/hwcodec.rs +++ b/libs/scrap/src/common/hwcodec.rs @@ -15,7 +15,7 @@ use hbb_common::{ }; use hwcodec::{ common::{ - DataFormat, + DataFormat, HwcodecErrno, Quality::{self, *}, RateControl::{self, *}, }, @@ -31,6 +31,7 @@ const DEFAULT_PIXFMT: AVPixelFormat = AVPixelFormat::AV_PIX_FMT_NV12; pub const DEFAULT_FPS: i32 = 30; const DEFAULT_GOP: i32 = i32::MAX; const DEFAULT_HW_QUALITY: Quality = Quality_Default; +pub const ERR_HEVC_POC: i32 = HwcodecErrno::HWCODEC_ERR_HEVC_COULD_NOT_FIND_POC as i32; crate::generate_call_macro!(call_yuv, false); diff --git a/src/client.rs b/src/client.rs index c36063530..18c3d268b 100644 --- a/src/client.rs +++ b/src/client.rs @@ -2417,6 +2417,24 @@ where // to-do: fix the error log::error!("handle video frame error, {}", e); session.refresh_video(display as _); + #[cfg(feature = "hwcodec")] + if format == CodecFormat::H265 { + if let Some(&scrap::hwcodec::ERR_HEVC_POC) = + e.downcast_ref::() + { + for (i, handler_controler) in + handler_controller_map.iter_mut() + { + if *i != display + && handler_controler.handler.decoder.format() + == CodecFormat::H265 + { + log::info!("refresh video {} due to hevc poc not found", i); + session.refresh_video(*i as _); + } + } + } + } } _ => {} } diff --git a/src/client/io_loop.rs b/src/client/io_loop.rs index 9aec89dd3..0766b6b51 100644 --- a/src/client/io_loop.rs +++ b/src/client/io_loop.rs @@ -1146,9 +1146,13 @@ impl Remote { .ok(); } else { if let Some(video_queue) = video_queue_write.get_mut(&display) { - video_queue.force_push(vf); + if video_queue.force_push(vf).is_some() { + while let Some(_) = video_queue.pop() {} + self.handler.refresh_video(display as _); + } else { + self.video_sender.send(MediaData::VideoQueue(display)).ok(); + } } - self.video_sender.send(MediaData::VideoQueue(display)).ok(); } self.fps_control .last_active_time