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
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;
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 */
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;
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)