[MPlayer-cvslog] r29080 - in branches/1.0rc3: TOOLS/aconvert.sh TOOLS/binary_codecs.sh TOOLS/divx2svcd.sh TOOLS/mencvcd.sh TOOLS/midentify.sh TOOLS/mpconsole.sh libaf/af_resample_template.c libao2/ao_jack.c libao2/...

diego subversion at mplayerhq.hu
Sat Mar 28 13:15:10 CET 2009


Author: diego
Date: Sat Mar 28 13:15:10 2009
New Revision: 29080

Log:
Revert r28917, which is incompatible with FFmpeg 0.5:
  Reuse libavutil fifo code instead of reimplementing it over and over.

Modified:
   branches/1.0rc3/TOOLS/aconvert.sh   (props changed)
   branches/1.0rc3/TOOLS/binary_codecs.sh   (props changed)
   branches/1.0rc3/TOOLS/divx2svcd.sh   (props changed)
   branches/1.0rc3/TOOLS/mencvcd.sh   (props changed)
   branches/1.0rc3/TOOLS/midentify.sh   (props changed)
   branches/1.0rc3/TOOLS/mpconsole.sh   (props changed)
   branches/1.0rc3/libaf/af_resample_template.c   (props changed)
   branches/1.0rc3/libao2/ao_jack.c
   branches/1.0rc3/libao2/ao_sdl.c
   branches/1.0rc3/libmpeg2/libmpeg2_changes.diff   (props changed)
   branches/1.0rc3/stream/stream_live555.c   (props changed)
   branches/1.0rc3/stream/stream_netstream.h   (props changed)

Modified: branches/1.0rc3/libao2/ao_jack.c
==============================================================================
--- branches/1.0rc3/libao2/ao_jack.c	Fri Mar 27 23:56:56 2009	(r29079)
+++ branches/1.0rc3/libao2/ao_jack.c	Sat Mar 28 13:15:10 2009	(r29080)
@@ -36,7 +36,7 @@
 #include "osdep/timer.h"
 #include "subopt-helper.h"
 
-#include "libavutil/fifo.h"
+#include "libvo/fastmemcpy.h"
 
 #include <jack/jack.h>
 
@@ -68,10 +68,47 @@ static volatile float callback_time = 0;
 #define CHUNK_SIZE (16 * 1024)
 //! number of "virtual" chunks the buffer consists of
 #define NUM_CHUNKS 8
-#define BUFFSIZE (NUM_CHUNKS * CHUNK_SIZE)
+// 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)
 
 //! buffer for audio data
-static AVFifoBuffer *buffer;
+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;
+}
 
 /**
  * \brief insert len bytes into buffer
@@ -82,34 +119,22 @@ static AVFifoBuffer *buffer;
  * If there is not enough room, the buffer is filled up
  */
 static int write_buffer(unsigned char* data, int len) {
-  int free = BUFFSIZE - av_fifo_size(buffer);
+  int first_len = BUFFSIZE - write_pos;
+  int free = buf_free();
   if (len > free) len = free;
-  return av_fifo_generic_write(buffer, data, len, NULL);
+  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;
 }
 
 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
@@ -124,13 +149,18 @@ static void deinterleave(void *info, voi
  * with silence.
  */
 static int read_buffer(float **bufs, int cnt, int num_bufs) {
-  struct deinterleave di = {bufs, num_bufs, 0, 0};
-  int buffered = av_fifo_size(buffer);
+  int buffered = buf_used();
+  int i, j;
   if (cnt * sizeof(float) * num_bufs > buffered) {
     silence(bufs, cnt, num_bufs);
     cnt = buffered / sizeof(float) / num_bufs;
   }
-  av_fifo_generic_read(buffer, &di, cnt * num_bufs * sizeof(float), deinterleave);
+  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;
+    }
+  }
   return cnt;
 }
 
@@ -238,7 +268,7 @@ static int init(int rate, int channels, 
     mp_msg(MSGT_AO, MSGL_FATAL, "[JACK] cannot open server\n");
     goto err_out;
   }
-  buffer = av_fifo_alloc(BUFFSIZE);
+  reset();
   jack_set_process_callback(client, outputaudio, 0);
 
   // list matching ports
@@ -278,6 +308,7 @@ 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;
@@ -296,7 +327,7 @@ err_out:
   free(client_name);
   if (client)
     jack_client_close(client);
-  av_fifo_free(buffer);
+  free(buffer);
   buffer = NULL;
   return 0;
 }
@@ -309,7 +340,7 @@ static void uninit(int immed) {
   reset();
   usec_sleep(100 * 1000);
   jack_client_close(client);
-  av_fifo_free(buffer);
+  free(buffer);
   buffer = NULL;
 }
 
@@ -318,7 +349,8 @@ static void uninit(int immed) {
  */
 static void reset(void) {
   paused = 1;
-  av_fifo_reset(buffer);
+  read_pos = 0;
+  write_pos = 0;
   paused = 0;
 }
 
@@ -337,7 +369,7 @@ static void audio_resume(void) {
 }
 
 static int get_space(void) {
-  return BUFFSIZE - av_fifo_size(buffer);
+  return buf_free();
 }
 
 /**
@@ -351,7 +383,7 @@ static int play(void *data, int len, int
 }
 
 static float get_delay(void) {
-  int buffered = av_fifo_size(buffer); // could be less
+  int buffered = BUFFSIZE - CHUNK_SIZE - buf_free(); // could be less
   float in_jack = jack_latency;
   if (estimate && callback_interval > 0) {
     float elapsed = (float)GetTimer() / 1000000.0 - callback_time;

Modified: branches/1.0rc3/libao2/ao_sdl.c
==============================================================================
--- branches/1.0rc3/libao2/ao_sdl.c	Fri Mar 27 23:56:56 2009	(r29079)
+++ branches/1.0rc3/libao2/ao_sdl.c	Sat Mar 28 13:15:10 2009	(r29080)
@@ -3,6 +3,8 @@
  *
  * 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
@@ -34,7 +36,7 @@
 #include <SDL.h>
 #include "osdep/timer.h"
 
-#include "libavutil/fifo.h"
+#include "libvo/fastmemcpy.h"
 
 static const ao_info_t info = 
 {
@@ -58,34 +60,76 @@ LIBAO_EXTERN(sdl)
 
 #define CHUNK_SIZE 4096
 #define NUM_CHUNKS 8
-#define BUFFSIZE (NUM_CHUNKS * CHUNK_SIZE)
+// 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 AVFifoBuffer *buffer;
+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;
 #ifdef USE_SDL_INTERNAL_MIXER
 static unsigned char volume=SDL_MIX_MAXVOLUME;
 #endif
 
-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);
+// 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;
 }
 
-#ifdef USE_SDL_INTERNAL_MIXER
-static void mix_audio(void *dst, void *src, int len) {
-  SDL_MixAudio(dst, src, len, volume);
+// 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();
+  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;
 }
-#endif
 
 static int read_buffer(unsigned char* data,int len){
-  int buffered = av_fifo_size(buffer);
+  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
-  return av_fifo_generic_read(buffer, data, len, mix_audio);
+  SDL_MixAudio (data, &buffer[read_pos], first_len, volume);
 #else
-  return av_fifo_generic_read(buffer, data, len, NULL);
+  fast_memcpy (data, &buffer[read_pos], first_len);
 #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
@@ -131,7 +175,7 @@ static int init(int rate,int channels,in
 	SDL_AudioSpec aspec, obtained;
 	
 	/* Allocate ring-buffer memory */
-	buffer = av_fifo_alloc(BUFFSIZE);
+	buffer = (unsigned char *) malloc(BUFFSIZE);
 
 	mp_msg(MSGT_AO,MSGL_INFO,MSGTR_AO_SDL_INFO, rate, (channels > 1) ? "Stereo" : "Mono", af_fmt2str_short(format));
 
@@ -234,6 +278,7 @@ 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);
 
@@ -247,7 +292,6 @@ 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)
@@ -257,7 +301,8 @@ static void reset(void){
 
 	SDL_PauseAudio(1);
 	/* Reset ring-buffer state */
-	av_fifo_reset(buffer);
+	read_pos = 0;
+	write_pos = 0;
 	SDL_PauseAudio(0);
 }
 
@@ -280,7 +325,7 @@ static void audio_resume(void)
 
 // return: how many bytes can be played without blocking
 static int get_space(void){
-    return BUFFSIZE - av_fifo_size(buffer);
+    return buf_free();
 }
 
 // plays 'len' bytes of 'data'
@@ -307,7 +352,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 = av_fifo_size(buffer); // could be less
+    int buffered = BUFFSIZE - CHUNK_SIZE - buf_free(); // could be less
     return (float)(buffered + ao_data.buffersize)/(float)ao_data.bps;
 }
 


More information about the MPlayer-cvslog mailing list