X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=blobdiff_plain;f=play.c;h=fac551aa161d14f258e1495a4530462ca1146357;hp=61c30aed08b131384e099a945cfed3011b9a0f97;hb=21c6e0b09b42e61e72b741bd726856ab0bcd1d64;hpb=6e0b28e02a1013c019a3225e922b71f913bfbae4 diff --git a/play.c b/play.c index 61c30aed..fac551aa 100644 --- a/play.c +++ b/play.c @@ -13,7 +13,6 @@ #include "para.h" #include "list.h" #include "play.cmdline.h" -#include "filter.cmdline.h" #include "error.h" #include "ggo.h" #include "buffer_tree.h" @@ -37,6 +36,9 @@ * Playlist handling is done exclusively in play context. */ +/** Array of error strings. */ +DEFINE_PARA_ERRLIST; + /** * Describes a request to change the state of para_play. * @@ -96,9 +98,6 @@ struct play_task { char *afhi_txt; }; -/** Initialize the array of errors for para_play. */ -INIT_PLAY_ERRLISTS; - /* Activate the afh receiver. */ extern void afh_recv_init(struct receiver *r); #undef AFH_RECEIVER @@ -184,10 +183,10 @@ static void parse_config_or_die(int argc, char *argv[]) loglevel = get_loglevel_by_name(conf.loglevel_arg); } for (i = 0; i < conf.key_map_given; i++) { - char *s = strchr(conf.key_map_arg[i] + 1, ':'); - if (s) + char *kma = conf.key_map_arg[i]; + if (*kma && strchr(kma + 1, ':')) continue; - PARA_EMERG_LOG("invalid key map arg: %s\n", conf.key_map_arg[i]); + PARA_EMERG_LOG("invalid key map arg: %s\n", kma); goto err; } free(config_file); @@ -263,7 +262,7 @@ static int get_playback_error(struct play_task *pt) static int eof_cleanup(struct play_task *pt) { struct writer *w = writers + DEFAULT_WRITER; - struct filter *decoder = filters + pt->fn.filter_num; + const struct filter *decoder = filter_get(pt->fn.filter_num); int ret; ret = get_playback_error(pt); @@ -277,7 +276,8 @@ static int eof_cleanup(struct play_task *pt) memset(&pt->wn, 0, sizeof(struct writer_node)); task_reap(&pt->fn.task); - decoder->close(&pt->fn); + if (decoder->close) + decoder->close(&pt->fn); btr_remove_node(&pt->fn.btrn); free(pt->fn.conf); memset(&pt->fn, 0, sizeof(struct filter_node)); @@ -328,8 +328,7 @@ static int open_new_file(struct play_task *pt) pt->rn.receiver = afh_recv; ret = afh_recv->open(&pt->rn); if (ret < 0) { - PARA_ERROR_LOG("could not open %s: %s\n", path, - para_strerror(-ret)); + PARA_ERROR_LOG("could not open %s\n", path); goto fail; } pt->audio_format_num = ret; @@ -368,7 +367,7 @@ static int load_file(struct play_task *pt) const char *af; char *tmp, buf[20]; int ret; - struct filter *decoder; + const struct filter *decoder; btr_remove_node(&pt->rn.btrn); if (!pt->rn.receiver || pt->next_file != pt->current_file) { @@ -388,16 +387,20 @@ static int load_file(struct play_task *pt) /* set up decoding filter */ af = audio_format_name(pt->audio_format_num); tmp = make_message("%sdec", af); + PARA_INFO_LOG("decoder: %s\n", tmp); ret = check_filter_arg(tmp, &pt->fn.conf); freep(&tmp); if (ret < 0) goto fail; pt->fn.filter_num = ret; - decoder = filters + ret; + decoder = filter_get(ret); pt->fn.btrn = btr_new_node(&(struct btr_node_description) EMBRACE(.name = decoder->name, .parent = pt->rn.btrn, .handler = decoder->execute, .context = &pt->fn)); - decoder->open(&pt->fn); + if (decoder->open) + decoder->open(&pt->fn); + PARA_INFO_LOG("buffer tree:\n"); + btr_log_tree(pt->rn.btrn, LL_INFO); /* setup default writer */ pt->wn.conf = check_writer_arg_or_die(NULL, &pt->wn.writer_num); @@ -452,6 +455,8 @@ again: pt->next_file = pt->current_file; ret = load_file(pt); if (ret < 0) { + PARA_ERROR_LOG("%s: marking file as invalid\n", + para_strerror(-ret)); pt->invalid[pt->next_file] = true; pt->rq = CRT_NONE; goto again; @@ -591,6 +596,28 @@ static char *get_key_map_seq(int key) get_internal_key_map_seq(key) : get_user_key_map_seq(key); } +static char *get_key_map_seq_safe(int key) +{ + const char hex[] = "0123456789abcdef"; + char *seq = get_key_map_seq(key), *sseq; + size_t n, len = strlen(seq); + + if (len == 1 && isprint(*seq)) + return seq; + sseq = para_malloc(2 + 2 * len + 1); + sseq[0] = '0'; + sseq[1] = 'x'; + for (n = 0; n < len; n++) { + uint8_t val = (seq[n] & 0xf0) >> 4; + sseq[2 + 2 * n] = hex[val]; + val = seq[n] & 0xf; + sseq[2 + 2 * n + 1] = hex[val]; + } + free(seq); + sseq[2 + 2 * n] = '\0'; + return sseq; +} + static inline char *get_internal_key_map_cmd(int key) { return para_strdup(default_commands[get_internal_key_map_idx(key)]); @@ -619,15 +646,8 @@ static char **get_mapped_keyseqs(void) result = para_malloc((NUM_MAPPED_KEYS + 1) * sizeof(char *)); FOR_EACH_MAPPED_KEY(i) { - int idx = get_key_map_idx(i); char *seq = get_key_map_seq(i); - char *cmd = get_key_map_cmd(i); - bool internal = is_internal_key(i); - PARA_DEBUG_LOG("%s key sequence #%d: %s -> %s\n", - internal? "internal" : "user-defined", - idx, seq, cmd); result[i] = seq; - free(cmd); } result[i] = NULL; return result; @@ -716,7 +736,7 @@ static int com_help(struct play_task *pt, int argc, char **argv) FOR_EACH_MAPPED_KEY(i) { bool internal = is_internal_key(i); int idx = get_key_map_idx(i); - char *seq = get_key_map_seq(i); + char *seq = get_key_map_seq_safe(i); char *cmd = get_key_map_cmd(i); sz = xasprintf(&buf, "%s key #%d: %s -> %s\n", @@ -768,7 +788,7 @@ static void list_file(struct play_task *pt, int num) char *buf; size_t sz; - sz = xasprintf(&buf, "%s %4u %s\n", num == pt->current_file? + sz = xasprintf(&buf, "%s %4d %s\n", num == pt->current_file? "*" : " ", num, conf.inputs[num]); btr_add_output(buf, sz, pt->btrn); } @@ -921,6 +941,8 @@ static int com_jmp(struct play_task *pt, int argc, char **argv) return ret; if (percent < 0 || percent > 100) return -ERRNO_TO_PARA_ERROR(EINVAL); + if (percent == 100) + return com_next(pt, 1, (char *[]){"next", NULL}); if (pt->playing && !pt->fn.btrn) return 0; pt->start_chunk = percent * pt->num_chunks / 100; @@ -1029,7 +1051,7 @@ static void sigint_handler(int sig) * stderr. Once the i9e subsystem has been initialized, we switch to the i9e * log facility. */ -static void session_open(__a_unused struct play_task *pt) +static void session_open(struct play_task *pt) { int ret; char *history_file;