mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-02 09:01:50 -05:00
Use the DSP format for dsp formats
Use the DSP media subtype to describe DSP formats. DSP formats don't include the rate, channels and channel position in the format and must use the rate and duration from the position io. This makes it possible to later change the samplerate dynamically without having to renegotiate the graph. The same goes for the video DSP format, which uses the io_video_size from the io_position to get the size/stride. Set this up in the node based on the defaults from the context. Make it possible to define defaults in the daemon config file, such as samplerate, quantum, video size and framerate. This is stored in the context and used for the DSP formats.
This commit is contained in:
parent
5a6da7d5e1
commit
852ac043d3
20 changed files with 402 additions and 270 deletions
|
|
@ -195,9 +195,6 @@ struct port {
|
|||
struct spa_io_buffers io;
|
||||
struct spa_list mix;
|
||||
|
||||
bool have_format;
|
||||
uint32_t rate;
|
||||
|
||||
bool zeroed;
|
||||
float *emptyptr;
|
||||
float empty[MAX_BUFFER_FRAMES + MAX_ALIGN];
|
||||
|
|
@ -1267,10 +1264,8 @@ static int param_enum_format(struct client *c, struct port *p,
|
|||
*param = spa_pod_builder_add_object(b,
|
||||
SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat,
|
||||
SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_audio),
|
||||
SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw),
|
||||
SPA_FORMAT_AUDIO_format, SPA_POD_Id(SPA_AUDIO_FORMAT_F32P),
|
||||
SPA_FORMAT_AUDIO_rate, SPA_POD_CHOICE_RANGE_Int(DEFAULT_SAMPLE_RATE, 1, INT32_MAX),
|
||||
SPA_FORMAT_AUDIO_channels, SPA_POD_Int(1));
|
||||
SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_dsp),
|
||||
SPA_FORMAT_AUDIO_format, SPA_POD_Id(SPA_AUDIO_FORMAT_DSP_F32));
|
||||
break;
|
||||
case 1:
|
||||
*param = spa_pod_builder_add_object(b,
|
||||
|
|
@ -1282,16 +1277,8 @@ static int param_enum_format(struct client *c, struct port *p,
|
|||
*param = spa_pod_builder_add_object(b,
|
||||
SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat,
|
||||
SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_video),
|
||||
SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw),
|
||||
SPA_FORMAT_VIDEO_format, SPA_POD_Id(SPA_VIDEO_FORMAT_RGBA_F32),
|
||||
SPA_FORMAT_VIDEO_size, SPA_POD_CHOICE_RANGE_Rectangle(
|
||||
&SPA_RECTANGLE(320, 240),
|
||||
&SPA_RECTANGLE(1,1),
|
||||
&SPA_RECTANGLE(INT32_MAX, INT32_MAX)),
|
||||
SPA_FORMAT_VIDEO_framerate, SPA_POD_CHOICE_RANGE_Fraction(
|
||||
&SPA_FRACTION(25,1),
|
||||
&SPA_FRACTION(0,1),
|
||||
&SPA_FRACTION(INT32_MAX,1)));
|
||||
SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_dsp),
|
||||
SPA_FORMAT_VIDEO_format, SPA_POD_Id(SPA_VIDEO_FORMAT_DSP_F32));
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
|
|
@ -1302,48 +1289,26 @@ static int param_enum_format(struct client *c, struct port *p,
|
|||
static int param_format(struct client *c, struct port *p,
|
||||
struct spa_pod **param, struct spa_pod_builder *b)
|
||||
{
|
||||
uint32_t channels[] = { SPA_AUDIO_CHANNEL_MONO };
|
||||
struct spa_pod_frame f;
|
||||
switch (p->object->port.type_id) {
|
||||
case 0:
|
||||
spa_pod_builder_push_object(b, &f, SPA_TYPE_OBJECT_Format, SPA_PARAM_Format);
|
||||
spa_pod_builder_add(b,
|
||||
SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_audio),
|
||||
SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw),
|
||||
SPA_FORMAT_AUDIO_format, SPA_POD_Id(SPA_AUDIO_FORMAT_F32P), NULL);
|
||||
if (p->have_format) {
|
||||
spa_pod_builder_add(b,
|
||||
SPA_FORMAT_AUDIO_rate, SPA_POD_Int(p->rate), NULL);
|
||||
} else {
|
||||
spa_pod_builder_add(b,
|
||||
SPA_FORMAT_AUDIO_rate, SPA_POD_CHOICE_RANGE_Int(DEFAULT_SAMPLE_RATE,
|
||||
1, INT32_MAX), NULL);
|
||||
}
|
||||
spa_pod_builder_add(b,
|
||||
SPA_FORMAT_AUDIO_channels, SPA_POD_Int(1),
|
||||
SPA_FORMAT_AUDIO_position, SPA_POD_Array(sizeof(uint32_t), SPA_TYPE_Id, 1, channels), NULL);
|
||||
*param = spa_pod_builder_pop(b, &f);
|
||||
*param = spa_pod_builder_add_object(b,
|
||||
SPA_TYPE_OBJECT_Format, SPA_PARAM_Format,
|
||||
SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_audio),
|
||||
SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_dsp),
|
||||
SPA_FORMAT_AUDIO_format, SPA_POD_Id(SPA_AUDIO_FORMAT_DSP_F32));
|
||||
break;
|
||||
case 1:
|
||||
*param = spa_pod_builder_add_object(b,
|
||||
SPA_TYPE_OBJECT_Format, SPA_PARAM_Format,
|
||||
SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_application),
|
||||
SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_control));
|
||||
SPA_TYPE_OBJECT_Format, SPA_PARAM_Format,
|
||||
SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_application),
|
||||
SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_control));
|
||||
break;
|
||||
case 2:
|
||||
*param = spa_pod_builder_add_object(b,
|
||||
SPA_TYPE_OBJECT_Format, SPA_PARAM_Format,
|
||||
SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_video),
|
||||
SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw),
|
||||
SPA_FORMAT_VIDEO_format, SPA_POD_Id(SPA_VIDEO_FORMAT_RGBA_F32),
|
||||
SPA_FORMAT_VIDEO_size, SPA_POD_CHOICE_RANGE_Rectangle(
|
||||
&SPA_RECTANGLE(320, 240),
|
||||
&SPA_RECTANGLE(1,1),
|
||||
&SPA_RECTANGLE(INT32_MAX, INT32_MAX)),
|
||||
SPA_FORMAT_VIDEO_framerate, SPA_POD_CHOICE_RANGE_Fraction(
|
||||
&SPA_FRACTION(25,1),
|
||||
&SPA_FRACTION(0,1),
|
||||
&SPA_FRACTION(INT32_MAX,1)));
|
||||
SPA_TYPE_OBJECT_Format, SPA_PARAM_Format,
|
||||
SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_video),
|
||||
SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_dsp),
|
||||
SPA_FORMAT_VIDEO_format, SPA_POD_Id(SPA_VIDEO_FORMAT_DSP_F32));
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
|
|
@ -1407,7 +1372,6 @@ static int port_set_format(struct client *c, struct port *p,
|
|||
|
||||
spa_list_for_each(mix, &p->mix, port_link)
|
||||
clear_buffers(c, mix);
|
||||
p->have_format = false;
|
||||
}
|
||||
else {
|
||||
struct spa_audio_info info = { 0 };
|
||||
|
|
@ -1416,13 +1380,13 @@ static int port_set_format(struct client *c, struct port *p,
|
|||
switch (info.media_type) {
|
||||
case SPA_MEDIA_TYPE_audio:
|
||||
{
|
||||
if (info.media_subtype != SPA_MEDIA_SUBTYPE_raw)
|
||||
if (info.media_subtype != SPA_MEDIA_SUBTYPE_dsp)
|
||||
return -EINVAL;
|
||||
|
||||
if (spa_format_audio_raw_parse(param, &info.info.raw) < 0)
|
||||
if (spa_format_audio_dsp_parse(param, &info.info.dsp) < 0)
|
||||
return -EINVAL;
|
||||
if (info.info.dsp.format != SPA_AUDIO_FORMAT_DSP_F32)
|
||||
return -EINVAL;
|
||||
|
||||
p->rate = info.info.raw.rate;
|
||||
break;
|
||||
}
|
||||
case SPA_MEDIA_TYPE_application:
|
||||
|
|
@ -1433,16 +1397,17 @@ static int port_set_format(struct client *c, struct port *p,
|
|||
{
|
||||
struct spa_video_info vinfo = { 0 };
|
||||
|
||||
if (info.media_subtype != SPA_MEDIA_SUBTYPE_raw)
|
||||
if (info.media_subtype != SPA_MEDIA_SUBTYPE_dsp)
|
||||
return -EINVAL;
|
||||
if (spa_format_video_raw_parse(param, &vinfo.info.raw) < 0)
|
||||
if (spa_format_video_dsp_parse(param, &vinfo.info.dsp) < 0)
|
||||
return -EINVAL;
|
||||
if (vinfo.info.dsp.format != SPA_VIDEO_FORMAT_DSP_F32)
|
||||
return -EINVAL;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
p->have_format = true;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,6 +54,16 @@ spa_format_audio_raw_parse(const struct spa_pod *format, struct spa_audio_info_r
|
|||
return res;
|
||||
}
|
||||
|
||||
static inline int
|
||||
spa_format_audio_dsp_parse(const struct spa_pod *format, struct spa_audio_info_dsp *info)
|
||||
{
|
||||
int res;
|
||||
res = spa_pod_parse_object(format,
|
||||
SPA_TYPE_OBJECT_Format, NULL,
|
||||
SPA_FORMAT_AUDIO_format, SPA_POD_Id(&info->format));
|
||||
return res;
|
||||
}
|
||||
|
||||
static inline struct spa_pod *
|
||||
spa_format_audio_raw_build(struct spa_pod_builder *builder, uint32_t id, struct spa_audio_info_raw *info)
|
||||
{
|
||||
|
|
@ -75,6 +85,18 @@ spa_format_audio_raw_build(struct spa_pod_builder *builder, uint32_t id, struct
|
|||
return (struct spa_pod*)spa_pod_builder_pop(builder, &f);
|
||||
}
|
||||
|
||||
static inline struct spa_pod *
|
||||
spa_format_audio_dsp_build(struct spa_pod_builder *builder, uint32_t id, struct spa_audio_info_dsp *info)
|
||||
{
|
||||
struct spa_pod_frame f;
|
||||
spa_pod_builder_push_object(builder, &f, SPA_TYPE_OBJECT_Format, id);
|
||||
spa_pod_builder_add(builder,
|
||||
SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_audio),
|
||||
SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_dsp),
|
||||
SPA_FORMAT_AUDIO_format, SPA_POD_Id(info->format),
|
||||
0);
|
||||
return (struct spa_pod*)spa_pod_builder_pop(builder, &f);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ struct spa_audio_info {
|
|||
uint32_t media_subtype;
|
||||
union {
|
||||
struct spa_audio_info_raw raw;
|
||||
struct spa_audio_info_dsp dsp;
|
||||
} info;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -82,8 +82,17 @@ enum spa_audio_format {
|
|||
SPA_AUDIO_FORMAT_F32P,
|
||||
SPA_AUDIO_FORMAT_F64P,
|
||||
|
||||
SPA_AUDIO_FORMAT_START_Other = 0x300,
|
||||
/* other formats start here */
|
||||
SPA_AUDIO_FORMAT_START_Other = 0x400,
|
||||
|
||||
/* Aliases */
|
||||
|
||||
/* DSP formats */
|
||||
SPA_AUDIO_FORMAT_DSP_S32 = SPA_AUDIO_FORMAT_S24_32P,
|
||||
SPA_AUDIO_FORMAT_DSP_F32 = SPA_AUDIO_FORMAT_F32P,
|
||||
SPA_AUDIO_FORMAT_DSP_F64 = SPA_AUDIO_FORMAT_F64P,
|
||||
|
||||
/* native endian */
|
||||
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||
SPA_AUDIO_FORMAT_S16 = SPA_AUDIO_FORMAT_S16_BE,
|
||||
SPA_AUDIO_FORMAT_U16 = SPA_AUDIO_FORMAT_U16_BE,
|
||||
|
|
@ -210,6 +219,11 @@ struct spa_audio_info_raw {
|
|||
|
||||
#define SPA_KEY_AUDIO_CHANNEL "audio.channel" /**< an audio channel as string,
|
||||
* Ex. "FL" */
|
||||
struct spa_audio_info_dsp {
|
||||
enum spa_audio_format format; /*< format, one of the DSP formats in enum spa_audio_format_dsp */
|
||||
};
|
||||
|
||||
#define SPA_AUDIO_INFO_DSP_INIT(...) (struct spa_audio_info_dsp) { __VA_ARGS__ }
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
|
|
|||
|
|
@ -57,6 +57,16 @@ spa_format_video_raw_parse(const struct spa_pod *format,
|
|||
SPA_FORMAT_VIDEO_colorPrimaries, SPA_POD_OPT_Id(&info->color_primaries));
|
||||
}
|
||||
|
||||
static inline int
|
||||
spa_format_video_dsp_parse(const struct spa_pod *format,
|
||||
struct spa_video_info_dsp *info)
|
||||
{
|
||||
return spa_pod_parse_object(format,
|
||||
SPA_TYPE_OBJECT_Format, NULL,
|
||||
SPA_FORMAT_VIDEO_format, SPA_POD_Id(&info->format),
|
||||
SPA_FORMAT_VIDEO_modifier, SPA_POD_OPT_Long(&info->modifier));
|
||||
}
|
||||
|
||||
static inline struct spa_pod *
|
||||
spa_format_video_raw_build(struct spa_pod_builder *builder, uint32_t id,
|
||||
struct spa_video_info_raw *info)
|
||||
|
|
@ -109,6 +119,23 @@ spa_format_video_raw_build(struct spa_pod_builder *builder, uint32_t id,
|
|||
return (struct spa_pod*)spa_pod_builder_pop(builder, &f);
|
||||
}
|
||||
|
||||
static inline struct spa_pod *
|
||||
spa_format_video_dsp_build(struct spa_pod_builder *builder, uint32_t id,
|
||||
struct spa_video_info_dsp *info)
|
||||
{
|
||||
struct spa_pod_frame f;
|
||||
spa_pod_builder_push_object(builder, &f, SPA_TYPE_OBJECT_Format, id);
|
||||
spa_pod_builder_add(builder,
|
||||
SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_video),
|
||||
SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_dsp),
|
||||
SPA_FORMAT_VIDEO_format, SPA_POD_Id(info->format),
|
||||
0);
|
||||
if (info->modifier)
|
||||
spa_pod_builder_add(builder,
|
||||
SPA_FORMAT_VIDEO_modifier, SPA_POD_Long(info->modifier), 0);
|
||||
return (struct spa_pod*)spa_pod_builder_pop(builder, &f);
|
||||
}
|
||||
|
||||
static inline int
|
||||
spa_format_video_h264_parse(const struct spa_pod *format,
|
||||
struct spa_video_info_h264 *info)
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ struct spa_video_info {
|
|||
uint32_t media_subtype;
|
||||
union {
|
||||
struct spa_video_info_raw raw;
|
||||
struct spa_video_info_dsp dsp;
|
||||
struct spa_video_info_h264 h264;
|
||||
struct spa_video_info_mjpg mjpg;
|
||||
} info;
|
||||
|
|
|
|||
|
|
@ -120,6 +120,9 @@ enum spa_video_format {
|
|||
|
||||
SPA_VIDEO_FORMAT_RGBA_F16,
|
||||
SPA_VIDEO_FORMAT_RGBA_F32,
|
||||
|
||||
/* Aliases */
|
||||
SPA_VIDEO_FORMAT_DSP_F32 = SPA_VIDEO_FORMAT_RGBA_F32,
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -204,6 +207,13 @@ struct spa_video_info_raw {
|
|||
|
||||
#define SPA_VIDEO_INFO_RAW_INIT(...) (struct spa_video_info_raw) { __VA_ARGS__ }
|
||||
|
||||
struct spa_video_info_dsp {
|
||||
enum spa_video_format format;
|
||||
int64_t modifier;
|
||||
};
|
||||
|
||||
#define SPA_VIDEO_INFO_DSP_INIT(...) (struct spa_video_info_dsp) { __VA_ARGS__ }
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ static void emit_port_info(struct impl *this, struct port *port, bool full)
|
|||
}
|
||||
|
||||
static int init_port(struct impl *this, enum spa_direction direction, uint32_t port_id,
|
||||
uint32_t rate, uint32_t position)
|
||||
uint32_t position)
|
||||
{
|
||||
struct port *port = GET_PORT(this, direction, port_id);
|
||||
|
||||
|
|
@ -184,15 +184,12 @@ static int init_port(struct impl *this, enum spa_direction direction, uint32_t p
|
|||
port->n_buffers = 0;
|
||||
port->have_format = false;
|
||||
port->format.media_type = SPA_MEDIA_TYPE_audio;
|
||||
port->format.media_subtype = SPA_MEDIA_SUBTYPE_raw;
|
||||
port->format.info.raw.format = SPA_AUDIO_FORMAT_F32P;
|
||||
port->format.info.raw.rate = rate;
|
||||
port->format.info.raw.channels = 1;
|
||||
port->format.info.raw.position[0] = position;
|
||||
port->format.media_subtype = SPA_MEDIA_SUBTYPE_dsp;
|
||||
port->format.info.dsp.format = SPA_AUDIO_FORMAT_DSP_F32;
|
||||
spa_list_init(&port->queue);
|
||||
|
||||
spa_log_debug(this->log, NAME " %p: add port %d:%d rate:%d position:%s",
|
||||
this, direction, port_id, rate, port->position);
|
||||
spa_log_debug(this->log, NAME " %p: add port %d:%d position:%s",
|
||||
this, direction, port_id, port->position);
|
||||
emit_port_info(this, port, true);
|
||||
|
||||
return 0;
|
||||
|
|
@ -310,10 +307,9 @@ static int impl_node_set_param(void *object, uint32_t id, uint32_t flags,
|
|||
this->port_count = info.info.raw.channels;
|
||||
this->monitor_count = this->monitor ? this->port_count : 0;
|
||||
for (i = 0; i < this->port_count; i++) {
|
||||
init_port(this, SPA_DIRECTION_INPUT, i, info.info.raw.rate,
|
||||
info.info.raw.position[i]);
|
||||
init_port(this, SPA_DIRECTION_INPUT, i, info.info.raw.position[i]);
|
||||
if (this->monitor)
|
||||
init_port(this, SPA_DIRECTION_OUTPUT, i+1, info.info.raw.rate,
|
||||
init_port(this, SPA_DIRECTION_OUTPUT, i+1,
|
||||
info.info.raw.position[i]);
|
||||
}
|
||||
return 0;
|
||||
|
|
@ -403,7 +399,10 @@ static int port_enum_formats(void *object,
|
|||
|
||||
switch (index) {
|
||||
case 0:
|
||||
if (PORT_IS_DSP(direction, port_id) || port->have_format) {
|
||||
if (PORT_IS_DSP(direction, port_id)) {
|
||||
*param = spa_format_audio_dsp_build(builder,
|
||||
SPA_PARAM_EnumFormat, &port->format.info.dsp);
|
||||
} else if (port->have_format) {
|
||||
*param = spa_format_audio_raw_build(builder,
|
||||
SPA_PARAM_EnumFormat, &port->format.info.raw);
|
||||
}
|
||||
|
|
@ -481,7 +480,10 @@ impl_node_port_enum_params(void *object, int seq,
|
|||
if (result.index > 0)
|
||||
return 0;
|
||||
|
||||
param = spa_format_audio_raw_build(&b, id, &port->format.info.raw);
|
||||
if (PORT_IS_DSP(direction, port_id))
|
||||
param = spa_format_audio_dsp_build(&b, id, &port->format.info.dsp);
|
||||
else
|
||||
param = spa_format_audio_raw_build(&b, id, &port->format.info.raw);
|
||||
break;
|
||||
case SPA_PARAM_Buffers:
|
||||
if (!port->have_format)
|
||||
|
|
@ -557,7 +559,7 @@ static int setup_convert(struct impl *this)
|
|||
|
||||
outport = GET_OUT_PORT(this, 0);
|
||||
|
||||
src_fmt = SPA_AUDIO_FORMAT_F32P;
|
||||
src_fmt = SPA_AUDIO_FORMAT_DSP_F32;
|
||||
dst_fmt = outport->format.info.raw.format;
|
||||
|
||||
spa_log_info(this->log, NAME " %p: %s/%d@%dx%d->%s/%d@%d", this,
|
||||
|
|
@ -630,53 +632,52 @@ static int port_set_format(void *object,
|
|||
spa_log_error(this->log, "can't parse format %s", spa_strerror(res));
|
||||
return res;
|
||||
}
|
||||
|
||||
if (info.media_type != SPA_MEDIA_TYPE_audio ||
|
||||
info.media_subtype != SPA_MEDIA_SUBTYPE_raw) {
|
||||
spa_log_error(this->log, "unexpected types %d/%d",
|
||||
info.media_type, info.media_subtype);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((res = spa_format_audio_raw_parse(format, &info.info.raw)) < 0) {
|
||||
spa_log_error(this->log, "can't parse format %s", spa_strerror(res));
|
||||
return res;
|
||||
}
|
||||
|
||||
if (PORT_IS_DSP(direction, port_id)) {
|
||||
if (info.info.raw.rate != port->format.info.raw.rate) {
|
||||
spa_log_error(this->log, "unexpected rate %d<->%d",
|
||||
info.info.raw.rate, port->format.info.raw.rate);
|
||||
if (info.media_type != SPA_MEDIA_TYPE_audio ||
|
||||
info.media_subtype != SPA_MEDIA_SUBTYPE_dsp) {
|
||||
spa_log_error(this->log, "unexpected types %d/%d",
|
||||
info.media_type, info.media_subtype);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (info.info.raw.format != SPA_AUDIO_FORMAT_F32P) {
|
||||
if ((res = spa_format_audio_dsp_parse(format, &info.info.dsp)) < 0) {
|
||||
spa_log_error(this->log, "can't parse format %s", spa_strerror(res));
|
||||
return res;
|
||||
}
|
||||
if (info.info.dsp.format != SPA_AUDIO_FORMAT_DSP_F32) {
|
||||
spa_log_error(this->log, "unexpected format %d<->%d",
|
||||
info.info.raw.format, SPA_AUDIO_FORMAT_F32P);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (info.info.raw.channels != 1) {
|
||||
spa_log_error(this->log, "unexpected channels %d<->1",
|
||||
info.info.raw.channels);
|
||||
info.info.dsp.format, SPA_AUDIO_FORMAT_DSP_F32);
|
||||
return -EINVAL;
|
||||
}
|
||||
port->blocks = 1;
|
||||
port->stride = 4;
|
||||
}
|
||||
else {
|
||||
if (info.media_type != SPA_MEDIA_TYPE_audio ||
|
||||
info.media_subtype != SPA_MEDIA_SUBTYPE_raw) {
|
||||
spa_log_error(this->log, "unexpected types %d/%d",
|
||||
info.media_type, info.media_subtype);
|
||||
return -EINVAL;
|
||||
}
|
||||
if ((res = spa_format_audio_raw_parse(format, &info.info.raw)) < 0) {
|
||||
spa_log_error(this->log, "can't parse format %s", spa_strerror(res));
|
||||
return res;
|
||||
}
|
||||
if (info.info.raw.channels != this->port_count) {
|
||||
spa_log_error(this->log, "unexpected channels %d<->%d",
|
||||
info.info.raw.channels, this->port_count);
|
||||
return -EINVAL;
|
||||
}
|
||||
port->stride = calc_width(&info);
|
||||
if (SPA_AUDIO_FORMAT_IS_PLANAR(info.info.raw.format)) {
|
||||
port->blocks = info.info.raw.channels;
|
||||
}
|
||||
else {
|
||||
port->stride *= info.info.raw.channels;
|
||||
port->blocks = 1;
|
||||
}
|
||||
}
|
||||
|
||||
port->format = info;
|
||||
port->stride = calc_width(&info);
|
||||
if (SPA_AUDIO_FORMAT_IS_PLANAR(info.info.raw.format)) {
|
||||
port->blocks = info.info.raw.channels;
|
||||
}
|
||||
else {
|
||||
port->stride *= info.info.raw.channels;
|
||||
port->blocks = 1;
|
||||
}
|
||||
|
||||
spa_log_debug(this->log, NAME " %p: %d %d %d", this,
|
||||
port_id, port->stride, port->blocks);
|
||||
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ static void emit_port_info(struct impl *this, struct port *port, bool full)
|
|||
}
|
||||
|
||||
static int init_port(struct impl *this, enum spa_direction direction,
|
||||
uint32_t port_id, uint32_t rate, uint32_t position)
|
||||
uint32_t port_id, uint32_t position)
|
||||
{
|
||||
struct port *port = GET_OUT_PORT(this, port_id);
|
||||
|
||||
|
|
@ -178,14 +178,11 @@ static int init_port(struct impl *this, enum spa_direction direction,
|
|||
port->n_buffers = 0;
|
||||
port->have_format = false;
|
||||
port->format.media_type = SPA_MEDIA_TYPE_audio;
|
||||
port->format.media_subtype = SPA_MEDIA_SUBTYPE_raw;
|
||||
port->format.info.raw.format = SPA_AUDIO_FORMAT_F32P;
|
||||
port->format.info.raw.rate = rate;
|
||||
port->format.info.raw.channels = 1;
|
||||
port->format.info.raw.position[0] = position;
|
||||
port->format.media_subtype = SPA_MEDIA_SUBTYPE_dsp;
|
||||
port->format.info.dsp.format = SPA_AUDIO_FORMAT_DSP_F32;
|
||||
|
||||
spa_log_debug(this->log, NAME " %p: init port %d:%d rate:%d position:%s",
|
||||
this, direction, port_id, rate, port->position);
|
||||
spa_log_debug(this->log, NAME " %p: init port %d:%d position:%s",
|
||||
this, direction, port_id, port->position);
|
||||
emit_port_info(this, port, true);
|
||||
|
||||
return 0;
|
||||
|
|
@ -280,7 +277,8 @@ static int impl_node_set_param(void *object, uint32_t id, uint32_t flags,
|
|||
if (port->have_format && memcmp(&port->format, &info, sizeof(info)) == 0)
|
||||
return 0;
|
||||
|
||||
spa_log_debug(this->log, NAME " %p: profile %d", this, info.info.raw.channels);
|
||||
spa_log_debug(this->log, NAME " %p: port config %d/%d", this,
|
||||
info.info.raw.rate, info.info.raw.channels);
|
||||
|
||||
for (i = 0; i < this->port_count; i++)
|
||||
spa_node_emit_port_info(&this->hooks,
|
||||
|
|
@ -293,7 +291,7 @@ static int impl_node_set_param(void *object, uint32_t id, uint32_t flags,
|
|||
|
||||
this->port_count = info.info.raw.channels;
|
||||
for (i = 0; i < this->port_count; i++) {
|
||||
init_port(this, SPA_DIRECTION_OUTPUT, i, info.info.raw.rate,
|
||||
init_port(this, SPA_DIRECTION_OUTPUT, i,
|
||||
info.info.raw.position[i]);
|
||||
}
|
||||
return 0;
|
||||
|
|
@ -379,7 +377,10 @@ static int port_enum_formats(void *object,
|
|||
|
||||
switch (index) {
|
||||
case 0:
|
||||
if (direction == SPA_DIRECTION_OUTPUT || port->have_format) {
|
||||
if (direction == SPA_DIRECTION_OUTPUT) {
|
||||
*param = spa_format_audio_dsp_build(builder,
|
||||
SPA_PARAM_EnumFormat, &port->format.info.dsp);
|
||||
} else if (port->have_format) {
|
||||
*param = spa_format_audio_raw_build(builder,
|
||||
SPA_PARAM_EnumFormat, &port->format.info.raw);
|
||||
}
|
||||
|
|
@ -462,7 +463,10 @@ impl_node_port_enum_params(void *object, int seq,
|
|||
if (result.index > 0)
|
||||
return 0;
|
||||
|
||||
param = spa_format_audio_raw_build(&b, id, &port->format.info.raw);
|
||||
if (direction == SPA_DIRECTION_OUTPUT)
|
||||
param = spa_format_audio_dsp_build(&b, id, &port->format.info.dsp);
|
||||
else
|
||||
param = spa_format_audio_raw_build(&b, id, &port->format.info.raw);
|
||||
break;
|
||||
case SPA_PARAM_Buffers:
|
||||
if (!port->have_format)
|
||||
|
|
@ -540,7 +544,7 @@ static int setup_convert(struct impl *this)
|
|||
inport = GET_IN_PORT(this, 0);
|
||||
|
||||
src_fmt = inport->format.info.raw.format;
|
||||
dst_fmt = SPA_AUDIO_FORMAT_F32P;
|
||||
dst_fmt = SPA_AUDIO_FORMAT_DSP_F32;
|
||||
|
||||
spa_log_info(this->log, NAME " %p: %s/%d@%d->%s/%d@%dx%d", this,
|
||||
spa_debug_type_find_name(spa_type_audio_format, src_fmt),
|
||||
|
|
@ -615,35 +619,38 @@ static int port_set_format(void *object,
|
|||
if ((res = spa_format_parse(format, &info.media_type, &info.media_subtype)) < 0)
|
||||
return res;
|
||||
|
||||
if (info.media_type != SPA_MEDIA_TYPE_audio ||
|
||||
info.media_subtype != SPA_MEDIA_SUBTYPE_raw)
|
||||
return -EINVAL;
|
||||
|
||||
if (spa_format_audio_raw_parse(format, &info.info.raw) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (direction == SPA_DIRECTION_OUTPUT) {
|
||||
if (info.info.raw.rate != port->format.info.raw.rate)
|
||||
if (info.media_type != SPA_MEDIA_TYPE_audio ||
|
||||
info.media_subtype != SPA_MEDIA_SUBTYPE_dsp)
|
||||
return -EINVAL;
|
||||
if (info.info.raw.format != SPA_AUDIO_FORMAT_F32P)
|
||||
if (spa_format_audio_dsp_parse(format, &info.info.dsp) < 0)
|
||||
return -EINVAL;
|
||||
if (info.info.raw.channels != 1)
|
||||
if (info.info.dsp.format != SPA_AUDIO_FORMAT_DSP_F32)
|
||||
return -EINVAL;
|
||||
|
||||
port->stride = 4;
|
||||
port->blocks = 1;
|
||||
}
|
||||
else {
|
||||
if (info.media_type != SPA_MEDIA_TYPE_audio ||
|
||||
info.media_subtype != SPA_MEDIA_SUBTYPE_raw)
|
||||
return -EINVAL;
|
||||
if (spa_format_audio_raw_parse(format, &info.info.raw) < 0)
|
||||
return -EINVAL;
|
||||
if (info.info.raw.channels != this->port_count)
|
||||
return -EINVAL;
|
||||
|
||||
port->stride = calc_width(&info);
|
||||
if (SPA_AUDIO_FORMAT_IS_PLANAR(info.info.raw.format)) {
|
||||
port->blocks = info.info.raw.channels;
|
||||
} else {
|
||||
port->stride *= info.info.raw.channels;
|
||||
port->blocks = 1;
|
||||
}
|
||||
}
|
||||
|
||||
port->format = info;
|
||||
port->stride = calc_width(&info);
|
||||
|
||||
if (SPA_AUDIO_FORMAT_IS_PLANAR(info.info.raw.format)) {
|
||||
port->blocks = info.info.raw.channels;
|
||||
} else {
|
||||
port->stride *= info.info.raw.channels;
|
||||
port->blocks = 1;
|
||||
}
|
||||
spa_log_debug(this->log, NAME " %p: %d %d %d", this, port_id, port->stride, port->blocks);
|
||||
|
||||
if (direction == SPA_DIRECTION_INPUT)
|
||||
|
|
|
|||
|
|
@ -315,16 +315,14 @@ static int port_enum_formats(void *object,
|
|||
switch (index) {
|
||||
case 0:
|
||||
if (this->have_format) {
|
||||
*param = spa_format_audio_raw_build(builder, SPA_PARAM_EnumFormat,
|
||||
&this->format.info.raw);
|
||||
*param = spa_format_audio_dsp_build(builder, SPA_PARAM_EnumFormat,
|
||||
&this->format.info.dsp);
|
||||
} else {
|
||||
*param = spa_pod_builder_add_object(builder,
|
||||
SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat,
|
||||
SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_audio),
|
||||
SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw),
|
||||
SPA_FORMAT_AUDIO_format, SPA_POD_Id(SPA_AUDIO_FORMAT_F32P),
|
||||
SPA_FORMAT_AUDIO_rate, SPA_POD_CHOICE_RANGE_Int(44100, 1, INT32_MAX),
|
||||
SPA_FORMAT_AUDIO_channels, SPA_POD_Int(1));
|
||||
SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_dsp),
|
||||
SPA_FORMAT_AUDIO_format, SPA_POD_Id(SPA_AUDIO_FORMAT_DSP_F32));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
@ -373,7 +371,7 @@ next:
|
|||
if (result.index > 0)
|
||||
return 0;
|
||||
|
||||
param = spa_format_audio_raw_build(&b, id, &this->format.info.raw);
|
||||
param = spa_format_audio_dsp_build(&b, id, &this->format.info.dsp);
|
||||
break;
|
||||
|
||||
case SPA_PARAM_Buffers:
|
||||
|
|
@ -495,23 +493,18 @@ static int port_set_format(void *object,
|
|||
return res;
|
||||
|
||||
if (info.media_type != SPA_MEDIA_TYPE_audio ||
|
||||
info.media_subtype != SPA_MEDIA_SUBTYPE_raw)
|
||||
info.media_subtype != SPA_MEDIA_SUBTYPE_dsp)
|
||||
return -EINVAL;
|
||||
|
||||
if (spa_format_audio_raw_parse(format, &info.info.raw) < 0)
|
||||
if (spa_format_audio_dsp_parse(format, &info.info.dsp) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (info.info.raw.format != SPA_AUDIO_FORMAT_F32P)
|
||||
return -EINVAL;
|
||||
if (info.info.raw.channels != 1)
|
||||
if (info.info.dsp.format != SPA_AUDIO_FORMAT_DSP_F32)
|
||||
return -EINVAL;
|
||||
|
||||
if (this->have_format) {
|
||||
if (info.info.raw.rate != this->format.info.raw.rate)
|
||||
return -EINVAL;
|
||||
} else {
|
||||
this->ops.fmt = info.info.raw.format;
|
||||
this->ops.n_channels = info.info.raw.channels;
|
||||
if (!this->have_format) {
|
||||
this->ops.fmt = info.info.dsp.format;
|
||||
this->ops.n_channels = 1;
|
||||
this->ops.cpu_flags = this->cpu_flags;
|
||||
|
||||
if ((res = mix_ops_init(&this->ops)) < 0)
|
||||
|
|
|
|||
|
|
@ -146,8 +146,8 @@ static int impl_node_enum_params(void *object, int seq,
|
|||
case SPA_PARAM_Format:
|
||||
switch (result.index) {
|
||||
case 0:
|
||||
param = spa_format_audio_raw_build(&b,
|
||||
id, &this->current_format.info.raw);
|
||||
param = spa_format_audio_dsp_build(&b,
|
||||
id, &this->current_format.info.dsp);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
|
|
@ -447,11 +447,8 @@ static int init_ports(struct impl *this)
|
|||
}
|
||||
this->n_in_ports = i;
|
||||
|
||||
this->current_format.info.raw = SPA_AUDIO_INFO_RAW_INIT(
|
||||
.format = SPA_AUDIO_FORMAT_F32P,
|
||||
.flags = SPA_AUDIO_FLAG_UNPOSITIONED,
|
||||
.rate = jack_get_sample_rate(client),
|
||||
.channels = this->n_in_ports);
|
||||
this->current_format.info.dsp = SPA_AUDIO_INFO_DSP_INIT(
|
||||
.format = SPA_AUDIO_FORMAT_DSP_F32);
|
||||
|
||||
spa_jack_client_add_listener(this->client,
|
||||
&this->client_listener,
|
||||
|
|
@ -499,10 +496,8 @@ static int port_enum_formats(struct impl *this,
|
|||
*param = spa_pod_builder_add_object(builder,
|
||||
SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat,
|
||||
SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_audio),
|
||||
SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw),
|
||||
SPA_FORMAT_AUDIO_format, SPA_POD_Id(SPA_AUDIO_FORMAT_F32P),
|
||||
SPA_FORMAT_AUDIO_rate, SPA_POD_Int(this->client->frame_rate),
|
||||
SPA_FORMAT_AUDIO_channels, SPA_POD_Int(1));
|
||||
SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_dsp),
|
||||
SPA_FORMAT_AUDIO_format, SPA_POD_Id(SPA_AUDIO_FORMAT_DSP_F32));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
|
|
@ -552,7 +547,7 @@ impl_node_port_enum_params(void *object, int seq,
|
|||
if (result.index > 0)
|
||||
return 0;
|
||||
|
||||
param = spa_format_audio_raw_build(&b, id, &port->current_format.info.raw);
|
||||
param = spa_format_audio_dsp_build(&b, id, &port->current_format.info.dsp);
|
||||
break;
|
||||
|
||||
case SPA_PARAM_Buffers:
|
||||
|
|
@ -627,17 +622,16 @@ static int port_set_format(struct impl *this, struct port *port,
|
|||
return res;
|
||||
|
||||
if (info.media_type != SPA_MEDIA_TYPE_audio &&
|
||||
info.media_subtype != SPA_MEDIA_SUBTYPE_raw)
|
||||
info.media_subtype != SPA_MEDIA_SUBTYPE_dsp)
|
||||
return -EINVAL;
|
||||
|
||||
if (spa_format_audio_raw_parse(format, &info.info.raw) < 0)
|
||||
if (spa_format_audio_dsp_parse(format, &info.info.dsp) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (info.info.raw.format == SPA_AUDIO_FORMAT_F32P)
|
||||
port->stride = 4;
|
||||
else
|
||||
if (info.info.dsp.format != SPA_AUDIO_FORMAT_DSP_F32)
|
||||
return -EINVAL;
|
||||
|
||||
port->stride = 4;
|
||||
port->current_format = info;
|
||||
port->have_format = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -148,8 +148,8 @@ static int impl_node_enum_params(void *object, int seq,
|
|||
case SPA_PARAM_Format:
|
||||
switch (result.index) {
|
||||
case 0:
|
||||
param = spa_format_audio_raw_build(&b,
|
||||
id, &this->current_format.info.raw);
|
||||
param = spa_format_audio_dsp_build(&b,
|
||||
id, &this->current_format.info.dsp);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
|
|
@ -446,11 +446,8 @@ static int init_ports(struct impl *this)
|
|||
}
|
||||
this->n_out_ports = i;
|
||||
|
||||
this->current_format.info.raw = SPA_AUDIO_INFO_RAW_INIT(
|
||||
.format = SPA_AUDIO_FORMAT_F32P,
|
||||
.flags = SPA_AUDIO_FLAG_UNPOSITIONED,
|
||||
.rate = jack_get_sample_rate(client),
|
||||
.channels = this->n_out_ports);
|
||||
this->current_format.info.dsp = SPA_AUDIO_INFO_DSP_INIT(
|
||||
.format = SPA_AUDIO_FORMAT_DSP_F32);
|
||||
|
||||
spa_jack_client_add_listener(this->client,
|
||||
&this->client_listener,
|
||||
|
|
@ -498,10 +495,8 @@ static int port_enum_formats(struct impl *this,
|
|||
*param = spa_pod_builder_add_object(builder,
|
||||
SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat,
|
||||
SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_audio),
|
||||
SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw),
|
||||
SPA_FORMAT_AUDIO_format, SPA_POD_Id(SPA_AUDIO_FORMAT_F32P),
|
||||
SPA_FORMAT_AUDIO_rate, SPA_POD_Int(this->client->frame_rate),
|
||||
SPA_FORMAT_AUDIO_channels, SPA_POD_Int(1));
|
||||
SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_dsp),
|
||||
SPA_FORMAT_AUDIO_format, SPA_POD_Id(SPA_AUDIO_FORMAT_DSP_F32));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
|
|
@ -551,7 +546,7 @@ impl_node_port_enum_params(void *object, int seq,
|
|||
if (result.index > 0)
|
||||
return 0;
|
||||
|
||||
param = spa_format_audio_raw_build(&b, id, &port->current_format.info.raw);
|
||||
param = spa_format_audio_dsp_build(&b, id, &port->current_format.info.dsp);
|
||||
break;
|
||||
|
||||
case SPA_PARAM_Buffers:
|
||||
|
|
@ -627,17 +622,16 @@ static int port_set_format(struct impl *this, struct port *port,
|
|||
return res;
|
||||
|
||||
if (info.media_type != SPA_MEDIA_TYPE_audio &&
|
||||
info.media_subtype != SPA_MEDIA_SUBTYPE_raw)
|
||||
info.media_subtype != SPA_MEDIA_SUBTYPE_dsp)
|
||||
return -EINVAL;
|
||||
|
||||
if (spa_format_audio_raw_parse(format, &info.info.raw) < 0)
|
||||
if (spa_format_audio_dsp_parse(format, &info.info.dsp) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (info.info.raw.format == SPA_AUDIO_FORMAT_F32P)
|
||||
port->stride = 4;
|
||||
else
|
||||
if (info.info.dsp.format != SPA_AUDIO_FORMAT_DSP_F32)
|
||||
return -EINVAL;
|
||||
|
||||
port->stride = 4;
|
||||
port->current_format = info;
|
||||
port->have_format = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,11 +46,13 @@
|
|||
|
||||
#define NAME "vulkan-compute-source"
|
||||
|
||||
#define FRAMES_TO_TIME(port,f) ((port->current_format.info.raw.framerate.denom * (f) * SPA_NSEC_PER_SEC) / \
|
||||
(port->current_format.info.raw.framerate.num))
|
||||
#define FRAMES_TO_TIME(this,f) ((this->position->video.framerate.denom * (f) * SPA_NSEC_PER_SEC) / \
|
||||
(this->position->video.framerate.num))
|
||||
|
||||
#define DEFAULT_LIVE true
|
||||
|
||||
#define MAX_HEIGHT 1024
|
||||
|
||||
struct props {
|
||||
bool live;
|
||||
};
|
||||
|
|
@ -80,8 +82,6 @@ struct port {
|
|||
|
||||
bool have_format;
|
||||
struct spa_video_info current_format;
|
||||
size_t bpp;
|
||||
int stride;
|
||||
|
||||
struct buffer buffers[MAX_BUFFERS];
|
||||
uint32_t n_buffers;
|
||||
|
|
@ -98,6 +98,9 @@ struct impl {
|
|||
struct spa_loop *data_loop;
|
||||
struct spa_system *data_system;
|
||||
|
||||
struct spa_io_clock *clock;
|
||||
struct spa_io_position *position;
|
||||
|
||||
uint64_t info_all;
|
||||
struct spa_node_info info;
|
||||
struct spa_param_info params[2];
|
||||
|
|
@ -193,7 +196,23 @@ static int impl_node_enum_params(void *object, int seq,
|
|||
|
||||
static int impl_node_set_io(void *object, uint32_t id, void *data, size_t size)
|
||||
{
|
||||
return -ENOTSUP;
|
||||
struct impl *this = object;
|
||||
|
||||
spa_return_val_if_fail(this != NULL, -EINVAL);
|
||||
|
||||
switch (id) {
|
||||
case SPA_IO_Clock:
|
||||
if (size > 0 && size < sizeof(struct spa_io_clock))
|
||||
return -EINVAL;
|
||||
this->clock = data;
|
||||
break;
|
||||
case SPA_IO_Position:
|
||||
this->position = data;
|
||||
break;
|
||||
default:
|
||||
return -ENOENT;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int impl_node_set_param(void *object, uint32_t id, uint32_t flags,
|
||||
|
|
@ -300,7 +319,7 @@ static int make_buffer(struct impl *this)
|
|||
|
||||
b->outbuf->datas[0].chunk->offset = 0;
|
||||
b->outbuf->datas[0].chunk->size = n_bytes;
|
||||
b->outbuf->datas[0].chunk->stride = port->stride;
|
||||
b->outbuf->datas[0].chunk->stride = this->position->video.stride;
|
||||
|
||||
if (b->h) {
|
||||
b->h->seq = this->frame_count;
|
||||
|
|
@ -315,7 +334,7 @@ static int make_buffer(struct impl *this)
|
|||
}
|
||||
next:
|
||||
this->frame_count++;
|
||||
this->elapsed_time = FRAMES_TO_TIME(port, this->frame_count);
|
||||
this->elapsed_time = FRAMES_TO_TIME(this, this->frame_count);
|
||||
set_timer(this, true);
|
||||
|
||||
return res;
|
||||
|
|
@ -507,16 +526,8 @@ static int port_enum_formats(void *object,
|
|||
*param = spa_pod_builder_add_object(builder,
|
||||
SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat,
|
||||
SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_video),
|
||||
SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw),
|
||||
SPA_FORMAT_VIDEO_format, SPA_POD_Id(SPA_VIDEO_FORMAT_RGBA_F32),
|
||||
SPA_FORMAT_VIDEO_size, SPA_POD_CHOICE_RANGE_Rectangle(
|
||||
&SPA_RECTANGLE(320, 240),
|
||||
&SPA_RECTANGLE(1, 1),
|
||||
&SPA_RECTANGLE(INT32_MAX, INT32_MAX)),
|
||||
SPA_FORMAT_VIDEO_framerate, SPA_POD_CHOICE_RANGE_Fraction(
|
||||
&SPA_FRACTION(25,1),
|
||||
&SPA_FRACTION(0, 1),
|
||||
&SPA_FRACTION(INT32_MAX, 1)));
|
||||
SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_dsp),
|
||||
SPA_FORMAT_VIDEO_format, SPA_POD_Id(SPA_VIDEO_FORMAT_DSP_F32));
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
|
|
@ -565,15 +576,15 @@ impl_node_port_enum_params(void *object, int seq,
|
|||
if (result.index > 0)
|
||||
return 0;
|
||||
|
||||
param = spa_format_video_raw_build(&b, id, &port->current_format.info.raw);
|
||||
param = spa_format_video_dsp_build(&b, id, &port->current_format.info.dsp);
|
||||
break;
|
||||
|
||||
case SPA_PARAM_Buffers:
|
||||
{
|
||||
struct spa_video_info_raw *raw_info = &port->current_format.info.raw;
|
||||
|
||||
if (!port->have_format)
|
||||
return -EIO;
|
||||
if (this->position == NULL)
|
||||
return -EIO;
|
||||
if (result.index > 0)
|
||||
return 0;
|
||||
|
||||
|
|
@ -581,8 +592,8 @@ impl_node_port_enum_params(void *object, int seq,
|
|||
SPA_TYPE_OBJECT_ParamBuffers, id,
|
||||
SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(2, 1, MAX_BUFFERS),
|
||||
SPA_PARAM_BUFFERS_blocks, SPA_POD_Int(1),
|
||||
SPA_PARAM_BUFFERS_size, SPA_POD_Int(port->stride * raw_info->size.height),
|
||||
SPA_PARAM_BUFFERS_stride, SPA_POD_Int(port->stride),
|
||||
SPA_PARAM_BUFFERS_size, SPA_POD_Int(this->position->video.stride * MAX_HEIGHT),
|
||||
SPA_PARAM_BUFFERS_stride, SPA_POD_Int(this->position->video.stride),
|
||||
SPA_PARAM_BUFFERS_align, SPA_POD_Int(16));
|
||||
break;
|
||||
}
|
||||
|
|
@ -645,19 +656,17 @@ static int port_set_format(struct impl *this, struct port *port,
|
|||
return res;
|
||||
|
||||
if (info.media_type != SPA_MEDIA_TYPE_video &&
|
||||
info.media_subtype != SPA_MEDIA_SUBTYPE_raw)
|
||||
info.media_subtype != SPA_MEDIA_SUBTYPE_dsp)
|
||||
return -EINVAL;
|
||||
|
||||
if (spa_format_video_raw_parse(format, &info.info.raw) < 0)
|
||||
if (spa_format_video_dsp_parse(format, &info.info.dsp) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (info.info.raw.format == SPA_VIDEO_FORMAT_RGBA_F32)
|
||||
port->bpp = 16;
|
||||
else
|
||||
if (info.info.dsp.format != SPA_VIDEO_FORMAT_DSP_F32)
|
||||
return -EINVAL;
|
||||
|
||||
this->state.constants.width = info.info.raw.size.width;
|
||||
this->state.constants.height = info.info.raw.size.height;
|
||||
this->state.constants.width = this->position->video.size.width;
|
||||
this->state.constants.height = this->position->video.size.height;
|
||||
|
||||
port->current_format = info;
|
||||
port->have_format = true;
|
||||
|
|
@ -666,8 +675,6 @@ static int port_set_format(struct impl *this, struct port *port,
|
|||
|
||||
port->info.change_mask |= SPA_PORT_CHANGE_MASK_PARAMS;
|
||||
if (port->have_format) {
|
||||
struct spa_video_info_raw *raw_info = &port->current_format.info.raw;
|
||||
port->stride = SPA_ROUND_UP_N(port->bpp * raw_info->size.width, 4);
|
||||
port->params[3] = SPA_PARAM_INFO(SPA_PARAM_Format, SPA_PARAM_INFO_READWRITE);
|
||||
port->params[4] = SPA_PARAM_INFO(SPA_PARAM_Buffers, SPA_PARAM_INFO_READ);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,15 @@
|
|||
#set-prop context.data-loop.library.name.system support/libspa-support
|
||||
#set-prop link.max-buffers 64
|
||||
|
||||
#set-prop default.clock.rate 48000
|
||||
#set-prop default.clock.quantum 1024
|
||||
#set-prop default.clock.min-quantum 32
|
||||
#set-prop default.clock.max-quantum 8192
|
||||
#set-prop default.video.width 320
|
||||
#set-prop default.video.height 240
|
||||
#set-prop default.video.rate.num 25
|
||||
#set-prop default.video.rate.denom 1
|
||||
|
||||
add-spa-lib audio.convert* audioconvert/libspa-audioconvert
|
||||
add-spa-lib api.alsa.* alsa/libspa-alsa
|
||||
add-spa-lib api.v4l2.* v4l2/libspa-v4l2
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include <spa/utils/result.h>
|
||||
#include <spa/param/video/format-utils.h>
|
||||
#include <spa/param/props.h>
|
||||
#include <spa/debug/format.h>
|
||||
|
|
@ -34,7 +35,6 @@
|
|||
|
||||
#define WIDTH 640
|
||||
#define HEIGHT 480
|
||||
#define BPP 3
|
||||
|
||||
#define MAX_BUFFERS 64
|
||||
|
||||
|
|
@ -57,8 +57,11 @@ struct data {
|
|||
struct pw_stream *stream;
|
||||
struct spa_hook stream_listener;
|
||||
|
||||
struct spa_video_info_raw format;
|
||||
struct spa_io_position *position;
|
||||
|
||||
struct spa_video_info format;
|
||||
int32_t stride;
|
||||
struct spa_rectangle size;
|
||||
|
||||
int counter;
|
||||
SDL_Rect rect;
|
||||
|
|
@ -177,10 +180,10 @@ on_process(void *_data)
|
|||
src = sdata;
|
||||
dst = ddata;
|
||||
|
||||
if (data->format.format == SPA_VIDEO_FORMAT_RGBA_F32) {
|
||||
for (i = 0; i < data->format.size.height; i++) {
|
||||
if (data->format.media_subtype == SPA_MEDIA_SUBTYPE_dsp) {
|
||||
for (i = 0; i < data->size.height; i++) {
|
||||
struct pixel *p = (struct pixel *) src;
|
||||
for (j = 0; j < data->format.size.width; j++) {
|
||||
for (j = 0; j < data->size.width; j++) {
|
||||
dst[j * 4 + 0] = SPA_CLAMP(lrintf(p[j].r * 255.0f), 0, 255);
|
||||
dst[j * 4 + 1] = SPA_CLAMP(lrintf(p[j].g * 255.0f), 0, 255);
|
||||
dst[j * 4 + 2] = SPA_CLAMP(lrintf(p[j].b * 255.0f), 0, 255);
|
||||
|
|
@ -191,7 +194,7 @@ on_process(void *_data)
|
|||
}
|
||||
}
|
||||
else {
|
||||
for (i = 0; i < data->format.size.height; i++) {
|
||||
for (i = 0; i < data->size.height; i++) {
|
||||
memcpy(dst, src, ostride);
|
||||
src += sstride;
|
||||
dst += dstride;
|
||||
|
|
@ -229,6 +232,18 @@ static void on_stream_state_changed(void *_data, enum pw_stream_state old,
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
on_stream_io_changed(void *_data, uint32_t id, void *area, uint32_t size)
|
||||
{
|
||||
struct data *data = _data;
|
||||
|
||||
switch (id) {
|
||||
case SPA_IO_Position:
|
||||
data->position = area;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Be notified when the stream param changes. We're only looking at the
|
||||
* format changes.
|
||||
*
|
||||
|
|
@ -258,13 +273,32 @@ on_stream_param_changed(void *_data, uint32_t id, const struct spa_pod *param)
|
|||
fprintf(stderr, "got format:\n");
|
||||
spa_debug_format(2, NULL, param);
|
||||
|
||||
/* call a helper function to parse the format for us. */
|
||||
spa_format_video_raw_parse(param, &data->format);
|
||||
if (spa_format_parse(param, &data->format.media_type, &data->format.media_subtype) < 0)
|
||||
return;
|
||||
|
||||
if (data->format.format == SPA_VIDEO_FORMAT_RGBA_F32)
|
||||
if (data->format.media_type != SPA_MEDIA_TYPE_video)
|
||||
return;
|
||||
|
||||
switch (data->format.media_subtype) {
|
||||
case SPA_MEDIA_SUBTYPE_raw:
|
||||
/* call a helper function to parse the format for us. */
|
||||
spa_format_video_raw_parse(param, &data->format.info.raw);
|
||||
sdl_format = id_to_sdl_format(data->format.info.raw.format);
|
||||
data->size = SPA_RECTANGLE(data->format.info.raw.size.width,
|
||||
data->format.info.raw.size.height);
|
||||
break;
|
||||
case SPA_MEDIA_SUBTYPE_dsp:
|
||||
spa_format_video_dsp_parse(param, &data->format.info.dsp);
|
||||
if (data->format.info.dsp.format != SPA_VIDEO_FORMAT_DSP_F32)
|
||||
return;
|
||||
sdl_format = SDL_PIXELFORMAT_RGBA32;
|
||||
else
|
||||
sdl_format = id_to_sdl_format(data->format.format);
|
||||
data->size = SPA_RECTANGLE(data->position->video.size.width,
|
||||
data->position->video.size.height);
|
||||
break;
|
||||
default:
|
||||
sdl_format = SDL_PIXELFORMAT_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
|
||||
if (sdl_format == SDL_PIXELFORMAT_UNKNOWN) {
|
||||
pw_stream_set_error(stream, -EINVAL, "unknown pixel format");
|
||||
|
|
@ -274,15 +308,15 @@ on_stream_param_changed(void *_data, uint32_t id, const struct spa_pod *param)
|
|||
data->texture = SDL_CreateTexture(data->renderer,
|
||||
sdl_format,
|
||||
SDL_TEXTUREACCESS_STREAMING,
|
||||
data->format.size.width,
|
||||
data->format.size.height);
|
||||
data->size.width,
|
||||
data->size.height);
|
||||
SDL_LockTexture(data->texture, NULL, &d, &data->stride);
|
||||
SDL_UnlockTexture(data->texture);
|
||||
|
||||
data->rect.x = 0;
|
||||
data->rect.y = 0;
|
||||
data->rect.w = data->format.size.width;
|
||||
data->rect.h = data->format.size.height;
|
||||
data->rect.w = data->size.width;
|
||||
data->rect.h = data->size.height;
|
||||
|
||||
/* a SPA_TYPE_OBJECT_ParamBuffers object defines the acceptable size,
|
||||
* number, stride etc of the buffers */
|
||||
|
|
@ -290,7 +324,7 @@ on_stream_param_changed(void *_data, uint32_t id, const struct spa_pod *param)
|
|||
SPA_TYPE_OBJECT_ParamBuffers, SPA_PARAM_Buffers,
|
||||
SPA_PARAM_BUFFERS_buffers, SPA_POD_CHOICE_RANGE_Int(8, 2, MAX_BUFFERS),
|
||||
SPA_PARAM_BUFFERS_blocks, SPA_POD_Int(1),
|
||||
SPA_PARAM_BUFFERS_size, SPA_POD_Int(data->stride * data->format.size.height),
|
||||
SPA_PARAM_BUFFERS_size, SPA_POD_Int(data->stride * data->size.height),
|
||||
SPA_PARAM_BUFFERS_stride, SPA_POD_Int(data->stride),
|
||||
SPA_PARAM_BUFFERS_align, SPA_POD_Int(16));
|
||||
|
||||
|
|
@ -323,6 +357,7 @@ on_stream_param_changed(void *_data, uint32_t id, const struct spa_pod *param)
|
|||
static const struct pw_stream_events stream_events = {
|
||||
PW_VERSION_STREAM_EVENTS,
|
||||
.state_changed = on_stream_state_changed,
|
||||
.io_changed = on_stream_io_changed,
|
||||
.param_changed = on_stream_param_changed,
|
||||
.process = on_process,
|
||||
};
|
||||
|
|
@ -334,18 +369,28 @@ static int build_format(struct data *data, struct spa_pod_builder *b, const stru
|
|||
SDL_GetRendererInfo(data->renderer, &info);
|
||||
params[0] = sdl_build_formats(&info, b);
|
||||
|
||||
fprintf(stderr, "supported formats:\n");
|
||||
fprintf(stderr, "supported SDL formats:\n");
|
||||
spa_debug_format(2, NULL, params[0]);
|
||||
|
||||
return 0;
|
||||
params[1] = spa_pod_builder_add_object(b,
|
||||
SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat,
|
||||
SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_video),
|
||||
SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_dsp),
|
||||
SPA_FORMAT_VIDEO_format, SPA_POD_Id(SPA_VIDEO_FORMAT_DSP_F32));
|
||||
|
||||
fprintf(stderr, "supported DSP formats:\n");
|
||||
spa_debug_format(2, NULL, params[1]);
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
struct data data = { 0, };
|
||||
const struct spa_pod *params[1];
|
||||
const struct spa_pod *params[2];
|
||||
uint8_t buffer[1024];
|
||||
struct spa_pod_builder b = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
|
||||
int res, n_params;
|
||||
|
||||
pw_init(&argc, &argv);
|
||||
|
||||
|
|
@ -390,19 +435,22 @@ int main(int argc, char *argv[])
|
|||
/* build the extra parameters to connect with. To connect, we can provide
|
||||
* a list of supported formats. We use a builder that writes the param
|
||||
* object to the stack. */
|
||||
build_format(&data, &b, params);
|
||||
n_params = build_format(&data, &b, params);
|
||||
|
||||
/* now connect the stream, we need a direction (input/output),
|
||||
* an optional target node to connect to, some flags and parameters
|
||||
*/
|
||||
pw_stream_connect(data.stream,
|
||||
if ((res = pw_stream_connect(data.stream,
|
||||
PW_DIRECTION_INPUT,
|
||||
data.path ? (uint32_t)atoi(data.path) : SPA_ID_INVALID,
|
||||
PW_STREAM_FLAG_AUTOCONNECT | /* try to automatically connect this stream */
|
||||
PW_STREAM_FLAG_INACTIVE | /* we will activate ourselves */
|
||||
PW_STREAM_FLAG_EXCLUSIVE | /* require exclusive access */
|
||||
PW_STREAM_FLAG_MAP_BUFFERS, /* mmap the buffer data for us */
|
||||
params, 1); /* extra parameters, see above */
|
||||
params, n_params)) /* extra parameters, see above */ < 0) {
|
||||
fprintf(stderr, "can't connect: %s\n", spa_strerror(res));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* do things until we quit the mainloop */
|
||||
pw_main_loop_run(data.loop);
|
||||
|
|
|
|||
|
|
@ -43,6 +43,16 @@
|
|||
|
||||
#define NAME "context"
|
||||
|
||||
|
||||
#define DEFAULT_CLOCK_RATE 48000u
|
||||
#define DEFAULT_CLOCK_QUANTUM 1024u
|
||||
#define DEFAULT_CLOCK_MIN_QUANTUM 32u
|
||||
#define DEFAULT_CLOCK_MAX_QUANTUM 8192u
|
||||
#define DEFAULT_VIDEO_WIDTH 640
|
||||
#define DEFAULT_VIDEO_HEIGHT 480
|
||||
#define DEFAULT_VIDEO_RATE_NUM 25u
|
||||
#define DEFAULT_VIDEO_RATE_DENOM 1u
|
||||
|
||||
/** \cond */
|
||||
struct impl {
|
||||
struct pw_context this;
|
||||
|
|
@ -109,6 +119,29 @@ static void fill_properties(struct pw_context *context)
|
|||
pw_properties_set(properties, PW_KEY_CORE_NAME, context->core->info.name);
|
||||
}
|
||||
|
||||
static uint32_t get_default(struct pw_properties *properties, const char *name, uint32_t def)
|
||||
{
|
||||
uint32_t val;
|
||||
const char *str;
|
||||
if ((str = pw_properties_get(properties, name)) != NULL)
|
||||
val = atoi(str);
|
||||
else
|
||||
val = def;
|
||||
return val;
|
||||
}
|
||||
|
||||
static void fill_defaults(struct pw_context *this)
|
||||
{
|
||||
struct pw_properties *p = this->properties;
|
||||
this->defaults.clock_rate = get_default(p, "default.clock.rate", DEFAULT_CLOCK_RATE);
|
||||
this->defaults.clock_quantum = get_default(p, "default.clock.quantum", DEFAULT_CLOCK_QUANTUM);
|
||||
this->defaults.clock_min_quantum = get_default(p, "default.clock.min-quantum", DEFAULT_CLOCK_MIN_QUANTUM);
|
||||
this->defaults.clock_max_quantum = get_default(p, "default.clock.max-quantum", DEFAULT_CLOCK_MAX_QUANTUM);
|
||||
this->defaults.video_size.width = get_default(p, "default.video.width", DEFAULT_VIDEO_WIDTH);
|
||||
this->defaults.video_size.height = get_default(p, "default.video.height", DEFAULT_VIDEO_HEIGHT);
|
||||
this->defaults.video_rate.num = get_default(p, "default.video.rate.num", DEFAULT_VIDEO_RATE_NUM);
|
||||
this->defaults.video_rate.denom = get_default(p, "default.video.rate.denom", DEFAULT_VIDEO_RATE_DENOM);
|
||||
}
|
||||
|
||||
/** Create a new context object
|
||||
*
|
||||
|
|
@ -154,6 +187,8 @@ struct pw_context *pw_context_new(struct pw_loop *main_loop,
|
|||
|
||||
this->properties = properties;
|
||||
|
||||
fill_defaults(this);
|
||||
|
||||
pr = pw_properties_copy(properties);
|
||||
if ((str = pw_properties_get(pr, "context.data-loop." PW_KEY_LIBRARY_NAME_SYSTEM)))
|
||||
pw_properties_set(pr, PW_KEY_LIBRARY_NAME_SYSTEM, str);
|
||||
|
|
@ -716,11 +751,13 @@ static int collect_nodes(struct pw_impl_node *driver)
|
|||
|
||||
quantum = min_quantum;
|
||||
if (quantum == 0)
|
||||
quantum = DEFAULT_QUANTUM;
|
||||
quantum = driver->context->defaults.clock_quantum;
|
||||
|
||||
/* for now, we try to limit the latency between min and default, We can
|
||||
* go to max but we should really only do this when in power save mode */
|
||||
driver->quantum_current = SPA_CLAMP(quantum, MIN_QUANTUM, DEFAULT_QUANTUM);
|
||||
driver->quantum_current = SPA_CLAMP(quantum,
|
||||
driver->context->defaults.clock_min_quantum,
|
||||
driver->context->defaults.clock_quantum);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -779,7 +816,8 @@ int pw_context_recalc_graph(struct pw_context *context)
|
|||
|
||||
if (target != NULL) {
|
||||
if (n->quantum_size > 0 && n->quantum_size < target->quantum_current)
|
||||
target->quantum_current = SPA_MAX(MIN_QUANTUM, n->quantum_size);
|
||||
target->quantum_current =
|
||||
SPA_MAX(context->defaults.clock_min_quantum, n->quantum_size);
|
||||
}
|
||||
pw_impl_node_set_driver(n, target);
|
||||
pw_impl_node_set_state(n, target && n->active ?
|
||||
|
|
|
|||
|
|
@ -1266,11 +1266,8 @@ static void add_audio_dsp_port_params(struct filter *impl, struct port *port)
|
|||
spa_pod_builder_add_object(&b,
|
||||
SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat,
|
||||
SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_audio),
|
||||
SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw),
|
||||
SPA_FORMAT_AUDIO_format, SPA_POD_Id(SPA_AUDIO_FORMAT_F32P),
|
||||
SPA_FORMAT_AUDIO_rate, SPA_POD_CHOICE_RANGE_Int(
|
||||
48000, 1, INT32_MAX),
|
||||
SPA_FORMAT_AUDIO_channels, SPA_POD_Int(1)));
|
||||
SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_dsp),
|
||||
SPA_FORMAT_AUDIO_format, SPA_POD_Id(SPA_AUDIO_FORMAT_DSP_F32)));
|
||||
|
||||
spa_pod_builder_init(&b, buffer, sizeof(buffer));
|
||||
add_param(impl, port, SPA_PARAM_Buffers,
|
||||
|
|
@ -1297,16 +1294,8 @@ static void add_video_dsp_port_params(struct filter *impl, struct port *port)
|
|||
spa_pod_builder_add_object(&b,
|
||||
SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat,
|
||||
SPA_FORMAT_mediaType, SPA_POD_Id(SPA_MEDIA_TYPE_video),
|
||||
SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_raw),
|
||||
SPA_FORMAT_VIDEO_format, SPA_POD_Id(SPA_VIDEO_FORMAT_RGBA_F32),
|
||||
SPA_FORMAT_VIDEO_size, SPA_POD_CHOICE_RANGE_Rectangle(
|
||||
&SPA_RECTANGLE(320, 240),
|
||||
&SPA_RECTANGLE(1,1),
|
||||
&SPA_RECTANGLE(INT32_MAX, INT32_MAX)),
|
||||
SPA_FORMAT_VIDEO_framerate, SPA_POD_CHOICE_RANGE_Fraction(
|
||||
&SPA_FRACTION(25,1),
|
||||
&SPA_FRACTION(0,1),
|
||||
&SPA_FRACTION(INT32_MAX,1))));
|
||||
SPA_FORMAT_mediaSubtype, SPA_POD_Id(SPA_MEDIA_SUBTYPE_dsp),
|
||||
SPA_FORMAT_VIDEO_format, SPA_POD_Id(SPA_VIDEO_FORMAT_DSP_F32)));
|
||||
}
|
||||
|
||||
SPA_EXPORT
|
||||
|
|
|
|||
|
|
@ -908,12 +908,17 @@ static void reset_segment(struct spa_io_segment *seg)
|
|||
seg->rate = 1.0;
|
||||
}
|
||||
|
||||
static void reset_position(struct spa_io_position *pos)
|
||||
static void reset_position(struct pw_impl_node *this, struct spa_io_position *pos)
|
||||
{
|
||||
uint32_t i;
|
||||
struct defaults *def = &this->context->defaults;
|
||||
|
||||
pos->clock.rate = SPA_FRACTION(1, 48000);
|
||||
pos->clock.duration = DEFAULT_QUANTUM;
|
||||
pos->clock.rate = SPA_FRACTION(1, def->clock_rate);
|
||||
pos->clock.duration = def->clock_quantum;
|
||||
pos->video.flags = SPA_IO_VIDEO_SIZE_VALID;
|
||||
pos->video.size = def->video_size;
|
||||
pos->video.stride = pos->video.size.width * 16;
|
||||
pos->video.framerate = def->video_rate;
|
||||
pos->offset = INT64_MIN;
|
||||
|
||||
pos->n_segments = 1;
|
||||
|
|
@ -1008,7 +1013,7 @@ struct pw_impl_node *pw_context_create_node(struct pw_context *context,
|
|||
this->rt.target.data = this;
|
||||
this->rt.driver_target.signal = process_node;
|
||||
|
||||
reset_position(&this->rt.activation->position);
|
||||
reset_position(this, &this->rt.activation->position);
|
||||
this->rt.activation->sync_timeout = 5 * SPA_NSEC_PER_SEC;
|
||||
this->rt.activation->sync_left = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -502,13 +502,13 @@ static int setup_mixer(struct pw_impl_port *port, const struct spa_pod *param)
|
|||
switch (media_type) {
|
||||
case SPA_MEDIA_TYPE_audio:
|
||||
switch (media_subtype) {
|
||||
case SPA_MEDIA_SUBTYPE_raw:
|
||||
case SPA_MEDIA_SUBTYPE_dsp:
|
||||
{
|
||||
struct spa_audio_info_raw info;
|
||||
if ((res = spa_format_audio_raw_parse(param, &info)) < 0)
|
||||
struct spa_audio_info_dsp info;
|
||||
if ((res = spa_format_audio_dsp_parse(param, &info)) < 0)
|
||||
return res;
|
||||
|
||||
if (info.format != SPA_AUDIO_FORMAT_F32P || info.channels != 1)
|
||||
if (info.format != SPA_AUDIO_FORMAT_DSP_F32)
|
||||
return -ENOTSUP;
|
||||
|
||||
fallback_lib = "audiomixer/libspa-audiomixer";
|
||||
|
|
|
|||
|
|
@ -48,9 +48,14 @@ struct ucred {
|
|||
#define spa_debug pw_log_trace
|
||||
#endif
|
||||
|
||||
#define DEFAULT_QUANTUM 1024u
|
||||
#define MIN_QUANTUM 32u
|
||||
#define MAX_QUANTUM 8192u
|
||||
struct defaults {
|
||||
uint32_t clock_rate;
|
||||
uint32_t clock_quantum;
|
||||
uint32_t clock_min_quantum;
|
||||
uint32_t clock_max_quantum;
|
||||
struct spa_rectangle video_size;
|
||||
struct spa_fraction video_rate;
|
||||
};
|
||||
|
||||
#define MAX_PARAMS 32
|
||||
|
||||
|
|
@ -228,6 +233,8 @@ struct pw_context {
|
|||
|
||||
struct pw_properties *properties; /**< properties of the context */
|
||||
|
||||
struct defaults defaults; /**< default parameters */
|
||||
|
||||
struct pw_mempool *pool; /**< global memory pool */
|
||||
|
||||
struct pw_map globals; /**< map of globals */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue