[mpd] return outputs by ascending ID
Simply casting the speaker ID from a 64-bits int to an unsigned short and hoping that there will be no clashes is just optimistic. Use an ascending number instead which is what MPD does too. The MPD server specifically documents no persistence in these IDs so we can simply enumerate the speakers to meet the requirements. Signed-off-by: Fabian Groffen <grobian@gentoo.org>
This commit is contained in:
parent
d672332750
commit
b2a957cdec
35
src/mpd.c
35
src/mpd.c
|
@ -281,10 +281,17 @@ struct output
|
||||||
|
|
||||||
struct output_get_param
|
struct output_get_param
|
||||||
{
|
{
|
||||||
|
unsigned short curid;
|
||||||
unsigned short shortid;
|
unsigned short shortid;
|
||||||
struct output *output;
|
struct output *output;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct output_outputs_param
|
||||||
|
{
|
||||||
|
unsigned short nextid;
|
||||||
|
struct evbuffer *buf;
|
||||||
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
free_output(struct output *output)
|
free_output(struct output *output)
|
||||||
{
|
{
|
||||||
|
@ -3586,15 +3593,17 @@ output_get_cb(struct player_speaker_info *spk, void *arg)
|
||||||
struct output_get_param *param = arg;
|
struct output_get_param *param = arg;
|
||||||
|
|
||||||
if (!param->output
|
if (!param->output
|
||||||
&& param->shortid == (unsigned short) spk->id)
|
&& param->shortid == param->curid)
|
||||||
{
|
{
|
||||||
CHECK_NULL(L_MPD, param->output = calloc(1, sizeof(struct output)));
|
CHECK_NULL(L_MPD, param->output = calloc(1, sizeof(struct output)));
|
||||||
|
|
||||||
param->output->id = spk->id;
|
param->output->id = spk->id;
|
||||||
param->output->shortid = (unsigned short) spk->id;
|
param->output->shortid = param->shortid;
|
||||||
param->output->name = strdup(spk->name);
|
param->output->name = strdup(spk->name);
|
||||||
param->output->selected = spk->selected;
|
param->output->selected = spk->selected;
|
||||||
|
|
||||||
|
param->curid++;
|
||||||
|
|
||||||
DPRINTF(E_DBG, L_MPD, "Output found: shortid %d, id %" PRIu64 ", name '%s', selected %d\n",
|
DPRINTF(E_DBG, L_MPD, "Output found: shortid %d, id %" PRIu64 ", name '%s', selected %d\n",
|
||||||
param->output->shortid, param->output->id, param->output->name, param->output->selected);
|
param->output->shortid, param->output->id, param->output->name, param->output->selected);
|
||||||
}
|
}
|
||||||
|
@ -3731,19 +3740,19 @@ mpd_command_toggleoutput(struct evbuffer *evbuf, int argc, char **argv, char **e
|
||||||
static void
|
static void
|
||||||
speaker_enum_cb(struct player_speaker_info *spk, void *arg)
|
speaker_enum_cb(struct player_speaker_info *spk, void *arg)
|
||||||
{
|
{
|
||||||
struct evbuffer *evbuf;
|
struct output_outputs_param *param = arg;
|
||||||
|
struct evbuffer *evbuf = param->buf;
|
||||||
evbuf = (struct evbuffer *)arg;
|
|
||||||
|
|
||||||
evbuffer_add_printf(evbuf,
|
evbuffer_add_printf(evbuf,
|
||||||
"outputid: %d\n"
|
"outputid: %u\n"
|
||||||
"outputname: %s\n"
|
"outputname: %s\n"
|
||||||
"outputenabled: %d\n"
|
"outputenabled: %d\n"
|
||||||
"outputvolume: %d\n",
|
"outputvolume: %d\n",
|
||||||
(unsigned short) spk->id,
|
param->nextid,
|
||||||
spk->name,
|
spk->name,
|
||||||
spk->selected,
|
spk->selected,
|
||||||
spk->absvol);
|
spk->absvol);
|
||||||
|
param->nextid++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -3753,7 +3762,17 @@ speaker_enum_cb(struct player_speaker_info *spk, void *arg)
|
||||||
static int
|
static int
|
||||||
mpd_command_outputs(struct evbuffer *evbuf, int argc, char **argv, char **errmsg, struct mpd_client_ctx *ctx)
|
mpd_command_outputs(struct evbuffer *evbuf, int argc, char **argv, char **errmsg, struct mpd_client_ctx *ctx)
|
||||||
{
|
{
|
||||||
player_speaker_enumerate(speaker_enum_cb, evbuf);
|
struct output_outputs_param param;
|
||||||
|
|
||||||
|
/* Reference:
|
||||||
|
* https://mpd.readthedocs.io/en/latest/protocol.html#audio-output-devices
|
||||||
|
* the ID returned by mpd may change between excutions, so what we do
|
||||||
|
* is simply enumerate the speakers, and for get/set commands we count
|
||||||
|
* ID times to the output referenced. */
|
||||||
|
memset(¶m, 0, sizeof(param));
|
||||||
|
param.buf = evbuf;
|
||||||
|
|
||||||
|
player_speaker_enumerate(speaker_enum_cb, ¶m);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue