Abandon raop_metadata_arg, and defer metadata time setting

This commit is contained in:
ejurgensen 2015-04-09 21:04:35 +02:00
parent ad81e05ab4
commit f1931bfc1a
3 changed files with 60 additions and 70 deletions

View File

@ -139,6 +139,16 @@ struct icy_artwork
char *artwork_url; char *artwork_url;
}; };
struct player_metadata
{
int id;
uint64_t rtptime;
uint64_t offset;
int startup;
struct raop_metadata *rmd;
};
struct player_command struct player_command
{ {
pthread_mutex_t lck; pthread_mutex_t lck;
@ -154,9 +164,9 @@ struct player_command
void *noarg; void *noarg;
struct spk_enum *spk_enum; struct spk_enum *spk_enum;
struct raop_device *rd; struct raop_device *rd;
struct raop_metadata *rmd;
struct player_status *status; struct player_status *status;
struct player_source *ps; struct player_source *ps;
struct player_metadata *pmd;
player_status_handler status_handler; player_status_handler status_handler;
uint32_t *id_ptr; uint32_t *id_ptr;
uint64_t *raop_ids; uint64_t *raop_ids;
@ -580,7 +590,7 @@ static int
queue_clear(struct player_command *cmd); queue_clear(struct player_command *cmd);
static void static void
player_metadata_send(struct raop_metadata *rmd); player_metadata_send(struct player_metadata *pmd);
static void static void
player_laudio_status_cb(enum laudio_state status) player_laudio_status_cb(enum laudio_state status)
@ -647,12 +657,12 @@ playcount_inc_cb(void *arg)
static void static void
metadata_prepare_cb(void *arg) metadata_prepare_cb(void *arg)
{ {
struct raop_metadata *rmd; struct player_metadata *pmd = arg;
rmd = raop_metadata_prepare(arg); pmd->rmd = raop_metadata_prepare(pmd->id);
if (rmd) if (pmd->rmd)
player_metadata_send(rmd); player_metadata_send(pmd);
} }
/* Callback from the worker thread (async operation as it may block) */ /* Callback from the worker thread (async operation as it may block) */
@ -682,37 +692,37 @@ metadata_purge(void)
static void static void
metadata_trigger(struct player_source *ps, int startup) metadata_trigger(struct player_source *ps, int startup)
{ {
struct raop_metadata_arg rma; struct player_metadata pmd;
rma.id = ps->id; memset(&pmd, 0, sizeof(struct player_metadata));
rma.offset = 0;
rma.startup = startup; pmd.id = ps->id;
pmd.startup = startup;
/* Determine song boundaries, dependent on context */ /* Determine song boundaries, dependent on context */
/* Restart after pause/seek */ /* Restart after pause/seek */
if (ps->stream_start) if (ps->stream_start)
{ {
rma.offset = ps->output_start - ps->stream_start; pmd.offset = ps->output_start - ps->stream_start;
rma.rtptime = ps->stream_start; pmd.rtptime = ps->stream_start;
} }
else if (startup) else if (startup)
{ {
rma.rtptime = last_rtptime + AIRTUNES_V2_PACKET_SAMPLES; /* Will be set later, right before sending */
} }
/* Generic case */ /* Generic case */
else if (cur_streaming && (cur_streaming->end)) else if (cur_streaming && (cur_streaming->end))
{ {
rma.rtptime = cur_streaming->end + 1; pmd.rtptime = cur_streaming->end + 1;
} }
else else
{ {
rma.rtptime = 0;
DPRINTF(E_LOG, L_PLAYER, "PTOH! Unhandled song boundary case in metadata_trigger()\n"); DPRINTF(E_LOG, L_PLAYER, "PTOH! Unhandled song boundary case in metadata_trigger()\n");
} }
/* Defer the actual work of preparing the metadata to the worker thread */ /* Defer the actual work of preparing the metadata to the worker thread */
worker_execute(metadata_prepare_cb, &rma, sizeof(struct raop_metadata_arg), 0); worker_execute(metadata_prepare_cb, &pmd, sizeof(struct player_metadata), 0);
} }
static void static void
@ -2175,11 +2185,17 @@ device_remove_family(struct player_command *cmd)
static int static int
metadata_send(struct player_command *cmd) metadata_send(struct player_command *cmd)
{ {
struct raop_metadata *rmd; struct player_metadata *pmd;
rmd = cmd->arg.rmd; pmd = cmd->arg.pmd;
raop_metadata_send(rmd); /* Do the setting of rtptime which was deferred in metadata_trigger because we
* wanted to wait until we had the actual last_rtptime
*/
if ((pmd->rtptime == 0) && (pmd->startup))
pmd->rtptime = last_rtptime + AIRTUNES_V2_PACKET_SAMPLES;
raop_metadata_send(pmd->rmd, pmd->rtptime, pmd->offset, pmd->startup);
return 0; return 0;
} }
@ -4896,35 +4912,19 @@ player_device_remove(struct raop_device *rd)
/* Thread: worker */ /* Thread: worker */
static void static void
player_metadata_send(struct raop_metadata *rmd) player_metadata_send(struct player_metadata *pmd)
{ {
struct player_command *cmd; struct player_command cmd;
int ret;
cmd = (struct player_command *)malloc(sizeof(struct player_command)); command_init(&cmd);
if (!cmd)
{
DPRINTF(E_LOG, L_PLAYER, "Could not allocate player_command\n");
raop_metadata_free(rmd); cmd.func = metadata_send;
return; cmd.func_bh = NULL;
} cmd.arg.pmd = pmd;
memset(cmd, 0, sizeof(struct player_command)); sync_command(&cmd);
cmd->nonblock = 1; command_deinit(&cmd);
cmd->func = metadata_send;
cmd->arg.rmd = rmd;
ret = nonblock_command(cmd);
if (ret < 0)
{
free(cmd);
raop_metadata_free(rmd);
return;
}
} }

View File

@ -154,9 +154,6 @@ struct raop_metadata
uint64_t start; uint64_t start;
uint64_t end; uint64_t end;
uint64_t offset;
int startup;
struct raop_metadata *next; struct raop_metadata *next;
}; };
@ -756,7 +753,7 @@ raop_metadata_prune(uint64_t rtptime)
/* Thread: worker */ /* Thread: worker */
struct raop_metadata * struct raop_metadata *
raop_metadata_prepare(struct raop_metadata_arg *rma) raop_metadata_prepare(int id)
{ {
struct query_params qp; struct query_params qp;
struct db_media_file_info dbmfi; struct db_media_file_info dbmfi;
@ -785,10 +782,10 @@ raop_metadata_prepare(struct raop_metadata_arg *rma)
goto skip_artwork; goto skip_artwork;
} }
ret = artwork_get_item(rma->id, 600, 600, rmd->artwork); ret = artwork_get_item(id, 600, 600, rmd->artwork);
if (ret < 0) if (ret < 0)
{ {
DPRINTF(E_INFO, L_RAOP, "Failed to retrieve artwork for file id %d; no artwork will be sent\n", rma->id); DPRINTF(E_INFO, L_RAOP, "Failed to retrieve artwork for file id %d; no artwork will be sent\n", id);
evbuffer_free(rmd->artwork); evbuffer_free(rmd->artwork);
rmd->artwork = NULL; rmd->artwork = NULL;
@ -805,10 +802,10 @@ raop_metadata_prepare(struct raop_metadata_arg *rma)
qp.sort = S_NONE; qp.sort = S_NONE;
qp.filter = filter; qp.filter = filter;
ret = snprintf(filter, sizeof(filter), "id = %d", rma->id); ret = snprintf(filter, sizeof(filter), "id = %d", id);
if ((ret < 0) || (ret >= sizeof(filter))) if ((ret < 0) || (ret >= sizeof(filter)))
{ {
DPRINTF(E_LOG, L_RAOP, "Could not build filter for file id %d; metadata will not be sent\n", rma->id); DPRINTF(E_LOG, L_RAOP, "Could not build filter for file id %d; metadata will not be sent\n", id);
goto out_rmd; goto out_rmd;
} }
@ -824,7 +821,7 @@ raop_metadata_prepare(struct raop_metadata_arg *rma)
ret = db_query_fetch_file(&qp, &dbmfi); ret = db_query_fetch_file(&qp, &dbmfi);
if (ret < 0) if (ret < 0)
{ {
DPRINTF(E_LOG, L_RAOP, "Couldn't fetch file id %d; metadata will not be sent\n", rma->id); DPRINTF(E_LOG, L_RAOP, "Couldn't fetch file id %d; metadata will not be sent\n", id);
goto out_query; goto out_query;
} }
@ -867,11 +864,9 @@ raop_metadata_prepare(struct raop_metadata_arg *rma)
db_query_end(&qp); db_query_end(&qp);
rmd->start = rma->rtptime; /* raop_metadata_send() will add rtptime to these */
rmd->end = rma->rtptime + (duration * 44100UL) / 1000UL; rmd->start = 0;
rmd->end = (duration * 44100UL) / 1000UL;
rmd->startup = rma->startup;
rmd->offset = rma->offset;
return rmd; return rmd;
@ -2162,12 +2157,15 @@ raop_metadata_startup_send(struct raop_session *rs)
} }
void void
raop_metadata_send(struct raop_metadata *rmd) raop_metadata_send(struct raop_metadata *rmd, uint64_t rtptime, uint64_t offset, int startup)
{ {
struct raop_session *rs; struct raop_session *rs;
uint32_t delay; uint32_t delay;
int ret; int ret;
rmd->start += rtptime;
rmd->end += rtptime;
/* Add the rmd to the metadata list */ /* Add the rmd to the metadata list */
if (metadata_tail) if (metadata_tail)
metadata_tail->next = rmd; metadata_tail->next = rmd;
@ -2185,9 +2183,9 @@ raop_metadata_send(struct raop_metadata *rmd)
if (!rs->wants_metadata) if (!rs->wants_metadata)
continue; continue;
delay = (rmd->startup) ? RAOP_MD_DELAY_STARTUP : RAOP_MD_DELAY_SWITCH; delay = (startup) ? RAOP_MD_DELAY_STARTUP : RAOP_MD_DELAY_SWITCH;
ret = raop_metadata_send_internal(rs, rmd, rmd->offset, delay); ret = raop_metadata_send_internal(rs, rmd, offset, delay);
if (ret < 0) if (ret < 0)
{ {
raop_session_failure(rs); raop_session_failure(rs);

View File

@ -55,14 +55,6 @@ struct raop_device
struct raop_device *next; struct raop_device *next;
}; };
struct raop_metadata_arg
{
int id;
uint64_t rtptime;
uint64_t offset;
int startup;
};
/* RAOP session state */ /* RAOP session state */
/* Session is starting up */ /* Session is starting up */
@ -109,10 +101,10 @@ void
raop_metadata_prune(uint64_t rtptime); raop_metadata_prune(uint64_t rtptime);
struct raop_metadata * struct raop_metadata *
raop_metadata_prepare(struct raop_metadata_arg *rma); raop_metadata_prepare(int id);
void void
raop_metadata_send(struct raop_metadata *rmd); raop_metadata_send(struct raop_metadata *rmd, uint64_t rtptime, uint64_t offset, int startup);
int int
raop_device_probe(struct raop_device *rd, raop_status_cb cb); raop_device_probe(struct raop_device *rd, raop_status_cb cb);