summaryrefslogtreecommitdiffstats
path: root/libao2/ao_sdl.c
diff options
context:
space:
mode:
authorreimar <reimar@b3059339-0415-0410-9bf9-f77b7e298cf2>2009-03-09 18:21:47 +0000
committerreimar <reimar@b3059339-0415-0410-9bf9-f77b7e298cf2>2009-03-09 18:21:47 +0000
commit28531054594678e6807cc8b34092903e3e445504 (patch)
treecdb3de58ebd749fda905dd6288fb0fabff80e105 /libao2/ao_sdl.c
parent72304af23b416364e5e500f699b7c2daf9708c8f (diff)
downloadmpv-28531054594678e6807cc8b34092903e3e445504.tar.bz2
mpv-28531054594678e6807cc8b34092903e3e445504.tar.xz
Reuse libavutil fifo code instead of reimplementing it over and over.
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@28917 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libao2/ao_sdl.c')
-rw-r--r--libao2/ao_sdl.c87
1 files changed, 21 insertions, 66 deletions
diff --git a/libao2/ao_sdl.c b/libao2/ao_sdl.c
index 6cbd607e67..d5652ccf09 100644
--- a/libao2/ao_sdl.c
+++ b/libao2/ao_sdl.c
@@ -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 @@ LIBAO_EXTERN(sdl)
#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)
-
-static unsigned char *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;
+#define BUFFSIZE (NUM_CHUNKS * CHUNK_SIZE)
+
+static AVFifoBuffer *buffer;
+
#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 first_len = BUFFSIZE - write_pos;
- int free = buf_free();
+ int free = BUFFSIZE - av_fifo_size(buffer);
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;
+ return av_fifo_generic_write(buffer, data, len, NULL);
}
-static int read_buffer(unsigned char* data,int len){
- int first_len = BUFFSIZE - read_pos;
- int buffered = buf_used();
- 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);
-#else
- fast_memcpy (data, &buffer[read_pos], first_len);
+static void mix_audio(void *dst, void *src, int len) {
+ SDL_MixAudio(dst, src, len, volume);
+}
#endif
- if (len > first_len) { // we have to wrap around
- // remaining part from beginning of buffer
+
+static int read_buffer(unsigned char* data,int len){
+ int buffered = av_fifo_size(buffer);
+ if (len > buffered) len = buffered;
#ifdef USE_SDL_INTERNAL_MIXER
- SDL_MixAudio (&data[first_len], buffer, len - first_len, volume);
+ return av_fifo_generic_read(buffer, data, len, mix_audio);
#else
- fast_memcpy (&data[first_len], buffer, len - first_len);
+ return av_fifo_generic_read(buffer, data, len, NULL);
#endif
- }
- read_pos = (read_pos + len) % BUFFSIZE;
- return len;
}
// end ring buffer stuff
@@ -175,7 +131,7 @@ static int init(int rate,int channels,int format,int flags){
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 @@ void callback(void *userdata, Uint8 *stream, int len); userdata is the pointer s
ao_data.buffersize=obtained.size;
ao_data.outburst = CHUNK_SIZE;
- reset();
/* unsilence audio, if callback is ready */
SDL_PauseAudio(0);
@@ -292,6 +247,7 @@ static void uninit(int immed){
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 @@ static void reset(void){
SDL_PauseAudio(1);
/* Reset ring-buffer state */
- read_pos = 0;
- write_pos = 0;
+ av_fifo_reset(buffer);
SDL_PauseAudio(0);
}
@@ -325,7 +280,7 @@ static void audio_resume(void)
// 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 @@ static int play(void* data,int len,int flags){
// 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;
}