[MPlayer-cvslog] r37399 - in trunk: libmpdemux/stheader.h mplayer.c

cigaes subversion at mplayerhq.hu
Tue May 12 19:53:41 CEST 2015


Author: cigaes
Date: Tue May 12 19:53:41 2015
New Revision: 37399

Log:
mplayer: fix buffer handling during channel change.

Without this change, when changing from, for example, stereo
to 5.1, there may be a little stereo data left in the output
buffer when the audio output is reinitialized with the new
format. If that little stereo data is not a multiple of 6 samples
it causes a shift in the mapping of the 5.1 channels.

With this patch, decoded audio data in new format is not filtered
as long as there are still samples in old format that have not
yet been sent to the AO driver.

Based on a suggestion by Reimar Döffinger.

Modified:
   trunk/libmpdemux/stheader.h
   trunk/mplayer.c

Modified: trunk/libmpdemux/stheader.h
==============================================================================
--- trunk/libmpdemux/stheader.h	Mon May 11 22:10:01 2015	(r37398)
+++ trunk/libmpdemux/stheader.h	Tue May 12 19:53:41 2015	(r37399)
@@ -68,6 +68,9 @@ typedef struct sh_audio {
   char* a_buffer;
   int a_buffer_len;
   int a_buffer_size;
+  int a_buffer_format_change; // audio data in the input buffer is subject
+                              // to a format change but data in the old
+                              // format is still present in the out buffer
   // output buffers:
   char* a_out_buffer;
   int a_out_buffer_len;

Modified: trunk/mplayer.c
==============================================================================
--- trunk/mplayer.c	Mon May 11 22:10:01 2015	(r37398)
+++ trunk/mplayer.c	Tue May 12 19:53:41 2015	(r37399)
@@ -2135,7 +2135,6 @@ static int fill_audio_out_buffers(void)
     int playflags = 0;
     int audio_eof = 0;
     int bytes_to_write;
-    int format_change = 0;
     int timeout = 0;
     sh_audio_t *const sh_audio = mpctx->sh_audio;
 
@@ -2174,11 +2173,11 @@ static int fill_audio_out_buffers(void)
         // Fill buffer if needed:
         current_module = "decode_audio";
         t = GetTimer();
-        if (!format_change) {
+        if (!sh_audio->a_buffer_format_change) {
             res = mp_decode_audio(sh_audio, playsize);
-            format_change = res == -2;
+            sh_audio->a_buffer_format_change = res == -2;
         }
-        if (!format_change && res < 0) // EOF or error
+        if (!sh_audio->a_buffer_format_change && res < 0) // EOF or error
             if (mpctx->d_audio->eof) {
                 audio_eof = 1;
                 if (sh_audio->a_out_buffer_len == 0)
@@ -2189,7 +2188,7 @@ static int fill_audio_out_buffers(void)
         audio_time_usage += tt;
         if (playsize > sh_audio->a_out_buffer_len) {
             playsize = sh_audio->a_out_buffer_len;
-            if (audio_eof || format_change)
+            if (audio_eof || sh_audio->a_buffer_format_change)
                 playflags |= AOPLAY_FINAL_CHUNK;
         }
         if (!playsize)
@@ -2209,19 +2208,21 @@ static int fill_audio_out_buffers(void)
             memmove(sh_audio->a_out_buffer, &sh_audio->a_out_buffer[playsize],
                     sh_audio->a_out_buffer_len);
             mpctx->delay += playback_speed * playsize / (double)ao_data.bps;
-        } else if ((format_change || audio_eof) && mpctx->audio_out->get_delay() < .04) {
+        } else if ((sh_audio->a_buffer_format_change || audio_eof) &&
+                   mpctx->audio_out->get_delay() < .04) {
             // Sanity check to avoid hanging in case current ao doesn't output
             // partial chunks and doesn't check for AOPLAY_FINAL_CHUNK
             mp_msg(MSGT_CPLAYER, MSGL_WARN, MSGTR_AudioOutputTruncated);
             sh_audio->a_out_buffer_len = 0;
         }
     }
-    if (format_change) {
+    if (sh_audio->a_buffer_format_change && !sh_audio->a_out_buffer_len) {
         uninit_player(INITIALIZED_AO);
         af_uninit(sh_audio->afilter);
         free(sh_audio->afilter);
         sh_audio->afilter = NULL;
         reinit_audio_chain();
+        sh_audio->a_buffer_format_change = 0;
     }
     return 1;
 }


More information about the MPlayer-cvslog mailing list