mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
implement NEAREST flag
when the NEAREST flag is set and the param could not be completely set, set_param should return 1 to indicate this.
This commit is contained in:
parent
955e1a6a18
commit
1ca7713057
3 changed files with 21 additions and 17 deletions
|
|
@ -404,6 +404,7 @@ int spa_alsa_set_format(struct state *state, struct spa_audio_info *fmt, uint32_
|
||||||
struct spa_audio_info_raw *info = &fmt->info.raw;
|
struct spa_audio_info_raw *info = &fmt->info.raw;
|
||||||
snd_pcm_t *hndl;
|
snd_pcm_t *hndl;
|
||||||
unsigned int periods;
|
unsigned int periods;
|
||||||
|
bool match = true;
|
||||||
|
|
||||||
if ((err = spa_alsa_open(state)) < 0)
|
if ((err = spa_alsa_open(state)) < 0)
|
||||||
return err;
|
return err;
|
||||||
|
|
@ -439,10 +440,10 @@ int spa_alsa_set_format(struct state *state, struct spa_audio_info *fmt, uint32_
|
||||||
if (rchannels != info->channels) {
|
if (rchannels != info->channels) {
|
||||||
spa_log_warn(state->log, NAME" %p: Channels doesn't match (requested %u, get %u",
|
spa_log_warn(state->log, NAME" %p: Channels doesn't match (requested %u, get %u",
|
||||||
state, info->channels, rchannels);
|
state, info->channels, rchannels);
|
||||||
if (flags & SPA_NODE_PARAM_FLAG_NEAREST)
|
if (!SPA_FLAG_IS_SET(flags, SPA_NODE_PARAM_FLAG_NEAREST))
|
||||||
info->channels = rchannels;
|
|
||||||
else
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
info->channels = rchannels;
|
||||||
|
match = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set the stream rate */
|
/* set the stream rate */
|
||||||
|
|
@ -451,10 +452,10 @@ int spa_alsa_set_format(struct state *state, struct spa_audio_info *fmt, uint32_
|
||||||
if (rrate != info->rate) {
|
if (rrate != info->rate) {
|
||||||
spa_log_warn(state->log, NAME" %p: Rate doesn't match (requested %iHz, get %iHz)",
|
spa_log_warn(state->log, NAME" %p: Rate doesn't match (requested %iHz, get %iHz)",
|
||||||
state, info->rate, rrate);
|
state, info->rate, rrate);
|
||||||
if (flags & SPA_NODE_PARAM_FLAG_NEAREST)
|
if (!SPA_FLAG_IS_SET(flags, SPA_NODE_PARAM_FLAG_NEAREST))
|
||||||
info->rate = rrate;
|
|
||||||
else
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
info->rate = rrate;
|
||||||
|
match = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
state->format = format;
|
state->format = format;
|
||||||
|
|
@ -480,7 +481,7 @@ int spa_alsa_set_format(struct state *state, struct spa_audio_info *fmt, uint32_
|
||||||
/* write the parameters to device */
|
/* write the parameters to device */
|
||||||
CHECK(snd_pcm_hw_params(hndl, params), "set_hw_params");
|
CHECK(snd_pcm_hw_params(hndl, params), "set_hw_params");
|
||||||
|
|
||||||
return 0;
|
return match ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int set_swparams(struct state *state)
|
static int set_swparams(struct state *state)
|
||||||
|
|
|
||||||
|
|
@ -639,7 +639,7 @@ static int port_set_format(void *object,
|
||||||
port->have_format = false;
|
port->have_format = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spa_v4l2_set_format(this, &info, flags & SPA_NODE_PARAM_FLAG_TEST_ONLY) < 0)
|
if (spa_v4l2_set_format(this, &info, flags) < 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (!(flags & SPA_NODE_PARAM_FLAG_TEST_ONLY)) {
|
if (!(flags & SPA_NODE_PARAM_FLAG_TEST_ONLY)) {
|
||||||
|
|
|
||||||
|
|
@ -826,7 +826,7 @@ spa_v4l2_enum_format(struct impl *this, int seq,
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int spa_v4l2_set_format(struct impl *this, struct spa_video_info *format, bool try_only)
|
static int spa_v4l2_set_format(struct impl *this, struct spa_video_info *format, uint32_t flags)
|
||||||
{
|
{
|
||||||
struct port *port = &this->out_ports[0];
|
struct port *port = &this->out_ports[0];
|
||||||
struct spa_v4l2_device *dev = &port->dev;
|
struct spa_v4l2_device *dev = &port->dev;
|
||||||
|
|
@ -837,6 +837,7 @@ static int spa_v4l2_set_format(struct impl *this, struct spa_video_info *format,
|
||||||
uint32_t video_format;
|
uint32_t video_format;
|
||||||
struct spa_rectangle *size = NULL;
|
struct spa_rectangle *size = NULL;
|
||||||
struct spa_fraction *framerate = NULL;
|
struct spa_fraction *framerate = NULL;
|
||||||
|
bool match;
|
||||||
|
|
||||||
spa_zero(fmt);
|
spa_zero(fmt);
|
||||||
spa_zero(streamparm);
|
spa_zero(streamparm);
|
||||||
|
|
@ -891,7 +892,7 @@ static int spa_v4l2_set_format(struct impl *this, struct spa_video_info *format,
|
||||||
if ((res = spa_v4l2_open(dev, this->props.device)) < 0)
|
if ((res = spa_v4l2_open(dev, this->props.device)) < 0)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
cmd = try_only ? VIDIOC_TRY_FMT : VIDIOC_S_FMT;
|
cmd = (flags & SPA_NODE_PARAM_FLAG_TEST_ONLY) ? VIDIOC_TRY_FMT : VIDIOC_S_FMT;
|
||||||
if (xioctl(dev->fd, cmd, &fmt) < 0) {
|
if (xioctl(dev->fd, cmd, &fmt) < 0) {
|
||||||
res = -errno;
|
res = -errno;
|
||||||
spa_log_error(this->log, "VIDIOC_S_FMT: %m");
|
spa_log_error(this->log, "VIDIOC_S_FMT: %m");
|
||||||
|
|
@ -902,9 +903,11 @@ static int spa_v4l2_set_format(struct impl *this, struct spa_video_info *format,
|
||||||
if (xioctl(dev->fd, VIDIOC_S_PARM, &streamparm) < 0)
|
if (xioctl(dev->fd, VIDIOC_S_PARM, &streamparm) < 0)
|
||||||
spa_log_warn(this->log, "VIDIOC_S_PARM: %m");
|
spa_log_warn(this->log, "VIDIOC_S_PARM: %m");
|
||||||
|
|
||||||
if (reqfmt.fmt.pix.pixelformat != fmt.fmt.pix.pixelformat ||
|
match = (reqfmt.fmt.pix.pixelformat == fmt.fmt.pix.pixelformat &&
|
||||||
reqfmt.fmt.pix.width != fmt.fmt.pix.width ||
|
reqfmt.fmt.pix.width == fmt.fmt.pix.width &&
|
||||||
reqfmt.fmt.pix.height != fmt.fmt.pix.height) {
|
reqfmt.fmt.pix.height == fmt.fmt.pix.height);
|
||||||
|
|
||||||
|
if (!match && !SPA_FLAG_IS_SET(flags, SPA_NODE_PARAM_FLAG_NEAREST)) {
|
||||||
spa_log_error(this->log, "v4l2: wanted %.4s %dx%d, got %.4s %dx%d",
|
spa_log_error(this->log, "v4l2: wanted %.4s %dx%d, got %.4s %dx%d",
|
||||||
(char *)&reqfmt.fmt.pix.pixelformat,
|
(char *)&reqfmt.fmt.pix.pixelformat,
|
||||||
reqfmt.fmt.pix.width, reqfmt.fmt.pix.height,
|
reqfmt.fmt.pix.width, reqfmt.fmt.pix.height,
|
||||||
|
|
@ -913,14 +916,14 @@ static int spa_v4l2_set_format(struct impl *this, struct spa_video_info *format,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (flags & SPA_NODE_PARAM_FLAG_TEST_ONLY)
|
||||||
|
return match ? 0 : 1;
|
||||||
|
|
||||||
spa_log_info(this->log, "v4l2: got %.4s %dx%d %d/%d", (char *)&fmt.fmt.pix.pixelformat,
|
spa_log_info(this->log, "v4l2: got %.4s %dx%d %d/%d", (char *)&fmt.fmt.pix.pixelformat,
|
||||||
fmt.fmt.pix.width, fmt.fmt.pix.height,
|
fmt.fmt.pix.width, fmt.fmt.pix.height,
|
||||||
streamparm.parm.capture.timeperframe.denominator,
|
streamparm.parm.capture.timeperframe.denominator,
|
||||||
streamparm.parm.capture.timeperframe.numerator);
|
streamparm.parm.capture.timeperframe.numerator);
|
||||||
|
|
||||||
if (try_only)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
dev->have_format = true;
|
dev->have_format = true;
|
||||||
size->width = fmt.fmt.pix.width;
|
size->width = fmt.fmt.pix.width;
|
||||||
size->height = fmt.fmt.pix.height;
|
size->height = fmt.fmt.pix.height;
|
||||||
|
|
@ -935,7 +938,7 @@ static int spa_v4l2_set_format(struct impl *this, struct spa_video_info *format,
|
||||||
SPA_PORT_FLAG_TERMINAL;
|
SPA_PORT_FLAG_TERMINAL;
|
||||||
port->info.rate = SPA_FRACTION(port->rate.num, port->rate.denom);
|
port->info.rate = SPA_FRACTION(port->rate.num, port->rate.denom);
|
||||||
|
|
||||||
return 0;
|
return match ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int query_ext_ctrl_ioctl(struct port *port, struct v4l2_query_ext_ctrl *qctrl)
|
static int query_ext_ctrl_ioctl(struct port *port, struct v4l2_query_ext_ctrl *qctrl)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue