From: Kostya Shishkov Date: Fri, 30 Jun 2023 16:13:31 +0000 (+0200) Subject: videoplayer: add a hack to play AAC with SBR properly X-Git-Url: https://git.nihav.org/?p=nihav-player.git;a=commitdiff_plain;h=e2ca0dbe4e8c92c3c95cda0cf1dc57da164b1c8a videoplayer: add a hack to play AAC with SBR properly --- diff --git a/videoplayer/src/audiodec.rs b/videoplayer/src/audiodec.rs index bddec57..ad906f0 100644 --- a/videoplayer/src/audiodec.rs +++ b/videoplayer/src/audiodec.rs @@ -155,20 +155,21 @@ fn dummy_audio_thread(aprecv: Receiver) -> JoinHandle<()> { type AudioPlaybackType = Option>; -fn start_audio_decoding(asystem: &AudioSubsystem, ainfo: NAAudioInfo, mut audio_dec: DecoderStuff, aprecv: Receiver) -> (AudioPlaybackType, JoinHandle<()>) { +fn start_audio_decoding(asystem: &AudioSubsystem, ainfo: NAAudioInfo, sbr_hack: bool, mut audio_dec: DecoderStuff, aprecv: Receiver) -> (AudioPlaybackType, JoinHandle<()>) { let ch = ainfo.channels.max(2); + let sample_rate = if !sbr_hack { ainfo.sample_rate } else { ainfo.sample_rate * 2 }; let desired_spec = AudioSpecDesired { - freq: Some(ainfo.sample_rate as i32), + freq: Some(sample_rate as i32), channels: Some(ch), samples: None }; let dst_info = NAAudioInfo { - sample_rate: ainfo.sample_rate, + sample_rate: sample_rate, channels: ch, format: SND_S16_FORMAT, block_len: 0, }; - let queue = Arc::new(Mutex::new(AudioQueue::new(ainfo.sample_rate as usize, ch as usize))); + let queue = Arc::new(Mutex::new(AudioQueue::new(sample_rate as usize, ch as usize))); let qclone = queue.clone(); let ret = asystem.open_playback(None, &desired_spec, |_spec| { AudioOutput { @@ -203,6 +204,9 @@ fn start_audio_decoding(asystem: &AudioSubsystem, ainfo: NAAudioInfo, mut audio_ let buf = frm.get_buffer(); if let Some(pts) = frm.get_pts() { samplepos = NATimeInfo::ts_to_time(pts, u64::from(dst_info.sample_rate), frm.ts.tb_num, frm.ts.tb_den) as usize; + if sbr_hack { + samplepos >>= 2; + } } samplepos += buf.get_audio_length(); if let Ok(out_buf) = convert_audio_frame(&buf, &dst_info, &dst_chmap) { @@ -260,10 +264,10 @@ pub struct AudioControl { } impl AudioControl { - pub fn new(audio_dec: Option, ainfo: Option, asystem: &AudioSubsystem) -> Self { + pub fn new(audio_dec: Option, ainfo: Option, sbr_hack: bool, asystem: &AudioSubsystem) -> Self { let (apsend, aprecv) = std::sync::mpsc::sync_channel::(20); let (adevice, athread) = if let Some(audio_dec) = audio_dec { - start_audio_decoding(asystem, ainfo.expect("audio info should be present"), audio_dec, aprecv) + start_audio_decoding(asystem, ainfo.expect("audio info should be present"), sbr_hack, audio_dec, aprecv) } else { (None, dummy_audio_thread(aprecv)) }; diff --git a/videoplayer/src/main.rs b/videoplayer/src/main.rs index 674a243..e3d2d00 100644 --- a/videoplayer/src/main.rs +++ b/videoplayer/src/main.rs @@ -332,7 +332,7 @@ impl Player { let vsystem = sdl_context.video().expect("video subsystem init failure"); let asystem = sdl_context.audio().expect("audio subsystem init failure"); vsystem.disable_screen_saver(); - let acontrol = AudioControl::new(None, None, &asystem); + let acontrol = AudioControl::new(None, None, false, &asystem); let vcontrol = VideoControl::new(None, 0, 0, 0, 0); Self { sdl_context, asystem, vsystem, @@ -596,6 +596,7 @@ impl Player { let mut tb_num = 0; let mut tb_den = 0; let mut ainfo: Option = None; + let mut sbr_hack = false; let mut video_dec: Option = None; let mut audio_dec: Option = None; @@ -677,6 +678,11 @@ impl Player { let mut dec = (decfunc)(); let mut dsupp = Box::new(NADecoderSupport::new()); ainfo = info.get_properties().get_audio_info(); + if let (true, Some(ref ai)) = (info.get_name() == "aac", ainfo) { + if ai.sample_rate < 32000 { + sbr_hack = true; + } + } if dec.init(&mut dsupp, info).is_err() { println!("failed to initialise audio decoder"); return; @@ -706,7 +712,7 @@ impl Player { let mut new_vcontrol = VideoControl::new(video_dec, width, height, tb_num, tb_den); std::mem::swap(&mut self.vcontrol, &mut new_vcontrol); - let mut new_acontrol = AudioControl::new(audio_dec, ainfo, &self.asystem); + let mut new_acontrol = AudioControl::new(audio_dec, ainfo, sbr_hack, &self.asystem); std::mem::swap(&mut self.acontrol, &mut new_acontrol); if self.mute {