X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=audiod.c;h=e5f9c6be513103334f8a9203e6fbb5079fece853;hp=3fe654a73c1f71004baf554996df82d100f83933;hb=74322f0fab30777d8e34486fce1d81d4bc1106a0;hpb=cb193b91d68778125739fe129d49f3c5f4abf999 diff --git a/audiod.c b/audiod.c index 3fe654a7..e5f9c6be 100644 --- a/audiod.c +++ b/audiod.c @@ -69,6 +69,30 @@ struct audio_format_info { struct timeval restart_barrier; }; +/* Describes one instance of a receiver-filter-writer chain. */ +struct slot_info { + /* Number of the audio format in this slot. */ + int format; + /* The stream_start status item announced by para_server. */ + struct timeval server_stream_start; + /* The offset status item announced by para_server. */ + unsigned offset_seconds; + /* The seconds_total status item announced by para_server. */ + unsigned seconds_total; + /* The receiver info associated with this slot. */ + struct receiver_node *receiver_node; + /* The array of filter nodes. */ + struct filter_node *fns; + /* The array of writers attached to the last filter. */ + struct writer_node *wns; +}; + +/** Maximal number of simultaneous instances. */ +#define MAX_STREAM_SLOTS 5 + +/** Iterate over all slots. */ +#define FOR_EACH_SLOT(_slot) for (_slot = 0; _slot < MAX_STREAM_SLOTS; _slot++) + /** * para_audiod uses \p MAX_STREAM_SLOTS different slots, each of which may * be associated with a receiver/filter/writer triple. This array holds all @@ -201,6 +225,35 @@ static int get_audio_format_num(const char *name) return -E_UNSUPPORTED_AUDIO_FORMAT; } +/** + * Return the flags for the \a decoder_flags status item. + * + * Allocates a string which contains one octal digit per slot. Bit zero (value + * 1) is set if a receiver is active. Bit one (value 2) and bit three (value 4) + * have the analogous meaning for filter and writer, respectively. + * + * \return String that must be freed by the caller. + */ +__malloc char *audiod_get_decoder_flags(void) +{ + int i; + char flags[MAX_STREAM_SLOTS + 1]; + + FOR_EACH_SLOT(i) { + struct slot_info *s = &slot[i]; + char flag = '0'; + if (s->receiver_node) + flag += 1; + if (s->fns) + flag += 2; + if (s->wns) + flag += 4; + flags[i] = flag; + } + flags[MAX_STREAM_SLOTS] = '\0'; + return para_strdup(flags); +} + static int get_matching_audio_format_nums(const char *re) { int i, ret; @@ -217,28 +270,44 @@ static int get_matching_audio_format_nums(const char *re) return ret; } +static int get_play_time_slot_num(void) +{ + int i, oldest_slot = -1; + struct timeval oldest_wstime = {0, 0}; + + FOR_EACH_SLOT(i) { + struct slot_info *s = &slot[i]; + struct timeval wstime; + if (!s->wns || !s->wns[0].btrn) + continue; + btr_get_node_start(s->wns[0].btrn, &wstime); + if (oldest_slot >= 0 && tv_diff(&wstime, &oldest_wstime, NULL) > 0) + continue; + oldest_wstime = wstime; + oldest_slot = i; + } + return oldest_slot; +} + /** - * Compute the play time based on information of the given slot. - * - * \param slot_num The slot number (negative means: no slot). + * Compute the play time based on information of the current slot. * * This computes a string of the form "0:07 [3:33] (3%/3:40)" using information * from the status items received from para_server and the start time of the - * (first) writer of the given slot. + * (first) writer of the current slot. * * It has to take into account that the stream was probably not started at * the beginning of the file, that the clock between the server and the client * host may differ and that playback of the stream was delayed, e.g. because - * the prebuffer filter is used in the filter configuration of the given slot. + * the prebuffer filter is used in the filter configuration. * - * If no writer is active in the given slot, or \a slot_num is negative - * (indicating that para_audiod runs in standby mode), an approximation based - * only on the status items is computed and the returned string is prefixed - * with "~". + * If no writer is active, for example because para_audiod runs in standby + * mode, an approximation based only on the status items is computed and the + * returned string is prefixed with "~". * * \return A string that must be freed by the caller. */ -char *get_time_string(int slot_num) +char *get_time_string(void) { int ret, seconds = 0, length; struct timeval *tmp, sum, sss, /* server stream start */ @@ -246,6 +315,7 @@ char *get_time_string(int slot_num) wstime, /* writer start time */ wtime, /* now - writer start */ rskip; /* receiver start - sss */ + int slot_num = get_play_time_slot_num(); struct slot_info *s = slot_num < 0? NULL : &slot[slot_num]; char *msg; @@ -1404,6 +1474,7 @@ int main(int argc, char *argv[]) writer_init(); if (conf.help_given || conf.detailed_help_given) print_help_and_die(); + daemon_set_priority(conf.priority_arg); daemon_drop_privileges_or_die(conf.user_arg, conf.group_arg); parse_config_or_die(); daemon_init_colors_or_die(conf.color_arg, color_arg_auto, color_arg_no, @@ -1423,7 +1494,7 @@ int main(int argc, char *argv[]) PARA_EMERG_LOG("%s\n", para_strerror(-ret)); exit(EXIT_FAILURE); } - daemon_log_welcome("para_audiod"); + daemon_log_welcome("audiod"); daemon_set_start_time(); set_initial_status(); FOR_EACH_SLOT(i)