summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTorsten Jager <t.jager@gmx.de>2013-09-13 12:50:30 +0200
committerTorsten Jager <t.jager@gmx.de>2013-09-13 12:50:30 +0200
commit005a3bd67c9569d5252125c402f6d9b4ae8729f5 (patch)
tree228496e05b1af6eba0a8b28779a65553502981a1
parent50caa6c2122224df42c6d8a5c88ffb5b2d4afb8b (diff)
downloadxine-lib-005a3bd67c9569d5252125c402f6d9b4ae8729f5.tar.gz
xine-lib-005a3bd67c9569d5252125c402f6d9b4ae8729f5.tar.bz2
audio_out speed control fix
This addresses an old fixme, and an occasional pthread mutex issue.
-rw-r--r--src/xine-engine/audio_out.c31
1 files changed, 21 insertions, 10 deletions
diff --git a/src/xine-engine/audio_out.c b/src/xine-engine/audio_out.c
index 3afad16fd..ca8475898 100644
--- a/src/xine-engine/audio_out.c
+++ b/src/xine-engine/audio_out.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2000-2012 the xine project
+ * Copyright (C) 2000-2013 the xine project
*
* This file is part of xine, a free video player.
*
@@ -250,8 +250,6 @@ typedef struct {
int64_t last_audio_vpts;
pthread_mutex_t current_speed_lock;
uint32_t current_speed; /* the current playback speed */
- /* FIXME: replace all this->clock->speed with this->current_speed. we should make
- * sure nobody will change speed without going through xine.c:set_speed_internal */
int slow_fast_audio; /* play audio even on slow/fast speeds */
int16_t last_sample[RESAMPLE_MAX_CHANNELS];
@@ -1045,6 +1043,12 @@ static void *ao_loop (void *this_gen) {
}
pthread_mutex_unlock(&this->flush_audio_driver_lock);
+ /* Paranoia? */
+ {
+ int new_speed = this->clock->speed;
+ if (new_speed != this->current_speed)
+ ao_set_property (&this->ao, AO_PROP_CLOCK_SPEED, new_speed);
+ }
/*
* wait until user unpauses stream
@@ -1054,11 +1058,11 @@ static void *ao_loop (void *this_gen) {
pthread_mutex_lock(&this->current_speed_lock);
if ( this->audio_loop_running &&
- (this->clock->speed == XINE_SPEED_PAUSE ||
- (this->clock->speed != XINE_FINE_SPEED_NORMAL &&
+ (this->current_speed == XINE_SPEED_PAUSE ||
+ (this->current_speed != XINE_FINE_SPEED_NORMAL &&
!this->slow_fast_audio) ) ) {
- if (this->clock->speed != XINE_SPEED_PAUSE) {
+ if (this->current_speed != XINE_SPEED_PAUSE) {
cur_time = this->clock->get_current_time (this->clock);
if (in_buf->vpts < cur_time ) {
@@ -1640,8 +1644,8 @@ static void ao_close(xine_audio_port_t *this_gen, xine_stream_t *stream) {
if (this->audio_loop_running) {
/* make sure there are no more buffers on queue */
- if (this->clock->speed == XINE_SPEED_PAUSE ||
- (this->clock->speed != XINE_FINE_SPEED_NORMAL && !this->slow_fast_audio)) {
+ if (this->current_speed == XINE_SPEED_PAUSE ||
+ (this->current_speed != XINE_FINE_SPEED_NORMAL && !this->slow_fast_audio)) {
int discard = ao_get_property(this_gen, AO_PROP_DISCARD_BUFFERS);
/* discard buffers while waiting, otherwise we'll wait forever */
ao_set_property(this_gen, AO_PROP_DISCARD_BUFFERS, 1);
@@ -1948,6 +1952,14 @@ static int ao_set_property (xine_audio_port_t *this_gen, int property, int value
break;
case AO_PROP_CLOCK_SPEED:
+ /* something to do? */
+ if (value == this->current_speed)
+ break;
+ /* TJ. pthread mutex implementation on my multicore AMD box is somewhat buggy.
+ When fed by a fast single threaded decoder like mad, audio out loop does
+ not release current speed lock long enough to wake us up here.
+ So tell loop to enter unpause waiting _before_ we wait. */
+ this->current_speed = value;
/*
* slow motion / fast forward does not play sound, drop buffered
* samples from the sound driver (check slow_fast_audio flag)
@@ -1964,7 +1976,6 @@ static int ao_set_property (xine_audio_port_t *this_gen, int property, int value
} else {
this->ao.control(&this->ao, AO_CTRL_PLAY_RESUME, NULL);
}
- this->current_speed = value;
if( this->slow_fast_audio )
ao_update_resample_factor(this);
break;
@@ -2016,7 +2027,7 @@ static void ao_flush (xine_audio_port_t *this_gen) {
this->flush_audio_driver++;
/* do not try this in paused mode */
- while( this->flush_audio_driver && this->clock->speed != XINE_SPEED_PAUSE) {
+ while( this->flush_audio_driver && this->current_speed != XINE_SPEED_PAUSE) {
struct timeval tv;
struct timespec ts;