Call the unfixable error handler if the output device can't be opened or disappears. Clang-format.
This commit is contained in:
+29
-10
@@ -444,13 +444,19 @@ static int actual_open_alsa_device(int do_auto_setup) {
|
||||
warn("The output device \"%s\" is busy and can't be used by Shairport Sync at present.",
|
||||
alsa_out_dev);
|
||||
debug(2, "the alsa output_device \"%s\" is busy.", alsa_out_dev);
|
||||
} else if (ret == -ENOENT) {
|
||||
die("the alsa output_device \"%s\" can not be found.", alsa_out_dev);
|
||||
} else {
|
||||
char errorstring[1024];
|
||||
strerror_r(-ret, (char *)errorstring, sizeof(errorstring));
|
||||
die("alsa: error %d (\"%s\") opening alsa device \"%s\".", ret, (char *)errorstring,
|
||||
alsa_out_dev);
|
||||
if (config.unfixable_error_reported == 0) {
|
||||
config.unfixable_error_reported = 1;
|
||||
char messageString[1024];
|
||||
messageString[0] = '\0';
|
||||
snprintf(messageString, sizeof(messageString), "output_device_error %d", -ret);
|
||||
if (config.cmd_unfixable) {
|
||||
command_execute(config.cmd_unfixable, messageString, 1);
|
||||
} else {
|
||||
die("an unrecoverable error, \"output_device_error %d\", has been "
|
||||
"detected.", -ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
alsa_handle_status = ret;
|
||||
frames_sent_break_occurred = 1;
|
||||
@@ -1795,10 +1801,23 @@ static int do_play(void *buf, int samples) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
char errorstring[1024];
|
||||
strerror_r(-ret, (char *)errorstring, sizeof(errorstring));
|
||||
debug(1, "alsa: error %d (\"%s\") writing %d samples to alsa device.", ret,
|
||||
(char *)errorstring, samples);
|
||||
|
||||
if (ret == -ENODEV) {
|
||||
if (config.unfixable_error_reported == 0) {
|
||||
config.unfixable_error_reported = 1;
|
||||
if (config.cmd_unfixable) {
|
||||
command_execute(config.cmd_unfixable, "output_device_error 19", 1);
|
||||
} else {
|
||||
die("an unrecoverable error, \"output_device_error 19\", has been "
|
||||
"detected.");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
char errorstring[1024];
|
||||
strerror_r(-ret, (char *)errorstring, sizeof(errorstring));
|
||||
debug(1, "alsa: error %d (\"%s\") writing %d samples to alsa device.", ret,
|
||||
(char *)errorstring, samples);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-2
@@ -39,11 +39,10 @@
|
||||
static int fd = -1;
|
||||
static int warned = 0;
|
||||
|
||||
|
||||
static void start(__attribute__((unused)) int sample_rate,
|
||||
__attribute__((unused)) int sample_format) {
|
||||
fd = STDOUT_FILENO;
|
||||
warned = 0;
|
||||
warned = 0;
|
||||
}
|
||||
|
||||
static int play(void *buf, int samples, __attribute__((unused)) int sample_type,
|
||||
|
||||
@@ -37,7 +37,8 @@ typedef enum {
|
||||
typedef enum {
|
||||
TOE_normal,
|
||||
TOE_emergency,
|
||||
TOE_dbus // a request was made on a D-Bus interface (the native D-Bus or MPRIS interfaces)-- don't wait for the dbus thread to exit
|
||||
TOE_dbus // a request was made on a D-Bus interface (the native D-Bus or MPRIS interfaces)-- don't
|
||||
// wait for the dbus thread to exit
|
||||
} type_of_exit_type;
|
||||
|
||||
#define sps_extra_code_output_stalled 32768
|
||||
@@ -160,7 +161,7 @@ typedef struct {
|
||||
int mqtt_enable_remote;
|
||||
char *mqtt_empty_payload_substitute;
|
||||
#endif
|
||||
uint8_t ap1_prefix[6];
|
||||
uint8_t ap1_prefix[6];
|
||||
uint8_t hw_addr[8]; // only needs 6 but 8 is handy when converting this to a number
|
||||
int port;
|
||||
int udp_port_base;
|
||||
@@ -313,6 +314,7 @@ typedef struct {
|
||||
char *airplay_pi; // UUID in the Bonjour advertisement and the GETINFO Plist
|
||||
char *nqptp_shared_memory_interface_name; // client name for nqptp service
|
||||
#endif
|
||||
int unfixable_error_reported; // only report once.
|
||||
} shairport_cfg;
|
||||
|
||||
// accessors to config for multi-thread access
|
||||
|
||||
+2
-1
@@ -111,7 +111,8 @@ void dbus_metadata_watcher(struct metadata_bundle *argc, __attribute__((unused))
|
||||
th = shairport_sync_get_first_frame_position(shairportSyncSkeleton);
|
||||
if ((th == NULL) || (strcasecmp(th, argc->first_frame_position_string) != 0)) {
|
||||
// debug(1, "First frame position string should be changed");
|
||||
shairport_sync_set_first_frame_position(shairportSyncSkeleton, argc->first_frame_position_string);
|
||||
shairport_sync_set_first_frame_position(shairportSyncSkeleton,
|
||||
argc->first_frame_position_string);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -598,7 +598,8 @@ void metadata_hub_process_metadata(uint32_t type, uint32_t code, char *data, uin
|
||||
if (string_update(&metadata_store.first_frame_position_string,
|
||||
&metadata_store.first_frame_position_string_changed, cs)) {
|
||||
changed = 1;
|
||||
debug(2, "MH First Frame Position String set to: \"%s\"", metadata_store.first_frame_position_string);
|
||||
debug(2, "MH First Frame Position String set to: \"%s\"",
|
||||
metadata_store.first_frame_position_string);
|
||||
}
|
||||
free(cs);
|
||||
break;
|
||||
|
||||
+3
-5
@@ -48,7 +48,7 @@ typedef struct metadata_bundle {
|
||||
|
||||
char *server_ip; // IP number used by Shairport Sync
|
||||
int server_ip_changed;
|
||||
|
||||
|
||||
char *stream_type; // Realtime or Buffered
|
||||
int stream_type_changed;
|
||||
|
||||
@@ -79,7 +79,7 @@ typedef struct metadata_bundle {
|
||||
|
||||
char *cover_art_pathname;
|
||||
int cover_art_pathname_changed;
|
||||
|
||||
|
||||
uint64_t item_id; // seems to be a track ID -- see itemid in DACP.c
|
||||
int item_id_changed;
|
||||
int item_id_is_valid;
|
||||
@@ -89,11 +89,10 @@ typedef struct metadata_bundle {
|
||||
int item_composite_id_changed;
|
||||
int item_composite_id_is_valid;
|
||||
|
||||
|
||||
int song_data_kind;
|
||||
int song_data_kind_changed;
|
||||
int song_data_kind_is_valid;
|
||||
|
||||
|
||||
char *track_name;
|
||||
int track_name_changed;
|
||||
|
||||
@@ -139,7 +138,6 @@ typedef struct metadata_bundle {
|
||||
uint32_t songtime_in_milliseconds;
|
||||
int songtime_in_milliseconds_changed;
|
||||
int songtime_in_milliseconds_is_valid;
|
||||
|
||||
|
||||
// end
|
||||
|
||||
|
||||
@@ -106,7 +106,7 @@ int64_t first_frame_early_bias = 8;
|
||||
|
||||
// default buffer size
|
||||
// needs to be a power of 2 because of the way BUFIDX(seqno) works
|
||||
//#define BUFFER_FRAMES 512
|
||||
// #define BUFFER_FRAMES 512
|
||||
#define MAX_PACKET 2048
|
||||
|
||||
// DAC buffer occupancy stuff
|
||||
@@ -531,9 +531,9 @@ void player_put_packet(int original_format, seq_t seqno, uint32_t actual_timesta
|
||||
(uint64_t)(config.resend_control_first_check_time * (uint64_t)1000000000);
|
||||
uint64_t resend_repeat_interval =
|
||||
(uint64_t)(config.resend_control_check_interval_time * (uint64_t)1000000000);
|
||||
uint64_t minimum_remaining_time = (uint64_t)(
|
||||
(config.resend_control_last_check_time + config.audio_backend_buffer_desired_length) *
|
||||
(uint64_t)1000000000);
|
||||
uint64_t minimum_remaining_time = (uint64_t)((config.resend_control_last_check_time +
|
||||
config.audio_backend_buffer_desired_length) *
|
||||
(uint64_t)1000000000);
|
||||
uint64_t latency_time = (uint64_t)(conn->latency * (uint64_t)1000000000);
|
||||
latency_time = latency_time / (uint64_t)conn->input_rate;
|
||||
|
||||
@@ -1271,14 +1271,13 @@ static abuf_t *buffer_get_frame(rtsp_conn_info *conn) {
|
||||
} else {
|
||||
|
||||
if (resp == sps_extra_code_output_stalled) {
|
||||
if (conn->unfixable_error_reported == 0) {
|
||||
conn->unfixable_error_reported = 1;
|
||||
if (config.unfixable_error_reported == 0) {
|
||||
config.unfixable_error_reported = 1;
|
||||
if (config.cmd_unfixable) {
|
||||
command_execute(config.cmd_unfixable, "output_device_stalled", 1);
|
||||
} else {
|
||||
die("an unrecoverable error, \"output_device_stalled\", has been "
|
||||
"detected.",
|
||||
conn->connection_number);
|
||||
"detected.");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -1838,7 +1837,8 @@ void player_thread_cleanup_handler(void *arg) {
|
||||
void *player_thread_func(void *arg) {
|
||||
rtsp_conn_info *conn = (rtsp_conn_info *)arg;
|
||||
#ifdef CONFIG_METADATA
|
||||
uint64_t time_of_last_metadata_progress_update = 0; // the assignment is to stop a compiler warning...
|
||||
uint64_t time_of_last_metadata_progress_update =
|
||||
0; // the assignment is to stop a compiler warning...
|
||||
#endif
|
||||
uint64_t previous_frames_played = 0; // initialised to avoid a "possibly uninitialised" warning
|
||||
uint64_t previous_raw_measurement_time =
|
||||
@@ -1982,15 +1982,16 @@ void *player_thread_func(void *arg) {
|
||||
|
||||
debug(3, "Output frame bytes is %d.", conn->output_bytes_per_frame);
|
||||
|
||||
conn->dac_buffer_queue_minimum_length = (uint64_t)(
|
||||
config.audio_backend_buffer_interpolation_threshold_in_seconds * config.output_rate);
|
||||
conn->dac_buffer_queue_minimum_length =
|
||||
(uint64_t)(config.audio_backend_buffer_interpolation_threshold_in_seconds *
|
||||
config.output_rate);
|
||||
debug(3, "dac_buffer_queue_minimum_length is %" PRIu64 " frames.",
|
||||
conn->dac_buffer_queue_minimum_length);
|
||||
|
||||
conn->session_corrections = 0;
|
||||
conn->connection_state_to_output = get_requested_connection_state_to_output();
|
||||
// this is about half a minute
|
||||
//#define trend_interval 3758
|
||||
// #define trend_interval 3758
|
||||
|
||||
// this is about 8 seconds
|
||||
#define trend_interval 1003
|
||||
@@ -2629,8 +2630,8 @@ void *player_thread_func(void *arg) {
|
||||
} else {
|
||||
current_delay = 0;
|
||||
if ((resp == sps_extra_code_output_stalled) &&
|
||||
(conn->unfixable_error_reported == 0)) {
|
||||
conn->unfixable_error_reported = 1;
|
||||
(config.unfixable_error_reported == 0)) {
|
||||
config.unfixable_error_reported = 1;
|
||||
if (config.cmd_unfixable) {
|
||||
warn("Connection %d: An unfixable error has been detected -- output device is "
|
||||
"stalled. Executing the "
|
||||
@@ -2780,7 +2781,8 @@ void *player_thread_func(void *arg) {
|
||||
send_ssnc_metadata('styp', "Classic", strlen("Classic"), 1);
|
||||
#endif
|
||||
if (config.statistics_requested)
|
||||
inform("Connection %d: Playback started at frame %" PRId64 " -- Classic AirPlay (\"AirPlay 1\").",
|
||||
inform("Connection %d: Playback started at frame %" PRId64
|
||||
" -- Classic AirPlay (\"AirPlay 1\").",
|
||||
conn->connection_number, inframe->given_timestamp);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -168,8 +168,7 @@ typedef struct {
|
||||
volatile int stop;
|
||||
volatile int running;
|
||||
volatile uint64_t watchdog_bark_time;
|
||||
volatile int watchdog_barks; // number of times the watchdog has timed out and done something
|
||||
int unfixable_error_reported; // set when an unfixable error command has been executed.
|
||||
volatile int watchdog_barks; // number of times the watchdog has timed out and done something
|
||||
|
||||
uint64_t playstart;
|
||||
uint64_t connection_start_time; // the time the device is selected, which could be a long time
|
||||
|
||||
Reference in New Issue
Block a user