mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-02 09:01:50 -05:00
pw-top: show negotiated formats
Add a column with negotiated formats. It requires an adapter that will enumerate the port formats so it does not work for video streams yet. Fixes #2566
This commit is contained in:
parent
305f2104ee
commit
76631e6251
1 changed files with 113 additions and 4 deletions
|
|
@ -32,10 +32,14 @@
|
||||||
#include <spa/utils/string.h>
|
#include <spa/utils/string.h>
|
||||||
#include <spa/pod/parser.h>
|
#include <spa/pod/parser.h>
|
||||||
#include <spa/debug/pod.h>
|
#include <spa/debug/pod.h>
|
||||||
|
#include <spa/param/format-utils.h>
|
||||||
|
#include <spa/param/audio/format-utils.h>
|
||||||
|
#include <spa/param/video/format-utils.h>
|
||||||
|
|
||||||
#include <pipewire/impl.h>
|
#include <pipewire/impl.h>
|
||||||
#include <pipewire/extensions/profiler.h>
|
#include <pipewire/extensions/profiler.h>
|
||||||
|
|
||||||
|
#define MAX_FORMAT 16
|
||||||
#define MAX_NAME 128
|
#define MAX_NAME 128
|
||||||
|
|
||||||
struct driver {
|
struct driver {
|
||||||
|
|
@ -59,13 +63,17 @@ struct measurement {
|
||||||
struct node {
|
struct node {
|
||||||
struct spa_list link;
|
struct spa_list link;
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
char name[MAX_NAME];
|
char name[MAX_NAME+1];
|
||||||
struct measurement measurement;
|
struct measurement measurement;
|
||||||
struct driver info;
|
struct driver info;
|
||||||
struct node *driver;
|
struct node *driver;
|
||||||
uint32_t errors;
|
uint32_t errors;
|
||||||
int32_t last_error_status;
|
int32_t last_error_status;
|
||||||
uint32_t generation;
|
uint32_t generation;
|
||||||
|
char format[MAX_FORMAT+1];
|
||||||
|
struct pw_proxy *proxy;
|
||||||
|
struct spa_hook proxy_listener;
|
||||||
|
struct spa_hook object_listener;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct data {
|
struct data {
|
||||||
|
|
@ -131,6 +139,91 @@ static struct node *find_node(struct data *d, uint32_t id)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void on_node_removed(void *data)
|
||||||
|
{
|
||||||
|
struct node *n = data;
|
||||||
|
pw_proxy_destroy(n->proxy);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void on_node_destroy(void *data)
|
||||||
|
{
|
||||||
|
struct node *n = data;
|
||||||
|
n->proxy = NULL;
|
||||||
|
spa_hook_remove(&n->proxy_listener);
|
||||||
|
spa_hook_remove(&n->object_listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct pw_proxy_events proxy_events = {
|
||||||
|
PW_VERSION_PROXY_EVENTS,
|
||||||
|
.removed = on_node_removed,
|
||||||
|
.destroy = on_node_destroy,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void node_param(void *data, int seq,
|
||||||
|
uint32_t id, uint32_t index, uint32_t next,
|
||||||
|
const struct spa_pod *param)
|
||||||
|
{
|
||||||
|
struct node *n = data;
|
||||||
|
|
||||||
|
switch (id) {
|
||||||
|
case SPA_PARAM_Format:
|
||||||
|
{
|
||||||
|
uint32_t media_type, media_subtype;
|
||||||
|
|
||||||
|
spa_format_parse(param, &media_type, &media_subtype);
|
||||||
|
|
||||||
|
switch(media_type) {
|
||||||
|
case SPA_MEDIA_TYPE_audio:
|
||||||
|
switch(media_subtype) {
|
||||||
|
case SPA_MEDIA_SUBTYPE_raw:
|
||||||
|
{
|
||||||
|
struct spa_audio_info_raw info;
|
||||||
|
if (spa_format_audio_raw_parse(param, &info) >= 0) {
|
||||||
|
snprintf(n->format, sizeof(n->format), "%6.6s/%d %-6d",
|
||||||
|
spa_debug_type_find_short_name(spa_type_audio_format, info.format),
|
||||||
|
info.channels, info.rate);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SPA_MEDIA_SUBTYPE_dsd:
|
||||||
|
{
|
||||||
|
struct spa_audio_info_dsd info;
|
||||||
|
if (spa_format_audio_dsd_parse(param, &info) >= 0) {
|
||||||
|
snprintf(n->format, sizeof(n->format), "DSD%d/%2d ",
|
||||||
|
8 * info.rate / 44100, info.channels);
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SPA_MEDIA_TYPE_video:
|
||||||
|
switch(media_subtype) {
|
||||||
|
case SPA_MEDIA_SUBTYPE_raw:
|
||||||
|
{
|
||||||
|
struct spa_video_info_raw info;
|
||||||
|
if (spa_format_video_raw_parse(param, &info) >= 0) {
|
||||||
|
snprintf(n->format, sizeof(n->format), "%6.6s %dx%d",
|
||||||
|
spa_debug_type_find_short_name(spa_type_video_format, info.format),
|
||||||
|
info.size.width, info.size.height);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct pw_node_events node_events = {
|
||||||
|
PW_VERSION_NODE,
|
||||||
|
.param = node_param,
|
||||||
|
};
|
||||||
|
|
||||||
static struct node *add_node(struct data *d, uint32_t id, const char *name)
|
static struct node *add_node(struct data *d, uint32_t id, const char *name)
|
||||||
{
|
{
|
||||||
struct node *n;
|
struct node *n;
|
||||||
|
|
@ -139,11 +232,23 @@ static struct node *add_node(struct data *d, uint32_t id, const char *name)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (name)
|
if (name)
|
||||||
strncpy(n->name, name, MAX_NAME-1);
|
strncpy(n->name, name, MAX_NAME);
|
||||||
else
|
else
|
||||||
snprintf(n->name, sizeof(n->name), "%u", id);
|
snprintf(n->name, sizeof(n->name), "%u", id);
|
||||||
n->id = id;
|
n->id = id;
|
||||||
n->driver = n;
|
n->driver = n;
|
||||||
|
n->proxy = pw_registry_bind(d->registry, id, PW_TYPE_INTERFACE_Node, PW_VERSION_NODE, 0);
|
||||||
|
if (n->proxy) {
|
||||||
|
uint32_t ids[1] = { SPA_PARAM_Format };
|
||||||
|
|
||||||
|
pw_proxy_add_listener(n->proxy,
|
||||||
|
&n->proxy_listener, &proxy_events, n);
|
||||||
|
pw_proxy_add_object_listener(n->proxy,
|
||||||
|
&n->object_listener, &node_events, n);
|
||||||
|
|
||||||
|
pw_node_subscribe_params((struct pw_node*)n->proxy,
|
||||||
|
ids, 1);
|
||||||
|
}
|
||||||
spa_list_append(&d->node_list, &n->link);
|
spa_list_append(&d->node_list, &n->link);
|
||||||
d->n_nodes++;
|
d->n_nodes++;
|
||||||
|
|
||||||
|
|
@ -152,6 +257,8 @@ static struct node *add_node(struct data *d, uint32_t id, const char *name)
|
||||||
|
|
||||||
static void remove_node(struct data *d, struct node *n)
|
static void remove_node(struct data *d, struct node *n)
|
||||||
{
|
{
|
||||||
|
if (n->proxy)
|
||||||
|
pw_proxy_destroy(n->proxy);
|
||||||
spa_list_remove(&n->link);
|
spa_list_remove(&n->link);
|
||||||
d->n_nodes--;
|
d->n_nodes--;
|
||||||
free(n);
|
free(n);
|
||||||
|
|
@ -290,7 +397,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 %s%s",
|
mvwprintw(d->win, y, 0, "%s %4.1u %6.1u %6.1u %s %s %s %s %3.1u %16.16s %s%s",
|
||||||
n->measurement.status != 3 ? "!" : " ",
|
n->measurement.status != 3 ? "!" : " ",
|
||||||
n->id,
|
n->id,
|
||||||
frac.num, frac.denom,
|
frac.num, frac.denom,
|
||||||
|
|
@ -299,6 +406,7 @@ static void print_node(struct data *d, struct driver *i, struct node *n, int y)
|
||||||
print_perc(buf3, 64, waiting, quantum),
|
print_perc(buf3, 64, waiting, quantum),
|
||||||
print_perc(buf4, 64, busy, quantum),
|
print_perc(buf4, 64, busy, quantum),
|
||||||
i->xrun_count + n->errors,
|
i->xrun_count + n->errors,
|
||||||
|
n->measurement.status != 3 ? "" : n->format,
|
||||||
n->driver == n ? "" : " + ",
|
n->driver == n ? "" : " + ",
|
||||||
n->name);
|
n->name);
|
||||||
}
|
}
|
||||||
|
|
@ -310,7 +418,7 @@ static void do_refresh(struct data *d)
|
||||||
|
|
||||||
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 NAME ");
|
wprintw(d->win, "%-*.*s", COLS, COLS, "S ID QUANT RATE WAIT BUSY W/Q B/Q ERR FORMAT NAME ");
|
||||||
wattroff(d->win, A_REVERSE);
|
wattroff(d->win, A_REVERSE);
|
||||||
wprintw(d->win, "\n");
|
wprintw(d->win, "\n");
|
||||||
|
|
||||||
|
|
@ -327,6 +435,7 @@ static void do_refresh(struct data *d)
|
||||||
f->driver = f;
|
f->driver = f;
|
||||||
spa_zero(f->measurement);
|
spa_zero(f->measurement);
|
||||||
spa_zero(f->info);
|
spa_zero(f->info);
|
||||||
|
spa_zero(f->format);
|
||||||
f->errors = 0;
|
f->errors = 0;
|
||||||
f->last_error_status = 0;
|
f->last_error_status = 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue