summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiguel Freitas <miguelfreitas@users.sourceforge.net>2002-05-21 20:39:03 +0000
committerMiguel Freitas <miguelfreitas@users.sourceforge.net>2002-05-21 20:39:03 +0000
commit55b3044b0866913d8a08717c5c35ba5a3a5c0428 (patch)
treea15f1ffa741a44dd2c5296bfcb571734ff085479
parent8851e1a66d79d6a88f4dbd053ed1545335ca5422 (diff)
downloadxine-lib-55b3044b0866913d8a08717c5c35ba5a3a5c0428.tar.gz
xine-lib-55b3044b0866913d8a08717c5c35ba5a3a5c0428.tar.bz2
better output buffer calculations (when resampling) by Ian Goldberg
<ian@cypherpunks.ca> CVS patchset: 1926 CVS date: 2002/05/21 20:39:03
-rw-r--r--src/xine-engine/audio_out.c31
-rw-r--r--src/xine-engine/audio_out.h3
2 files changed, 29 insertions, 5 deletions
diff --git a/src/xine-engine/audio_out.c b/src/xine-engine/audio_out.c
index 12f2bbf9c..d63e2443d 100644
--- a/src/xine-engine/audio_out.c
+++ b/src/xine-engine/audio_out.c
@@ -17,7 +17,7 @@
* along with self program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: audio_out.c,v 1.53 2002/04/29 23:32:00 jcdutton Exp $
+ * $Id: audio_out.c,v 1.54 2002/05/21 20:39:03 miguelfreitas Exp $
*
* 22-8-2001 James imported some useful AC3 sections from the previous alsa driver.
* (c) 2001 Andy Lo A Foe <andy@alsaplayer.org>
@@ -255,6 +255,14 @@ static void ao_fill_gap (ao_instance_t *this, int64_t pts_len) {
}
}
+static void ensure_buffer_size (ao_instance_t *this, int size)
+{
+ if (this->frame_buffer_size < size) {
+ free (this->frame_buffer);
+ this->frame_buffer = xine_xmalloc (size);
+ this->frame_buffer_size = size;
+ }
+}
static void *ao_loop (void *this_gen) {
@@ -268,6 +276,7 @@ static void *ao_loop (void *this_gen) {
int paused_wait;
int64_t last_sync_time;
int bufs_since_sync;
+ double acc_output_frames, output_frame_excess = 0;
last_sync_time = bufs_since_sync = 0;
@@ -363,13 +372,22 @@ static void *ao_loop (void *this_gen) {
* resample and output audio data
*/
- num_output_frames = (double) buf->num_frames * this->frame_rate_factor;
+ /* calculate number of output frames (after resampling) */
+ acc_output_frames = (double) buf->num_frames * this->frame_rate_factor
+ + output_frame_excess;
+
+ /* Truncate to an integer */
+ num_output_frames = acc_output_frames;
+
+ /* Keep track of the amount truncated */
+ output_frame_excess = acc_output_frames - (double) num_output_frames;
#ifdef LOG
printf ("audio_out: outputting %d frames\n", num_output_frames);
#endif
- if ((!this->do_resample)
+ /* check if resample is needed */
+ if (((!this->do_resample) || (buf->num_frames == num_output_frames))
&& (this->mode != AO_CAP_MODE_A52)
&& (this->mode != AO_CAP_MODE_AC5)) {
@@ -377,26 +395,31 @@ static void *ao_loop (void *this_gen) {
buf->num_frames );
} else switch (this->mode) {
case AO_CAP_MODE_MONO:
+ ensure_buffer_size(this, 2*num_output_frames);
audio_out_resample_mono (buf->mem, buf->num_frames,
this->frame_buffer, num_output_frames);
this->driver->write(this->driver, this->frame_buffer, num_output_frames);
break;
case AO_CAP_MODE_STEREO:
+ ensure_buffer_size(this, 4*num_output_frames);
audio_out_resample_stereo (buf->mem, buf->num_frames,
this->frame_buffer, num_output_frames);
this->driver->write(this->driver, this->frame_buffer, num_output_frames);
break;
case AO_CAP_MODE_4CHANNEL:
+ ensure_buffer_size(this, 8*num_output_frames);
audio_out_resample_4channel (buf->mem, buf->num_frames,
this->frame_buffer, num_output_frames);
this->driver->write(this->driver, this->frame_buffer, num_output_frames);
break;
case AO_CAP_MODE_5CHANNEL:
+ ensure_buffer_size(this, 10*num_output_frames);
audio_out_resample_5channel (buf->mem, buf->num_frames,
this->frame_buffer, num_output_frames);
this->driver->write(this->driver, this->frame_buffer, num_output_frames);
break;
case AO_CAP_MODE_5_1CHANNEL:
+ ensure_buffer_size(this, 12*num_output_frames);
audio_out_resample_6channel (buf->mem, buf->num_frames,
this->frame_buffer, num_output_frames);
this->driver->write(this->driver, this->frame_buffer, num_output_frames);
@@ -654,8 +677,8 @@ ao_instance_t *ao_new_instance (ao_driver_t *driver, xine_t *xine) {
this->control = ao_control;
this->audio_loop_running = 0;
this->audio_paused = 0;
- /* FIXME: is 4* good enough for all resample cases?? */
this->frame_buffer = xine_xmalloc (4 * AUDIO_BUF_SIZE);
+ this->frame_buffer_size = 4 * AUDIO_BUF_SIZE;
this->zero_space = xine_xmalloc (ZERO_BUF_SIZE * 2 * 6);
this->gap_tolerance = driver->get_gap_tolerance (this->driver);
diff --git a/src/xine-engine/audio_out.h b/src/xine-engine/audio_out.h
index fb73dc483..5784c6b39 100644
--- a/src/xine-engine/audio_out.h
+++ b/src/xine-engine/audio_out.h
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: audio_out.h,v 1.28 2002/03/26 01:47:17 miguelfreitas Exp $
+ * $Id: audio_out.h,v 1.29 2002/05/21 20:39:03 miguelfreitas Exp $
*/
#ifndef HAVE_AUDIO_OUT_H
#define HAVE_AUDIO_OUT_H
@@ -219,6 +219,7 @@ struct ao_instance_s {
audio_fifo_t *free_fifo;
audio_fifo_t *out_fifo;
uint16_t *frame_buffer;
+ uint32_t frame_buffer_size;
int16_t *zero_space;
};