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 /mplayer.c | |
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.
Diffstat (limited to 'mplayer.c')
-rw-r--r-- | mplayer.c | 89 |
1 files changed, 41 insertions, 48 deletions
@@ -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; } |