[MPlayer-dev-eng] [PATCH] mplayer: fix buffer handling during channel change.

Reimar Döffinger Reimar.Doeffinger at gmx.de
Sun May 10 13:10:28 CEST 2015


On Sun, May 10, 2015 at 12:16:55PM +0200, Nicolas George wrote:
> With this patch, ensure that the output buffer is flushed before
> performing the format change. It may cause a small A-V sync glitch
> at the time, but it is better than completely wrong surround
> arrangement.

As there seems to be no difference between eof and format change,
won't this also cause a (completely unnecessary) glitch on EOF?

> --- a/mplayer.c
> +++ b/mplayer.c
> @@ -2187,7 +2187,7 @@ static int fill_audio_out_buffers(void)
>          t  = GetTimer() - t;
>          tt = t * 0.000001f;
>          audio_time_usage += tt;
> -        if (playsize > sh_audio->a_out_buffer_len) {
> +        if (playsize >= sh_audio->a_out_buffer_len) {
>              playsize = sh_audio->a_out_buffer_len;
>              if (audio_eof || format_change)
>                  playflags |= AOPLAY_FINAL_CHUNK;

AOs should not need AOPLAY_FINAL_CHUNK if they get a full-size packet.
Anything else is a bug in the AO and should be fixed there.

> @@ -2215,6 +2215,8 @@ static int fill_audio_out_buffers(void)
>              mp_msg(MSGT_CPLAYER, MSGL_WARN, MSGTR_AudioOutputTruncated);
>              sh_audio->a_out_buffer_len = 0;
>          }
> +        if (audio_eof || format_change)
> +            bytes_to_write = sh_audio->a_out_buffer_len;

I don't think AOs are required to support writes with larger than
get_size data, and this might cause all kinds of bad effects.
Even just dropping the remaining data seems safer/better.
This is a horrible hack and the variable should be moved into the
context instead (so it can be properly reset on seek for example),
but doesn't this work:
--- a/mplayer.c
+++ b/mplayer.c
@@ -2135,7 +2135,7 @@ static int fill_audio_out_buffers(void)
     int playflags = 0;
     int audio_eof = 0;
     int bytes_to_write;
-    int format_change = 0;
+    static int format_change = 0;
     int timeout = 0;
     sh_audio_t *const sh_audio = mpctx->sh_audio;
 
@@ -2216,12 +2216,13 @@ static int fill_audio_out_buffers(void)
             sh_audio->a_out_buffer_len = 0;
         }
     }
-    if (format_change) {
+    if (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();
+        format_change = 0;
     }
     return 1;
 }


More information about the MPlayer-dev-eng mailing list