mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05: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