[outputs] Move device_add/rm to outputs and get rid of advertised flag
This commit is contained in:
parent
a7e8476996
commit
936103f462
196
src/outputs.c
196
src/outputs.c
|
@ -35,6 +35,7 @@
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "transcode.h"
|
#include "transcode.h"
|
||||||
#include "listener.h"
|
#include "listener.h"
|
||||||
|
#include "db.h"
|
||||||
#include "player.h" //TODO remove me when player_pmap is removed again
|
#include "player.h" //TODO remove me when player_pmap is removed again
|
||||||
#include "outputs.h"
|
#include "outputs.h"
|
||||||
|
|
||||||
|
@ -122,6 +123,22 @@ callback_remove(struct output_device *device)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
callback_remove_all(enum output_types type)
|
||||||
|
{
|
||||||
|
struct output_device *device;
|
||||||
|
|
||||||
|
for (device = output_device_list; device; device = device->next)
|
||||||
|
{
|
||||||
|
if (type != device->type)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
outputs_device_cb_set(device, NULL);
|
||||||
|
|
||||||
|
callback_remove(device);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
callback_add(struct output_device *device, output_status_cb cb)
|
callback_add(struct output_device *device, output_status_cb cb)
|
||||||
{
|
{
|
||||||
|
@ -162,22 +179,6 @@ callback_add(struct output_device *device, output_status_cb cb)
|
||||||
return callback_id;
|
return callback_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
|
||||||
callback_remove_all(enum output_types type)
|
|
||||||
{
|
|
||||||
struct output_device *device;
|
|
||||||
|
|
||||||
for (device = output_device_list; device; device = device->next)
|
|
||||||
{
|
|
||||||
if (type != device->type)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
outputs_device_cb_set(device, NULL);
|
|
||||||
|
|
||||||
callback_remove(device);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
deferred_cb(int fd, short what, void *arg)
|
deferred_cb(int fd, short what, void *arg)
|
||||||
{
|
{
|
||||||
|
@ -213,6 +214,15 @@ deferred_cb(int fd, short what, void *arg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
device_stop_cb(struct output_device *device, enum output_device_state status)
|
||||||
|
{
|
||||||
|
if (status == OUTPUT_STATE_FAILED)
|
||||||
|
DPRINTF(E_WARN, L_PLAYER, "Failed to stop device\n");
|
||||||
|
else
|
||||||
|
DPRINTF(E_INFO, L_PLAYER, "Device stopped properly\n");
|
||||||
|
}
|
||||||
|
|
||||||
static enum transcode_profile
|
static enum transcode_profile
|
||||||
quality_to_xcode(struct media_quality *quality)
|
quality_to_xcode(struct media_quality *quality)
|
||||||
{
|
{
|
||||||
|
@ -338,6 +348,41 @@ buffer_drain(struct output_buffer *obuf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
device_list_sort(void)
|
||||||
|
{
|
||||||
|
struct output_device *device;
|
||||||
|
struct output_device *next;
|
||||||
|
struct output_device *prev;
|
||||||
|
int swaps;
|
||||||
|
|
||||||
|
// Swap sorting since even the most inefficient sorting should do fine here
|
||||||
|
do
|
||||||
|
{
|
||||||
|
swaps = 0;
|
||||||
|
prev = NULL;
|
||||||
|
for (device = output_device_list; device && device->next; device = device->next)
|
||||||
|
{
|
||||||
|
next = device->next;
|
||||||
|
if ( (outputs_priority(device) > outputs_priority(next)) ||
|
||||||
|
(outputs_priority(device) == outputs_priority(next) && strcasecmp(device->name, next->name) > 0) )
|
||||||
|
{
|
||||||
|
if (device == output_device_list)
|
||||||
|
output_device_list = next;
|
||||||
|
if (prev)
|
||||||
|
prev->next = next;
|
||||||
|
|
||||||
|
device->next = next->next;
|
||||||
|
next->next = device;
|
||||||
|
swaps++;
|
||||||
|
}
|
||||||
|
prev = device;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (swaps > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ----------------------------------- API ---------------------------------- */
|
/* ----------------------------------- API ---------------------------------- */
|
||||||
|
|
||||||
struct output_device *
|
struct output_device *
|
||||||
|
@ -489,6 +534,125 @@ outputs_listener_notify(void)
|
||||||
|
|
||||||
/* ---------------------------- Called by player ---------------------------- */
|
/* ---------------------------- Called by player ---------------------------- */
|
||||||
|
|
||||||
|
int
|
||||||
|
outputs_device_add(struct output_device *add, bool new_deselect, int default_volume)
|
||||||
|
{
|
||||||
|
struct output_device *device;
|
||||||
|
char *keep_name;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
for (device = output_device_list; device; device = device->next)
|
||||||
|
{
|
||||||
|
if (device->id == add->id)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// New device
|
||||||
|
if (!device)
|
||||||
|
{
|
||||||
|
device = add;
|
||||||
|
|
||||||
|
keep_name = strdup(device->name);
|
||||||
|
ret = db_speaker_get(device, device->id);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
device->selected = 0;
|
||||||
|
device->volume = default_volume;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(device->name);
|
||||||
|
device->name = keep_name;
|
||||||
|
|
||||||
|
if (new_deselect)
|
||||||
|
device->selected = 0;
|
||||||
|
|
||||||
|
device->next = output_device_list;
|
||||||
|
output_device_list = device;
|
||||||
|
}
|
||||||
|
// Update to a device already in the list
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (add->v4_address)
|
||||||
|
{
|
||||||
|
free(device->v4_address);
|
||||||
|
|
||||||
|
device->v4_address = add->v4_address;
|
||||||
|
device->v4_port = add->v4_port;
|
||||||
|
|
||||||
|
// Address is ours now
|
||||||
|
add->v4_address = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (add->v6_address)
|
||||||
|
{
|
||||||
|
free(device->v6_address);
|
||||||
|
|
||||||
|
device->v6_address = add->v6_address;
|
||||||
|
device->v6_port = add->v6_port;
|
||||||
|
|
||||||
|
// Address is ours now
|
||||||
|
add->v6_address = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(device->name);
|
||||||
|
device->name = add->name;
|
||||||
|
add->name = NULL;
|
||||||
|
|
||||||
|
device->has_password = add->has_password;
|
||||||
|
device->password = add->password;
|
||||||
|
|
||||||
|
outputs_device_free(add);
|
||||||
|
}
|
||||||
|
|
||||||
|
device_list_sort();
|
||||||
|
|
||||||
|
listener_notify(LISTENER_SPEAKER);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
outputs_device_remove(struct output_device *remove)
|
||||||
|
{
|
||||||
|
struct output_device *device;
|
||||||
|
struct output_device *prev;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
// Device stop should be able to handle that we invalidate the device, even
|
||||||
|
// if it is an async stop. It might call outputs_device_session_remove(), but
|
||||||
|
// that just won't do anything since the id will be unknown.
|
||||||
|
if (remove->session)
|
||||||
|
outputs_device_stop(remove, device_stop_cb);
|
||||||
|
|
||||||
|
prev = NULL;
|
||||||
|
for (device = output_device_list; device; device = device->next)
|
||||||
|
{
|
||||||
|
if (device == remove)
|
||||||
|
break;
|
||||||
|
|
||||||
|
prev = device;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!device)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Save device volume
|
||||||
|
ret = db_speaker_save(remove);
|
||||||
|
if (ret < 0)
|
||||||
|
DPRINTF(E_LOG, L_PLAYER, "Could not save state for %s device '%s'\n", remove->type_name, remove->name);
|
||||||
|
|
||||||
|
DPRINTF(E_INFO, L_PLAYER, "Removing %s device '%s'; stopped advertising\n", remove->type_name, remove->name);
|
||||||
|
|
||||||
|
if (!prev)
|
||||||
|
output_device_list = remove->next;
|
||||||
|
else
|
||||||
|
prev->next = remove->next;
|
||||||
|
|
||||||
|
outputs_device_free(remove);
|
||||||
|
|
||||||
|
listener_notify(LISTENER_SPEAKER);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
outputs_device_start(struct output_device *device, output_status_cb cb)
|
outputs_device_start(struct output_device *device, output_status_cb cb)
|
||||||
{
|
{
|
||||||
|
|
|
@ -114,7 +114,7 @@ struct output_device
|
||||||
|
|
||||||
// Misc device flags
|
// Misc device flags
|
||||||
unsigned selected:1;
|
unsigned selected:1;
|
||||||
unsigned advertised:1;
|
// unsigned advertised:1;
|
||||||
unsigned has_password:1;
|
unsigned has_password:1;
|
||||||
unsigned has_video:1;
|
unsigned has_video:1;
|
||||||
unsigned requires_auth:1;
|
unsigned requires_auth:1;
|
||||||
|
@ -266,6 +266,12 @@ outputs_listener_notify(void);
|
||||||
|
|
||||||
/* ---------------------------- Called by player ---------------------------- */
|
/* ---------------------------- Called by player ---------------------------- */
|
||||||
|
|
||||||
|
int
|
||||||
|
outputs_device_add(struct output_device *add, bool new_deselect, int default_volume);
|
||||||
|
|
||||||
|
void
|
||||||
|
outputs_device_remove(struct output_device *remove);
|
||||||
|
|
||||||
int
|
int
|
||||||
outputs_device_start(struct output_device *device, output_status_cb cb);
|
outputs_device_start(struct output_device *device, output_status_cb cb);
|
||||||
|
|
||||||
|
|
|
@ -1028,7 +1028,6 @@ alsa_init(void)
|
||||||
device->name = strdup(nickname);
|
device->name = strdup(nickname);
|
||||||
device->type = OUTPUT_TYPE_ALSA;
|
device->type = OUTPUT_TYPE_ALSA;
|
||||||
device->type_name = outputs_name(device->type);
|
device->type_name = outputs_name(device->type);
|
||||||
device->advertised = 1;
|
|
||||||
device->has_video = 0;
|
device->has_video = 0;
|
||||||
|
|
||||||
DPRINTF(E_INFO, L_LAUDIO, "Adding ALSA device '%s' with name '%s'\n", card_name, nickname);
|
DPRINTF(E_INFO, L_LAUDIO, "Adding ALSA device '%s' with name '%s'\n", card_name, nickname);
|
||||||
|
|
|
@ -1299,8 +1299,6 @@ cast_device_cb(const char *name, const char *type, const char *domain, const cha
|
||||||
|
|
||||||
DPRINTF(E_INFO, L_CAST, "Adding Chromecast device '%s'\n", name);
|
DPRINTF(E_INFO, L_CAST, "Adding Chromecast device '%s'\n", name);
|
||||||
|
|
||||||
device->advertised = 1;
|
|
||||||
|
|
||||||
switch (family)
|
switch (family)
|
||||||
{
|
{
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
|
|
|
@ -203,7 +203,6 @@ dummy_init(void)
|
||||||
device->name = strdup(nickname);
|
device->name = strdup(nickname);
|
||||||
device->type = OUTPUT_TYPE_DUMMY;
|
device->type = OUTPUT_TYPE_DUMMY;
|
||||||
device->type_name = outputs_name(device->type);
|
device->type_name = outputs_name(device->type);
|
||||||
device->advertised = 1;
|
|
||||||
device->has_video = 0;
|
device->has_video = 0;
|
||||||
|
|
||||||
DPRINTF(E_INFO, L_LAUDIO, "Adding dummy output device '%s'\n", nickname);
|
DPRINTF(E_INFO, L_LAUDIO, "Adding dummy output device '%s'\n", nickname);
|
||||||
|
|
|
@ -505,7 +505,6 @@ fifo_init(void)
|
||||||
device->name = strdup(nickname);
|
device->name = strdup(nickname);
|
||||||
device->type = OUTPUT_TYPE_FIFO;
|
device->type = OUTPUT_TYPE_FIFO;
|
||||||
device->type_name = outputs_name(device->type);
|
device->type_name = outputs_name(device->type);
|
||||||
device->advertised = 1;
|
|
||||||
device->has_video = 0;
|
device->has_video = 0;
|
||||||
device->extra_device_info = path;
|
device->extra_device_info = path;
|
||||||
DPRINTF(E_INFO, L_FIFO, "Adding fifo output device '%s' with path '%s'\n", nickname, path);
|
DPRINTF(E_INFO, L_FIFO, "Adding fifo output device '%s' with path '%s'\n", nickname, path);
|
||||||
|
|
|
@ -428,7 +428,6 @@ sinklist_cb(pa_context *ctx, const pa_sink_info *info, int eol, void *userdata)
|
||||||
device->name = strdup(name);
|
device->name = strdup(name);
|
||||||
device->type = OUTPUT_TYPE_PULSE;
|
device->type = OUTPUT_TYPE_PULSE;
|
||||||
device->type_name = outputs_name(device->type);
|
device->type_name = outputs_name(device->type);
|
||||||
device->advertised = 1;
|
|
||||||
device->extra_device_info = strdup(info->name);
|
device->extra_device_info = strdup(info->name);
|
||||||
|
|
||||||
player_device_add(device);
|
player_device_add(device);
|
||||||
|
|
|
@ -4712,8 +4712,6 @@ raop_device_cb(const char *name, const char *type, const char *domain, const cha
|
||||||
free(et);
|
free(et);
|
||||||
}
|
}
|
||||||
|
|
||||||
rd->advertised = 1;
|
|
||||||
|
|
||||||
switch (family)
|
switch (family)
|
||||||
{
|
{
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
|
|
277
src/player.c
277
src/player.c
|
@ -1203,198 +1203,37 @@ playback_cb(int fd, short what, void *arg)
|
||||||
|
|
||||||
/* ----------------- Output device handling (add/remove etc) ---------------- */
|
/* ----------------- Output device handling (add/remove etc) ---------------- */
|
||||||
|
|
||||||
static void
|
|
||||||
device_list_sort(void)
|
|
||||||
{
|
|
||||||
struct output_device *device;
|
|
||||||
struct output_device *next;
|
|
||||||
struct output_device *prev;
|
|
||||||
int swaps;
|
|
||||||
|
|
||||||
// Swap sorting since even the most inefficient sorting should do fine here
|
|
||||||
do
|
|
||||||
{
|
|
||||||
swaps = 0;
|
|
||||||
prev = NULL;
|
|
||||||
for (device = output_device_list; device && device->next; device = device->next)
|
|
||||||
{
|
|
||||||
next = device->next;
|
|
||||||
if ( (outputs_priority(device) > outputs_priority(next)) ||
|
|
||||||
(outputs_priority(device) == outputs_priority(next) && strcasecmp(device->name, next->name) > 0) )
|
|
||||||
{
|
|
||||||
if (device == output_device_list)
|
|
||||||
output_device_list = next;
|
|
||||||
if (prev)
|
|
||||||
prev->next = next;
|
|
||||||
|
|
||||||
device->next = next->next;
|
|
||||||
next->next = device;
|
|
||||||
swaps++;
|
|
||||||
}
|
|
||||||
prev = device;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (swaps > 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
device_remove(struct output_device *remove)
|
|
||||||
{
|
|
||||||
struct output_device *device;
|
|
||||||
struct output_device *prev;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
prev = NULL;
|
|
||||||
for (device = output_device_list; device; device = device->next)
|
|
||||||
{
|
|
||||||
if (device == remove)
|
|
||||||
break;
|
|
||||||
|
|
||||||
prev = device;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!device)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Save device volume
|
|
||||||
ret = db_speaker_save(remove);
|
|
||||||
if (ret < 0)
|
|
||||||
DPRINTF(E_LOG, L_PLAYER, "Could not save state for %s device '%s'\n", remove->type_name, remove->name);
|
|
||||||
|
|
||||||
DPRINTF(E_INFO, L_PLAYER, "Removing %s device '%s'; stopped advertising\n", remove->type_name, remove->name);
|
|
||||||
|
|
||||||
// Make sure device isn't selected anymore
|
|
||||||
if (remove->selected)
|
|
||||||
speaker_deselect_output(remove);
|
|
||||||
|
|
||||||
if (!prev)
|
|
||||||
output_device_list = remove->next;
|
|
||||||
else
|
|
||||||
prev->next = remove->next;
|
|
||||||
|
|
||||||
outputs_device_free(remove);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
device_check(struct output_device *check)
|
|
||||||
{
|
|
||||||
struct output_device *device;
|
|
||||||
|
|
||||||
for (device = output_device_list; device; device = device->next)
|
|
||||||
{
|
|
||||||
if (device == check)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (device) ? 0 : -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static enum command_state
|
static enum command_state
|
||||||
device_add(void *arg, int *retval)
|
device_add(void *arg, int *retval)
|
||||||
{
|
{
|
||||||
union player_arg *cmdarg;
|
union player_arg *cmdarg = arg;
|
||||||
struct output_device *add;
|
struct output_device *device = cmdarg->device;
|
||||||
struct output_device *device;
|
bool new_deselect;
|
||||||
char *keep_name;
|
int default_volume;
|
||||||
int ret;
|
|
||||||
|
|
||||||
cmdarg = arg;
|
default_volume = (master_volume >= 0) ? master_volume : PLAYER_DEFAULT_VOLUME;
|
||||||
add = cmdarg->device;
|
|
||||||
|
|
||||||
for (device = output_device_list; device; device = device->next)
|
// Never turn on new devices during playback
|
||||||
{
|
new_deselect = (player_state == PLAY_PLAYING);
|
||||||
if (device->id == add->id)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// New device
|
*retval = outputs_device_add(device, new_deselect, default_volume);
|
||||||
if (!device)
|
|
||||||
{
|
|
||||||
device = add;
|
|
||||||
|
|
||||||
keep_name = strdup(device->name);
|
if (device->selected)
|
||||||
ret = db_speaker_get(device, device->id);
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
device->selected = 0;
|
|
||||||
device->volume = (master_volume >= 0) ? master_volume : PLAYER_DEFAULT_VOLUME;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(device->name);
|
|
||||||
device->name = keep_name;
|
|
||||||
|
|
||||||
if (device->selected && (player_state != PLAY_PLAYING))
|
|
||||||
speaker_select_output(device);
|
speaker_select_output(device);
|
||||||
else
|
|
||||||
device->selected = 0;
|
|
||||||
|
|
||||||
device->next = output_device_list;
|
|
||||||
output_device_list = device;
|
|
||||||
}
|
|
||||||
// Update to a device already in the list
|
|
||||||
else
|
|
||||||
{
|
|
||||||
device->advertised = 1;
|
|
||||||
|
|
||||||
if (add->v4_address)
|
|
||||||
{
|
|
||||||
if (device->v4_address)
|
|
||||||
free(device->v4_address);
|
|
||||||
|
|
||||||
device->v4_address = add->v4_address;
|
|
||||||
device->v4_port = add->v4_port;
|
|
||||||
|
|
||||||
// Address is ours now
|
|
||||||
add->v4_address = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (add->v6_address)
|
|
||||||
{
|
|
||||||
if (device->v6_address)
|
|
||||||
free(device->v6_address);
|
|
||||||
|
|
||||||
device->v6_address = add->v6_address;
|
|
||||||
device->v6_port = add->v6_port;
|
|
||||||
|
|
||||||
// Address is ours now
|
|
||||||
add->v6_address = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (device->name)
|
|
||||||
free(device->name);
|
|
||||||
device->name = add->name;
|
|
||||||
add->name = NULL;
|
|
||||||
|
|
||||||
device->has_password = add->has_password;
|
|
||||||
device->password = add->password;
|
|
||||||
|
|
||||||
outputs_device_free(add);
|
|
||||||
}
|
|
||||||
|
|
||||||
device_list_sort();
|
|
||||||
|
|
||||||
listener_notify(LISTENER_SPEAKER);
|
|
||||||
|
|
||||||
*retval = 0;
|
|
||||||
return COMMAND_END;
|
return COMMAND_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum command_state
|
static enum command_state
|
||||||
device_remove_family(void *arg, int *retval)
|
device_remove_family(void *arg, int *retval)
|
||||||
{
|
{
|
||||||
union player_arg *cmdarg;
|
union player_arg *cmdarg = arg;
|
||||||
struct output_device *remove;
|
struct output_device *remove;
|
||||||
struct output_device *device;
|
struct output_device *device;
|
||||||
|
|
||||||
cmdarg = arg;
|
|
||||||
remove = cmdarg->device;
|
remove = cmdarg->device;
|
||||||
|
|
||||||
for (device = output_device_list; device; device = device->next)
|
device = outputs_device_get(remove->id);
|
||||||
{
|
|
||||||
if (device->id == remove->id)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!device)
|
if (!device)
|
||||||
{
|
{
|
||||||
DPRINTF(E_WARN, L_PLAYER, "The %s device '%s' stopped advertising, but not in our list\n", remove->type_name, remove->name);
|
DPRINTF(E_WARN, L_PLAYER, "The %s device '%s' stopped advertising, but not in our list\n", remove->type_name, remove->name);
|
||||||
|
@ -1421,16 +1260,16 @@ device_remove_family(void *arg, int *retval)
|
||||||
|
|
||||||
if (!device->v4_address && !device->v6_address)
|
if (!device->v4_address && !device->v6_address)
|
||||||
{
|
{
|
||||||
device->advertised = 0;
|
// Make sure device isn't selected anymore
|
||||||
|
if (device->selected)
|
||||||
|
speaker_deselect_output(device);
|
||||||
|
|
||||||
if (!device->session)
|
// Will also stop sessions on the device, if any
|
||||||
device_remove(device);
|
outputs_device_remove(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
outputs_device_free(remove);
|
outputs_device_free(remove);
|
||||||
|
|
||||||
listener_notify(LISTENER_SPEAKER);
|
|
||||||
|
|
||||||
*retval = 0;
|
*retval = 0;
|
||||||
return COMMAND_END;
|
return COMMAND_END;
|
||||||
}
|
}
|
||||||
|
@ -1471,12 +1310,7 @@ device_metadata_send(void *arg, int *retval)
|
||||||
static void
|
static void
|
||||||
device_streaming_cb(struct output_device *device, enum output_device_state status)
|
device_streaming_cb(struct output_device *device, enum output_device_state status)
|
||||||
{
|
{
|
||||||
int ret;
|
if (!device)
|
||||||
|
|
||||||
DPRINTF(E_DBG, L_PLAYER, "Callback from %s to device_streaming_cb (status %d)\n", outputs_name(device->type), status);
|
|
||||||
|
|
||||||
ret = device_check(device);
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_PLAYER, "Output device disappeared during streaming!\n");
|
DPRINTF(E_LOG, L_PLAYER, "Output device disappeared during streaming!\n");
|
||||||
|
|
||||||
|
@ -1484,6 +1318,8 @@ device_streaming_cb(struct output_device *device, enum output_device_state statu
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DPRINTF(E_DBG, L_PLAYER, "Callback from %s to device_streaming_cb (status %d)\n", outputs_name(device->type), status);
|
||||||
|
|
||||||
if (status == OUTPUT_STATE_FAILED)
|
if (status == OUTPUT_STATE_FAILED)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_PLAYER, "The %s device '%s' FAILED\n", device->type_name, device->name);
|
DPRINTF(E_LOG, L_PLAYER, "The %s device '%s' FAILED\n", device->type_name, device->name);
|
||||||
|
@ -1493,9 +1329,6 @@ device_streaming_cb(struct output_device *device, enum output_device_state statu
|
||||||
if (player_state == PLAY_PLAYING)
|
if (player_state == PLAY_PLAYING)
|
||||||
speaker_deselect_output(device);
|
speaker_deselect_output(device);
|
||||||
|
|
||||||
if (!device->advertised)
|
|
||||||
device_remove(device);
|
|
||||||
|
|
||||||
if (output_sessions == 0)
|
if (output_sessions == 0)
|
||||||
playback_abort();
|
playback_abort();
|
||||||
}
|
}
|
||||||
|
@ -1504,9 +1337,6 @@ device_streaming_cb(struct output_device *device, enum output_device_state statu
|
||||||
DPRINTF(E_INFO, L_PLAYER, "The %s device '%s' stopped\n", device->type_name, device->name);
|
DPRINTF(E_INFO, L_PLAYER, "The %s device '%s' stopped\n", device->type_name, device->name);
|
||||||
|
|
||||||
output_sessions--;
|
output_sessions--;
|
||||||
|
|
||||||
if (!device->advertised)
|
|
||||||
device_remove(device);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
outputs_device_cb_set(device, device_streaming_cb);
|
outputs_device_cb_set(device, device_streaming_cb);
|
||||||
|
@ -1515,6 +1345,12 @@ device_streaming_cb(struct output_device *device, enum output_device_state statu
|
||||||
static void
|
static void
|
||||||
device_command_cb(struct output_device *device, enum output_device_state status)
|
device_command_cb(struct output_device *device, enum output_device_state status)
|
||||||
{
|
{
|
||||||
|
if (!device)
|
||||||
|
{
|
||||||
|
DPRINTF(E_LOG, L_PLAYER, "Output device disappeared before command completion!\n");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
DPRINTF(E_DBG, L_PLAYER, "Callback from %s to device_command_cb (status %d)\n", outputs_name(device->type), status);
|
DPRINTF(E_DBG, L_PLAYER, "Callback from %s to device_command_cb (status %d)\n", outputs_name(device->type), status);
|
||||||
|
|
||||||
outputs_device_cb_set(device, device_streaming_cb);
|
outputs_device_cb_set(device, device_streaming_cb);
|
||||||
|
@ -1530,6 +1366,7 @@ device_command_cb(struct output_device *device, enum output_device_state status)
|
||||||
input_buffer_full_cb(player_playback_start);
|
input_buffer_full_cb(player_playback_start);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
commands_exec_end(cmdbase, 0);
|
commands_exec_end(cmdbase, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1537,16 +1374,12 @@ static void
|
||||||
device_shutdown_cb(struct output_device *device, enum output_device_state status)
|
device_shutdown_cb(struct output_device *device, enum output_device_state status)
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
int ret;
|
|
||||||
|
|
||||||
DPRINTF(E_DBG, L_PLAYER, "Callback from %s to device_shutdown_cb (status %d)\n", outputs_name(device->type), status);
|
|
||||||
|
|
||||||
if (output_sessions)
|
if (output_sessions)
|
||||||
output_sessions--;
|
output_sessions--;
|
||||||
|
|
||||||
retval = commands_exec_returnvalue(cmdbase);
|
retval = commands_exec_returnvalue(cmdbase);
|
||||||
ret = device_check(device);
|
if (!device)
|
||||||
if (ret < 0)
|
|
||||||
{
|
{
|
||||||
DPRINTF(E_WARN, L_PLAYER, "Output device disappeared before shutdown completion!\n");
|
DPRINTF(E_WARN, L_PLAYER, "Output device disappeared before shutdown completion!\n");
|
||||||
|
|
||||||
|
@ -1555,8 +1388,7 @@ device_shutdown_cb(struct output_device *device, enum output_device_state status
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!device->advertised)
|
DPRINTF(E_DBG, L_PLAYER, "Callback from %s to device_shutdown_cb (status %d)\n", outputs_name(device->type), status);
|
||||||
device_remove(device);
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
/* cur_cmd->ret already set
|
/* cur_cmd->ret already set
|
||||||
|
@ -1566,39 +1398,23 @@ device_shutdown_cb(struct output_device *device, enum output_device_state status
|
||||||
commands_exec_end(cmdbase, retval);
|
commands_exec_end(cmdbase, retval);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
device_lost_cb(struct output_device *device, enum output_device_state status)
|
|
||||||
{
|
|
||||||
DPRINTF(E_DBG, L_PLAYER, "Callback from %s to device_lost_cb (status %d)\n", outputs_name(device->type), status);
|
|
||||||
|
|
||||||
// We lost that device during startup for some reason, not much we can do here
|
|
||||||
if (status == OUTPUT_STATE_FAILED)
|
|
||||||
DPRINTF(E_WARN, L_PLAYER, "Failed to stop lost device\n");
|
|
||||||
else
|
|
||||||
DPRINTF(E_INFO, L_PLAYER, "Lost device stopped properly\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
device_activate_cb(struct output_device *device, enum output_device_state status)
|
device_activate_cb(struct output_device *device, enum output_device_state status)
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
int ret;
|
|
||||||
|
|
||||||
DPRINTF(E_DBG, L_PLAYER, "Callback from %s to device_activate_cb (status %d)\n", outputs_name(device->type), status);
|
|
||||||
|
|
||||||
retval = commands_exec_returnvalue(cmdbase);
|
retval = commands_exec_returnvalue(cmdbase);
|
||||||
ret = device_check(device);
|
if (!device)
|
||||||
if (ret < 0)
|
|
||||||
{
|
{
|
||||||
DPRINTF(E_WARN, L_PLAYER, "Output device disappeared during startup!\n");
|
DPRINTF(E_WARN, L_PLAYER, "Output device disappeared during startup!\n");
|
||||||
|
|
||||||
outputs_device_stop(device, device_lost_cb);
|
|
||||||
|
|
||||||
if (retval != -2)
|
if (retval != -2)
|
||||||
retval = -1;
|
retval = -1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DPRINTF(E_DBG, L_PLAYER, "Callback from %s to device_activate_cb (status %d)\n", outputs_name(device->type), status);
|
||||||
|
|
||||||
if (status == OUTPUT_STATE_PASSWORD)
|
if (status == OUTPUT_STATE_PASSWORD)
|
||||||
{
|
{
|
||||||
status = OUTPUT_STATE_FAILED;
|
status = OUTPUT_STATE_FAILED;
|
||||||
|
@ -1609,9 +1425,6 @@ device_activate_cb(struct output_device *device, enum output_device_state status
|
||||||
{
|
{
|
||||||
speaker_deselect_output(device);
|
speaker_deselect_output(device);
|
||||||
|
|
||||||
if (!device->advertised)
|
|
||||||
device_remove(device);
|
|
||||||
|
|
||||||
if (retval != -2)
|
if (retval != -2)
|
||||||
retval = -1;
|
retval = -1;
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -1634,13 +1447,9 @@ static void
|
||||||
device_probe_cb(struct output_device *device, enum output_device_state status)
|
device_probe_cb(struct output_device *device, enum output_device_state status)
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
int ret;
|
|
||||||
|
|
||||||
DPRINTF(E_DBG, L_PLAYER, "Callback from %s to device_probe_cb (status %d)\n", outputs_name(device->type), status);
|
|
||||||
|
|
||||||
retval = commands_exec_returnvalue(cmdbase);
|
retval = commands_exec_returnvalue(cmdbase);
|
||||||
ret = device_check(device);
|
if (!device)
|
||||||
if (ret < 0)
|
|
||||||
{
|
{
|
||||||
DPRINTF(E_WARN, L_PLAYER, "Output device disappeared during probe!\n");
|
DPRINTF(E_WARN, L_PLAYER, "Output device disappeared during probe!\n");
|
||||||
|
|
||||||
|
@ -1649,6 +1458,8 @@ device_probe_cb(struct output_device *device, enum output_device_state status)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DPRINTF(E_DBG, L_PLAYER, "Callback from %s to device_probe_cb (status %d)\n", outputs_name(device->type), status);
|
||||||
|
|
||||||
if (status == OUTPUT_STATE_PASSWORD)
|
if (status == OUTPUT_STATE_PASSWORD)
|
||||||
{
|
{
|
||||||
status = OUTPUT_STATE_FAILED;
|
status = OUTPUT_STATE_FAILED;
|
||||||
|
@ -1659,9 +1470,6 @@ device_probe_cb(struct output_device *device, enum output_device_state status)
|
||||||
{
|
{
|
||||||
speaker_deselect_output(device);
|
speaker_deselect_output(device);
|
||||||
|
|
||||||
if (!device->advertised)
|
|
||||||
device_remove(device);
|
|
||||||
|
|
||||||
if (retval != -2)
|
if (retval != -2)
|
||||||
retval = -1;
|
retval = -1;
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -1680,23 +1488,19 @@ static void
|
||||||
device_restart_cb(struct output_device *device, enum output_device_state status)
|
device_restart_cb(struct output_device *device, enum output_device_state status)
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
int ret;
|
|
||||||
|
|
||||||
DPRINTF(E_DBG, L_PLAYER, "Callback from %s to device_restart_cb (status %d)\n", outputs_name(device->type), status);
|
|
||||||
|
|
||||||
retval = commands_exec_returnvalue(cmdbase);
|
retval = commands_exec_returnvalue(cmdbase);
|
||||||
ret = device_check(device);
|
if (!device)
|
||||||
if (ret < 0)
|
|
||||||
{
|
{
|
||||||
DPRINTF(E_WARN, L_PLAYER, "Output device disappeared during restart!\n");
|
DPRINTF(E_WARN, L_PLAYER, "Output device disappeared during restart!\n");
|
||||||
|
|
||||||
outputs_device_stop(device, device_lost_cb);
|
|
||||||
|
|
||||||
if (retval != -2)
|
if (retval != -2)
|
||||||
retval = -1;
|
retval = -1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DPRINTF(E_DBG, L_PLAYER, "Callback from %s to device_restart_cb (status %d)\n", outputs_name(device->type), status);
|
||||||
|
|
||||||
if (status == OUTPUT_STATE_PASSWORD)
|
if (status == OUTPUT_STATE_PASSWORD)
|
||||||
{
|
{
|
||||||
status = OUTPUT_STATE_FAILED;
|
status = OUTPUT_STATE_FAILED;
|
||||||
|
@ -1707,9 +1511,6 @@ device_restart_cb(struct output_device *device, enum output_device_state status)
|
||||||
{
|
{
|
||||||
speaker_deselect_output(device);
|
speaker_deselect_output(device);
|
||||||
|
|
||||||
if (!device->advertised)
|
|
||||||
device_remove(device);
|
|
||||||
|
|
||||||
if (retval != -2)
|
if (retval != -2)
|
||||||
retval = -1;
|
retval = -1;
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -1733,8 +1534,6 @@ player_pmap(void *p)
|
||||||
return "device_activate_cb";
|
return "device_activate_cb";
|
||||||
else if (p == device_streaming_cb)
|
else if (p == device_streaming_cb)
|
||||||
return "device_streaming_cb";
|
return "device_streaming_cb";
|
||||||
else if (p == device_lost_cb)
|
|
||||||
return "device_lost_cb";
|
|
||||||
else if (p == device_command_cb)
|
else if (p == device_command_cb)
|
||||||
return "device_command_cb";
|
return "device_command_cb";
|
||||||
else if (p == device_shutdown_cb)
|
else if (p == device_shutdown_cb)
|
||||||
|
@ -2479,7 +2278,7 @@ speaker_enumerate(void *arg, int *retval)
|
||||||
|
|
||||||
for (device = output_device_list; device; device = device->next)
|
for (device = output_device_list; device; device = device->next)
|
||||||
{
|
{
|
||||||
if (device->advertised || device->selected)
|
if (device->selected)
|
||||||
{
|
{
|
||||||
device_to_speaker_info(&spk, device);
|
device_to_speaker_info(&spk, device);
|
||||||
spk_enum->cb(&spk, spk_enum->arg);
|
spk_enum->cb(&spk, spk_enum->arg);
|
||||||
|
|
Loading…
Reference in New Issue