Hook up active mode stuff to metadata, add two four-char codes, improve external command calling.
This commit is contained in:
+15
-6
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user