/** \file audiod.c the paraslash's audio daemon */
#include <regex.h>
#include <sys/types.h>
-#include <dirent.h>
#include <signal.h>
-#include <openssl/rc4.h>
#include <stdbool.h>
#include "para.h"
return -E_UNSUPPORTED_AUDIO_FORMAT;
}
+static int get_matching_audio_format_nums(const char *re)
+{
+ int i, ret;
+ regex_t preg;
+
+ ret = para_regcomp(&preg, re, REG_EXTENDED | REG_NOSUB);
+ if (ret < 0)
+ return ret;
+ ret = 0;
+ FOR_EACH_AUDIO_FORMAT(i)
+ if (regexec(&preg, audio_formats[i], 0, NULL, 0) != REG_NOMATCH)
+ ret |= (1 << i);
+ regfree(&preg);
+ return ret;
+}
+
/**
* Compute the play time based on information of the given slot.
*
static void kill_all_decoders(int error)
{
- int i, j;
+ int i;
FOR_EACH_SLOT(i) {
- struct slot_info *s = &slot[i];
- struct audio_format_info *a;
+ struct slot_info *s = slot + i;
if (s->format < 0)
continue;
- a = afi + s->format;
- if (s->wns)
- for (j = 0; j < a->num_writers; j++)
- kill_btrn(s->wns[j].btrn, &s->wns[j].task, error);
- if (s->fns)
- for (j = 0; j < a->num_writers; j++)
- kill_btrn(s->fns[j].btrn, &s->wns[j].task, error);
- if (s->receiver_node)
- kill_btrn(s->receiver_node->btrn, &s->receiver_node->task,
+ if (!s->receiver_node)
+ continue;
+ kill_btrn(s->receiver_node->btrn, &s->receiver_node->task,
error);
}
}
for (i = conf.receiver_given - 1; i >= 0; i--) {
char *arg = conf.receiver_arg[i];
char *recv_arg = strchr(arg, ':');
+ int af_mask, j;
+
ret = -E_MISSING_COLON;
if (!recv_arg)
goto out;
*recv_arg = '\0';
recv_arg++;
- ret = get_audio_format_num(arg);
+ ret = get_matching_audio_format_nums(arg);
if (ret < 0)
goto out;
- /*
- * If multiple receivers are given for this audio format, the
- * last one wins and we have to free the previous receiver
- * config here. Since we are iterating backwards, the winning
- * receiver arg is in fact the first one given.
- */
- if (afi[ret].receiver_conf)
- afi[ret].receiver->free_config(afi[ret].receiver_conf);
- afi[ret].receiver_conf = check_receiver_arg(recv_arg, &receiver_num);
- if (!afi[ret].receiver_conf) {
+ af_mask = ret;
+ FOR_EACH_AUDIO_FORMAT(j) {
+ a = afi + j;
+ if ((af_mask & (1 << j)) == 0) /* no match */
+ continue;
+ /*
+ * If multiple receivers are given for this audio format, the
+ * last one wins and we have to free the previous receiver
+ * config here. Since we are iterating backwards, the winning
+ * receiver arg is in fact the first one given.
+ */
+ if (a->receiver_conf)
+ a->receiver->free_config(a->receiver_conf);
+ a->receiver_conf = check_receiver_arg(recv_arg, &receiver_num);
ret = -E_RECV_SYNTAX;
- goto out;
+ if (!a->receiver_conf)
+ goto out;
+ a->receiver = receivers + receiver_num;
}
- afi[ret].receiver = &receivers[receiver_num];
}
/*
* Use the first available receiver with no arguments for those audio
return -E_RECV_SYNTAX;
a->receiver = &receivers[receiver_num];
}
+ FOR_EACH_AUDIO_FORMAT(i) {
+ a = afi + i;
+ PARA_INFO_LOG("receiving %s streams via %s receiver\n",
+ audio_formats[i], a->receiver->name);
+ }
ret = 1;
out:
free(cmd);