From 28531054594678e6807cc8b34092903e3e445504 Mon Sep 17 00:00:00 2001 From: reimar Date: Mon, 9 Mar 2009 18:21:47 +0000 Subject: 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 --- libao2/ao_jack.c | 102 +++++++++++++++++++------------------------------------ 1 file changed, 35 insertions(+), 67 deletions(-) (limited to 'libao2/ao_jack.c') diff --git a/libao2/ao_jack.c b/libao2/ao_jack.c index e861d08aed..494d44aa19 100644 --- a/libao2/ao_jack.c +++ b/libao2/ao_jack.c @@ -36,7 +36,7 @@ #include "osdep/timer.h" #include "subopt-helper.h" -#include "libvo/fastmemcpy.h" +#include "libavutil/fifo.h" #include @@ -68,47 +68,10 @@ static volatile float callback_time = 0; #define CHUNK_SIZE (16 * 1024) //! number of "virtual" chunks the buffer consists of #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) //! buffer for audio data -static unsigned char *buffer = NULL; - -//! buffer read position, may only be modified by playback thread or while it is stopped -static volatile int read_pos; -//! buffer write position, may only be modified by MPlayer's thread -static volatile int write_pos; - -/** - * \brief get the number of free bytes in the buffer - * \return number of free bytes in buffer - * - * 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; -} - -/** - * \brief get amount of data available in the buffer - * \return number of bytes available in buffer - * - * may only be called by the 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 AVFifoBuffer *buffer; /** * \brief insert len bytes into buffer @@ -119,22 +82,34 @@ static int buf_used(void) { * If there is not enough room, the buffer is filled up */ 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 void silence(float **bufs, int cnt, int num_bufs); +struct deinterleave { + float **bufs; + int num_bufs; + int cur_buf; + int pos; +}; + +static void deinterleave(void *info, void *src, int len) { + struct deinterleave *di = info; + float *s = src; + int i; + len /= sizeof(float); + for (i = 0; i < len; i++) { + di->bufs[di->cur_buf++][di->pos] = s[i]; + if (di->cur_buf >= di->num_bufs) { + di->cur_buf = 0; + di->pos++; + } + } +} + /** * \brief read data from buffer and splitting it into channels * \param bufs num_bufs float buffers, each will contain the data of one channel @@ -149,18 +124,13 @@ static void silence(float **bufs, int cnt, int num_bufs); * with silence. */ static int read_buffer(float **bufs, int cnt, int num_bufs) { - int buffered = buf_used(); - int i, j; + struct deinterleave di = {bufs, num_bufs, 0, 0}; + int buffered = av_fifo_size(buffer); if (cnt * sizeof(float) * num_bufs > buffered) { silence(bufs, cnt, num_bufs); cnt = buffered / sizeof(float) / num_bufs; } - for (i = 0; i < cnt; i++) { - for (j = 0; j < num_bufs; j++) { - bufs[j][i] = *(float *)&buffer[read_pos]; - read_pos = (read_pos + sizeof(float)) % BUFFSIZE; - } - } + av_fifo_generic_read(buffer, &di, cnt * num_bufs * sizeof(float), deinterleave); return cnt; } @@ -268,7 +238,7 @@ static int init(int rate, int channels, int format, int flags) { mp_msg(MSGT_AO, MSGL_FATAL, "[JACK] cannot open server\n"); goto err_out; } - reset(); + buffer = av_fifo_alloc(BUFFSIZE); jack_set_process_callback(client, outputaudio, 0); // list matching ports @@ -308,7 +278,6 @@ static int init(int rate, int channels, int format, int flags) { jack_latency = (float)(jack_port_get_total_latency(client, ports[0]) + jack_get_buffer_size(client)) / (float)rate; callback_interval = 0; - buffer = malloc(BUFFSIZE); ao_data.channels = channels; ao_data.samplerate = rate; @@ -327,7 +296,7 @@ err_out: free(client_name); if (client) jack_client_close(client); - free(buffer); + av_fifo_free(buffer); buffer = NULL; return 0; } @@ -340,7 +309,7 @@ static void uninit(int immed) { reset(); usec_sleep(100 * 1000); jack_client_close(client); - free(buffer); + av_fifo_free(buffer); buffer = NULL; } @@ -349,8 +318,7 @@ static void uninit(int immed) { */ static void reset(void) { paused = 1; - read_pos = 0; - write_pos = 0; + av_fifo_reset(buffer); paused = 0; } @@ -369,7 +337,7 @@ static void audio_resume(void) { } static int get_space(void) { - return buf_free(); + return BUFFSIZE - av_fifo_size(buffer); } /** @@ -383,7 +351,7 @@ static int play(void *data, int len, int flags) { } static float get_delay(void) { - int buffered = BUFFSIZE - CHUNK_SIZE - buf_free(); // could be less + int buffered = av_fifo_size(buffer); // could be less float in_jack = jack_latency; if (estimate && callback_interval > 0) { float elapsed = (float)GetTimer() / 1000000.0 - callback_time; -- cgit v1.2.3