[inputs/player] Fixup part 1

This commit is contained in:
ejurgensen 2019-02-17 10:41:11 +01:00
parent d008e241cf
commit b7add1d0fa
4 changed files with 55 additions and 18 deletions

View File

@ -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);
} }

View File

@ -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;
} }

View File

@ -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;
} }

View File

@ -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)