Mercurial > mplayer.hg
diff libao2/ao_sdl.c @ 28882:15f93fd5cd48
Reuse libavutil fifo code instead of reimplementing it over and over.
author | reimar |
---|---|
date | Mon, 09 Mar 2009 18:21:47 +0000 |
parents | 9a5b8c2ed6de |
children | f951680cfea2 |
line wrap: on
line diff
--- a/libao2/ao_sdl.c Mon Mar 09 17:25:43 2009 +0000 +++ b/libao2/ao_sdl.c Mon Mar 09 18:21:47 2009 +0000 @@ -3,8 +3,6 @@ * * Copyleft 2001 by Felix Bünemann (atmosfear@users.sf.net) * - * Thanks to Arpi for nice ringbuffer-code! - * * This file is part of MPlayer. * * MPlayer is free software; you can redistribute it and/or modify @@ -36,7 +34,7 @@ #include <SDL.h> #include "osdep/timer.h" -#include "libvo/fastmemcpy.h" +#include "libavutil/fifo.h" static const ao_info_t info = { @@ -60,76 +58,34 @@ #define CHUNK_SIZE 4096 #define NUM_CHUNKS 8 -// This type of ring buffer may never fill up completely, at least -// one byte must always be unused. -// For performance reasons (alignment etc.) one whole chunk always stays -// empty, not only one byte. -#define BUFFSIZE ((NUM_CHUNKS + 1) * CHUNK_SIZE) +#define BUFFSIZE (NUM_CHUNKS * CHUNK_SIZE) -static unsigned char *buffer; +static AVFifoBuffer *buffer; -// may only be modified by SDL's playback thread or while it is stopped -static volatile int read_pos; -// may only be modified by mplayer's thread -static volatile int write_pos; #ifdef USE_SDL_INTERNAL_MIXER static unsigned char volume=SDL_MIX_MAXVOLUME; #endif -// may only be called by mplayer's thread -// return value may change between immediately following two calls, -// and the real number of free bytes might be larger! -static int buf_free(void) { - int free = read_pos - write_pos - CHUNK_SIZE; - if (free < 0) free += BUFFSIZE; - return free; -} - -// may only be called by SDL's playback thread -// return value may change between immediately following two calls, -// and the real number of buffered bytes might be larger! -static int buf_used(void) { - int used = write_pos - read_pos; - if (used < 0) used += BUFFSIZE; - return used; +static int write_buffer(unsigned char* data,int len){ + int free = BUFFSIZE - av_fifo_size(buffer); + if (len > free) len = free; + return av_fifo_generic_write(buffer, data, len, NULL); } -static int write_buffer(unsigned char* data,int len){ - int first_len = BUFFSIZE - write_pos; - int free = buf_free(); - if (len > free) len = free; - if (first_len > len) first_len = len; - // till end of buffer - fast_memcpy (&buffer[write_pos], data, first_len); - if (len > first_len) { // we have to wrap around - // remaining part from beginning of buffer - fast_memcpy (buffer, &data[first_len], len - first_len); - } - write_pos = (write_pos + len) % BUFFSIZE; - return len; +#ifdef USE_SDL_INTERNAL_MIXER +static void mix_audio(void *dst, void *src, int len) { + SDL_MixAudio(dst, src, len, volume); } +#endif static int read_buffer(unsigned char* data,int len){ - int first_len = BUFFSIZE - read_pos; - int buffered = buf_used(); + int buffered = av_fifo_size(buffer); if (len > buffered) len = buffered; - if (first_len > len) first_len = len; - // till end of buffer #ifdef USE_SDL_INTERNAL_MIXER - SDL_MixAudio (data, &buffer[read_pos], first_len, volume); + return av_fifo_generic_read(buffer, data, len, mix_audio); #else - fast_memcpy (data, &buffer[read_pos], first_len); + return av_fifo_generic_read(buffer, data, len, NULL); #endif - if (len > first_len) { // we have to wrap around - // remaining part from beginning of buffer -#ifdef USE_SDL_INTERNAL_MIXER - SDL_MixAudio (&data[first_len], buffer, len - first_len, volume); -#else - fast_memcpy (&data[first_len], buffer, len - first_len); -#endif - } - read_pos = (read_pos + len) % BUFFSIZE; - return len; } // end ring buffer stuff @@ -175,7 +131,7 @@ SDL_AudioSpec aspec, obtained; /* Allocate ring-buffer memory */ - buffer = (unsigned char *) malloc(BUFFSIZE); + buffer = av_fifo_alloc(BUFFSIZE); mp_msg(MSGT_AO,MSGL_INFO,MSGTR_AO_SDL_INFO, rate, (channels > 1) ? "Stereo" : "Mono", af_fmt2str_short(format)); @@ -278,7 +234,6 @@ ao_data.buffersize=obtained.size; ao_data.outburst = CHUNK_SIZE; - reset(); /* unsilence audio, if callback is ready */ SDL_PauseAudio(0); @@ -292,6 +247,7 @@ usec_sleep(get_delay() * 1000 * 1000); SDL_CloseAudio(); SDL_QuitSubSystem(SDL_INIT_AUDIO); + av_fifo_free(buffer); } // stop playing and empty buffers (for seeking/pause) @@ -301,8 +257,7 @@ SDL_PauseAudio(1); /* Reset ring-buffer state */ - read_pos = 0; - write_pos = 0; + av_fifo_reset(buffer); SDL_PauseAudio(0); } @@ -325,7 +280,7 @@ // return: how many bytes can be played without blocking static int get_space(void){ - return buf_free(); + return BUFFSIZE - av_fifo_size(buffer); } // plays 'len' bytes of 'data' @@ -352,7 +307,7 @@ // return: delay in seconds between first and last sample in buffer static float get_delay(void){ - int buffered = BUFFSIZE - CHUNK_SIZE - buf_free(); // could be less + int buffered = av_fifo_size(buffer); // could be less return (float)(buffered + ao_data.buffersize)/(float)ao_data.bps; }