From 27091dec0e66858b0d71dd2d86cf24ed09f30d79 Mon Sep 17 00:00:00 2001 From: 21pages Date: Tue, 7 Jun 2022 10:21:02 +0800 Subject: [PATCH] scrap: remove lock on hwDecoder Signed-off-by: 21pages --- libs/scrap/src/common/codec.rs | 18 +++++------ libs/scrap/src/common/hwcodec.rs | 54 +++++++++++++++----------------- 2 files changed, 34 insertions(+), 38 deletions(-) diff --git a/libs/scrap/src/common/codec.rs b/libs/scrap/src/common/codec.rs index 1be47dc12..e6c925b28 100644 --- a/libs/scrap/src/common/codec.rs +++ b/libs/scrap/src/common/codec.rs @@ -75,7 +75,7 @@ impl DerefMut for Encoder { pub struct Decoder { vpx: VpxDecoder, #[cfg(feature = "hwcodec")] - hw: Arc>, + hw: HwDecoders, #[cfg(feature = "hwcodec")] i420: Vec, } @@ -191,11 +191,11 @@ impl Decoder { #[cfg(feature = "hwcodec")] { - let hw = HwDecoder::instance(); - state.H264 = hw.lock().unwrap().h264.is_some(); - state.ScoreH264 = hw.lock().unwrap().h264.as_ref().map_or(0, |d| d.info.score); - state.H265 = hw.lock().unwrap().h265.is_some(); - state.ScoreH265 = hw.lock().unwrap().h265.as_ref().map_or(0, |d| d.info.score); + let (h264, h265) = super::hwcodec::HwDecoder::best(); + state.H264 = h264.is_some(); + state.ScoreH264 = h264.map_or(0, |c| c.score); + state.H265 = h265.is_some(); + state.ScoreH265 = h265.map_or(0, |c| c.score); } state @@ -206,7 +206,7 @@ impl Decoder { Decoder { vpx, #[cfg(feature = "hwcodec")] - hw: HwDecoder::instance(), + hw: HwDecoder::new_decoders(), #[cfg(feature = "hwcodec")] i420: vec![], } @@ -223,7 +223,7 @@ impl Decoder { } #[cfg(feature = "hwcodec")] video_frame::Union::h264s(h264s) => { - if let Some(decoder) = &mut self.hw.lock().unwrap().h264 { + if let Some(decoder) = &mut self.hw.h264 { Decoder::handle_h264s_video_frame(decoder, h264s, rgb, &mut self.i420) } else { Err(anyhow!("don't support h264!")) @@ -231,7 +231,7 @@ impl Decoder { } #[cfg(feature = "hwcodec")] video_frame::Union::h265s(h265s) => { - if let Some(decoder) = &mut self.hw.lock().unwrap().h265 { + if let Some(decoder) = &mut self.hw.h265 { Decoder::handle_h265s_video_frame(decoder, h265s, rgb, &mut self.i420) } else { Err(anyhow!("don't support h265!")) diff --git a/libs/scrap/src/common/hwcodec.rs b/libs/scrap/src/common/hwcodec.rs index 6393be3eb..95dcd0353 100644 --- a/libs/scrap/src/common/hwcodec.rs +++ b/libs/scrap/src/common/hwcodec.rs @@ -16,14 +16,10 @@ use hwcodec::{ Quality::{self, *}, RateContorl::{self, *}, }; -use std::sync::{Arc, Mutex, Once}; +use std::sync::{Arc, Mutex}; lazy_static::lazy_static! { static ref HW_ENCODER_NAME: Arc>> = Default::default(); - static ref HW_DECODER_INSTANCE: Arc> = Arc::new(Mutex::new(HwDecoderInstance { - h264: None, - h265: None, - })); } const DEFAULT_PIXFMT: AVPixelFormat = AVPixelFormat::AV_PIX_FMT_YUV420P; @@ -220,36 +216,36 @@ pub struct HwDecoder { pub info: CodecInfo, } -pub struct HwDecoderInstance { +pub struct HwDecoders { pub h264: Option, pub h265: Option, } impl HwDecoder { - pub fn instance() -> Arc> { - static ONCE: Once = Once::new(); - // TODO: different process - ONCE.call_once(|| { - let (h264_info, h265_info) = CodecInfo::score(Decoder::avaliable_decoders()); - let mut h264: Option = None; - let mut h265: Option = None; + /// H264, H265 decoder info with the highest score. + /// Because available_decoders is singleton, it returns same result in the same process. + pub fn best() -> (Option, Option) { + CodecInfo::score(Decoder::avaliable_decoders()) + } - if let Some(info) = h264_info { - h264 = HwDecoder::new(info).ok(); - } - if let Some(info) = h265_info { - h265 = HwDecoder::new(info).ok(); - } - if h264.is_some() { - log::info!("h264 decoder:{:?}", h264.as_ref().unwrap().info); - } - if h265.is_some() { - log::info!("h265 decoder:{:?}", h265.as_ref().unwrap().info); - } - HW_DECODER_INSTANCE.lock().unwrap().h264 = h264; - HW_DECODER_INSTANCE.lock().unwrap().h265 = h265; - }); - HW_DECODER_INSTANCE.clone() + pub fn new_decoders() -> HwDecoders { + let (h264_info, h265_info) = HwDecoder::best(); + let mut h264: Option = None; + let mut h265: Option = None; + + if let Some(info) = h264_info { + h264 = HwDecoder::new(info).ok(); + } + if let Some(info) = h265_info { + h265 = HwDecoder::new(info).ok(); + } + if h264.is_some() { + log::info!("h264 decoder:{:?}", h264.as_ref().unwrap().info); + } + if h265.is_some() { + log::info!("h265 decoder:{:?}", h265.as_ref().unwrap().info); + } + HwDecoders { h264, h265 } } pub fn new(info: CodecInfo) -> ResultType {