From: Mike Brady Date: Mon, 21 Jan 2019 21:18:40 +0000 (+0000) Subject: Hook up active mode stuff to metadata, add two four-char codes, improve external... X-Git-Tag: 3.3RC0~66^2~48 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=604ca8dee458a07075453c0fde2b8a505846e3f5;p=thirdparty%2Fshairport-sync.git Hook up active mode stuff to metadata, add two four-char codes, improve external command calling. --- diff --git a/activity_monitor.c b/activity_monitor.c index aea75cd9..53e3d7f1 100644 --- a/activity_monitor.c +++ b/activity_monitor.c @@ -39,6 +39,7 @@ #include "config.h" #include "common.h" +#include "rtsp.h" #include "activity_monitor.h" enum am_state {am_inactive, am_active, am_timing_out} state; @@ -49,15 +50,23 @@ pthread_mutex_t activity_monitor_mutex; pthread_cond_t activity_monitor_cv; void going_active(int block) { - debug(1, "activity_monitor: state transitioning to \"active\" with%s blocking", block ? "" : "out"); + // debug(1, "activity_monitor: state transitioning to \"active\" with%s blocking", block ? "" : "out"); if (config.cmd_active_start) command_execute(config.cmd_active_start, "", block); +#ifdef CONFIG_METADATA + debug(2, "abeg"); // active mode begin + send_ssnc_metadata('pend', NULL, 0, 1); // contains cancellation points +#endif } void going_inactive(int block) { - debug(1, "activity_monitor: state transitioning to \"inactive\" with%s blocking", block ? "" : "out"); + // debug(1, "activity_monitor: state transitioning to \"inactive\" with%s blocking", block ? "" : "out"); if (config.cmd_active_stop) command_execute(config.cmd_active_stop, "", block); +#ifdef CONFIG_METADATA + debug(2, "aend"); // active mode end + send_ssnc_metadata('pend', NULL, 0, 1); // contains cancellation points +#endif } void activity_monitor_signify_activity(int active) { @@ -127,14 +136,14 @@ void *activity_monitor_thread_code(void *arg) { do { switch (state) { case am_inactive: - debug(1,"am_state: am_inactive"); + // debug(1,"am_state: am_inactive"); while (player_state != ps_active) pthread_cond_wait(&activity_monitor_cv, &activity_monitor_mutex); state = am_active; // going_active(); // this is done in activity_monitor_signify_activity break; case am_active: - debug(1,"am_state: am_active"); + // debug(1,"am_state: am_active"); while (player_state != ps_inactive) pthread_cond_wait(&activity_monitor_cv, &activity_monitor_mutex); if (config.active_mode_timeout == 0.0) { @@ -163,7 +172,7 @@ void *activity_monitor_thread_code(void *arg) { } break; case am_timing_out: - debug(1,"am_state: am_timing_out"); + // debug(1,"am_state: am_timing_out"); rc = 0; while ((player_state != ps_active) && (rc != ETIMEDOUT)) { #ifdef COMPILE_FOR_LINUX_AND_FREEBSD_AND_CYGWIN_AND_OPENBSD @@ -197,7 +206,7 @@ void *activity_monitor_thread_code(void *arg) { } void activity_monitor_start() { - debug(1,"activity_monitor_start"); + // debug(1,"activity_monitor_start"); pthread_create(&activity_monitor_thread, NULL, activity_monitor_thread_code, NULL); } diff --git a/common.c b/common.c index a1354621..2c2ede62 100644 --- a/common.c +++ b/common.c @@ -725,7 +725,8 @@ void command_start(void) { and if blocking is true, wait for process to finish */ pid_t rc = waitpid(pid, 0, 0); /* wait for child to exit */ - if (rc != pid) { + if ((rc != pid) && (errno != ECHILD)) { + // In this context, ECHILD means that the child process has already completed, I think! warn("Execution of on-start command returned an error."); debug(1, "on-start command %s finished with error %d", config.cmd_start, errno); } @@ -779,7 +780,8 @@ void command_execute(const char *command, const char *extra_argument, const int if (block) { /* pid!=0 means parent process and if blocking is true, wait for process to finish */ pid_t rc = waitpid(pid, 0, 0); /* wait for child to exit */ - if (rc != pid) { + if ((rc != pid) && (errno != ECHILD)) { + // In this context, ECHILD means that the child process has already completed, I think! warn("Execution of command \"%s\" returned an error.", full_command); debug(1, "Command \"%s\" finished with error %d", full_command, errno); } @@ -791,36 +793,8 @@ void command_execute(const char *command, const char *extra_argument, const int void command_stop(void) { // this has a cancellation point if waiting is enabled - if (config.cmd_stop) { - /*Spawn a child to run the program.*/ - pid_t pid = fork(); - if (pid == 0) { /* child process */ - int argC; - char **argV; - // debug(1,"on-stop command found."); - if (poptParseArgvString(config.cmd_stop, &argC, (const char ***)&argV) != - 0) // note that argV should be free()'d after use, but we expect this fork to exit - // eventually. - debug(1, "Can't decipher on-stop command arguments"); - else { - // debug(1,"Executing on-stop command %s",config.cmd_stop); - execv(argV[0], argV); - warn("Execution of on-stop command failed to start"); - debug(1, "Error executing on-stop command %s", config.cmd_stop); - exit(127); /* only if execv fails */ - } - } else { - if (config.cmd_blocking) { /* pid!=0 means parent process and if blocking is true, wait for - process to finish */ - pid_t rc = waitpid(pid, 0, 0); /* wait for child to exit */ - if (rc != pid) { - warn("Execution of on-stop command returned an error."); - debug(1, "Stop command %s finished with error %d", config.cmd_stop, errno); - } - } - // debug(1,"Continue after on-stop command"); - } - } + if (config.cmd_stop) + command_execute(config.cmd_stop,"",config.cmd_blocking); } // this is for reading an unsigned 32 bit number, such as an RTP timestamp diff --git a/metadata_hub.c b/metadata_hub.c index 84cd8076..398ad35b 100644 --- a/metadata_hub.c +++ b/metadata_hub.c @@ -535,6 +535,18 @@ void metadata_hub_process_metadata(uint32_t type, uint32_t code, char *data, uin break; // these could tell us about play / pause etc. but will only occur if metadata is enabled, so // we'll just ignore them + case 'abeg': { + metadata_hub_modify_prolog(); + int changed = (metadata_store.active_state != AM_ACTIVE); + metadata_store.active_state = AM_ACTIVE; + metadata_hub_modify_epilog(changed); + } break; + case 'aend': { + metadata_hub_modify_prolog(); + int changed = (metadata_store.active_state != AM_INACTIVE); + metadata_store.active_state = AM_INACTIVE; + metadata_hub_modify_epilog(changed); + } break; case 'pbeg': { metadata_hub_modify_prolog(); int changed = (metadata_store.player_state != PS_PLAYING); diff --git a/metadata_hub.h b/metadata_hub.h index 65e93a23..7acc6722 100644 --- a/metadata_hub.h +++ b/metadata_hub.h @@ -12,6 +12,11 @@ enum play_status_type { PS_PLAYING, } play_status_type; +enum active_mode_type { + AM_INACTIVE = 0, + AM_ACTIVE, +} active_mode_type; + enum shuffle_status_type { SS_NOT_AVAILABLE = 0, SS_OFF, @@ -77,6 +82,8 @@ typedef struct metadata_bundle { enum play_status_type player_state; // this is the state of the actual player itself, which can be a bit noisy. + enum active_mode_type + active_state; int speaker_volume; // this is the actual speaker volume, allowing for the main volume and the // speaker volume control diff --git a/rtsp.c b/rtsp.c index 5a1cbd05..2fcd3103 100644 --- a/rtsp.c +++ b/rtsp.c @@ -974,7 +974,7 @@ void handle_setup(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp) { msg_add_header(resp, "Session", "1"); resp->respcode = 200; // it all worked out okay - debug(1, "Connection %d: SETUP with UDP ports Control: %d, Timing: %d and Audio: %d.", + debug(2, "Connection %d: SETUP with UDP ports Control: %d, Timing: %d and Audio: %d.", conn->connection_number, conn->local_control_port, conn->local_timing_port, conn->local_audio_port); @@ -1087,6 +1087,8 @@ void handle_set_parameter_parameter(rtsp_conn_info *conn, rtsp_message *req, // 'PICT' -- the payload is a picture, either a JPEG or a PNG. Check the // first few bytes to see // which. +// 'abeg' -- active mode entered. No arguments +// 'aend' -- active mode exited. No arguments // 'pbeg' -- play stream begin. No arguments // 'pend' -- play stream end. No arguments // 'pfls' -- play stream flush. No arguments