[MPlayer-cvslog] r28917 - in trunk/libao2: ao_jack.c ao_sdl.c
reimar
subversion at mplayerhq.hu
Mon Mar 9 19:21:48 CET 2009
Author: reimar
Date: Mon Mar 9 19:21:47 2009
New Revision: 28917
Log:
Reuse libavutil fifo code instead of reimplementing it over and over.
Modified:
trunk/libao2/ao_jack.c
trunk/libao2/ao_sdl.c
Modified: trunk/libao2/ao_jack.c
==============================================================================
--- trunk/libao2/ao_jack.c Mon Mar 9 18:25:43 2009 (r28916)
+++ trunk/libao2/ao_jack.c Mon Mar 9 19:21:47 2009 (r28917)
@@ -36,7 +36,7 @@
#include "osdep/timer.h"
#include "subopt-helper.h"
-#include "libvo/fastmemcpy.h"
+#include "libavutil/fifo.h"
#include <jack/jack.h>
@@ -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 cn
* 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,
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,
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
}
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;
Modified: trunk/libao2/ao_sdl.c
==============================================================================
--- trunk/libao2/ao_sdl.c Mon Mar 9 18:25:43 2009 (r28916)
+++ trunk/libao2/ao_sdl.c Mon Mar 9 19:21:47 2009 (r28917)
@@ -3,8 +3,6 @@
*
* Copyleft 2001 by Felix Bünemann (atmosfear at 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)
+#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 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,in
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 *str
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 f
// 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;
}
More information about the MPlayer-cvslog
mailing list