videoplayer: add a hack to play AAC with SBR properly
authorKostya Shishkov <kostya.shishkov@gmail.com>
Fri, 30 Jun 2023 16:13:31 +0000 (18:13 +0200)
committerKostya Shishkov <kostya.shishkov@gmail.com>
Fri, 30 Jun 2023 16:13:31 +0000 (18:13 +0200)
videoplayer/src/audiodec.rs
videoplayer/src/main.rs

index bddec5745a6dce2df1eae5cfffb84e8d6fde039b..ad906f0f997f709bf9a4e97ee04629d2366a0f19 100644 (file)
@@ -155,20 +155,21 @@ fn dummy_audio_thread(aprecv: Receiver<PktSendEvent>) -> JoinHandle<()> {
 
 type AudioPlaybackType = Option<AudioDevice<AudioOutput>>;
 
-fn start_audio_decoding(asystem: &AudioSubsystem, ainfo: NAAudioInfo, mut audio_dec: DecoderStuff, aprecv: Receiver<PktSendEvent>) -> (AudioPlaybackType, JoinHandle<()>) {
+fn start_audio_decoding(asystem: &AudioSubsystem, ainfo: NAAudioInfo, sbr_hack: bool, mut audio_dec: DecoderStuff, aprecv: Receiver<PktSendEvent>) -> (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<DecoderStuff>, ainfo: Option<NAAudioInfo>, asystem: &AudioSubsystem) -> Self {
+    pub fn new(audio_dec: Option<DecoderStuff>, ainfo: Option<NAAudioInfo>, sbr_hack: bool, asystem: &AudioSubsystem) -> Self {
         let (apsend, aprecv) = std::sync::mpsc::sync_channel::<PktSendEvent>(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))
             };
index 674a243ae49ab9d55e9a3198deb63781e6deb01d..e3d2d002a1ddba0514859aada31504f043760825 100644 (file)
@@ -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<NAAudioInfo> = None;
+        let mut sbr_hack = false;
 
         let mut video_dec: Option<DecoderStuff> = None;
         let mut audio_dec: Option<DecoderStuff> = 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 {