mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-31 22:25:38 -04:00
v4l2: work on format enumeration
Start work on format enumeration fix fd leak in v4l2-source Improve spa-inspect output
This commit is contained in:
parent
61caf0e19c
commit
77bc2a1793
6 changed files with 282 additions and 84 deletions
|
|
@ -62,26 +62,40 @@ struct _V4l2Buffer {
|
|||
};
|
||||
|
||||
typedef struct {
|
||||
bool export_buf;
|
||||
bool have_buffers;
|
||||
|
||||
bool next_fmtdesc;
|
||||
struct v4l2_fmtdesc fmtdesc;
|
||||
bool next_frmsize;
|
||||
struct v4l2_frmsizeenum frmsize;
|
||||
bool next_frmival;
|
||||
struct v4l2_frmivalenum frmival;
|
||||
void *cookie;
|
||||
|
||||
SpaVideoRawFormat raw_format[2];
|
||||
SpaFormat *current_format;
|
||||
bool opened;
|
||||
bool have_buffers;
|
||||
|
||||
int fd;
|
||||
bool opened;
|
||||
struct v4l2_capability cap;
|
||||
struct v4l2_format fmt;
|
||||
enum v4l2_buf_type type;
|
||||
enum v4l2_memory memtype;
|
||||
|
||||
struct v4l2_requestbuffers reqbuf;
|
||||
V4l2Buffer buffers[MAX_BUFFERS];
|
||||
V4l2Buffer *ready;
|
||||
uint32_t ready_count;
|
||||
|
||||
SpaPollFd fds[1];
|
||||
SpaPollItem poll;
|
||||
|
||||
SpaPortInfo info;
|
||||
SpaAllocParam *params[1];
|
||||
SpaAllocParamBuffers param_buffers;
|
||||
bool export_buf;
|
||||
SpaPortStatus status;
|
||||
|
||||
} SpaV4l2State;
|
||||
|
||||
struct _SpaV4l2Source {
|
||||
|
|
@ -312,16 +326,18 @@ spa_v4l2_source_node_port_enum_formats (SpaHandle *handle,
|
|||
|
||||
state = &this->state[port_id];
|
||||
|
||||
/*
|
||||
switch (index) {
|
||||
case 0:
|
||||
spa_video_raw_format_init (&state->raw_format[0]);
|
||||
break;
|
||||
default:
|
||||
return SPA_RESULT_ENUM_END;
|
||||
break;
|
||||
}
|
||||
*format = &state->raw_format[0].format;
|
||||
*/
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
return spa_v4l2_enum_format (this, format, &state->cookie);
|
||||
}
|
||||
|
||||
static SpaResult
|
||||
|
|
|
|||
|
|
@ -256,6 +256,112 @@ video_format_to_fourcc (SpaVideoFormat format)
|
|||
return fourcc;
|
||||
}
|
||||
|
||||
#define FOURCC_ARGS(f) (f)&0x7f,((f)>>8)&0x7f,((f)>>16)&0x7f,((f)>>24)&0x7f
|
||||
|
||||
static SpaResult
|
||||
spa_v4l2_enum_format (SpaV4l2Source *this, SpaFormat **format, void **cookie)
|
||||
{
|
||||
SpaV4l2State *state = &this->state[0];
|
||||
int res;
|
||||
|
||||
if (spa_v4l2_open (this) < 0)
|
||||
return SPA_RESULT_ERROR;
|
||||
|
||||
*format = NULL;
|
||||
|
||||
if (*cookie == NULL) {
|
||||
CLEAR (state->fmtdesc);
|
||||
state->fmtdesc.index = 0;
|
||||
state->fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
state->next_fmtdesc = true;
|
||||
|
||||
CLEAR (state->frmsize);
|
||||
state->next_frmsize = true;
|
||||
|
||||
CLEAR (state->frmival);
|
||||
state->next_frmival = true;
|
||||
|
||||
*cookie = state;
|
||||
}
|
||||
|
||||
again:
|
||||
if (state->next_fmtdesc) {
|
||||
if ((res = xioctl (state->fd, VIDIOC_ENUM_FMT, &state->fmtdesc)) < 0) {
|
||||
if (errno != EINVAL)
|
||||
perror ("VIDIOC_ENUM_FMT");
|
||||
return SPA_RESULT_ENUM_END;
|
||||
}
|
||||
state->next_fmtdesc = false;
|
||||
|
||||
state->frmsize.index = 0;
|
||||
state->frmsize.pixel_format = state->fmtdesc.pixelformat;
|
||||
state->next_frmsize = true;
|
||||
}
|
||||
if (state->next_frmsize) {
|
||||
if ((res = xioctl (state->fd, VIDIOC_ENUM_FRAMESIZES, &state->frmsize)) < 0) {
|
||||
if (errno == EINVAL) {
|
||||
state->fmtdesc.index++;
|
||||
state->next_fmtdesc = true;
|
||||
goto again;
|
||||
}
|
||||
perror ("VIDIOC_ENUM_FRAMESIZES");
|
||||
return SPA_RESULT_ENUM_END;
|
||||
}
|
||||
state->next_frmsize = false;
|
||||
|
||||
if (state->frmsize.type == V4L2_FRMSIZE_TYPE_DISCRETE) {
|
||||
state->frmival.index = 0;
|
||||
state->frmival.pixel_format = state->frmsize.pixel_format;
|
||||
state->frmival.width = state->frmsize.discrete.width;
|
||||
state->frmival.height = state->frmsize.discrete.height;
|
||||
state->next_frmival = true;
|
||||
}
|
||||
}
|
||||
if (state->next_frmival) {
|
||||
if ((res = xioctl (state->fd, VIDIOC_ENUM_FRAMEINTERVALS, &state->frmival)) < 0) {
|
||||
if (errno == EINVAL) {
|
||||
state->frmsize.index++;
|
||||
state->next_frmsize = true;
|
||||
goto again;
|
||||
}
|
||||
perror ("VIDIOC_ENUM_FRAMEINTERVALS");
|
||||
return SPA_RESULT_ENUM_END;
|
||||
}
|
||||
state->frmival.index++;
|
||||
}
|
||||
fprintf (stderr, "format %c%c%c%c\n", FOURCC_ARGS (state->fmtdesc.pixelformat));
|
||||
if (state->frmsize.type == V4L2_FRMSIZE_TYPE_DISCRETE) {
|
||||
fprintf (stderr, "size %dx%d\n", state->frmsize.discrete.width, state->frmsize.discrete.height);
|
||||
} else if (state->frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
|
||||
fprintf (stderr, "size %dx%d - %dx%d with step %d/%d\n",
|
||||
state->frmsize.stepwise.min_width,
|
||||
state->frmsize.stepwise.min_height,
|
||||
state->frmsize.stepwise.max_width,
|
||||
state->frmsize.stepwise.max_height,
|
||||
state->frmsize.stepwise.step_width,
|
||||
state->frmsize.stepwise.step_height);
|
||||
}
|
||||
if (state->frmival.type == V4L2_FRMIVAL_TYPE_DISCRETE) {
|
||||
fprintf (stderr, "framerate %u/%u\n",
|
||||
state->frmival.discrete.numerator,
|
||||
state->frmival.discrete.denominator);
|
||||
} else if (state->frmival.type == V4L2_FRMIVAL_TYPE_CONTINUOUS) {
|
||||
fprintf (stderr, "framerate %u/%u - %u/%u\n",
|
||||
state->frmival.stepwise.min.numerator,
|
||||
state->frmival.stepwise.min.denominator,
|
||||
state->frmival.stepwise.max.numerator,
|
||||
state->frmival.stepwise.max.denominator);
|
||||
} else if (state->frmival.type == V4L2_FRMIVAL_TYPE_STEPWISE) {
|
||||
fprintf (stderr, "framerate %u/%u - %u/%u step %u/%u\n",
|
||||
state->frmival.stepwise.min.numerator,
|
||||
state->frmival.stepwise.min.denominator,
|
||||
state->frmival.stepwise.max.numerator,
|
||||
state->frmival.stepwise.max.denominator,
|
||||
state->frmival.stepwise.step.numerator,
|
||||
state->frmival.stepwise.step.denominator);
|
||||
}
|
||||
return SPA_RESULT_OK;
|
||||
}
|
||||
|
||||
static int
|
||||
spa_v4l2_set_format (SpaV4l2Source *this, SpaFormat *format, bool try_only)
|
||||
|
|
@ -493,6 +599,8 @@ mmap_init (SpaV4l2Source *this)
|
|||
fprintf (stderr, "can't allocate enough buffers\n");
|
||||
return -1;
|
||||
}
|
||||
if (state->export_buf)
|
||||
fprintf (stderr, "using EXPBUF\n");
|
||||
|
||||
state->reqbuf = reqbuf;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue