mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-03 09:01:54 -05:00
pw-top: add 'batch-mode' and iterations known from top
This commit is contained in:
parent
7f30621b86
commit
71653e04d2
1 changed files with 89 additions and 34 deletions
|
|
@ -82,6 +82,9 @@ struct data {
|
||||||
unsigned pending_refresh:1;
|
unsigned pending_refresh:1;
|
||||||
|
|
||||||
WINDOW *win;
|
WINDOW *win;
|
||||||
|
|
||||||
|
unsigned int batch_mode:1;
|
||||||
|
int iterations;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct point {
|
struct point {
|
||||||
|
|
@ -89,6 +92,22 @@ struct point {
|
||||||
struct driver info;
|
struct driver info;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static SPA_PRINTF_FUNC(4, 5) void print_mode_dependent(struct data *d, int y, int x, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list argp;
|
||||||
|
if (!d->batch_mode)
|
||||||
|
mvwprintw(d->win, y, x, "%s", "");
|
||||||
|
|
||||||
|
va_start(argp, fmt);
|
||||||
|
if (d->batch_mode) {
|
||||||
|
vprintf(fmt, argp);
|
||||||
|
printf("\n");
|
||||||
|
} else
|
||||||
|
vw_printw(d->win, fmt, argp);
|
||||||
|
va_end(argp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int process_info(struct data *d, const struct spa_pod *pod, struct driver *info)
|
static int process_info(struct data *d, const struct spa_pod *pod, struct driver *info)
|
||||||
{
|
{
|
||||||
return spa_pod_parse_struct(pod,
|
return spa_pod_parse_struct(pod,
|
||||||
|
|
@ -144,7 +163,7 @@ static const struct pw_proxy_events proxy_events = {
|
||||||
.destroy = on_node_destroy,
|
.destroy = on_node_destroy,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void do_refresh(struct data *d);
|
static void do_refresh(struct data *d, bool force_refresh);
|
||||||
|
|
||||||
static void node_info(void *data, const struct pw_node_info *info)
|
static void node_info(void *data, const struct pw_node_info *info)
|
||||||
{
|
{
|
||||||
|
|
@ -152,7 +171,7 @@ static void node_info(void *data, const struct pw_node_info *info)
|
||||||
|
|
||||||
if (n->state != info->state) {
|
if (n->state != info->state) {
|
||||||
n->state = info->state;
|
n->state = info->state;
|
||||||
do_refresh(n->data);
|
do_refresh(n->data, !n->data->batch_mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -259,7 +278,7 @@ static void node_param(void *data, int seq,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
done:
|
done:
|
||||||
do_refresh(n->data);
|
do_refresh(n->data, !n->data->batch_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct pw_node_events node_events = {
|
static const struct pw_node_events node_events = {
|
||||||
|
|
@ -296,6 +315,7 @@ static struct node *add_node(struct data *d, uint32_t id, const char *name)
|
||||||
}
|
}
|
||||||
spa_list_append(&d->node_list, &n->link);
|
spa_list_append(&d->node_list, &n->link);
|
||||||
d->n_nodes++;
|
d->n_nodes++;
|
||||||
|
if (!d->batch_mode)
|
||||||
d->pending_refresh = true;
|
d->pending_refresh = true;
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
|
|
@ -307,6 +327,7 @@ static void remove_node(struct data *d, struct node *n)
|
||||||
pw_proxy_destroy(n->proxy);
|
pw_proxy_destroy(n->proxy);
|
||||||
spa_list_remove(&n->link);
|
spa_list_remove(&n->link);
|
||||||
d->n_nodes--;
|
d->n_nodes--;
|
||||||
|
if (!d->batch_mode)
|
||||||
d->pending_refresh = true;
|
d->pending_refresh = true;
|
||||||
free(n);
|
free(n);
|
||||||
}
|
}
|
||||||
|
|
@ -462,7 +483,7 @@ static void print_node(struct data *d, struct driver *i, struct node *n, int y)
|
||||||
else
|
else
|
||||||
busy = -1;
|
busy = -1;
|
||||||
|
|
||||||
mvwprintw(d->win, y, 0, "%s %4.1u %6.1u %6.1u %s %s %s %s %3.1u %16.16s %s%s",
|
print_mode_dependent(d, y, 0, "%s %4.1u %6.1u %6.1u %s %s %s %s %3.1u %16.16s %s%s",
|
||||||
state_as_string(n->state),
|
state_as_string(n->state),
|
||||||
n->id,
|
n->id,
|
||||||
frac.num, frac.denom,
|
frac.num, frac.denom,
|
||||||
|
|
@ -484,23 +505,31 @@ static void clear_node(struct node *n)
|
||||||
spa_zero(n->info);
|
spa_zero(n->info);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void do_refresh(struct data *d)
|
#define HEADER "S ID QUANT RATE WAIT BUSY W/Q B/Q ERR FORMAT NAME "
|
||||||
|
|
||||||
|
static void do_refresh(struct data *d, bool force_refresh)
|
||||||
{
|
{
|
||||||
struct node *n, *t, *f;
|
struct node *n, *t, *f;
|
||||||
int y = 1;
|
int y = 1;
|
||||||
|
|
||||||
|
if (!d->pending_refresh && !force_refresh)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!d->batch_mode) {
|
||||||
wclear(d->win);
|
wclear(d->win);
|
||||||
wattron(d->win, A_REVERSE);
|
wattron(d->win, A_REVERSE);
|
||||||
wprintw(d->win, "%-*.*s", COLS, COLS, "S ID QUANT RATE WAIT BUSY W/Q B/Q ERR FORMAT NAME ");
|
wprintw(d->win, "%-*.*s", COLS, COLS, HEADER);
|
||||||
wattroff(d->win, A_REVERSE);
|
wattroff(d->win, A_REVERSE);
|
||||||
wprintw(d->win, "\n");
|
wprintw(d->win, "\n");
|
||||||
|
} else
|
||||||
|
printf(HEADER "\n");
|
||||||
|
|
||||||
spa_list_for_each_safe(n, t, &d->node_list, link) {
|
spa_list_for_each_safe(n, t, &d->node_list, link) {
|
||||||
if (n->driver != n)
|
if (n->driver != n)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
print_node(d, &n->info, n, y++);
|
print_node(d, &n->info, n, y++);
|
||||||
if(y > LINES)
|
if(!d->batch_mode && y > LINES)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
spa_list_for_each(f, &d->node_list, link) {
|
spa_list_for_each(f, &d->node_list, link) {
|
||||||
|
|
@ -517,19 +546,28 @@ static void do_refresh(struct data *d)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!d->batch_mode) {
|
||||||
// Clear from last line to the end of the window to hide text wrapping from the last node
|
// Clear from last line to the end of the window to hide text wrapping from the last node
|
||||||
wmove(d->win, y, 0);
|
wmove(d->win, y, 0);
|
||||||
wclrtobot(d->win);
|
wclrtobot(d->win);
|
||||||
|
|
||||||
wrefresh(d->win);
|
wrefresh(d->win);
|
||||||
|
}
|
||||||
|
|
||||||
d->pending_refresh = false;
|
d->pending_refresh = false;
|
||||||
|
|
||||||
|
if (d->iterations > 0)
|
||||||
|
d->iterations--;
|
||||||
|
|
||||||
|
if (d->iterations == 0)
|
||||||
|
pw_main_loop_quit(d->loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void do_timeout(void *data, uint64_t expirations)
|
static void do_timeout(void *data, uint64_t expirations)
|
||||||
{
|
{
|
||||||
struct data *d = data;
|
struct data *d = data;
|
||||||
d->generation++;
|
d->generation++;
|
||||||
do_refresh(d);
|
do_refresh(d, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void profiler_profile(void *data, const struct spa_pod *pod)
|
static void profiler_profile(void *data, const struct spa_pod *pod)
|
||||||
|
|
@ -568,8 +606,8 @@ static void profiler_profile(void *data, const struct spa_pod *pod)
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (d->pending_refresh)
|
|
||||||
do_refresh(d);
|
do_refresh(d, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct pw_profiler_events profiler_events = {
|
static const struct pw_profiler_events profiler_events = {
|
||||||
|
|
@ -608,8 +646,8 @@ static void registry_event_global(void *data, uint32_t id,
|
||||||
d->profiler = proxy;
|
d->profiler = proxy;
|
||||||
pw_proxy_add_object_listener(proxy, &d->profiler_listener, &profiler_events, d);
|
pw_proxy_add_object_listener(proxy, &d->profiler_listener, &profiler_events, d);
|
||||||
}
|
}
|
||||||
if (d->pending_refresh)
|
|
||||||
do_refresh(d);
|
do_refresh(d, false);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
error_proxy:
|
error_proxy:
|
||||||
|
|
@ -623,8 +661,8 @@ static void registry_event_global_remove(void *data, uint32_t id)
|
||||||
struct node *n;
|
struct node *n;
|
||||||
if ((n = find_node(d, id)) != NULL)
|
if ((n = find_node(d, id)) != NULL)
|
||||||
remove_node(d, n);
|
remove_node(d, n);
|
||||||
if (d->pending_refresh)
|
|
||||||
do_refresh(d);
|
do_refresh(d, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct pw_registry_events registry_events = {
|
static const struct pw_registry_events registry_events = {
|
||||||
|
|
@ -662,7 +700,7 @@ static void on_core_done(void *_data, uint32_t id, int seq)
|
||||||
pw_log_error("no Profiler Interface found, please load one in the server");
|
pw_log_error("no Profiler Interface found, please load one in the server");
|
||||||
pw_main_loop_quit(d->loop);
|
pw_main_loop_quit(d->loop);
|
||||||
} else {
|
} else {
|
||||||
do_refresh(d);
|
do_refresh(d, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -683,6 +721,8 @@ static void show_help(const char *name, bool error)
|
||||||
{
|
{
|
||||||
fprintf(error ? stderr : stdout, "Usage:\n%s [options]\n\n"
|
fprintf(error ? stderr : stdout, "Usage:\n%s [options]\n\n"
|
||||||
"Options:\n"
|
"Options:\n"
|
||||||
|
" -b, --batch-mode run in non-interactive batch_mode mode\n"
|
||||||
|
" -n, --iterations = NUMBER exit on maximum iterations NUMBER\n"
|
||||||
" -r, --remote Remote daemon name\n"
|
" -r, --remote Remote daemon name\n"
|
||||||
"\n"
|
"\n"
|
||||||
" -h, --help Show this help\n"
|
" -h, --help Show this help\n"
|
||||||
|
|
@ -715,7 +755,7 @@ static void do_handle_io(void *data, int fd, uint32_t mask)
|
||||||
pw_main_loop_quit(d->loop);
|
pw_main_loop_quit(d->loop);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
do_refresh(d);
|
do_refresh(d, !d->batch_mode);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -727,9 +767,11 @@ int main(int argc, char *argv[])
|
||||||
struct pw_loop *l;
|
struct pw_loop *l;
|
||||||
const char *opt_remote = NULL;
|
const char *opt_remote = NULL;
|
||||||
static const struct option long_options[] = {
|
static const struct option long_options[] = {
|
||||||
|
{ "batch-mode", no_argument, NULL, 'b' },
|
||||||
|
{ "iterations", required_argument, NULL, 'n' },
|
||||||
|
{ "remote", required_argument, NULL, 'r' },
|
||||||
{ "help", no_argument, NULL, 'h' },
|
{ "help", no_argument, NULL, 'h' },
|
||||||
{ "version", no_argument, NULL, 'V' },
|
{ "version", no_argument, NULL, 'V' },
|
||||||
{ "remote", required_argument, NULL, 'r' },
|
|
||||||
{ NULL, 0, NULL, 0}
|
{ NULL, 0, NULL, 0}
|
||||||
};
|
};
|
||||||
int c;
|
int c;
|
||||||
|
|
@ -739,9 +781,11 @@ int main(int argc, char *argv[])
|
||||||
setlocale(LC_ALL, "");
|
setlocale(LC_ALL, "");
|
||||||
pw_init(&argc, &argv);
|
pw_init(&argc, &argv);
|
||||||
|
|
||||||
|
data.iterations = -1;
|
||||||
|
|
||||||
spa_list_init(&data.node_list);
|
spa_list_init(&data.node_list);
|
||||||
|
|
||||||
while ((c = getopt_long(argc, argv, "hVr:o:", long_options, NULL)) != -1) {
|
while ((c = getopt_long(argc, argv, "hVr:o:bn:", long_options, NULL)) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'h':
|
case 'h':
|
||||||
show_help(argv[0], false);
|
show_help(argv[0], false);
|
||||||
|
|
@ -757,6 +801,12 @@ int main(int argc, char *argv[])
|
||||||
case 'r':
|
case 'r':
|
||||||
opt_remote = optarg;
|
opt_remote = optarg;
|
||||||
break;
|
break;
|
||||||
|
case 'b':
|
||||||
|
data.batch_mode = 1;
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
spa_atoi32(optarg, &data.iterations, 10);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
show_help(argv[0], true);
|
show_help(argv[0], true);
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -769,6 +819,9 @@ int main(int argc, char *argv[])
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!data.batch_mode)
|
||||||
|
data.iterations = -1;
|
||||||
|
|
||||||
l = pw_main_loop_get_loop(data.loop);
|
l = pw_main_loop_get_loop(data.loop);
|
||||||
pw_loop_add_signal(l, SIGINT, do_quit, &data);
|
pw_loop_add_signal(l, SIGINT, do_quit, &data);
|
||||||
pw_loop_add_signal(l, SIGTERM, do_quit, &data);
|
pw_loop_add_signal(l, SIGTERM, do_quit, &data);
|
||||||
|
|
@ -802,9 +855,10 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
data.check_profiler = pw_core_sync(data.core, 0, 0);
|
data.check_profiler = pw_core_sync(data.core, 0, 0);
|
||||||
|
|
||||||
|
if (!data.batch_mode) {
|
||||||
terminal_start();
|
terminal_start();
|
||||||
|
|
||||||
data.win = newwin(LINES, COLS, 0, 0);
|
data.win = newwin(LINES, COLS, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
data.timer = pw_loop_add_timer(l, do_timeout, &data);
|
data.timer = pw_loop_add_timer(l, do_timeout, &data);
|
||||||
value.tv_sec = 1;
|
value.tv_sec = 1;
|
||||||
|
|
@ -813,15 +867,16 @@ int main(int argc, char *argv[])
|
||||||
interval.tv_nsec = 0;
|
interval.tv_nsec = 0;
|
||||||
pw_loop_update_timer(l, data.timer, &value, &interval, false);
|
pw_loop_update_timer(l, data.timer, &value, &interval, false);
|
||||||
|
|
||||||
|
if (!data.batch_mode)
|
||||||
pw_loop_add_io(l, fileno(stdin), SPA_IO_IN, false, do_handle_io, &data);
|
pw_loop_add_io(l, fileno(stdin), SPA_IO_IN, false, do_handle_io, &data);
|
||||||
|
|
||||||
pw_main_loop_run(data.loop);
|
pw_main_loop_run(data.loop);
|
||||||
|
|
||||||
|
if (!data.batch_mode)
|
||||||
terminal_stop();
|
terminal_stop();
|
||||||
|
|
||||||
spa_list_consume(n, &data.node_list, link)
|
spa_list_consume(n, &data.node_list, link)
|
||||||
remove_node(&data, n);
|
remove_node(&data, n);
|
||||||
|
|
||||||
if (data.profiler) {
|
if (data.profiler) {
|
||||||
spa_hook_remove(&data.profiler_listener);
|
spa_hook_remove(&data.profiler_listener);
|
||||||
pw_proxy_destroy((struct pw_proxy*)data.profiler);
|
pw_proxy_destroy((struct pw_proxy*)data.profiler);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue