/*
- * Copyright (C) 2012-2014 Andre Noll <maan@tuebingen.mpg.de>
+ * Copyright (C) 2012 Andre Noll <maan@tuebingen.mpg.de>
*
* Licensed under the GPL v2. For licencing details see COPYING.
*/
#include "para.h"
#include "list.h"
#include "play.cmdline.h"
-#include "filter.cmdline.h"
#include "error.h"
#include "ggo.h"
#include "buffer_tree.h"
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);
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);
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));
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;
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) {
/* 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);
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;
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)]);
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;
}
-#include "play_completion.h"
+#include "play.command_list.h"
+typedef int play_command_handler_t(struct play_task *, int, char**);
+static play_command_handler_t PLAY_COMMAND_HANDLERS;
/* defines one command of para_play */
struct pp_command {
const char *name;
- int (*handler)(struct play_task *, int, char**);
+ play_command_handler_t *handler;
const char *description;
const char *usage;
const char *help;
};
-#include "play_command_list.h"
static struct pp_command pp_cmds[] = {DEFINE_PLAY_CMD_ARRAY};
#define FOR_EACH_COMMAND(c) for (c = 0; pp_cmds[c].name; c++)
-#include "play_completion.h"
+#include "play.completion.h"
static struct i9e_completer pp_completers[];
I9E_DUMMY_COMPLETER(jmp);
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",
kill_stream(pt);
pt->next_file = ret;
pt->rq = CRT_FILE_CHANGE;
+ pt->start_chunk = 0;
return 0;
}
kill_stream(pt);
pt->next_file = ret;
pt->rq = CRT_FILE_CHANGE;
+ pt->start_chunk = 0;
return 0;
}
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;
* 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;