scrap: remove lock on hwDecoder

Signed-off-by: 21pages <pages21@163.com>
This commit is contained in:
21pages 2022-06-07 10:21:02 +08:00
parent 91012b5da5
commit 27091dec0e
2 changed files with 34 additions and 38 deletions

View File

@ -75,7 +75,7 @@ impl DerefMut for Encoder {
pub struct Decoder { pub struct Decoder {
vpx: VpxDecoder, vpx: VpxDecoder,
#[cfg(feature = "hwcodec")] #[cfg(feature = "hwcodec")]
hw: Arc<Mutex<HwDecoderInstance>>, hw: HwDecoders,
#[cfg(feature = "hwcodec")] #[cfg(feature = "hwcodec")]
i420: Vec<u8>, i420: Vec<u8>,
} }
@ -191,11 +191,11 @@ impl Decoder {
#[cfg(feature = "hwcodec")] #[cfg(feature = "hwcodec")]
{ {
let hw = HwDecoder::instance(); let (h264, h265) = super::hwcodec::HwDecoder::best();
state.H264 = hw.lock().unwrap().h264.is_some(); state.H264 = h264.is_some();
state.ScoreH264 = hw.lock().unwrap().h264.as_ref().map_or(0, |d| d.info.score); state.ScoreH264 = h264.map_or(0, |c| c.score);
state.H265 = hw.lock().unwrap().h265.is_some(); state.H265 = h265.is_some();
state.ScoreH265 = hw.lock().unwrap().h265.as_ref().map_or(0, |d| d.info.score); state.ScoreH265 = h265.map_or(0, |c| c.score);
} }
state state
@ -206,7 +206,7 @@ impl Decoder {
Decoder { Decoder {
vpx, vpx,
#[cfg(feature = "hwcodec")] #[cfg(feature = "hwcodec")]
hw: HwDecoder::instance(), hw: HwDecoder::new_decoders(),
#[cfg(feature = "hwcodec")] #[cfg(feature = "hwcodec")]
i420: vec![], i420: vec![],
} }
@ -223,7 +223,7 @@ impl Decoder {
} }
#[cfg(feature = "hwcodec")] #[cfg(feature = "hwcodec")]
video_frame::Union::h264s(h264s) => { 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) Decoder::handle_h264s_video_frame(decoder, h264s, rgb, &mut self.i420)
} else { } else {
Err(anyhow!("don't support h264!")) Err(anyhow!("don't support h264!"))
@ -231,7 +231,7 @@ impl Decoder {
} }
#[cfg(feature = "hwcodec")] #[cfg(feature = "hwcodec")]
video_frame::Union::h265s(h265s) => { 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) Decoder::handle_h265s_video_frame(decoder, h265s, rgb, &mut self.i420)
} else { } else {
Err(anyhow!("don't support h265!")) Err(anyhow!("don't support h265!"))

View File

@ -16,14 +16,10 @@ use hwcodec::{
Quality::{self, *}, Quality::{self, *},
RateContorl::{self, *}, RateContorl::{self, *},
}; };
use std::sync::{Arc, Mutex, Once}; use std::sync::{Arc, Mutex};
lazy_static::lazy_static! { lazy_static::lazy_static! {
static ref HW_ENCODER_NAME: Arc<Mutex<Option<String>>> = Default::default(); static ref HW_ENCODER_NAME: Arc<Mutex<Option<String>>> = Default::default();
static ref HW_DECODER_INSTANCE: Arc<Mutex<HwDecoderInstance>> = Arc::new(Mutex::new(HwDecoderInstance {
h264: None,
h265: None,
}));
} }
const DEFAULT_PIXFMT: AVPixelFormat = AVPixelFormat::AV_PIX_FMT_YUV420P; const DEFAULT_PIXFMT: AVPixelFormat = AVPixelFormat::AV_PIX_FMT_YUV420P;
@ -220,36 +216,36 @@ pub struct HwDecoder {
pub info: CodecInfo, pub info: CodecInfo,
} }
pub struct HwDecoderInstance { pub struct HwDecoders {
pub h264: Option<HwDecoder>, pub h264: Option<HwDecoder>,
pub h265: Option<HwDecoder>, pub h265: Option<HwDecoder>,
} }
impl HwDecoder { impl HwDecoder {
pub fn instance() -> Arc<Mutex<HwDecoderInstance>> { /// H264, H265 decoder info with the highest score.
static ONCE: Once = Once::new(); /// Because available_decoders is singleton, it returns same result in the same process.
// TODO: different process pub fn best() -> (Option<CodecInfo>, Option<CodecInfo>) {
ONCE.call_once(|| { CodecInfo::score(Decoder::avaliable_decoders())
let (h264_info, h265_info) = CodecInfo::score(Decoder::avaliable_decoders()); }
let mut h264: Option<HwDecoder> = None;
let mut h265: Option<HwDecoder> = None;
if let Some(info) = h264_info { pub fn new_decoders() -> HwDecoders {
h264 = HwDecoder::new(info).ok(); let (h264_info, h265_info) = HwDecoder::best();
} let mut h264: Option<HwDecoder> = None;
if let Some(info) = h265_info { let mut h265: Option<HwDecoder> = None;
h265 = HwDecoder::new(info).ok();
} if let Some(info) = h264_info {
if h264.is_some() { h264 = HwDecoder::new(info).ok();
log::info!("h264 decoder:{:?}", h264.as_ref().unwrap().info); }
} if let Some(info) = h265_info {
if h265.is_some() { h265 = HwDecoder::new(info).ok();
log::info!("h265 decoder:{:?}", h265.as_ref().unwrap().info); }
} if h264.is_some() {
HW_DECODER_INSTANCE.lock().unwrap().h264 = h264; log::info!("h264 decoder:{:?}", h264.as_ref().unwrap().info);
HW_DECODER_INSTANCE.lock().unwrap().h265 = h265; }
}); if h265.is_some() {
HW_DECODER_INSTANCE.clone() log::info!("h265 decoder:{:?}", h265.as_ref().unwrap().info);
}
HwDecoders { h264, h265 }
} }
pub fn new(info: CodecInfo) -> ResultType<Self> { pub fn new(info: CodecInfo) -> ResultType<Self> {