mirror of
https://github.com/owntone/owntone-server.git
synced 2025-01-15 16:53:18 -05:00
[input] Pass read errors to the player through the input buffer
This commit is contained in:
parent
6c94cdd635
commit
5d74c98431
40
src/input.c
40
src/input.c
@ -71,6 +71,8 @@ struct input_buffer
|
|||||||
|
|
||||||
// If non-zero, remaining length of buffer until EOF
|
// If non-zero, remaining length of buffer until EOF
|
||||||
size_t eof;
|
size_t eof;
|
||||||
|
// If non-zero, remaining length of buffer until read error occurred
|
||||||
|
size_t error;
|
||||||
// If non-zero, remaining length of buffer until (possible) new metadata
|
// If non-zero, remaining length of buffer until (possible) new metadata
|
||||||
size_t metadata;
|
size_t metadata;
|
||||||
|
|
||||||
@ -104,6 +106,17 @@ flags_set(size_t len)
|
|||||||
{
|
{
|
||||||
short flags = 0;
|
short flags = 0;
|
||||||
|
|
||||||
|
if (input_buffer.error)
|
||||||
|
{
|
||||||
|
if (len >= input_buffer.error)
|
||||||
|
{
|
||||||
|
flags |= INPUT_FLAG_ERROR;
|
||||||
|
input_buffer.error = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
input_buffer.error -= len;
|
||||||
|
}
|
||||||
|
|
||||||
if (input_buffer.eof)
|
if (input_buffer.eof)
|
||||||
{
|
{
|
||||||
if (len >= input_buffer.eof)
|
if (len >= input_buffer.eof)
|
||||||
@ -187,22 +200,25 @@ source_check_and_map(struct player_source *ps, const char *action, char check_se
|
|||||||
/* ----------------------------- PLAYBACK LOOP ---------------------------- */
|
/* ----------------------------- PLAYBACK LOOP ---------------------------- */
|
||||||
/* Thread: input */
|
/* Thread: input */
|
||||||
|
|
||||||
// TODO Thread safety of ps? Do we need the return of the loop?
|
// TODO Thread safety of ps?
|
||||||
static void *
|
static void *
|
||||||
playback(void *arg)
|
playback(void *arg)
|
||||||
{
|
{
|
||||||
struct player_source *ps = arg;
|
struct player_source *ps = arg;
|
||||||
int type;
|
int type;
|
||||||
|
int ret;
|
||||||
|
|
||||||
type = source_check_and_map(ps, "start", 1);
|
type = source_check_and_map(ps, "start", 1);
|
||||||
if ((type < 0) || (inputs[type]->disabled))
|
if ((type < 0) || (inputs[type]->disabled))
|
||||||
goto thread_exit;
|
goto thread_exit;
|
||||||
|
|
||||||
// Loops until input_loop_break is set or no more input, e.g. EOF
|
// Loops until input_loop_break is set or no more input, e.g. EOF
|
||||||
inputs[type]->start(ps);
|
ret = inputs[type]->start(ps);
|
||||||
|
if (ret < 0)
|
||||||
|
input_write(NULL, INPUT_FLAG_ERROR);
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
DPRINTF(E_DBG, L_PLAYER, "Playback loop stopped (break is %d)\n", input_loop_break);
|
DPRINTF(E_DBG, L_PLAYER, "Playback loop stopped (break is %d, ret %d)\n", input_loop_break, ret);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
thread_exit:
|
thread_exit:
|
||||||
@ -231,7 +247,7 @@ input_write(struct evbuffer *evbuf, short flags)
|
|||||||
|
|
||||||
pthread_mutex_lock(&input_buffer.mutex);
|
pthread_mutex_lock(&input_buffer.mutex);
|
||||||
|
|
||||||
while ( (!input_loop_break) && (evbuffer_get_length(input_buffer.evbuf) > INPUT_BUFFER_THRESHOLD) )
|
while ( (!input_loop_break) && (evbuffer_get_length(input_buffer.evbuf) > INPUT_BUFFER_THRESHOLD) && evbuf )
|
||||||
{
|
{
|
||||||
if (input_buffer.full_cb)
|
if (input_buffer.full_cb)
|
||||||
{
|
{
|
||||||
@ -249,19 +265,26 @@ input_write(struct evbuffer *evbuf, short flags)
|
|||||||
pthread_cond_timedwait(&input_buffer.cond, &input_buffer.mutex, &ts);
|
pthread_cond_timedwait(&input_buffer.cond, &input_buffer.mutex, &ts);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!input_loop_break)
|
if (input_loop_break)
|
||||||
{
|
{
|
||||||
|
pthread_mutex_unlock(&input_buffer.mutex);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (evbuf)
|
||||||
ret = evbuffer_add_buffer(input_buffer.evbuf, evbuf);
|
ret = evbuffer_add_buffer(input_buffer.evbuf, evbuf);
|
||||||
|
else
|
||||||
|
ret = 0;
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
DPRINTF(E_LOG, L_PLAYER, "Error adding stream data to input buffer\n");
|
DPRINTF(E_LOG, L_PLAYER, "Error adding stream data to input buffer\n");
|
||||||
|
|
||||||
|
if (!input_buffer.error && (flags & INPUT_FLAG_ERROR))
|
||||||
|
input_buffer.error = evbuffer_get_length(input_buffer.evbuf);
|
||||||
if (!input_buffer.eof && (flags & INPUT_FLAG_EOF))
|
if (!input_buffer.eof && (flags & INPUT_FLAG_EOF))
|
||||||
input_buffer.eof = evbuffer_get_length(input_buffer.evbuf);
|
input_buffer.eof = evbuffer_get_length(input_buffer.evbuf);
|
||||||
if (!input_buffer.metadata && (flags & INPUT_FLAG_METADATA))
|
if (!input_buffer.metadata && (flags & INPUT_FLAG_METADATA))
|
||||||
input_buffer.metadata = evbuffer_get_length(input_buffer.evbuf);
|
input_buffer.metadata = evbuffer_get_length(input_buffer.evbuf);
|
||||||
}
|
|
||||||
else
|
|
||||||
ret = 0;
|
|
||||||
|
|
||||||
pthread_mutex_unlock(&input_buffer.mutex);
|
pthread_mutex_unlock(&input_buffer.mutex);
|
||||||
|
|
||||||
@ -452,6 +475,7 @@ input_flush(short *flags)
|
|||||||
|
|
||||||
*flags = flags_set(len);
|
*flags = flags_set(len);
|
||||||
|
|
||||||
|
input_buffer.error = 0;
|
||||||
input_buffer.eof = 0;
|
input_buffer.eof = 0;
|
||||||
input_buffer.metadata = 0;
|
input_buffer.metadata = 0;
|
||||||
input_buffer.full_cb = NULL;
|
input_buffer.full_cb = NULL;
|
||||||
|
@ -25,8 +25,10 @@ enum input_flags
|
|||||||
INPUT_FLAG_NONBLOCK = (1 << 0),
|
INPUT_FLAG_NONBLOCK = (1 << 0),
|
||||||
// Flags end of file
|
// Flags end of file
|
||||||
INPUT_FLAG_EOF = (1 << 1),
|
INPUT_FLAG_EOF = (1 << 1),
|
||||||
|
// Flags error reading file
|
||||||
|
INPUT_FLAG_ERROR = (1 << 2),
|
||||||
// Flags possible new stream metadata
|
// Flags possible new stream metadata
|
||||||
INPUT_FLAG_METADATA = (1 << 2),
|
INPUT_FLAG_METADATA = (1 << 3),
|
||||||
};
|
};
|
||||||
|
|
||||||
struct player_source
|
struct player_source
|
||||||
@ -164,7 +166,7 @@ input_wait(void);
|
|||||||
*
|
*
|
||||||
* @in data Output buffer
|
* @in data Output buffer
|
||||||
* @in size How much data to move to the output buffer
|
* @in size How much data to move to the output buffer
|
||||||
* @out flags Flags INPUT_FLAG_EOF or INPUT_FLAG_METADATA
|
* @out flags Flags INPUT_FLAG_*
|
||||||
* @return Number of bytes moved, -1 on error
|
* @return Number of bytes moved, -1 on error
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
|
@ -1058,7 +1058,7 @@ source_read(uint8_t *buf, int len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
nbytes = input_read(buf, len, &flags);
|
nbytes = input_read(buf, len, &flags);
|
||||||
if (nbytes < 0)
|
if ((nbytes < 0) || (flags & INPUT_FLAG_ERROR))
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_PLAYER, "Error reading source %d\n", cur_streaming->id);
|
DPRINTF(E_LOG, L_PLAYER, "Error reading source %d\n", cur_streaming->id);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user