[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:
Fabian Groffen 2024-08-05 16:14:02 +02:00 committed by ejurgensen
parent d672332750
commit b2a957cdec
1 changed files with 27 additions and 8 deletions

View File

@ -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(&param, 0, sizeof(param));
param.buf = evbuf;
player_speaker_enumerate(speaker_enum_cb, &param);
return 0; return 0;
} }