diff options
author | Uoti Urpala <uau@glyph.nonexistent.invalid> | 2009-12-29 15:51:59 +0200 |
---|---|---|
committer | Uoti Urpala <uau@glyph.nonexistent.invalid> | 2009-12-29 15:51:59 +0200 |
commit | 57ce95b96a9d5ff75b5afa608bdda8366a999cf5 (patch) | |
tree | 416883d01181a719c50d460b49a2a7aa575bcfde | |
parent | d7d8babe61914f14df1fc1bab173574e1fabad1e (diff) | |
download | mpv-57ce95b96a9d5ff75b5afa608bdda8366a999cf5.tar.bz2 mpv-57ce95b96a9d5ff75b5afa608bdda8366a999cf5.tar.xz |
audio: Remove fixed decode_audio() return size limit (MAX_OUTBURST)
A couple of months ago MPlayer's ALSA driver started rounding the
amount of input data it was willing to accept in one call down to an
integer multiple of the value it set in ao_data.outburst. In some
configurations it was possible for this value to exceed the 64 KiB
limit on the amount MPlayer was willing to write in a single call to
the AO. As a result ao_alsa accepted 0 bytes in each play() call and
audio playback failed. Fix this by removing the fixed 64 KiB limit on
the amount of audio sent to AO at once; the limit was mostly a remnant
of older code anyway.
-rwxr-xr-x | configure | 3 | ||||
-rw-r--r-- | libao2/ao_oss.c | 2 | ||||
-rw-r--r-- | libmpcodecs/dec_audio.c | 6 | ||||
-rw-r--r-- | mencoder.c | 1 | ||||
-rw-r--r-- | mplayer.c | 89 |
5 files changed, 45 insertions, 56 deletions
@@ -8010,9 +8010,6 @@ cat > $TMPH << EOF */ #define CONFIG_FAKE_MONO 1 -/* set up max. outburst. use 65536 for ALSA 0.5, for others 16384 is enough */ -#define MAX_OUTBURST 65536 - /* set up audio OUTBURST. Do not change this! */ #define OUTBURST 512 diff --git a/libao2/ao_oss.c b/libao2/ao_oss.c index b4e5ab49b8..6872b15946 100644 --- a/libao2/ao_oss.c +++ b/libao2/ao_oss.c @@ -519,8 +519,6 @@ static int get_space(void){ if(ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &zz)!=-1){ // calculate exact buffer space: playsize = zz.fragments*zz.fragsize; - if (playsize > MAX_OUTBURST) - playsize = (MAX_OUTBURST / zz.fragsize) * zz.fragsize; return playsize; } #endif diff --git a/libmpcodecs/dec_audio.c b/libmpcodecs/dec_audio.c index cd63b15b25..8d80e01ff4 100644 --- a/libmpcodecs/dec_audio.c +++ b/libmpcodecs/dec_audio.c @@ -74,10 +74,12 @@ static int init_audio_codec(sh_audio_t *sh_audio) sh_audio->a_in_buffer_len = 0; } - sh_audio->a_buffer_size = sh_audio->audio_out_minsize + MAX_OUTBURST; + const int base_size = 65536; + // At least 64 KiB plus rounding up to next decodable unit size + sh_audio->a_buffer_size = base_size + sh_audio->audio_out_minsize; mp_tmsg(MSGT_DECAUDIO, MSGL_V, "dec_audio: Allocating %d + %d = %d bytes for output buffer.\n", - sh_audio->audio_out_minsize, MAX_OUTBURST, sh_audio->a_buffer_size); + sh_audio->audio_out_minsize, base_size, sh_audio->a_buffer_size); sh_audio->a_buffer = av_mallocz(sh_audio->a_buffer_size); if (!sh_audio->a_buffer) { diff --git a/mencoder.c b/mencoder.c index 1f00adc7f0..908f9a80e4 100644 --- a/mencoder.c +++ b/mencoder.c @@ -330,7 +330,6 @@ static int dec_audio(sh_audio_t *sh_audio,unsigned char* buffer,int total){ int at_eof=0; while(size<total && !at_eof){ int len=total-size; - if(len>MAX_OUTBURST) len=MAX_OUTBURST; if (decode_audio(sh_audio, len) < 0) at_eof=1; if(len>sh_audio->a_out_buffer_len) len=sh_audio->a_out_buffer_len; fast_memcpy(buffer+size,sh_audio->a_out_buffer,len); @@ -2020,7 +2020,6 @@ static int fill_audio_out_buffers(struct MPContext *mpctx) int playsize; int playflags=0; int audio_eof=0; - int bytes_to_write; sh_audio_t * const sh_audio = mpctx->sh_audio; current_module="play_audio"; @@ -2031,65 +2030,59 @@ static int fill_audio_out_buffers(struct MPContext *mpctx) // sync completely wrong; there should be no need to use ao_data.pts // in get_space() ao_data.pts = ((mpctx->sh_video?mpctx->sh_video->timer:0)+mpctx->delay)*90000.0; - bytes_to_write = mpctx->audio_out->get_space(); - if (mpctx->sh_video || bytes_to_write >= ao_data.outburst) + playsize = mpctx->audio_out->get_space(); + if (mpctx->sh_video || playsize >= ao_data.outburst) break; // handle audio-only case: // this is where mplayer sleeps during audio-only playback // to avoid 100% CPU use - sleep_time = (ao_data.outburst - bytes_to_write) * 1000 / ao_data.bps; + sleep_time = (ao_data.outburst - playsize) * 1000 / ao_data.bps; if (sleep_time < 10) sleep_time = 10; // limit to 100 wakeups per second usec_sleep(sleep_time * 1000); } - while (bytes_to_write) { - playsize = bytes_to_write; - if (playsize > MAX_OUTBURST) - playsize = MAX_OUTBURST; - bytes_to_write -= playsize; - - // Fill buffer if needed: - current_module="decode_audio"; - t = GetTimer(); - if (decode_audio(sh_audio, playsize) < 0) // EOF or error - if (mpctx->d_audio->eof) { - audio_eof = 1; - if (sh_audio->a_out_buffer_len == 0) - return 0; - } - t = GetTimer() - t; - tt = t*0.000001f; audio_time_usage+=tt; - if (playsize > sh_audio->a_out_buffer_len) { - playsize = sh_audio->a_out_buffer_len; - if (audio_eof) - playflags |= AOPLAY_FINAL_CHUNK; - } - if (!playsize) - break; - - // play audio: - current_module="play_audio"; + // Fill buffer if needed: + current_module="decode_audio"; + t = GetTimer(); + if (decode_audio(sh_audio, playsize) < 0) // EOF or error + if (mpctx->d_audio->eof) { + audio_eof = 1; + if (sh_audio->a_out_buffer_len == 0) + return 0; + } + t = GetTimer() - t; + tt = t*0.000001f; audio_time_usage+=tt; + if (playsize > sh_audio->a_out_buffer_len) { + playsize = sh_audio->a_out_buffer_len; + if (audio_eof) + playflags |= AOPLAY_FINAL_CHUNK; + } + if (!playsize) + return 1; - // Is this pts value actually useful for the aos that access it? - // They're obviously badly broken in the way they handle av sync; - // would not having access to this make them more broken? - ao_data.pts = ((mpctx->sh_video?mpctx->sh_video->timer:0)+mpctx->delay)*90000.0; - playsize = mpctx->audio_out->play(sh_audio->a_out_buffer, playsize, playflags); + // play audio: + current_module="play_audio"; - if (playsize > 0) { - sh_audio->a_out_buffer_len -= playsize; - memmove(sh_audio->a_out_buffer, &sh_audio->a_out_buffer[playsize], - sh_audio->a_out_buffer_len); - mpctx->delay += opts->playback_speed*playsize/(double)ao_data.bps; - } - else if (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, "Audio output truncated at end.\n"); - sh_audio->a_out_buffer_len = 0; - } + // Is this pts value actually useful for the aos that access it? + // They're obviously badly broken in the way they handle av sync; + // would not having access to this make them more broken? + ao_data.pts = ((mpctx->sh_video?mpctx->sh_video->timer:0)+mpctx->delay)*90000.0; + playsize = mpctx->audio_out->play(sh_audio->a_out_buffer, playsize, playflags); + + if (playsize > 0) { + sh_audio->a_out_buffer_len -= playsize; + memmove(sh_audio->a_out_buffer, &sh_audio->a_out_buffer[playsize], + sh_audio->a_out_buffer_len); + mpctx->delay += opts->playback_speed*playsize/(double)ao_data.bps; } + else if (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, "Audio output truncated at end.\n"); + sh_audio->a_out_buffer_len = 0; + } + return 1; } |