[inputs/player] Fixup part 1
This commit is contained in:
parent
d008e241cf
commit
b7add1d0fa
23
src/input.c
23
src/input.c
|
@ -236,7 +236,7 @@ stop(void *arg, int *retval)
|
||||||
|
|
||||||
type = input_now_reading.type;
|
type = input_now_reading.type;
|
||||||
|
|
||||||
if (inputs[type]->stop)
|
if (inputs[type]->stop && input_now_reading.open)
|
||||||
inputs[type]->stop(&input_now_reading);
|
inputs[type]->stop(&input_now_reading);
|
||||||
|
|
||||||
flush(&flags);
|
flush(&flags);
|
||||||
|
@ -491,10 +491,18 @@ input_write(struct evbuffer *evbuf, struct media_quality *quality, short flags)
|
||||||
|
|
||||||
if (flags)
|
if (flags)
|
||||||
{
|
{
|
||||||
if (input_buffer.bytes_written > INPUT_BUFFER_THRESHOLD)
|
if (read_end)
|
||||||
marker_add(input_buffer.bytes_written - INPUT_BUFFER_THRESHOLD, INPUT_FLAG_START_NEXT);
|
{
|
||||||
else
|
input_now_reading.open = false;
|
||||||
marker_add(input_buffer.bytes_written, INPUT_FLAG_START_NEXT);
|
// This controls when the player will open the next track in the queue
|
||||||
|
if (input_buffer.bytes_read + INPUT_BUFFER_THRESHOLD < input_buffer.bytes_written)
|
||||||
|
// The player's read is behind, tell it to open when it reaches where
|
||||||
|
// we are minus the buffer size
|
||||||
|
marker_add(input_buffer.bytes_written - INPUT_BUFFER_THRESHOLD, INPUT_FLAG_START_NEXT);
|
||||||
|
else
|
||||||
|
// The player's read is close to our write, so open right away
|
||||||
|
marker_add(input_buffer.bytes_read, INPUT_FLAG_START_NEXT);
|
||||||
|
}
|
||||||
|
|
||||||
// Note this marker is added at the post-write position, since EOF, error
|
// Note this marker is added at the post-write position, since EOF, error
|
||||||
// and metadata belong there.
|
// and metadata belong there.
|
||||||
|
@ -578,7 +586,10 @@ play(evutil_socket_t fd, short flags, void *arg)
|
||||||
// loop any more. input_write() will pass the message to the player.
|
// loop any more. input_write() will pass the message to the player.
|
||||||
ret = inputs[input_now_reading.type]->play(&input_now_reading);
|
ret = inputs[input_now_reading.type]->play(&input_now_reading);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return; // Error or EOF, so don't come back
|
{
|
||||||
|
input_now_reading.open = false;
|
||||||
|
return; // Error or EOF, so don't come back
|
||||||
|
}
|
||||||
|
|
||||||
event_add(inputev, &tv);
|
event_add(inputev, &tv);
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,9 +69,12 @@ stop(struct input_source *source)
|
||||||
struct transcode_ctx *ctx = source->input_ctx;
|
struct transcode_ctx *ctx = source->input_ctx;
|
||||||
|
|
||||||
transcode_cleanup(&ctx);
|
transcode_cleanup(&ctx);
|
||||||
evbuffer_free(source->evbuf);
|
|
||||||
|
if (source->evbuf)
|
||||||
|
evbuffer_free(source->evbuf);
|
||||||
|
|
||||||
source->input_ctx = NULL;
|
source->input_ctx = NULL;
|
||||||
|
source->evbuf = NULL;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -840,7 +840,8 @@ stop(struct input_source *source)
|
||||||
|
|
||||||
DPRINTF(E_DBG, L_PLAYER, "Stopping pipe\n");
|
DPRINTF(E_DBG, L_PLAYER, "Stopping pipe\n");
|
||||||
|
|
||||||
evbuffer_free(source->evbuf);
|
if (source->evbuf)
|
||||||
|
evbuffer_free(source->evbuf);
|
||||||
|
|
||||||
pipe_close(pipe->fd);
|
pipe_close(pipe->fd);
|
||||||
|
|
||||||
|
@ -858,6 +859,7 @@ stop(struct input_source *source)
|
||||||
pipe_free(pipe);
|
pipe_free(pipe);
|
||||||
|
|
||||||
source->input_ctx = NULL;
|
source->input_ctx = NULL;
|
||||||
|
source->evbuf = NULL;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
41
src/player.c
41
src/player.c
|
@ -668,7 +668,10 @@ source_next_create(struct player_source *current)
|
||||||
struct db_queue_item *queue_item;
|
struct db_queue_item *queue_item;
|
||||||
|
|
||||||
if (!current)
|
if (!current)
|
||||||
return NULL;
|
{
|
||||||
|
DPRINTF(E_LOG, L_PLAYER, "Bug! source_next_create called without a current source\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
queue_item = queue_item_next(current->item_id);
|
queue_item = queue_item_next(current->item_id);
|
||||||
if (!queue_item)
|
if (!queue_item)
|
||||||
|
@ -783,7 +786,7 @@ session_update_read_next(void)
|
||||||
{
|
{
|
||||||
struct player_source *ps;
|
struct player_source *ps;
|
||||||
|
|
||||||
ps = source_next_create(pb_session.reading_next);
|
ps = source_next_create(pb_session.reading_now);
|
||||||
source_free(&pb_session.reading_next);
|
source_free(&pb_session.reading_next);
|
||||||
pb_session.reading_next = ps;
|
pb_session.reading_next = ps;
|
||||||
}
|
}
|
||||||
|
@ -799,12 +802,17 @@ session_update_read_eof(void)
|
||||||
pb_session.reading_now = pb_session.reading_next;
|
pb_session.reading_now = pb_session.reading_next;
|
||||||
pb_session.reading_next = NULL;
|
pb_session.reading_next = NULL;
|
||||||
|
|
||||||
|
|
||||||
// There is nothing else to play
|
// There is nothing else to play
|
||||||
if (!pb_session.reading_now)
|
if (!pb_session.reading_now)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// We inherit this because the input will only notify on quality changes, not
|
||||||
|
// if it the same as the previous track
|
||||||
|
pb_session.reading_now->quality = pb_session.reading_prev->quality;
|
||||||
|
pb_session.reading_now->output_buffer_samples = pb_session.reading_prev->output_buffer_samples;
|
||||||
|
|
||||||
pb_session.reading_now->read_start = pb_session.pos;
|
pb_session.reading_now->read_start = pb_session.pos;
|
||||||
|
pb_session.reading_now->play_start = pb_session.pos + pb_session.reading_now->output_buffer_samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -927,12 +935,14 @@ event_read_error()
|
||||||
event_read_eof();
|
event_read_eof();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Kicks of input reading of next source (async), session is not affected by
|
// Kicks of input reading of next source (async)
|
||||||
// this, so there is no session update
|
|
||||||
static void
|
static void
|
||||||
event_read_start_next()
|
event_read_start_next()
|
||||||
{
|
{
|
||||||
DPRINTF(E_DBG, L_PLAYER, "event_start_next()\n");
|
DPRINTF(E_DBG, L_PLAYER, "event_read_start_next()\n");
|
||||||
|
|
||||||
|
// Attaches next item to session as reading_next
|
||||||
|
session_update_read_next();
|
||||||
|
|
||||||
source_next();
|
source_next();
|
||||||
}
|
}
|
||||||
|
@ -1024,6 +1034,17 @@ source_read(int *nbytes, int *nsamples, struct media_quality *quality, uint8_t *
|
||||||
{
|
{
|
||||||
short flags;
|
short flags;
|
||||||
|
|
||||||
|
// Nothing to read, stream silence until event_read() stops playback
|
||||||
|
if (!pb_session.reading_now && pb_session.playing_now)
|
||||||
|
{
|
||||||
|
memset(buf, 0, len);
|
||||||
|
*quality = pb_session.playing_now->quality;
|
||||||
|
*nbytes = len;
|
||||||
|
*nsamples = BTOS(*nbytes, quality->bits_per_sample, quality->channels);
|
||||||
|
event_read(*nsamples);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
*quality = pb_session.reading_now->quality;
|
*quality = pb_session.reading_now->quality;
|
||||||
*nsamples = 0;
|
*nsamples = 0;
|
||||||
*nbytes = input_read(buf, len, &flags);
|
*nbytes = input_read(buf, len, &flags);
|
||||||
|
@ -1110,14 +1131,14 @@ playback_cb(int fd, short what, void *arg)
|
||||||
pb_write_recovery = false;
|
pb_write_recovery = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// debug_counter++;
|
debug_counter++;
|
||||||
// if (debug_counter % 100 == 0)
|
if (debug_counter % 100 == 0)
|
||||||
// session_dump();
|
session_dump();
|
||||||
|
|
||||||
// If there was an overrun, we will try to read/write a corresponding number
|
// If there was an overrun, we will try to read/write a corresponding number
|
||||||
// of times so we catch up. The read from the input is non-blocking, so it
|
// of times so we catch up. The read from the input is non-blocking, so it
|
||||||
// should not bring us further behind, even if there is no data.
|
// should not bring us further behind, even if there is no data.
|
||||||
for (i = 1 + overrun + pb_read_deficit; i > 0 && pb_session.reading_now; i--)
|
for (i = 1 + overrun + pb_read_deficit; i > 0; i--)
|
||||||
{
|
{
|
||||||
ret = source_read(&nbytes, &nsamples, &quality, pb_session.buffer, pb_session.bufsize);
|
ret = source_read(&nbytes, &nsamples, &quality, pb_session.buffer, pb_session.bufsize);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
|
|
Loading…
Reference in New Issue