mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -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
|
|
@ -142,8 +142,7 @@ static int
|
|||
tmpfile_create (PinosSpaV4l2Source * source, void *data, gsize size)
|
||||
{
|
||||
char filename[] = "/dev/shm/tmpfilepay.XXXXXX";
|
||||
int fd, result;
|
||||
void *p;
|
||||
int fd;
|
||||
|
||||
fd = mkostemp (filename, O_CLOEXEC);
|
||||
if (fd == -1) {
|
||||
|
|
@ -152,15 +151,8 @@ tmpfile_create (PinosSpaV4l2Source * source, void *data, gsize size)
|
|||
}
|
||||
unlink (filename);
|
||||
|
||||
result = ftruncate (fd, size);
|
||||
if (result == -1) {
|
||||
g_debug ("Failed to resize temporary file: %s", strerror (errno));
|
||||
close (fd);
|
||||
return -1;
|
||||
}
|
||||
p = mmap (0, size, PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
memcpy (p, data, size);
|
||||
munmap (p, size);
|
||||
if (write (fd, data, size) != (gssize) size)
|
||||
g_debug ("Failed to write data: %s", strerror (errno));
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
|
@ -185,6 +177,7 @@ on_source_event (SpaHandle *handle, SpaEvent *event, void *user_data)
|
|||
gint fd;
|
||||
guint8 buf[1024];
|
||||
gint fdbuf[8];
|
||||
gboolean do_close = FALSE;
|
||||
|
||||
if ((res = priv->source_node->port_pull_output (priv->source, 1, info)) < 0)
|
||||
g_debug ("spa-v4l2-source %p: got pull error %d", source, res);
|
||||
|
|
@ -193,7 +186,7 @@ on_source_event (SpaHandle *handle, SpaEvent *event, void *user_data)
|
|||
|
||||
hdr.flags = 0;
|
||||
hdr.seq = 0;
|
||||
hdr.pts = 0;
|
||||
hdr.pts = -1;
|
||||
hdr.dts_offset = 0;
|
||||
|
||||
pinos_buffer_builder_init_into (&builder, buf, 1024, fdbuf, 8);
|
||||
|
|
@ -203,6 +196,7 @@ on_source_event (SpaHandle *handle, SpaEvent *event, void *user_data)
|
|||
fd = *((int *)b->datas[0].ptr);
|
||||
} else {
|
||||
fd = tmpfile_create (source, b->datas[0].ptr, b->size);
|
||||
do_close = TRUE;
|
||||
}
|
||||
p.fd_index = pinos_buffer_builder_add_fd (&builder, fd);
|
||||
p.id = pinos_fd_manager_get_id (priv->fdmanager);
|
||||
|
|
@ -223,7 +217,8 @@ on_source_event (SpaHandle *handle, SpaEvent *event, void *user_data)
|
|||
g_clear_error (&error);
|
||||
}
|
||||
}
|
||||
pinos_buffer_steal_fds (&pbuf, NULL);
|
||||
if (!do_close)
|
||||
pinos_buffer_steal_fds (&pbuf, NULL);
|
||||
pinos_buffer_unref (&pbuf);
|
||||
|
||||
spa_buffer_unref (b);
|
||||
|
|
@ -410,7 +405,6 @@ set_state (PinosNode *node,
|
|||
PinosNodeState state)
|
||||
{
|
||||
PinosSpaV4l2Source *this = PINOS_SPA_V4L2_SOURCE (node);
|
||||
PinosSpaV4l2SourcePrivate *priv = this->priv;
|
||||
|
||||
g_debug ("spa-source %p: set state %s", node, pinos_node_state_as_string (state));
|
||||
|
||||
|
|
@ -442,9 +436,6 @@ get_property (GObject *object,
|
|||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
PinosSpaV4l2Source *source = PINOS_SPA_V4L2_SOURCE (object);
|
||||
PinosSpaV4l2SourcePrivate *priv = source->priv;
|
||||
|
||||
switch (prop_id) {
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
|
|
@ -458,9 +449,6 @@ set_property (GObject *object,
|
|||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
PinosSpaV4l2Source *source = PINOS_SPA_V4L2_SOURCE (object);
|
||||
PinosSpaV4l2SourcePrivate *priv = source->priv;
|
||||
|
||||
switch (prop_id) {
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
|
|
@ -473,7 +461,6 @@ on_linked (PinosPort *port, PinosPort *peer, gpointer user_data)
|
|||
{
|
||||
SourcePortData *data = user_data;
|
||||
PinosSpaV4l2Source *source = data->source;
|
||||
PinosSpaV4l2SourcePrivate *priv = source->priv;
|
||||
guint n_links;
|
||||
|
||||
pinos_port_get_links (port, &n_links);
|
||||
|
|
@ -489,7 +476,6 @@ on_unlinked (PinosPort *port, PinosPort *peer, gpointer user_data)
|
|||
{
|
||||
SourcePortData *data = user_data;
|
||||
PinosSpaV4l2Source *source = data->source;
|
||||
PinosSpaV4l2SourcePrivate *priv = source->priv;
|
||||
guint n_links;
|
||||
|
||||
pinos_port_get_links (port, &n_links);
|
||||
|
|
@ -502,8 +488,6 @@ static void
|
|||
on_received_buffer (PinosPort *port,
|
||||
gpointer user_data)
|
||||
{
|
||||
PinosSpaV4l2Source *this = user_data;
|
||||
PinosSpaV4l2SourcePrivate *priv = this->priv;
|
||||
PinosBuffer *pbuf;
|
||||
PinosBufferIter it;
|
||||
|
||||
|
|
@ -522,9 +506,6 @@ on_received_buffer (PinosPort *port,
|
|||
static void
|
||||
free_source_port_data (SourcePortData *data)
|
||||
{
|
||||
PinosSpaV4l2Source *source = data->source;
|
||||
PinosSpaV4l2SourcePrivate *priv = source->priv;
|
||||
|
||||
g_slice_free (SourcePortData, data);
|
||||
}
|
||||
|
||||
|
|
@ -553,7 +534,6 @@ static void
|
|||
source_constructed (GObject * object)
|
||||
{
|
||||
PinosSpaV4l2Source *source = PINOS_SPA_V4L2_SOURCE (object);
|
||||
PinosSpaV4l2SourcePrivate *priv = source->priv;
|
||||
|
||||
G_OBJECT_CLASS (pinos_spa_v4l2_source_parent_class)->constructed (object);
|
||||
|
||||
|
|
@ -564,7 +544,6 @@ static void
|
|||
source_finalize (GObject * object)
|
||||
{
|
||||
PinosSpaV4l2Source *source = PINOS_SPA_V4L2_SOURCE (object);
|
||||
PinosSpaV4l2SourcePrivate *priv = source->priv;
|
||||
|
||||
g_debug ("spa-source %p: dispose", source);
|
||||
destroy_pipeline (source);
|
||||
|
|
|
|||
|
|
@ -54,8 +54,8 @@ typedef enum {
|
|||
} SpaPropType;
|
||||
|
||||
typedef struct {
|
||||
int32_t num;
|
||||
int32_t denom;
|
||||
uint32_t num;
|
||||
uint32_t denom;
|
||||
} SpaFraction;
|
||||
|
||||
/**
|
||||
|
|
@ -120,6 +120,7 @@ typedef struct {
|
|||
* @range_values: array of possible values
|
||||
* @tags: extra tags, NULL terminated
|
||||
* @offset: offset in structure with data
|
||||
* @mask_offset: offset in structure for the mask
|
||||
* @unset_mask: mask to clear when value is set
|
||||
* @priv: extra private data
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -111,7 +111,6 @@ static const uint32_t format_values[] = {
|
|||
};
|
||||
|
||||
static const SpaPropRangeInfo format_range[] = {
|
||||
{ "UNKNOWN", "UNKNOWN,", sizeof (uint32_t), &format_values[0] },
|
||||
{ "ENCODED,", "ENCODED", sizeof (uint32_t), &format_values[1] },
|
||||
{ "S16LE", "S16LE", sizeof (uint32_t), &format_values[2] },
|
||||
{ "S16BE", "S16BE", sizeof (uint32_t), &format_values[3] },
|
||||
|
|
@ -175,7 +174,6 @@ static const uint32_t multiview_modes[] = {
|
|||
};
|
||||
|
||||
static const SpaPropRangeInfo multiview_mode_range[] = {
|
||||
{ "none", "None", sizeof (uint32_t), &multiview_modes[0] },
|
||||
{ "mono", "Mono", sizeof (uint32_t), &multiview_modes[1] },
|
||||
{ "left", "Left", sizeof (uint32_t), &multiview_modes[2] },
|
||||
{ "right", "Right", sizeof (uint32_t), &multiview_modes[3] },
|
||||
|
|
@ -371,7 +369,7 @@ static const SpaPropInfo raw_format_prop_info[] =
|
|||
offsetof (SpaVideoRawFormat, unset_mask), 1 << 3,
|
||||
NULL },
|
||||
{ SPA_PROP_ID_VIDEO_MAX_FRAMERATE, "max-framerate", "Video max framerate",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL,
|
||||
SPA_PROP_TYPE_FRACTION, sizeof (SpaFraction),
|
||||
sizeof (SpaFraction), &default_info.max_framerate,
|
||||
SPA_PROP_RANGE_TYPE_MIN_MAX, 2, framerate_range,
|
||||
|
|
@ -380,7 +378,7 @@ static const SpaPropInfo raw_format_prop_info[] =
|
|||
offsetof (SpaVideoRawFormat, unset_mask), 1 << 4,
|
||||
NULL },
|
||||
{ SPA_PROP_ID_VIDEO_VIEWS, "views", "Video number of views",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
sizeof (uint32_t), &default_info.views,
|
||||
SPA_PROP_RANGE_TYPE_MIN_MAX, 2, uint32_range,
|
||||
|
|
@ -389,7 +387,7 @@ static const SpaPropInfo raw_format_prop_info[] =
|
|||
offsetof (SpaVideoRawFormat, unset_mask), 1 << 5,
|
||||
NULL },
|
||||
{ SPA_PROP_ID_VIDEO_INTERLACE_MODE, "interlace-mode", "Interlace mode",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
sizeof (uint32_t), &default_info.interlace_mode,
|
||||
SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (interlace_mode_range), interlace_mode_range,
|
||||
|
|
@ -398,7 +396,7 @@ static const SpaPropInfo raw_format_prop_info[] =
|
|||
offsetof (SpaVideoRawFormat, unset_mask), 1 << 6,
|
||||
NULL },
|
||||
{ SPA_PROP_ID_VIDEO_PIXEL_ASPECT_RATIO, "pixel-aspect-ratio", "Video pixel aspect ratio",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL,
|
||||
SPA_PROP_TYPE_FRACTION, sizeof (SpaFraction),
|
||||
sizeof (SpaFraction), &default_info.pixel_aspect_ratio,
|
||||
SPA_PROP_RANGE_TYPE_MIN_MAX, 2, framerate_range,
|
||||
|
|
@ -407,7 +405,7 @@ static const SpaPropInfo raw_format_prop_info[] =
|
|||
offsetof (SpaVideoRawFormat, unset_mask), 1 << 7,
|
||||
NULL },
|
||||
{ SPA_PROP_ID_VIDEO_MULTIVIEW_MODE, "multiview-mode", "Multiview mode",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
sizeof (uint32_t), &default_info.multiview_mode,
|
||||
SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (multiview_mode_range), multiview_mode_range,
|
||||
|
|
@ -416,7 +414,7 @@ static const SpaPropInfo raw_format_prop_info[] =
|
|||
offsetof (SpaVideoRawFormat, unset_mask), 1 << 8,
|
||||
NULL },
|
||||
{ SPA_PROP_ID_VIDEO_MULTIVIEW_FLAGS, "multiview-flags", "Multiview flags",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
sizeof (uint32_t), &default_info.multiview_flags,
|
||||
SPA_PROP_RANGE_TYPE_FLAGS, SPA_N_ELEMENTS (multiview_flags_range), multiview_flags_range,
|
||||
|
|
@ -425,7 +423,7 @@ static const SpaPropInfo raw_format_prop_info[] =
|
|||
offsetof (SpaVideoRawFormat, unset_mask), 1 << 9,
|
||||
NULL },
|
||||
{ SPA_PROP_ID_VIDEO_CHROMA_SITE, "chroma-site", "Chroma site",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
sizeof (uint32_t), &default_info.chroma_site,
|
||||
SPA_PROP_RANGE_TYPE_FLAGS, SPA_N_ELEMENTS (chroma_site_range), chroma_site_range,
|
||||
|
|
@ -434,7 +432,7 @@ static const SpaPropInfo raw_format_prop_info[] =
|
|||
offsetof (SpaVideoRawFormat, unset_mask), 1 << 10,
|
||||
NULL },
|
||||
{ SPA_PROP_ID_VIDEO_COLOR_RANGE, "color-range", "Color range",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
sizeof (uint32_t), &default_info.color_range,
|
||||
SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (color_range_range), color_range_range,
|
||||
|
|
@ -443,7 +441,7 @@ static const SpaPropInfo raw_format_prop_info[] =
|
|||
offsetof (SpaVideoRawFormat, unset_mask), 1 << 11,
|
||||
NULL },
|
||||
{ SPA_PROP_ID_VIDEO_COLOR_MATRIX, "color-matrix", "Color matrix",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
sizeof (uint32_t), &default_info.color_matrix,
|
||||
SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (color_matrix_range), color_matrix_range,
|
||||
|
|
@ -452,7 +450,7 @@ static const SpaPropInfo raw_format_prop_info[] =
|
|||
offsetof (SpaVideoRawFormat, unset_mask), 1 << 12,
|
||||
NULL },
|
||||
{ SPA_PROP_ID_VIDEO_TRANSFER_FUNCTION, "transfer-function", "Transfer function",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
sizeof (uint32_t), &default_info.transfer_function,
|
||||
SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (transfer_function_range), transfer_function_range,
|
||||
|
|
@ -461,7 +459,7 @@ static const SpaPropInfo raw_format_prop_info[] =
|
|||
offsetof (SpaVideoRawFormat, unset_mask), 1 << 13,
|
||||
NULL },
|
||||
{ SPA_PROP_ID_VIDEO_COLOR_PRIMARIES, "color-primaries", "Color primaries",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL,
|
||||
SPA_PROP_TYPE_UINT32, sizeof (uint32_t),
|
||||
sizeof (uint32_t), &default_info.color_primaries,
|
||||
SPA_PROP_RANGE_TYPE_ENUM, SPA_N_ELEMENTS (color_primaries_range), color_primaries_range,
|
||||
|
|
@ -470,7 +468,7 @@ static const SpaPropInfo raw_format_prop_info[] =
|
|||
offsetof (SpaVideoRawFormat, unset_mask), 1 << 14,
|
||||
NULL },
|
||||
{ SPA_PROP_ID_VIDEO_RAW_INFO, "info", "the SpaVideoRawInfo structure",
|
||||
SPA_PROP_FLAG_READWRITE,
|
||||
SPA_PROP_FLAG_READWRITE | SPA_PROP_FLAG_OPTIONAL,
|
||||
SPA_PROP_TYPE_STRUCT, sizeof (SpaVideoRawInfo),
|
||||
0, NULL,
|
||||
SPA_PROP_RANGE_TYPE_NONE, 0, NULL,
|
||||
|
|
@ -489,7 +487,7 @@ spa_video_raw_format_init (SpaVideoRawFormat *format)
|
|||
format->format.props.prop_info = raw_format_prop_info;
|
||||
format->format.props.set_prop = spa_props_generic_set_prop;
|
||||
format->format.props.get_prop = spa_props_generic_get_prop;
|
||||
format->unset_mask = (1 << 0) | (1 << 2) | (1 << 3) | (1 << 4);
|
||||
format->unset_mask = (1 << 15)-1;
|
||||
format->info = default_info;
|
||||
|
||||
return SPA_RESULT_OK;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -26,9 +26,8 @@
|
|||
#include <spa/node.h>
|
||||
|
||||
static void
|
||||
print_value (const char *prefix, SpaPropType type, int size, const void *value)
|
||||
print_value (SpaPropType type, int size, const void *value)
|
||||
{
|
||||
printf ("%s", prefix);
|
||||
switch (type) {
|
||||
case SPA_PROP_TYPE_INVALID:
|
||||
printf ("invalid");
|
||||
|
|
@ -67,21 +66,26 @@ print_value (const char *prefix, SpaPropType type, int size, const void *value)
|
|||
printf ("%g", *(double *)value);
|
||||
break;
|
||||
case SPA_PROP_TYPE_STRING:
|
||||
printf ("%s", (char *)value);
|
||||
printf ("\"%s\"", (char *)value);
|
||||
break;
|
||||
case SPA_PROP_TYPE_POINTER:
|
||||
printf ("%p", value);
|
||||
break;
|
||||
case SPA_PROP_TYPE_FRACTION:
|
||||
{
|
||||
const SpaFraction *f = value;
|
||||
printf ("%"PRIu32"/%"PRIu32, f->num, f->denom);
|
||||
break;
|
||||
}
|
||||
case SPA_PROP_TYPE_BITMASK:
|
||||
break;
|
||||
case SPA_PROP_TYPE_BYTES:
|
||||
break;
|
||||
case SPA_PROP_TYPE_STRUCT:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
printf ("\n");
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -91,44 +95,136 @@ print_props (const SpaProps *props, int print_ranges)
|
|||
const SpaPropInfo *info;
|
||||
int i, j;
|
||||
|
||||
printf ("Properties (%d items):\n", props->n_prop_info);
|
||||
for (i = 0; i < props->n_prop_info; i++) {
|
||||
SpaPropValue value;
|
||||
|
||||
info = &props->prop_info[i];
|
||||
|
||||
printf ("id:\t\t%d\n", info->id);
|
||||
printf ("name:\t\t%s\n", info->name);
|
||||
printf ("description:\t%s\n", info->description);
|
||||
printf ("flags:\t\t%d\n", info->flags);
|
||||
printf ("type:\t\t%d\n", info->type);
|
||||
printf ("maxsize:\t%zu\n", info->maxsize);
|
||||
printf (" %-20s: %s\n", info->name, info->description);
|
||||
printf ("%-23.23s flags: ", "");
|
||||
if (info->flags & SPA_PROP_FLAG_READABLE)
|
||||
printf ("readable ");
|
||||
if (info->flags & SPA_PROP_FLAG_WRITABLE)
|
||||
printf ("writable ");
|
||||
if (info->flags & SPA_PROP_FLAG_OPTIONAL)
|
||||
printf ("optional ");
|
||||
if (info->flags & SPA_PROP_FLAG_DEPRECATED)
|
||||
printf ("deprecated ");
|
||||
printf ("\n");
|
||||
|
||||
res = props->get_prop (props, info->id, &value);
|
||||
if (res == SPA_RESULT_PROPERTY_UNSET)
|
||||
printf ("value:\t\tunset\n");
|
||||
printf ("%-23.23s ", "");
|
||||
switch (info->type) {
|
||||
case SPA_PROP_TYPE_INVALID:
|
||||
printf ("Invalid.");
|
||||
break;
|
||||
case SPA_PROP_TYPE_BOOL:
|
||||
printf ("Boolean. ");
|
||||
break;
|
||||
case SPA_PROP_TYPE_INT8:
|
||||
printf ("Int8. ");
|
||||
break;
|
||||
case SPA_PROP_TYPE_UINT8:
|
||||
printf ("UInt8. ");
|
||||
break;
|
||||
case SPA_PROP_TYPE_INT16:
|
||||
printf ("Int16. ");
|
||||
break;
|
||||
case SPA_PROP_TYPE_UINT16:
|
||||
printf ("UInt16. ");
|
||||
break;
|
||||
case SPA_PROP_TYPE_INT32:
|
||||
printf ("Int32. ");
|
||||
break;
|
||||
case SPA_PROP_TYPE_UINT32:
|
||||
printf ("UInt32. ");
|
||||
break;
|
||||
case SPA_PROP_TYPE_INT64:
|
||||
printf ("Int64. ");
|
||||
break;
|
||||
case SPA_PROP_TYPE_UINT64:
|
||||
printf ("UInt64. ");
|
||||
break;
|
||||
case SPA_PROP_TYPE_FLOAT:
|
||||
printf ("Float. ");
|
||||
break;
|
||||
case SPA_PROP_TYPE_DOUBLE:
|
||||
printf ("Double. ");
|
||||
break;
|
||||
case SPA_PROP_TYPE_STRING:
|
||||
printf ("String. Maxsize %zd. ", info->maxsize);
|
||||
break;
|
||||
case SPA_PROP_TYPE_POINTER:
|
||||
printf ("Pointer. ");
|
||||
break;
|
||||
case SPA_PROP_TYPE_FRACTION:
|
||||
printf ("Fraction. ");
|
||||
break;
|
||||
case SPA_PROP_TYPE_BITMASK:
|
||||
printf ("Bitmask. ");
|
||||
break;
|
||||
case SPA_PROP_TYPE_BYTES:
|
||||
printf ("Bytes. ");
|
||||
break;
|
||||
case SPA_PROP_TYPE_STRUCT:
|
||||
printf ("Struct. ");
|
||||
break;
|
||||
default:
|
||||
printf ("*Unknown Property Type*. ");
|
||||
break;
|
||||
}
|
||||
|
||||
printf ("Default: ");
|
||||
if (info->default_value)
|
||||
print_value (info->type, info->default_size, info->default_value);
|
||||
else
|
||||
print_value ("value:\t\t", value.type, value.size, value.value);
|
||||
printf ("None");
|
||||
|
||||
if (print_ranges) {
|
||||
if (info->default_value)
|
||||
print_value ("default:\t", info->type, info->default_size, info->default_value);
|
||||
else
|
||||
printf ("default:\tunset\n");
|
||||
res = props->get_prop (props, i, &value);
|
||||
|
||||
printf ("range_type:\t%d\n", info->range_type);
|
||||
if (info->range_values) {
|
||||
for (j = 0; j < info->n_range_values; j++) {
|
||||
const SpaPropRangeInfo *rinfo = &info->range_values[j];
|
||||
printf (" name:\t%s\n", rinfo->name);
|
||||
printf (" description:\t%s\n", rinfo->description);
|
||||
print_value (" value:\t", info->type, rinfo->size, rinfo->value);
|
||||
}
|
||||
printf (". Current: ");
|
||||
if (res == SPA_RESULT_OK)
|
||||
print_value (info->type, value.size, value.value);
|
||||
else if (res == SPA_RESULT_PROPERTY_UNSET)
|
||||
printf ("Unset");
|
||||
else
|
||||
printf ("Error %d", res);
|
||||
printf (".\n");
|
||||
|
||||
if (info->range_type != SPA_PROP_RANGE_TYPE_NONE) {
|
||||
printf ("%-23.23s ", "");
|
||||
switch (info->range_type) {
|
||||
case SPA_PROP_RANGE_TYPE_MIN_MAX:
|
||||
printf ("Range");
|
||||
break;
|
||||
case SPA_PROP_RANGE_TYPE_STEP:
|
||||
printf ("Step");
|
||||
break;
|
||||
case SPA_PROP_RANGE_TYPE_ENUM:
|
||||
printf ("Enum");
|
||||
break;
|
||||
case SPA_PROP_RANGE_TYPE_FLAGS:
|
||||
printf ("Flags");
|
||||
break;
|
||||
default:
|
||||
printf ("Unknown");
|
||||
break;
|
||||
}
|
||||
printf (".\n");
|
||||
|
||||
for (j = 0; j < info->n_range_values; j++) {
|
||||
const SpaPropRangeInfo *rinfo = &info->range_values[j];
|
||||
printf ("%-23.23s ", "");
|
||||
print_value (info->type, rinfo->size, rinfo->value);
|
||||
printf ("\t: %-12s - %s \n", rinfo->name, rinfo->description);
|
||||
}
|
||||
}
|
||||
if (info->tags) {
|
||||
printf ("Tags: ");
|
||||
for (j = 0; info->tags[j]; j++) {
|
||||
printf ("tag:\t%s\n", info->tags[j]);
|
||||
printf ("\"%s\" ", info->tags[j]);
|
||||
}
|
||||
printf ("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -165,7 +261,8 @@ inspect_node (const SpaNode *node, SpaHandle *handle)
|
|||
printf ("got error %d\n", res);
|
||||
break;
|
||||
}
|
||||
print_format (format, 1);
|
||||
if (format)
|
||||
print_format (format, 1);
|
||||
}
|
||||
if ((res = node->port_get_props (handle, 0, &props)) < 0)
|
||||
printf ("port_get_props error: %d\n", res);
|
||||
|
|
@ -244,10 +341,9 @@ main (int argc, char *argv[])
|
|||
const SpaHandleFactory *factory;
|
||||
|
||||
if ((res = enum_func (i, &factory)) < 0) {
|
||||
if (res == SPA_RESULT_ENUM_END)
|
||||
break;
|
||||
else
|
||||
printf ("can't enumerate factories\n");
|
||||
if (res != SPA_RESULT_ENUM_END)
|
||||
printf ("can't enumerate factories: %d\n", res);
|
||||
break;
|
||||
}
|
||||
inspect_factory (factory);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue