added ob_set_lazy()
In lazy mode (previously the default), outputBuffer.c only wakes up the player when it was previously empty. That caused a deadlock when the player was waiting for buffered_before_play, since the decoder wouldn't wake up the player when buffered_before_play was reached. In non-lazy mode, always wake up the player when a new chunk was decoded. git-svn-id: https://svn.musicpd.org/mpd/trunk@7364 09075e82-0dd4-0310-85a5-a0d7c8717e4f
This commit is contained in:
parent
071c8f4ac7
commit
7c952c4f4b
@ -400,6 +400,8 @@ static void decodeParent(void)
|
|||||||
/** the position of the first chunk in the next song */
|
/** the position of the first chunk in the next song */
|
||||||
int next = -1;
|
int next = -1;
|
||||||
|
|
||||||
|
ob_set_lazy(0);
|
||||||
|
|
||||||
if (waitOnDecode(&decodeWaitedOn) < 0)
|
if (waitOnDecode(&decodeWaitedOn) < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -421,9 +423,11 @@ static void decodeParent(void)
|
|||||||
/* not enough decoded buffer space yet */
|
/* not enough decoded buffer space yet */
|
||||||
player_sleep();
|
player_sleep();
|
||||||
continue;
|
continue;
|
||||||
} else
|
} else {
|
||||||
/* buffering is complete */
|
/* buffering is complete */
|
||||||
buffering = 0;
|
buffering = 0;
|
||||||
|
ob_set_lazy(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (decodeWaitedOn) {
|
if (decodeWaitedOn) {
|
||||||
@ -513,6 +517,7 @@ static void decodeParent(void)
|
|||||||
}
|
}
|
||||||
nextChunk = ob_absolute(crossFadeChunks);
|
nextChunk = ob_absolute(crossFadeChunks);
|
||||||
if (nextChunk >= 0) {
|
if (nextChunk >= 0) {
|
||||||
|
ob_set_lazy(1);
|
||||||
crossFade(beginChunk,
|
crossFade(beginChunk,
|
||||||
ob_get_chunk(nextChunk),
|
ob_get_chunk(nextChunk),
|
||||||
&(ob.audioFormat),
|
&(ob.audioFormat),
|
||||||
@ -529,6 +534,7 @@ static void decodeParent(void)
|
|||||||
} else {
|
} else {
|
||||||
/* wait for the
|
/* wait for the
|
||||||
decoder */
|
decoder */
|
||||||
|
ob_set_lazy(0);
|
||||||
player_sleep();
|
player_sleep();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,7 @@ void ob_init(unsigned int size)
|
|||||||
ob.size = size;
|
ob.size = size;
|
||||||
ob.begin = 0;
|
ob.begin = 0;
|
||||||
ob.end = 0;
|
ob.end = 0;
|
||||||
|
ob.lazy = 0;
|
||||||
ob.chunks[0].chunkSize = 0;
|
ob.chunks[0].chunkSize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,7 +62,7 @@ static inline unsigned successor(unsigned i)
|
|||||||
*/
|
*/
|
||||||
static void output_buffer_expand(unsigned i)
|
static void output_buffer_expand(unsigned i)
|
||||||
{
|
{
|
||||||
int was_empty = ob_is_empty();
|
int was_empty = !ob.lazy || ob_is_empty();
|
||||||
|
|
||||||
assert(i == (ob.end + 1) % ob.size);
|
assert(i == (ob.end + 1) % ob.size);
|
||||||
assert(i != ob.end);
|
assert(i != ob.end);
|
||||||
@ -91,6 +92,11 @@ void ob_flush(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ob_set_lazy(int lazy)
|
||||||
|
{
|
||||||
|
ob.lazy = lazy;
|
||||||
|
}
|
||||||
|
|
||||||
int ob_is_empty(void)
|
int ob_is_empty(void)
|
||||||
{
|
{
|
||||||
return ob.begin == ob.end;
|
return ob.begin == ob.end;
|
||||||
|
@ -53,6 +53,10 @@ typedef struct _OutputBuffer {
|
|||||||
/** the index after the last decoded chunk */
|
/** the index after the last decoded chunk */
|
||||||
unsigned int volatile end;
|
unsigned int volatile end;
|
||||||
|
|
||||||
|
/** non-zero if the player thread should only we woken up if
|
||||||
|
the buffer becomes non-empty */
|
||||||
|
int lazy;
|
||||||
|
|
||||||
AudioFormat audioFormat;
|
AudioFormat audioFormat;
|
||||||
ConvState convState;
|
ConvState convState;
|
||||||
} OutputBuffer;
|
} OutputBuffer;
|
||||||
@ -65,6 +69,14 @@ void ob_clear(void);
|
|||||||
|
|
||||||
void ob_flush(void);
|
void ob_flush(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When a chunk is decoded, we wake up the player thread to tell him
|
||||||
|
* about it. In "lazy" mode, we only wake him up when the buffer was
|
||||||
|
* previously empty, i.e. when the player thread has really been
|
||||||
|
* waiting for us.
|
||||||
|
*/
|
||||||
|
void ob_set_lazy(int lazy);
|
||||||
|
|
||||||
/** is the buffer empty? */
|
/** is the buffer empty? */
|
||||||
int ob_is_empty(void);
|
int ob_is_empty(void);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user