v4l2: Add support for setting memory:DMABuf caps

This is the final step to allow negotiation of this caps features. Limiting the
features based on the io-mode shall come next.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7633>
This commit is contained in:
Nicolas Dufresne 2024-08-22 16:08:03 -04:00 committed by GStreamer Marge Bot
parent 58b196d62b
commit 77744c3d63
7 changed files with 306 additions and 178 deletions

View file

@ -449,7 +449,7 @@ gst_v4l2_buffer_pool_alloc_buffer (GstBufferPool * bpool, GstBuffer ** buffer,
GstVideoInfo *info; GstVideoInfo *info;
obj = pool->obj; obj = pool->obj;
info = &obj->info; info = &obj->info.vinfo;
switch (obj->mode) { switch (obj->mode) {
case GST_V4L2_IO_RW: case GST_V4L2_IO_RW:
@ -622,8 +622,8 @@ gst_v4l2_buffer_pool_set_config (GstBufferPool * bpool, GstStructure * config)
} }
/* Always update the config to ensure the configured size matches */ /* Always update the config to ensure the configured size matches */
gst_buffer_pool_config_set_params (config, caps, obj->info.size, min_buffers, gst_buffer_pool_config_set_params (config, caps, obj->info.vinfo.size,
max_buffers); min_buffers, max_buffers);
/* keep a GstVideoInfo with defaults for the when we need to copy */ /* keep a GstVideoInfo with defaults for the when we need to copy */
gst_video_info_from_caps (&pool->caps_info, caps); gst_video_info_from_caps (&pool->caps_info, caps);
@ -1244,7 +1244,7 @@ gst_v4l2_buffer_pool_dqbuf (GstV4l2BufferPool * pool, GstBuffer ** buffer,
GstV4l2Object *obj = pool->obj; GstV4l2Object *obj = pool->obj;
GstClockTime timestamp; GstClockTime timestamp;
GstV4l2MemoryGroup *group; GstV4l2MemoryGroup *group;
const GstVideoInfo *info = &obj->info; const GstVideoInfo *info = &obj->info.vinfo;
gint i; gint i;
gint old_buffer_state; gint old_buffer_state;
@ -1797,7 +1797,7 @@ gst_v4l2_buffer_pool_new (GstV4l2Object * obj, GstCaps * caps)
gst_object_ref (obj->element); gst_object_ref (obj->element);
config = gst_buffer_pool_get_config (GST_BUFFER_POOL_CAST (pool)); config = gst_buffer_pool_get_config (GST_BUFFER_POOL_CAST (pool));
gst_buffer_pool_config_set_params (config, caps, obj->info.size, 0, 0); gst_buffer_pool_config_set_params (config, caps, obj->info.vinfo.size, 0, 0);
/* This will simply set a default config, but will not configure the pool /* This will simply set a default config, but will not configure the pool
* because min and max are not valid */ * because min and max are not valid */
gst_buffer_pool_set_config (GST_BUFFER_POOL_CAST (pool), config); gst_buffer_pool_set_config (GST_BUFFER_POOL_CAST (pool), config);
@ -1827,7 +1827,7 @@ gst_v4l2_do_read (GstV4l2BufferPool * pool, GstBuffer * buf)
GstMapInfo map; GstMapInfo map;
gint toread; gint toread;
toread = obj->info.size; toread = obj->info.vinfo.size;
GST_LOG_OBJECT (pool, "reading %d bytes into buffer %p", toread, buf); GST_LOG_OBJECT (pool, "reading %d bytes into buffer %p", toread, buf);

View file

@ -1443,6 +1443,31 @@ gst_v4l2_object_get_desc_from_video_format (GstVideoFormat format,
return ret; return ret;
} }
static const GstV4L2FormatDesc *
gst_v4l2_object_get_desc_from_drm_fourcc (guint32 drm_fourcc,
guint64 drm_modifier, const GstV4L2FormatDesc ** fallback)
{
const GstV4L2FormatDesc *ret = NULL;
gint i;
if (fallback)
*fallback = NULL;
for (i = 0; i < GST_V4L2_FORMAT_COUNT; i++) {
if (gst_v4l2_formats[i].drm_fourcc == drm_fourcc
&& gst_v4l2_formats[i].drm_modifier == drm_modifier) {
if (!ret)
ret = &gst_v4l2_formats[i];
else if (fallback && !*fallback)
*fallback = &gst_v4l2_formats[i];
else
break;
}
}
return ret;
}
static gboolean static gboolean
gst_v4l2_object_v4l2fourcc_is_codec (guint32 fourcc) gst_v4l2_object_v4l2fourcc_is_codec (guint32 fourcc)
{ {
@ -1642,7 +1667,8 @@ gst_v4l2_object_is_raw (GstV4l2Object * v4l2object)
{ {
gint i; gint i;
if (GST_VIDEO_INFO_FORMAT (&v4l2object->info) != GST_VIDEO_FORMAT_ENCODED) if (GST_VIDEO_INFO_FORMAT (&v4l2object->info.vinfo) !=
GST_VIDEO_FORMAT_ENCODED)
return TRUE; return TRUE;
for (i = 0; i < GST_V4L2_FORMAT_COUNT; i++) { for (i = 0; i < GST_V4L2_FORMAT_COUNT; i++) {
@ -1876,6 +1902,8 @@ gst_v4l2_object_probe_template_caps (const gchar * device, gint video_fd,
} }
/* collect data for the given caps /* collect data for the given caps
* @v4l2object: the associated GstV4l2Object
* @info: the format information as GstVideoInfoDmaDrm
* @caps: given input caps * @caps: given input caps
* @format: location for the v4l format * @format: location for the v4l format
* @w/@h: location for width and height * @w/@h: location for width and height
@ -1884,7 +1912,7 @@ gst_v4l2_object_probe_template_caps (const gchar * device, gint video_fd,
*/ */
static gboolean static gboolean
gst_v4l2_object_get_caps_info (GstV4l2Object * v4l2object, GstCaps * caps, gst_v4l2_object_get_caps_info (GstV4l2Object * v4l2object, GstCaps * caps,
struct v4l2_fmtdesc **format, GstVideoInfo * info) struct v4l2_fmtdesc **format, GstVideoInfoDmaDrm * info)
{ {
GstStructure *structure; GstStructure *structure;
guint32 fourcc = 0, fourcc_nc = 0; guint32 fourcc = 0, fourcc_nc = 0;
@ -1895,13 +1923,27 @@ gst_v4l2_object_get_caps_info (GstV4l2Object * v4l2object, GstCaps * caps,
mimetype = gst_structure_get_name (structure); mimetype = gst_structure_get_name (structure);
if (!gst_video_info_from_caps (info, caps)) if (!gst_video_info_dma_drm_from_caps (info, caps) &&
!gst_video_info_from_caps (&info->vinfo, caps))
goto invalid_format; goto invalid_format;
if (g_str_equal (mimetype, "video/x-raw")) { if (g_str_equal (mimetype, "video/x-raw")) {
const GstV4L2FormatDesc *desc, *fallback_desc; const GstV4L2FormatDesc *desc, *fallback_desc = NULL;
GstVideoFormat format = GST_VIDEO_INFO_FORMAT (info); GstVideoFormat format = GST_VIDEO_INFO_FORMAT (&info->vinfo);
desc = gst_v4l2_object_get_desc_from_video_format (format, &fallback_desc); if (format == GST_VIDEO_FORMAT_DMA_DRM) {
const GstStructure *s = gst_caps_get_structure (caps, 0);
guint64 drm_modifier;
guint32 drm_fourcc =
gst_video_dma_drm_fourcc_from_string (gst_structure_get_string (s,
"drm-format"), &drm_modifier);
/* we can't support single plane fallback with opaque DRM fourcc since we
* don't know how to extrapolate the missing strides and offsets. */
desc = gst_v4l2_object_get_desc_from_drm_fourcc (drm_fourcc, drm_modifier,
NULL);
} else {
desc =
gst_v4l2_object_get_desc_from_video_format (format, &fallback_desc);
}
if (desc) if (desc)
fourcc_nc = desc->v4l2_format; fourcc_nc = desc->v4l2_format;
if (fallback_desc) if (fallback_desc)
@ -3149,11 +3191,12 @@ default_frame_sizes:
if (!v4l2object->skip_try_fmt_probes) { if (!v4l2object->skip_try_fmt_probes) {
gint probed_w, probed_h; gint probed_w, probed_h;
if (v4l2object->info.width >= min_w && v4l2object->info.width <= max_w && if (v4l2object->info.vinfo.width >= min_w &&
v4l2object->info.height >= min_h v4l2object->info.vinfo.width <= max_w &&
&& v4l2object->info.height <= max_h) { v4l2object->info.vinfo.height >= min_h
probed_w = v4l2object->info.width; && v4l2object->info.vinfo.height <= max_h) {
probed_h = v4l2object->info.height; probed_w = v4l2object->info.vinfo.width;
probed_h = v4l2object->info.vinfo.height;
} else { } else {
probed_w = max_w; probed_w = max_w;
probed_h = max_h; probed_h = max_h;
@ -3430,15 +3473,15 @@ gst_v4l2_object_extrapolate_info (GstV4l2Object * v4l2object,
static void static void
gst_v4l2_object_save_format (GstV4l2Object * v4l2object, gst_v4l2_object_save_format (GstV4l2Object * v4l2object,
struct v4l2_fmtdesc *fmtdesc, struct v4l2_format *format, struct v4l2_fmtdesc *fmtdesc, struct v4l2_format *format,
GstVideoInfo * info, GstVideoAlignment * align) GstVideoInfoDmaDrm * info, GstVideoAlignment * align)
{ {
const GstVideoFormatInfo *finfo = info->finfo; const GstVideoFormatInfo *finfo = info->vinfo.finfo;
gboolean standard_stride = TRUE; gboolean standard_stride = TRUE;
gint stride, pstride, padded_width, padded_height, i; gint stride, pstride, padded_width, padded_height, i;
if (GST_VIDEO_INFO_FORMAT (info) == GST_VIDEO_FORMAT_ENCODED) { if (GST_VIDEO_INFO_FORMAT (&info->vinfo) == GST_VIDEO_FORMAT_ENCODED) {
v4l2object->n_v4l2_planes = 1; v4l2object->n_v4l2_planes = 1;
info->size = format->fmt.pix.sizeimage; info->vinfo.size = format->fmt.pix.sizeimage;
goto store_info; goto store_info;
} }
@ -3455,7 +3498,7 @@ gst_v4l2_object_save_format (GstV4l2Object * v4l2object,
/* pstride can be 0 for complex formats */ /* pstride can be 0 for complex formats */
GST_WARNING_OBJECT (v4l2object->dbg_obj, GST_WARNING_OBJECT (v4l2object->dbg_obj,
"format %s has a pstride of 0, cannot compute padded with", "format %s has a pstride of 0, cannot compute padded with",
gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (info))); gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (&info->vinfo)));
padded_width = format->fmt.pix.width; padded_width = format->fmt.pix.width;
} }
@ -3464,7 +3507,7 @@ gst_v4l2_object_save_format (GstV4l2Object * v4l2object,
"Driver bug detected, stride (%d) is too small for the width (%d)", "Driver bug detected, stride (%d) is too small for the width (%d)",
padded_width, format->fmt.pix.width); padded_width, format->fmt.pix.width);
align->padding_right = padded_width - info->width - align->padding_left; align->padding_right = padded_width - info->vinfo.width - align->padding_left;
/* adjust bottom padding */ /* adjust bottom padding */
padded_height = format->fmt.pix.height; padded_height = format->fmt.pix.height;
@ -3477,8 +3520,8 @@ gst_v4l2_object_save_format (GstV4l2Object * v4l2object,
(padded_height + tile_height - 1) / tile_height * tile_height; (padded_height + tile_height - 1) / tile_height * tile_height;
} }
align->padding_bottom = align->padding_bottom = padded_height -
padded_height - GST_VIDEO_INFO_FIELD_HEIGHT (info) - align->padding_top; GST_VIDEO_INFO_FIELD_HEIGHT (&info->vinfo) - align->padding_top;
/* setup the strides and offset */ /* setup the strides and offset */
if (V4L2_TYPE_IS_MULTIPLANAR (v4l2object->type)) { if (V4L2_TYPE_IS_MULTIPLANAR (v4l2object->type)) {
@ -3486,33 +3529,40 @@ gst_v4l2_object_save_format (GstV4l2Object * v4l2object,
/* figure out the frame layout */ /* figure out the frame layout */
v4l2object->n_v4l2_planes = MAX (1, pix_mp->num_planes); v4l2object->n_v4l2_planes = MAX (1, pix_mp->num_planes);
info->size = 0; info->vinfo.size = 0;
for (i = 0; i < v4l2object->n_v4l2_planes; i++) { for (i = 0; i < v4l2object->n_v4l2_planes; i++) {
stride = pix_mp->plane_fmt[i].bytesperline; stride = pix_mp->plane_fmt[i].bytesperline;
if (info->stride[i] != stride) if (info->vinfo.stride[i] != stride)
standard_stride = FALSE; standard_stride = FALSE;
gst_v4l2_object_set_stride (info, align, i, stride); gst_v4l2_object_set_stride (&info->vinfo, align, i, stride);
info->offset[i] = info->size; info->vinfo.offset[i] = info->vinfo.size;
info->size += pix_mp->plane_fmt[i].sizeimage; info->vinfo.size += pix_mp->plane_fmt[i].sizeimage;
} }
/* Extrapolate stride if planar format are being set in 1 v4l2 plane */ /* Extrapolate stride if planar format are being set in 1 v4l2 plane */
if (v4l2object->n_v4l2_planes < finfo->n_planes) { if (v4l2object->n_v4l2_planes < finfo->n_planes) {
/* We should never negotiate single plane variant of formats unless the
* formats is mapped into libgstvideo, otherwise we don't know how to
* guess the missing strides and offsets. If you hit this assertion,
* please remove the mapping from V4L2 to DRM formats. */
g_assert (GST_VIDEO_INFO_FORMAT (&info->vinfo) !=
GST_VIDEO_FORMAT_UNKNOWN);
stride = format->fmt.pix_mp.plane_fmt[0].bytesperline; stride = format->fmt.pix_mp.plane_fmt[0].bytesperline;
gst_v4l2_object_extrapolate_info (v4l2object, info, align, stride); gst_v4l2_object_extrapolate_info (v4l2object, &info->vinfo, align,
stride);
} }
} else { } else {
/* only one plane in non-MPLANE mode */ /* only one plane in non-MPLANE mode */
v4l2object->n_v4l2_planes = 1; v4l2object->n_v4l2_planes = 1;
info->size = format->fmt.pix.sizeimage; info->vinfo.size = format->fmt.pix.sizeimage;
stride = format->fmt.pix.bytesperline; stride = format->fmt.pix.bytesperline;
if (info->stride[0] != stride) if (info->vinfo.stride[0] != stride)
standard_stride = FALSE; standard_stride = FALSE;
gst_v4l2_object_extrapolate_info (v4l2object, info, align, stride); gst_v4l2_object_extrapolate_info (v4l2object, &info->vinfo, align, stride);
} }
/* adjust the offset to take into account left and top */ /* adjust the offset to take into account left and top */
@ -3522,14 +3572,15 @@ gst_v4l2_object_save_format (GstV4l2Object * v4l2object,
"Left and top padding is not permitted for tiled formats"); "Left and top padding is not permitted for tiled formats");
memset (v4l2object->plane_size, 0, sizeof (v4l2object->plane_size)); memset (v4l2object->plane_size, 0, sizeof (v4l2object->plane_size));
} else { } else {
if (!gst_video_info_align_full (info, align, v4l2object->plane_size)) { if (!gst_video_info_align_full (&info->vinfo, align,
v4l2object->plane_size)) {
GST_WARNING_OBJECT (v4l2object->dbg_obj, "Failed to align video info"); GST_WARNING_OBJECT (v4l2object->dbg_obj, "Failed to align video info");
} }
} }
store_info: store_info:
GST_DEBUG_OBJECT (v4l2object->dbg_obj, "Got sizeimage %" G_GSIZE_FORMAT, GST_DEBUG_OBJECT (v4l2object->dbg_obj, "Got sizeimage %" G_GSIZE_FORMAT,
info->size); info->vinfo.size);
/* to avoid copies we need video meta if there is padding */ /* to avoid copies we need video meta if there is padding */
v4l2object->need_video_meta = v4l2object->need_video_meta =
@ -3550,10 +3601,10 @@ store_info:
v4l2object->fmtdesc = fmtdesc; v4l2object->fmtdesc = fmtdesc;
/* if we have a framerate pre-calculate duration */ /* if we have a framerate pre-calculate duration */
if (info->fps_n > 0 && info->fps_d > 0) { if (info->vinfo.fps_n > 0 && info->vinfo.fps_d > 0) {
v4l2object->duration = gst_util_uint64_scale_int (GST_SECOND, info->fps_d, v4l2object->duration = gst_util_uint64_scale_int (GST_SECOND,
info->fps_n); info->vinfo.fps_d, info->vinfo.fps_n);
if (GST_VIDEO_INFO_INTERLACE_MODE (info) == if (GST_VIDEO_INFO_INTERLACE_MODE (&info->vinfo) ==
GST_VIDEO_INTERLACE_MODE_ALTERNATE) GST_VIDEO_INTERLACE_MODE_ALTERNATE)
v4l2object->duration /= 2; v4l2object->duration /= 2;
} else { } else {
@ -3696,7 +3747,7 @@ gst_v4l2_object_set_format_full (GstV4l2Object * v4l2object, GstCaps * caps,
enum v4l2_field field; enum v4l2_field field;
guint32 pixelformat; guint32 pixelformat;
struct v4l2_fmtdesc *fmtdesc; struct v4l2_fmtdesc *fmtdesc;
GstVideoInfo info; GstVideoInfoDmaDrm info;
GstVideoAlignment align; GstVideoAlignment align;
gint width, height, fps_n, fps_d; gint width, height, fps_n, fps_d;
guint pixel_bitdepth = 8; guint pixel_bitdepth = 8;
@ -3720,7 +3771,7 @@ gst_v4l2_object_set_format_full (GstV4l2Object * v4l2object, GstCaps * caps,
is_mplane = V4L2_TYPE_IS_MULTIPLANAR (v4l2object->type); is_mplane = V4L2_TYPE_IS_MULTIPLANAR (v4l2object->type);
gst_video_info_init (&info); gst_video_info_dma_drm_init (&info);
gst_video_alignment_reset (&align); gst_video_alignment_reset (&align);
v4l2object->transfer = GST_VIDEO_TRANSFER_UNKNOWN; v4l2object->transfer = GST_VIDEO_TRANSFER_UNKNOWN;
v4l2object->matrix = GST_VIDEO_COLOR_MATRIX_UNKNOWN; v4l2object->matrix = GST_VIDEO_COLOR_MATRIX_UNKNOWN;
@ -3729,35 +3780,43 @@ gst_v4l2_object_set_format_full (GstV4l2Object * v4l2object, GstCaps * caps,
goto invalid_caps; goto invalid_caps;
pixelformat = fmtdesc->pixelformat; pixelformat = fmtdesc->pixelformat;
width = GST_VIDEO_INFO_WIDTH (&info); width = GST_VIDEO_INFO_WIDTH (&info.vinfo);
height = GST_VIDEO_INFO_FIELD_HEIGHT (&info); height = GST_VIDEO_INFO_FIELD_HEIGHT (&info.vinfo);
/* if caps has no width and height info, use default value */ /* if caps has no width and height info, use default value */
if (V4L2_TYPE_IS_OUTPUT (v4l2object->type) && width == 0 && height == 0) { if (V4L2_TYPE_IS_OUTPUT (v4l2object->type) && width == 0 && height == 0) {
width = GST_V4L2_DEFAULT_WIDTH; width = GST_V4L2_DEFAULT_WIDTH;
height = GST_V4L2_DEFAULT_HEIGHT; height = GST_V4L2_DEFAULT_HEIGHT;
} }
fps_n = GST_VIDEO_INFO_FPS_N (&info); fps_n = GST_VIDEO_INFO_FPS_N (&info.vinfo);
fps_d = GST_VIDEO_INFO_FPS_D (&info); fps_d = GST_VIDEO_INFO_FPS_D (&info.vinfo);
/* if encoded format (GST_VIDEO_INFO_N_PLANES return 0) n_v4l_planes = GST_VIDEO_INFO_N_PLANES (&info.vinfo);
* or if contiguous is preferred */ if (!n_v4l_planes) {
n_v4l_planes = GST_VIDEO_INFO_N_PLANES (&info); /* For opaque DRM format we let the driver tell us how many planes
if (!n_v4l_planes || !v4l2object->prefered_non_contiguous) * otherwise its an encoded format and we will have 1 plane */
if (GST_VIDEO_INFO_FORMAT (&info.vinfo) == GST_VIDEO_FORMAT_DMA_DRM)
n_v4l_planes = GST_VIDEO_MAX_PLANES;
else
n_v4l_planes = 1;
}
/* If our preference is single plane, then set te number of plane to 1 */
if (!v4l2object->prefered_non_contiguous)
n_v4l_planes = 1; n_v4l_planes = 1;
field = get_v4l2_field_for_info (&info); field = get_v4l2_field_for_info (&info.vinfo);
if (field != V4L2_FIELD_NONE) if (field != V4L2_FIELD_NONE)
GST_DEBUG_OBJECT (v4l2object->dbg_obj, "interlaced video"); GST_DEBUG_OBJECT (v4l2object->dbg_obj, "interlaced video");
else else
GST_DEBUG_OBJECT (v4l2object->dbg_obj, "progressive video"); GST_DEBUG_OBJECT (v4l2object->dbg_obj, "progressive video");
/* We first pick the main colorspace from the primaries */ /* We first pick the main colorspace from the primaries */
switch (info.colorimetry.primaries) { switch (info.vinfo.colorimetry.primaries) {
case GST_VIDEO_COLOR_PRIMARIES_BT709: case GST_VIDEO_COLOR_PRIMARIES_BT709:
/* There is three colorspaces using these primaries, use the range /* There is three colorspaces using these primaries, use the range
* and format type to differentiate them */ * and format type to differentiate them */
if (info.colorimetry.range == GST_VIDEO_COLOR_RANGE_16_235) { if (info.vinfo.colorimetry.range == GST_VIDEO_COLOR_RANGE_16_235) {
if (GST_VIDEO_INFO_IS_RGB (&info)) if (GST_VIDEO_INFO_IS_RGB (&info.vinfo))
colorspace = V4L2_COLORSPACE_SRGB; colorspace = V4L2_COLORSPACE_SRGB;
else else
colorspace = V4L2_COLORSPACE_REC709; colorspace = V4L2_COLORSPACE_REC709;
@ -3788,11 +3847,11 @@ gst_v4l2_object_set_format_full (GstV4l2Object * v4l2object, GstCaps * caps,
default: default:
GST_WARNING_OBJECT (v4l2object->dbg_obj, GST_WARNING_OBJECT (v4l2object->dbg_obj,
"Unknown colorimetry primaries %d", info.colorimetry.primaries); "Unknown colorimetry primaries %d", info.vinfo.colorimetry.primaries);
break; break;
} }
switch (info.colorimetry.range) { switch (info.vinfo.colorimetry.range) {
case GST_VIDEO_COLOR_RANGE_0_255: case GST_VIDEO_COLOR_RANGE_0_255:
range = V4L2_QUANTIZATION_FULL_RANGE; range = V4L2_QUANTIZATION_FULL_RANGE;
break; break;
@ -3804,11 +3863,11 @@ gst_v4l2_object_set_format_full (GstV4l2Object * v4l2object, GstCaps * caps,
break; break;
default: default:
GST_WARNING_OBJECT (v4l2object->dbg_obj, GST_WARNING_OBJECT (v4l2object->dbg_obj,
"Unknown colorimetry range %d", info.colorimetry.range); "Unknown colorimetry range %d", info.vinfo.colorimetry.range);
break; break;
} }
switch (info.colorimetry.matrix) { switch (info.vinfo.colorimetry.matrix) {
case GST_VIDEO_COLOR_MATRIX_RGB: case GST_VIDEO_COLOR_MATRIX_RGB:
/* save the matrix so we can restore it on get() call from default */ /* save the matrix so we can restore it on get() call from default */
v4l2object->matrix = GST_VIDEO_COLOR_MATRIX_RGB; v4l2object->matrix = GST_VIDEO_COLOR_MATRIX_RGB;
@ -3833,11 +3892,11 @@ gst_v4l2_object_set_format_full (GstV4l2Object * v4l2object, GstCaps * caps,
break; break;
default: default:
GST_WARNING_OBJECT (v4l2object->dbg_obj, GST_WARNING_OBJECT (v4l2object->dbg_obj,
"Unknown colorimetry matrix %d", info.colorimetry.matrix); "Unknown colorimetry matrix %d", info.vinfo.colorimetry.matrix);
break; break;
} }
switch (info.colorimetry.transfer) { switch (info.vinfo.colorimetry.transfer) {
case GST_VIDEO_TRANSFER_GAMMA18: case GST_VIDEO_TRANSFER_GAMMA18:
case GST_VIDEO_TRANSFER_GAMMA20: case GST_VIDEO_TRANSFER_GAMMA20:
case GST_VIDEO_TRANSFER_GAMMA22: case GST_VIDEO_TRANSFER_GAMMA22:
@ -3855,7 +3914,7 @@ gst_v4l2_object_set_format_full (GstV4l2Object * v4l2object, GstCaps * caps,
case GST_VIDEO_TRANSFER_BT2020_12: case GST_VIDEO_TRANSFER_BT2020_12:
case GST_VIDEO_TRANSFER_BT2020_10: case GST_VIDEO_TRANSFER_BT2020_10:
case GST_VIDEO_TRANSFER_BT709: case GST_VIDEO_TRANSFER_BT709:
v4l2object->transfer = info.colorimetry.transfer; v4l2object->transfer = info.vinfo.colorimetry.transfer;
transfer = V4L2_XFER_FUNC_709; transfer = V4L2_XFER_FUNC_709;
break; break;
case GST_VIDEO_TRANSFER_SMPTE240M: case GST_VIDEO_TRANSFER_SMPTE240M:
@ -3875,13 +3934,13 @@ gst_v4l2_object_set_format_full (GstV4l2Object * v4l2object, GstCaps * caps,
break; break;
default: default:
GST_WARNING_OBJECT (v4l2object->dbg_obj, GST_WARNING_OBJECT (v4l2object->dbg_obj,
"Unknown colorimetry transfer %d", info.colorimetry.transfer); "Unknown colorimetry transfer %d", info.vinfo.colorimetry.transfer);
break; break;
} }
if (colorspace == 0) { if (colorspace == 0) {
/* Try to guess colorspace according to pixelformat and size */ /* Try to guess colorspace according to pixelformat and size */
if (GST_VIDEO_INFO_IS_YUV (&info)) { if (GST_VIDEO_INFO_IS_YUV (&info.vinfo)) {
if (range == V4L2_QUANTIZATION_FULL_RANGE if (range == V4L2_QUANTIZATION_FULL_RANGE
&& matrix == V4L2_YCBCR_ENC_601 && transfer == 0) { && matrix == V4L2_YCBCR_ENC_601 && transfer == 0) {
/* Full range BT.601 YCbCr encoding with unknown primaries and transfer /* Full range BT.601 YCbCr encoding with unknown primaries and transfer
@ -3890,12 +3949,12 @@ gst_v4l2_object_set_format_full (GstV4l2Object * v4l2object, GstCaps * caps,
transfer = V4L2_XFER_FUNC_SRGB; transfer = V4L2_XFER_FUNC_SRGB;
} else { } else {
/* SD streams likely use SMPTE170M and HD streams REC709 */ /* SD streams likely use SMPTE170M and HD streams REC709 */
if (width <= 720 && GST_VIDEO_INFO_HEIGHT (&info) <= 576) if (width <= 720 && GST_VIDEO_INFO_HEIGHT (&info.vinfo) <= 576)
colorspace = V4L2_COLORSPACE_SMPTE170M; colorspace = V4L2_COLORSPACE_SMPTE170M;
else else
colorspace = V4L2_COLORSPACE_REC709; colorspace = V4L2_COLORSPACE_REC709;
} }
} else if (GST_VIDEO_INFO_IS_RGB (&info)) { } else if (GST_VIDEO_INFO_IS_RGB (&info.vinfo)) {
colorspace = V4L2_COLORSPACE_SRGB; colorspace = V4L2_COLORSPACE_SRGB;
transfer = V4L2_XFER_FUNC_NONE; transfer = V4L2_XFER_FUNC_NONE;
} }
@ -3903,7 +3962,8 @@ gst_v4l2_object_set_format_full (GstV4l2Object * v4l2object, GstCaps * caps,
GST_DEBUG_OBJECT (v4l2object->dbg_obj, "Desired format %dx%d, format " GST_DEBUG_OBJECT (v4l2object->dbg_obj, "Desired format %dx%d, format "
"%" GST_FOURCC_FORMAT " stride: %d", width, height, "%" GST_FOURCC_FORMAT " stride: %d", width, height,
GST_FOURCC_ARGS (pixelformat), GST_VIDEO_INFO_PLANE_STRIDE (&info, 0)); GST_FOURCC_ARGS (pixelformat),
GST_VIDEO_INFO_PLANE_STRIDE (&info.vinfo, 0));
s = gst_caps_get_structure (caps, 0); s = gst_caps_get_structure (caps, 0);
@ -3927,20 +3987,20 @@ gst_v4l2_object_set_format_full (GstV4l2Object * v4l2object, GstCaps * caps,
/* try to ask our preferred stride but it's not a failure if not /* try to ask our preferred stride but it's not a failure if not
* accepted */ * accepted */
for (i = 0; i < n_v4l_planes; i++) { for (i = 0; i < n_v4l_planes; i++) {
gint stride = GST_VIDEO_INFO_PLANE_STRIDE (&info, i); gint stride = GST_VIDEO_INFO_PLANE_STRIDE (&info.vinfo, i);
if (GST_VIDEO_FORMAT_INFO_IS_TILED (info.finfo)) if (GST_VIDEO_FORMAT_INFO_IS_TILED (info.vinfo.finfo))
stride = GST_VIDEO_TILE_X_TILES (stride) * stride = GST_VIDEO_TILE_X_TILES (stride) *
GST_VIDEO_FORMAT_INFO_TILE_STRIDE (info.finfo, i); GST_VIDEO_FORMAT_INFO_TILE_STRIDE (info.vinfo.finfo, i);
format.fmt.pix_mp.plane_fmt[i].bytesperline = stride; format.fmt.pix_mp.plane_fmt[i].bytesperline = stride;
} }
if (GST_VIDEO_INFO_FORMAT (&info) == GST_VIDEO_FORMAT_ENCODED) if (GST_VIDEO_INFO_FORMAT (&info.vinfo) == GST_VIDEO_FORMAT_ENCODED)
format.fmt.pix_mp.plane_fmt[0].sizeimage = format.fmt.pix_mp.plane_fmt[0].sizeimage =
calculate_max_sizeimage (v4l2object, pixel_bitdepth); calculate_max_sizeimage (v4l2object, pixel_bitdepth);
} else { } else {
gint stride = GST_VIDEO_INFO_PLANE_STRIDE (&info, 0); gint stride = GST_VIDEO_INFO_PLANE_STRIDE (&info.vinfo, 0);
format.type = v4l2object->type; format.type = v4l2object->type;
@ -3949,14 +4009,14 @@ gst_v4l2_object_set_format_full (GstV4l2Object * v4l2object, GstCaps * caps,
format.fmt.pix.pixelformat = pixelformat; format.fmt.pix.pixelformat = pixelformat;
format.fmt.pix.field = field; format.fmt.pix.field = field;
if (GST_VIDEO_FORMAT_INFO_IS_TILED (info.finfo)) if (GST_VIDEO_FORMAT_INFO_IS_TILED (info.vinfo.finfo))
stride = GST_VIDEO_TILE_X_TILES (stride) * stride = GST_VIDEO_TILE_X_TILES (stride) *
GST_VIDEO_FORMAT_INFO_TILE_STRIDE (info.finfo, i); GST_VIDEO_FORMAT_INFO_TILE_STRIDE (info.vinfo.finfo, i);
/* try to ask our preferred stride */ /* try to ask our preferred stride */
format.fmt.pix.bytesperline = stride; format.fmt.pix.bytesperline = stride;
if (GST_VIDEO_INFO_FORMAT (&info) == GST_VIDEO_FORMAT_ENCODED) if (GST_VIDEO_INFO_FORMAT (&info.vinfo) == GST_VIDEO_FORMAT_ENCODED)
format.fmt.pix.sizeimage = format.fmt.pix.sizeimage =
calculate_max_sizeimage (v4l2object, pixel_bitdepth); calculate_max_sizeimage (v4l2object, pixel_bitdepth);
} }
@ -4139,7 +4199,7 @@ gst_v4l2_object_set_format_full (GstV4l2Object * v4l2object, GstCaps * caps,
* For some codecs the dimensions are *not* in the bitstream, IIRC VC1 * For some codecs the dimensions are *not* in the bitstream, IIRC VC1
* in ASF mode for example, there is also not reason for a driver to * in ASF mode for example, there is also not reason for a driver to
* change the size. */ * change the size. */
if (info.finfo->format != GST_VIDEO_FORMAT_ENCODED) { if (GST_VIDEO_INFO_FORMAT (&info.vinfo) != GST_VIDEO_FORMAT_ENCODED) {
/* We can crop larger images */ /* We can crop larger images */
if (format.fmt.pix.width < width || format.fmt.pix.height < height) if (format.fmt.pix.width < width || format.fmt.pix.height < height)
goto invalid_dimensions; goto invalid_dimensions;
@ -4156,7 +4216,7 @@ gst_v4l2_object_set_format_full (GstV4l2Object * v4l2object, GstCaps * caps,
/* used to check colorimetry and interlace mode fields presence */ /* used to check colorimetry and interlace mode fields presence */
if (gst_v4l2_object_get_interlace_mode (format.fmt.pix.field, if (gst_v4l2_object_get_interlace_mode (format.fmt.pix.field,
&info.interlace_mode)) { &info.vinfo.interlace_mode)) {
if (gst_structure_has_field (s, "interlace-mode")) { if (gst_structure_has_field (s, "interlace-mode")) {
if (format.fmt.pix.field != field) if (format.fmt.pix.field != field)
goto invalid_field; goto invalid_field;
@ -4169,9 +4229,10 @@ gst_v4l2_object_set_format_full (GstV4l2Object * v4l2object, GstCaps * caps,
gst_structure_remove_field (s, "interlace-mode"); gst_structure_remove_field (s, "interlace-mode");
} }
if (gst_v4l2_object_get_colorspace (v4l2object, &format, &info.colorimetry)) { if (gst_v4l2_object_get_colorspace (v4l2object, &format,
&info.vinfo.colorimetry)) {
if (gst_structure_has_field (s, "colorimetry")) { if (gst_structure_has_field (s, "colorimetry")) {
if (!gst_v4l2_video_colorimetry_matches (&info.colorimetry, caps)) if (!gst_v4l2_video_colorimetry_matches (&info.vinfo.colorimetry, caps))
goto invalid_colorimetry; goto invalid_colorimetry;
} }
} else { } else {
@ -4187,10 +4248,10 @@ gst_v4l2_object_set_format_full (GstV4l2Object * v4l2object, GstCaps * caps,
if (v4l2object->skip_try_fmt_probes) { if (v4l2object->skip_try_fmt_probes) {
if (!disable_interlacing && !gst_structure_has_field (s, "interlace-mode")) { if (!disable_interlacing && !gst_structure_has_field (s, "interlace-mode")) {
gst_structure_set (s, "interlace-mode", G_TYPE_STRING, gst_structure_set (s, "interlace-mode", G_TYPE_STRING,
gst_video_interlace_mode_to_string (info.interlace_mode), NULL); gst_video_interlace_mode_to_string (info.vinfo.interlace_mode), NULL);
} }
if (!disable_colorimetry && !gst_structure_has_field (s, "colorimetry")) { if (!disable_colorimetry && !gst_structure_has_field (s, "colorimetry")) {
gchar *str = gst_video_colorimetry_to_string (&info.colorimetry); gchar *str = gst_video_colorimetry_to_string (&info.vinfo.colorimetry);
gst_structure_set (s, "colorimetry", G_TYPE_STRING, str, NULL); gst_structure_set (s, "colorimetry", G_TYPE_STRING, str, NULL);
g_free (str); g_free (str);
} }
@ -4281,7 +4342,7 @@ gst_v4l2_object_set_format_full (GstV4l2Object * v4l2object, GstCaps * caps,
if (try_only) /* good enough for trying only */ if (try_only) /* good enough for trying only */
return TRUE; return TRUE;
if (GST_VIDEO_INFO_HAS_ALPHA (&info)) { if (GST_VIDEO_INFO_HAS_ALPHA (&info.vinfo)) {
struct v4l2_control ctl = { 0, }; struct v4l2_control ctl = { 0, };
ctl.id = V4L2_CID_ALPHA_COMPONENT; ctl.id = V4L2_CID_ALPHA_COMPONENT;
ctl.value = 0xff; ctl.value = 0xff;
@ -4303,9 +4364,9 @@ gst_v4l2_object_set_format_full (GstV4l2Object * v4l2object, GstCaps * caps,
if (v4l2object->type == V4L2_BUF_TYPE_VIDEO_CAPTURE if (v4l2object->type == V4L2_BUF_TYPE_VIDEO_CAPTURE
|| v4l2object->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { || v4l2object->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
GST_VIDEO_INFO_FPS_N (&info) = GST_VIDEO_INFO_FPS_N (&info.vinfo) =
streamparm.parm.capture.timeperframe.denominator; streamparm.parm.capture.timeperframe.denominator;
GST_VIDEO_INFO_FPS_D (&info) = GST_VIDEO_INFO_FPS_D (&info.vinfo) =
streamparm.parm.capture.timeperframe.numerator; streamparm.parm.capture.timeperframe.numerator;
GST_DEBUG_OBJECT (v4l2object->dbg_obj, "Got capture framerate: %u/%u", GST_DEBUG_OBJECT (v4l2object->dbg_obj, "Got capture framerate: %u/%u",
@ -4374,13 +4435,13 @@ gst_v4l2_object_set_format_full (GstV4l2Object * v4l2object, GstCaps * caps,
"Reuse caps framerate %u/%u - fix v4l2 capture driver", fps_n, fps_d); "Reuse caps framerate %u/%u - fix v4l2 capture driver", fps_n, fps_d);
} }
GST_VIDEO_INFO_FPS_N (&info) = fps_n; GST_VIDEO_INFO_FPS_N (&info.vinfo) = fps_n;
GST_VIDEO_INFO_FPS_D (&info) = fps_d; GST_VIDEO_INFO_FPS_D (&info.vinfo) = fps_d;
} else if (v4l2object->type == V4L2_BUF_TYPE_VIDEO_OUTPUT } else if (v4l2object->type == V4L2_BUF_TYPE_VIDEO_OUTPUT
|| v4l2object->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) { || v4l2object->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
GST_VIDEO_INFO_FPS_N (&info) = GST_VIDEO_INFO_FPS_N (&info.vinfo) =
streamparm.parm.output.timeperframe.denominator; streamparm.parm.output.timeperframe.denominator;
GST_VIDEO_INFO_FPS_D (&info) = GST_VIDEO_INFO_FPS_D (&info.vinfo) =
streamparm.parm.output.timeperframe.numerator; streamparm.parm.output.timeperframe.numerator;
GST_DEBUG_OBJECT (v4l2object->dbg_obj, "Got output framerate: %u/%u", GST_DEBUG_OBJECT (v4l2object->dbg_obj, "Got output framerate: %u/%u",
@ -4426,8 +4487,8 @@ gst_v4l2_object_set_format_full (GstV4l2Object * v4l2object, GstCaps * caps,
"Reuse caps framerate %u/%u - fix v4l2 output driver", fps_n, fps_d); "Reuse caps framerate %u/%u - fix v4l2 output driver", fps_n, fps_d);
} }
GST_VIDEO_INFO_FPS_N (&info) = fps_n; GST_VIDEO_INFO_FPS_N (&info.vinfo) = fps_n;
GST_VIDEO_INFO_FPS_D (&info) = fps_d; GST_VIDEO_INFO_FPS_D (&info.vinfo) = fps_d;
} }
done: done:
@ -4544,7 +4605,8 @@ invalid_colorimetry:
{ {
gchar *wanted_colorimetry; gchar *wanted_colorimetry;
wanted_colorimetry = gst_video_colorimetry_to_string (&info.colorimetry); wanted_colorimetry =
gst_video_colorimetry_to_string (&info.vinfo.colorimetry);
GST_V4L2_ERROR (error, RESOURCE, SETTINGS, GST_V4L2_ERROR (error, RESOURCE, SETTINGS,
(_("Device '%s' does not support %s colorimetry"), (_("Device '%s' does not support %s colorimetry"),
@ -4607,7 +4669,8 @@ gst_v4l2_object_try_format (GstV4l2Object * v4l2object, GstCaps * caps,
* Returns: %TRUE on success, %FALSE on failure. * Returns: %TRUE on success, %FALSE on failure.
*/ */
gboolean gboolean
gst_v4l2_object_acquire_format (GstV4l2Object * v4l2object, GstVideoInfo * info) gst_v4l2_object_acquire_format (GstV4l2Object * v4l2object,
GstVideoInfoDmaDrm * info)
{ {
struct v4l2_fmtdesc *fmtdesc; struct v4l2_fmtdesc *fmtdesc;
struct v4l2_format fmt; struct v4l2_format fmt;
@ -4618,8 +4681,9 @@ gst_v4l2_object_acquire_format (GstV4l2Object * v4l2object, GstVideoInfo * info)
guint width, height; guint width, height;
GstVideoAlignment align; GstVideoAlignment align;
GstVideoInterlaceMode interlace_mode; GstVideoInterlaceMode interlace_mode;
const GstV4L2FormatDesc *desc;
gst_video_info_init (info); gst_video_info_dma_drm_init (info);
gst_video_alignment_reset (&align); gst_video_alignment_reset (&align);
v4l2object->transfer = GST_VIDEO_TRANSFER_UNKNOWN; v4l2object->transfer = GST_VIDEO_TRANSFER_UNKNOWN;
v4l2object->matrix = GST_VIDEO_COLOR_MATRIX_UNKNOWN; v4l2object->matrix = GST_VIDEO_COLOR_MATRIX_UNKNOWN;
@ -4635,12 +4699,18 @@ gst_v4l2_object_acquire_format (GstV4l2Object * v4l2object, GstVideoInfo * info)
goto unsupported_format; goto unsupported_format;
/* No need to care about mplane, the four first params are the same */ /* No need to care about mplane, the four first params are the same */
format = gst_v4l2_object_v4l2fourcc_to_video_format (fmt.fmt.pix.pixelformat); desc = gst_v4l2_object_get_desc_from_v4l2fourcc (fmt.fmt.pix.pixelformat);
if (!desc)
/* fails if we do no translate the fmt.pix.pixelformat to GstVideoFormat */
if (format == GST_VIDEO_FORMAT_UNKNOWN)
goto unsupported_format; goto unsupported_format;
if (desc->gst_format == GST_VIDEO_FORMAT_UNKNOWN) {
if (!desc->drm_fourcc)
goto unsupported_format;
format = GST_VIDEO_FORMAT_DMA_DRM;
} else {
format = desc->gst_format;
}
if (fmt.fmt.pix.width == 0 || fmt.fmt.pix.height == 0) if (fmt.fmt.pix.width == 0 || fmt.fmt.pix.height == 0)
goto invalid_dimensions; goto invalid_dimensions;
@ -4686,19 +4756,22 @@ gst_v4l2_object_acquire_format (GstV4l2Object * v4l2object, GstVideoInfo * info)
goto unsupported_field; goto unsupported_field;
} }
if (!gst_video_info_set_interlaced_format (info, format, interlace_mode, info->drm_fourcc = desc->drm_fourcc;
width, height)) info->drm_modifier = desc->drm_modifier;
if (!gst_video_info_set_interlaced_format (&info->vinfo, format,
interlace_mode, width, height))
goto invalid_dimensions; goto invalid_dimensions;
gst_v4l2_object_get_colorspace (v4l2object, &fmt, &info->colorimetry); gst_v4l2_object_get_colorspace (v4l2object, &fmt, &info->vinfo.colorimetry);
gst_v4l2_object_get_streamparm (v4l2object, info); gst_v4l2_object_get_streamparm (v4l2object, &info->vinfo);
if ((info->fps_n == 0 && v4l2object->info.fps_d != 0) if ((info->vinfo.fps_n == 0 && GST_V4L2_FPS_D (v4l2object) != 0)
&& (v4l2object->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && (v4l2object->type == V4L2_BUF_TYPE_VIDEO_CAPTURE
|| v4l2object->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)) { || v4l2object->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)) {
info->fps_d = v4l2object->info.fps_d; info->vinfo.fps_d = GST_V4L2_FPS_D (v4l2object);
info->fps_n = v4l2object->info.fps_n; info->vinfo.fps_n = GST_V4L2_FPS_N (v4l2object);
GST_DEBUG_OBJECT (v4l2object->dbg_obj, "Set capture fps to %d/%d", GST_DEBUG_OBJECT (v4l2object->dbg_obj, "Set capture fps to %d/%d",
info->fps_n, info->fps_d); info->vinfo.fps_n, info->vinfo.fps_d);
} }
gst_v4l2_object_save_format (v4l2object, fmtdesc, &fmt, info, &align); gst_v4l2_object_save_format (v4l2object, fmtdesc, &fmt, info, &align);
@ -4886,8 +4959,8 @@ gst_v4l2_object_setup_padding (GstV4l2Object * obj)
rect.left = align->padding_left; rect.left = align->padding_left;
rect.top = align->padding_top; rect.top = align->padding_top;
rect.width = obj->info.width; rect.width = GST_V4L2_WIDTH (obj);
rect.height = GST_VIDEO_INFO_FIELD_HEIGHT (&obj->info); rect.height = GST_V4L2_FIELD_HEIGHT (obj);
if (V4L2_TYPE_IS_OUTPUT (obj->type)) { if (V4L2_TYPE_IS_OUTPUT (obj->type)) {
return gst_v4l2_object_set_crop (obj, &rect); return gst_v4l2_object_set_crop (obj, &rect);
@ -5309,39 +5382,40 @@ gst_v4l2_object_match_buffer_layout (GstV4l2Object * obj, guint n_planes,
gsize offset[GST_VIDEO_MAX_PLANES], gint stride[GST_VIDEO_MAX_PLANES], gsize offset[GST_VIDEO_MAX_PLANES], gint stride[GST_VIDEO_MAX_PLANES],
gsize buffer_size, guint padded_height) gsize buffer_size, guint padded_height)
{ {
guint p;
gboolean need_fmt_update = FALSE; gboolean need_fmt_update = FALSE;
GstVideoInfo *info = &obj->info.vinfo;
guint p;
if (n_planes != GST_VIDEO_INFO_N_PLANES (&obj->info)) { if (n_planes != GST_V4L2_N_PLANES (obj)) {
GST_WARNING_OBJECT (obj->dbg_obj, GST_WARNING_OBJECT (obj->dbg_obj,
"Cannot match buffers with different number planes"); "Cannot match buffers with different number planes");
return FALSE; return FALSE;
} }
for (p = 0; p < n_planes; p++) { for (p = 0; p < n_planes; p++) {
if (stride[p] < obj->info.stride[p]) { if (stride[p] < info->stride[p]) {
GST_DEBUG_OBJECT (obj->dbg_obj, GST_DEBUG_OBJECT (obj->dbg_obj,
"Not matching as remote stride %i is smaller than %i on plane %u", "Not matching as remote stride %i is smaller than %i on plane %u",
stride[p], obj->info.stride[p], p); stride[p], info->stride[p], p);
return FALSE; return FALSE;
} else if (stride[p] > obj->info.stride[p]) { } else if (stride[p] > info->stride[p]) {
GST_LOG_OBJECT (obj->dbg_obj, GST_LOG_OBJECT (obj->dbg_obj,
"Remote stride %i is higher than %i on plane %u", "Remote stride %i is higher than %i on plane %u",
stride[p], obj->info.stride[p], p); stride[p], info->stride[p], p);
need_fmt_update = TRUE; need_fmt_update = TRUE;
} }
if (offset[p] < obj->info.offset[p]) { if (offset[p] < info->offset[p]) {
GST_DEBUG_OBJECT (obj->dbg_obj, GST_DEBUG_OBJECT (obj->dbg_obj,
"Not matching as offset %" G_GSIZE_FORMAT "Not matching as offset %" G_GSIZE_FORMAT
" is smaller than %" G_GSIZE_FORMAT " on plane %u", " is smaller than %" G_GSIZE_FORMAT " on plane %u",
offset[p], obj->info.offset[p], p); offset[p], info->offset[p], p);
return FALSE; return FALSE;
} else if (offset[p] > obj->info.offset[p]) { } else if (offset[p] > info->offset[p]) {
GST_LOG_OBJECT (obj->dbg_obj, GST_LOG_OBJECT (obj->dbg_obj,
"Remote offset %" G_GSIZE_FORMAT "Remote offset %" G_GSIZE_FORMAT
" is higher than %" G_GSIZE_FORMAT " on plane %u", " is higher than %" G_GSIZE_FORMAT " on plane %u",
offset[p], obj->info.offset[p], p); offset[p], info->offset[p], p);
need_fmt_update = TRUE; need_fmt_update = TRUE;
} }
} }
@ -5372,7 +5446,7 @@ gst_v4l2_object_match_buffer_layout (GstV4l2Object * obj, guint n_planes,
GST_DEBUG_OBJECT (obj->dbg_obj, "Padded height %u", padded_height); GST_DEBUG_OBJECT (obj->dbg_obj, "Padded height %u", padded_height);
obj->align.padding_bottom = obj->align.padding_bottom =
padded_height - GST_VIDEO_INFO_FIELD_HEIGHT (&obj->info); padded_height - GST_VIDEO_INFO_FIELD_HEIGHT (info);
} else { } else {
GST_WARNING_OBJECT (obj->dbg_obj, GST_WARNING_OBJECT (obj->dbg_obj,
"Failed to compute padded height; keep the default one"); "Failed to compute padded height; keep the default one");
@ -5388,9 +5462,9 @@ gst_v4l2_object_match_buffer_layout (GstV4l2Object * obj, guint n_planes,
for (i = 0; i < obj->n_v4l2_planes; i++) { for (i = 0; i < obj->n_v4l2_planes; i++) {
gint plane_stride = stride[i]; gint plane_stride = stride[i];
if (GST_VIDEO_FORMAT_INFO_IS_TILED (obj->info.finfo)) if (GST_VIDEO_FORMAT_INFO_IS_TILED (info->finfo))
plane_stride = GST_VIDEO_TILE_X_TILES (plane_stride) * plane_stride = GST_VIDEO_TILE_X_TILES (plane_stride) *
GST_VIDEO_FORMAT_INFO_TILE_STRIDE (obj->info.finfo, i); GST_VIDEO_FORMAT_INFO_TILE_STRIDE (info->finfo, i);
format.fmt.pix_mp.plane_fmt[i].bytesperline = plane_stride; format.fmt.pix_mp.plane_fmt[i].bytesperline = plane_stride;
wanted_stride[i] = plane_stride; wanted_stride[i] = plane_stride;
@ -5403,9 +5477,9 @@ gst_v4l2_object_match_buffer_layout (GstV4l2Object * obj, guint n_planes,
GST_DEBUG_OBJECT (obj->dbg_obj, "Wanted stride: %i", plane_stride); GST_DEBUG_OBJECT (obj->dbg_obj, "Wanted stride: %i", plane_stride);
if (GST_VIDEO_FORMAT_INFO_IS_TILED (obj->info.finfo)) if (GST_VIDEO_FORMAT_INFO_IS_TILED (info->finfo))
plane_stride = GST_VIDEO_TILE_X_TILES (plane_stride) * plane_stride = GST_VIDEO_TILE_X_TILES (plane_stride) *
GST_VIDEO_FORMAT_INFO_TILE_STRIDE (obj->info.finfo, 0); GST_VIDEO_FORMAT_INFO_TILE_STRIDE (info->finfo, 0);
format.fmt.pix.bytesperline = plane_stride; format.fmt.pix.bytesperline = plane_stride;
format.fmt.pix.height = padded_height; format.fmt.pix.height = padded_height;
@ -5620,13 +5694,13 @@ gst_v4l2_object_decide_allocation (GstV4l2Object * obj, GstQuery * query)
/* use the bigest size, when we use our own pool we can't really do any /* use the bigest size, when we use our own pool we can't really do any
* other size than what the hardware gives us but for downstream pools * other size than what the hardware gives us but for downstream pools
* we can try */ * we can try */
size = MAX (size, obj->info.size); size = MAX (size, GST_V4L2_SIZE (obj));
} else if (can_share_own_pool) { } else if (can_share_own_pool) {
/* no downstream pool, use our own then */ /* no downstream pool, use our own then */
GST_DEBUG_OBJECT (obj->dbg_obj, GST_DEBUG_OBJECT (obj->dbg_obj,
"read/write mode: no downstream pool, using our own"); "read/write mode: no downstream pool, using our own");
pool = gst_object_ref (obj_pool); pool = gst_object_ref (obj_pool);
size = obj->info.size; size = GST_V4L2_SIZE (obj);
pushing_from_our_pool = TRUE; pushing_from_our_pool = TRUE;
} }
break; break;
@ -5642,7 +5716,7 @@ gst_v4l2_object_decide_allocation (GstV4l2Object * obj, GstQuery * query)
other_pool = pool; other_pool = pool;
gst_object_unref (pool); gst_object_unref (pool);
pool = gst_object_ref (obj_pool); pool = gst_object_ref (obj_pool);
size = obj->info.size; size = GST_V4L2_SIZE (obj);
break; break;
case GST_V4L2_IO_MMAP: case GST_V4L2_IO_MMAP:
@ -5653,7 +5727,7 @@ gst_v4l2_object_decide_allocation (GstV4l2Object * obj, GstQuery * query)
if (pool) if (pool)
gst_object_unref (pool); gst_object_unref (pool);
pool = gst_object_ref (obj_pool); pool = gst_object_ref (obj_pool);
size = obj->info.size; size = GST_V4L2_SIZE (obj);
GST_DEBUG_OBJECT (obj->dbg_obj, GST_DEBUG_OBJECT (obj->dbg_obj,
"streaming mode: using our own pool %" GST_PTR_FORMAT, pool); "streaming mode: using our own pool %" GST_PTR_FORMAT, pool);
pushing_from_our_pool = TRUE; pushing_from_our_pool = TRUE;
@ -5664,7 +5738,7 @@ gst_v4l2_object_decide_allocation (GstV4l2Object * obj, GstQuery * query)
} else { } else {
GST_DEBUG_OBJECT (obj->dbg_obj, GST_DEBUG_OBJECT (obj->dbg_obj,
"streaming mode: no usable pool, copying to generic pool"); "streaming mode: no usable pool, copying to generic pool");
size = MAX (size, obj->info.size); size = MAX (size, GST_V4L2_SIZE (obj));
} }
break; break;
case GST_V4L2_IO_AUTO: case GST_V4L2_IO_AUTO:
@ -5851,7 +5925,7 @@ gst_v4l2_object_propose_allocation (GstV4l2Object * obj, GstQuery * query)
GstStructure *allocation_meta = NULL; GstStructure *allocation_meta = NULL;
/* Set defaults allocation parameters */ /* Set defaults allocation parameters */
size = obj->info.size; size = GST_V4L2_SIZE (obj);
min = GST_V4L2_MIN_BUFFERS (obj); min = GST_V4L2_MIN_BUFFERS (obj);
max = VIDEO_MAX_FRAME; max = VIDEO_MAX_FRAME;

View file

@ -44,7 +44,7 @@ typedef struct _GstV4l2ObjectClassHelper GstV4l2ObjectClassHelper;
/* size of v4l2 buffer pool in streaming case, obj->info needs to be valid */ /* size of v4l2 buffer pool in streaming case, obj->info needs to be valid */
#define GST_V4L2_MIN_BUFFERS(obj) \ #define GST_V4L2_MIN_BUFFERS(obj) \
((GST_VIDEO_INFO_INTERLACE_MODE (&obj->info) == \ ((GST_VIDEO_INFO_INTERLACE_MODE (&obj->info.vinfo) == \
GST_VIDEO_INTERLACE_MODE_ALTERNATE) ? \ GST_VIDEO_INTERLACE_MODE_ALTERNATE) ? \
/* 2x buffers needed with each field in its own buffer */ \ /* 2x buffers needed with each field in its own buffer */ \
4 : 2) 4 : 2)
@ -82,11 +82,14 @@ typedef int ioctl_req_t;
typedef gulong ioctl_req_t; typedef gulong ioctl_req_t;
#endif #endif
#define GST_V4L2_WIDTH(o) (GST_VIDEO_INFO_WIDTH (&(o)->info)) #define GST_V4L2_WIDTH(o) (GST_VIDEO_INFO_WIDTH (&(o)->info.vinfo))
#define GST_V4L2_HEIGHT(o) (GST_VIDEO_INFO_HEIGHT (&(o)->info)) #define GST_V4L2_HEIGHT(o) (GST_VIDEO_INFO_HEIGHT (&(o)->info.vinfo))
#define GST_V4L2_FIELD_HEIGHT(o) (GST_VIDEO_INFO_FIELD_HEIGHT (&(o)->info.vinfo))
#define GST_V4L2_PIXELFORMAT(o) ((o)->fmtdesc->pixelformat) #define GST_V4L2_PIXELFORMAT(o) ((o)->fmtdesc->pixelformat)
#define GST_V4L2_FPS_N(o) (GST_VIDEO_INFO_FPS_N (&(o)->info)) #define GST_V4L2_FPS_N(o) (GST_VIDEO_INFO_FPS_N (&(o)->info.vinfo))
#define GST_V4L2_FPS_D(o) (GST_VIDEO_INFO_FPS_D (&(o)->info)) #define GST_V4L2_FPS_D(o) (GST_VIDEO_INFO_FPS_D (&(o)->info.vinfo))
#define GST_V4L2_SIZE(o) (GST_VIDEO_INFO_SIZE (&(o)->info.vinfo))
#define GST_V4L2_N_PLANES(o) (GST_VIDEO_INFO_N_PLANES (&(o)->info.vinfo))
/* simple check whether the device is open */ /* simple check whether the device is open */
#define GST_V4L2_IS_OPEN(o) ((o)->video_fd > 0) #define GST_V4L2_IS_OPEN(o) ((o)->video_fd > 0)
@ -145,7 +148,7 @@ struct _GstV4l2Object {
/* the current format */ /* the current format */
struct v4l2_fmtdesc *fmtdesc; struct v4l2_fmtdesc *fmtdesc;
struct v4l2_format format; struct v4l2_format format;
GstVideoInfo info; GstVideoInfoDmaDrm info;
GstVideoAlignment align; GstVideoAlignment align;
GstVideoTransferFunction transfer; GstVideoTransferFunction transfer;
gsize plane_size[GST_VIDEO_MAX_PLANES]; gsize plane_size[GST_VIDEO_MAX_PLANES];
@ -315,7 +318,7 @@ gboolean gst_v4l2_object_stop (GstV4l2Object * v4l2object);
GstCaps * gst_v4l2_object_probe_caps (GstV4l2Object * v4l2object, GstCaps * filter); GstCaps * gst_v4l2_object_probe_caps (GstV4l2Object * v4l2object, GstCaps * filter);
GstCaps * gst_v4l2_object_get_caps (GstV4l2Object * v4l2object, GstCaps * filter); GstCaps * gst_v4l2_object_get_caps (GstV4l2Object * v4l2object, GstCaps * filter);
gboolean gst_v4l2_object_acquire_format (GstV4l2Object * v4l2object, GstVideoInfo * info); gboolean gst_v4l2_object_acquire_format (GstV4l2Object * v4l2object, GstVideoInfoDmaDrm * info);
gboolean gst_v4l2_object_setup_padding (GstV4l2Object * obj); gboolean gst_v4l2_object_setup_padding (GstV4l2Object * obj);

View file

@ -922,10 +922,10 @@ gst_v4l2src_decide_allocation (GstBaseSrc * bsrc, GstQuery * query)
if (gst_query_get_n_allocation_pools (query)) if (gst_query_get_n_allocation_pools (query))
gst_query_set_nth_allocation_pool (query, 0, pool, gst_query_set_nth_allocation_pool (query, 0, pool,
src->v4l2object->info.size, 1, 0); src->v4l2object->info.vinfo.size, 1, 0);
else else
gst_query_add_allocation_pool (query, pool, src->v4l2object->info.size, 1, gst_query_add_allocation_pool (query, pool,
0); src->v4l2object->info.vinfo.size, 1, 0);
if (pool) if (pool)
gst_object_unref (pool); gst_object_unref (pool);
@ -998,7 +998,7 @@ gst_v4l2src_query (GstBaseSrc * bsrc, GstQuery * query)
/* min latency is the time to capture one frame/field */ /* min latency is the time to capture one frame/field */
min_latency = gst_util_uint64_scale_int (GST_SECOND, fps_d, fps_n); min_latency = gst_util_uint64_scale_int (GST_SECOND, fps_d, fps_n);
if (GST_VIDEO_INFO_INTERLACE_MODE (&obj->info) == if (GST_VIDEO_INFO_INTERLACE_MODE (&obj->info.vinfo) ==
GST_VIDEO_INTERLACE_MODE_ALTERNATE) GST_VIDEO_INTERLACE_MODE_ALTERNATE)
min_latency /= 2; min_latency /= 2;
@ -1160,7 +1160,7 @@ gst_v4l2src_create (GstPushSrc * src, GstBuffer ** buf)
do { do {
ret = GST_BASE_SRC_CLASS (parent_class)->alloc (GST_BASE_SRC (src), 0, ret = GST_BASE_SRC_CLASS (parent_class)->alloc (GST_BASE_SRC (src), 0,
obj->info.size, buf); obj->info.vinfo.size, buf);
if (G_UNLIKELY (ret != GST_FLOW_OK)) { if (G_UNLIKELY (ret != GST_FLOW_OK)) {
if (ret == GST_V4L2_FLOW_RESOLUTION_CHANGE) { if (ret == GST_V4L2_FLOW_RESOLUTION_CHANGE) {

View file

@ -29,6 +29,8 @@
#include <unistd.h> #include <unistd.h>
#include <string.h> #include <string.h>
#include <gst/allocators/allocators.h>
#include "gstv4l2object.h" #include "gstv4l2object.h"
#include "gstv4l2transform.h" #include "gstv4l2transform.h"
@ -373,23 +375,45 @@ gst_v4l2_transform_caps_remove_format_info (GstCaps * caps)
n = gst_caps_get_size (caps); n = gst_caps_get_size (caps);
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
st = gst_caps_get_structure (caps, i); GstCapsFeatures *alt_f = NULL;
st = gst_structure_copy (gst_caps_get_structure (caps, i));
f = gst_caps_get_features (caps, i); f = gst_caps_get_features (caps, i);
alt_f = gst_caps_features_copy (f);
/* remove all the features we support, if anything is left it means we
* cannot convert */
if (!gst_caps_features_is_any (f)) {
gst_caps_features_remove (alt_f, GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY);
gst_caps_features_remove (alt_f, GST_CAPS_FEATURE_MEMORY_DMABUF);
gst_caps_features_remove (alt_f, GST_CAPS_FEATURE_FORMAT_INTERLACED);
}
/* Only remove format info for the cases when we can actually convert */
if (!gst_caps_features_is_any (f)
&& (gst_caps_features_get_size (alt_f) == 0)) {
gst_structure_remove_fields (st, "format", "drm-format", "colorimetry",
"chroma-site", "width", "height", "pixel-aspect-ratio", NULL);
/* create an alternate feature, so that we allow converting between system
* memory and dmabuf */
if (gst_caps_features_contains (f, GST_CAPS_FEATURE_FORMAT_INTERLACED))
gst_caps_features_add (alt_f, GST_CAPS_FEATURE_FORMAT_INTERLACED);
if (!gst_caps_features_contains (f, GST_CAPS_FEATURE_MEMORY_DMABUF))
gst_caps_features_add (alt_f, GST_CAPS_FEATURE_MEMORY_DMABUF);
}
/* If this is already expressed by the existing caps /* If this is already expressed by the existing caps
* skip this structure */ * skip this structure */
if (i > 0 && gst_caps_is_subset_structure_full (res, st, f)) if (!gst_caps_is_subset_structure_full (res, st, f))
continue; gst_caps_append_structure_full (res, gst_structure_copy (st),
gst_caps_features_copy (f));
if (!gst_caps_is_subset_structure_full (res, st, alt_f))
gst_caps_append_structure_full (res, gst_structure_copy (st),
gst_caps_features_copy (alt_f));
st = gst_structure_copy (st); gst_structure_free (st);
/* Only remove format info for the cases when we can actually convert */ gst_caps_features_free (alt_f);
if (!gst_caps_features_is_any (f)
&& gst_caps_features_is_equal (f,
GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY))
gst_structure_remove_fields (st, "format", "colorimetry", "chroma-site",
"width", "height", "pixel-aspect-ratio", NULL);
gst_caps_append_structure_full (res, st, gst_caps_features_copy (f));
} }
return res; return res;
@ -920,7 +944,7 @@ gst_v4l2_transform_prepare_output_buffer (GstBaseTransform * trans,
} }
gst_buffer_pool_config_set_params (config, self->incaps, gst_buffer_pool_config_set_params (config, self->incaps,
self->v4l2output->info.size, min, min); self->v4l2output->info.vinfo.size, min, min);
/* There is no reason to refuse this config */ /* There is no reason to refuse this config */
if (!gst_buffer_pool_set_config (pool, config)) if (!gst_buffer_pool_set_config (pool, config))

View file

@ -364,7 +364,7 @@ gst_v4l2_video_remove_padding (GstCapsFeatures * features,
{ {
GstV4l2VideoDec *self = GST_V4L2_VIDEO_DEC (user_data); GstV4l2VideoDec *self = GST_V4L2_VIDEO_DEC (user_data);
GstVideoAlignment *align = &self->v4l2capture->align; GstVideoAlignment *align = &self->v4l2capture->align;
GstVideoInfo *info = &self->v4l2capture->info; GstVideoInfo *info = &self->v4l2capture->info.vinfo;
int width, height; int width, height;
if (!gst_structure_get_int (structure, "width", &width)) if (!gst_structure_get_int (structure, "width", &width))
@ -397,13 +397,14 @@ gst_v4l2_video_dec_negotiate (GstVideoDecoder * decoder)
{ {
GstV4l2VideoDec *self = GST_V4L2_VIDEO_DEC (decoder); GstV4l2VideoDec *self = GST_V4L2_VIDEO_DEC (decoder);
GstV4l2Error error = GST_V4L2_ERROR_INIT; GstV4l2Error error = GST_V4L2_ERROR_INIT;
GstVideoInfo info; GstVideoInfoDmaDrm info;
GstVideoCodecState *output_state; GstVideoCodecState *output_state;
GstCaps *acquired_caps, *fixation_caps, *available_caps, *caps, *filter; GstCaps *acquired_caps, *acquired_drm_caps;
GstStructure *st; GstCaps *fixation_caps, *available_caps, *caps, *filter;
gboolean active; gboolean active;
GstBufferPool *cpool; GstBufferPool *cpool;
gboolean ret; gboolean ret;
gint i;
/* We don't allow renegotiation without careful disabling the pool */ /* We don't allow renegotiation without careful disabling the pool */
cpool = gst_v4l2_object_get_buffer_pool (self->v4l2capture); cpool = gst_v4l2_object_get_buffer_pool (self->v4l2capture);
@ -415,8 +416,8 @@ gst_v4l2_video_dec_negotiate (GstVideoDecoder * decoder)
} }
/* init capture fps according to output */ /* init capture fps according to output */
self->v4l2capture->info.fps_d = self->v4l2output->info.fps_d; GST_V4L2_FPS_D (self->v4l2capture) = GST_V4L2_FPS_D (self->v4l2output);
self->v4l2capture->info.fps_n = self->v4l2output->info.fps_n; GST_V4L2_FPS_N (self->v4l2capture) = GST_V4L2_FPS_N (self->v4l2output);
/* For decoders G_FMT returns coded size, G_SELECTION returns visible size /* For decoders G_FMT returns coded size, G_SELECTION returns visible size
* in the compose rectangle. gst_v4l2_object_acquire_format() checks both * in the compose rectangle. gst_v4l2_object_acquire_format() checks both
@ -426,19 +427,34 @@ gst_v4l2_video_dec_negotiate (GstVideoDecoder * decoder)
goto not_negotiated; goto not_negotiated;
/* gst_v4l2_object_acquire_format() does not set fps, copy from sink */ /* gst_v4l2_object_acquire_format() does not set fps, copy from sink */
info.fps_n = self->v4l2output->info.fps_n; info.vinfo.fps_n = GST_V4L2_FPS_N (self->v4l2output);
info.fps_d = self->v4l2output->info.fps_d; info.vinfo.fps_d = GST_V4L2_FPS_D (self->v4l2output);
gst_caps_replace (&self->probed_srccaps, NULL); gst_caps_replace (&self->probed_srccaps, NULL);
self->probed_srccaps = gst_v4l2_object_probe_caps (self->v4l2capture, self->probed_srccaps = gst_v4l2_object_probe_caps (self->v4l2capture,
gst_v4l2_object_get_raw_caps ()); gst_v4l2_object_get_raw_caps ());
/* Create caps from the acquired format, remove the format field */
acquired_caps = gst_video_info_to_caps (&info); /* Create caps from the acquired format, removing the format fields */
fixation_caps = gst_caps_new_empty ();
acquired_drm_caps = gst_video_info_dma_drm_to_caps (&info);
if (acquired_drm_caps) {
GST_DEBUG_OBJECT (self, "Acquired DRM caps: %" GST_PTR_FORMAT,
acquired_drm_caps);
gst_caps_append (fixation_caps, gst_caps_copy (acquired_drm_caps));
}
acquired_caps = gst_video_info_to_caps (&info.vinfo);
if (acquired_caps) {
GST_DEBUG_OBJECT (self, "Acquired caps: %" GST_PTR_FORMAT, acquired_caps); GST_DEBUG_OBJECT (self, "Acquired caps: %" GST_PTR_FORMAT, acquired_caps);
fixation_caps = gst_caps_copy (acquired_caps); gst_caps_append (fixation_caps, gst_caps_copy (acquired_drm_caps));
st = gst_caps_get_structure (fixation_caps, 0); }
gst_structure_remove_fields (st, "format", "colorimetry", "chroma-site",
NULL); for (i = 0; i < gst_caps_get_size (fixation_caps); i++) {
GstStructure *st = gst_caps_get_structure (fixation_caps, i);
gst_structure_remove_fields (st, "format", "drm-format", "colorimetry",
"chroma-site", NULL);
}
/* Probe currently available pixel formats */ /* Probe currently available pixel formats */
available_caps = gst_caps_copy (self->probed_srccaps); available_caps = gst_caps_copy (self->probed_srccaps);
@ -465,6 +481,16 @@ gst_v4l2_video_dec_negotiate (GstVideoDecoder * decoder)
/* Prefer the acquired caps over anything suggested downstream, this ensure /* Prefer the acquired caps over anything suggested downstream, this ensure
* that we preserves the bit depth, as we don't have any fancy fixation * that we preserves the bit depth, as we don't have any fancy fixation
* process */ * process */
if (acquired_drm_caps) {
if (gst_caps_is_subset (acquired_drm_caps, caps)) {
gst_caps_replace (&acquired_caps, acquired_drm_caps);
acquired_drm_caps = NULL;
goto use_acquired_caps;
}
gst_clear_caps (&acquired_drm_caps);
}
if (gst_caps_is_subset (acquired_caps, caps)) if (gst_caps_is_subset (acquired_caps, caps))
goto use_acquired_caps; goto use_acquired_caps;
@ -475,12 +501,11 @@ gst_v4l2_video_dec_negotiate (GstVideoDecoder * decoder)
/* Try to set negotiated format, on success replace acquired format */ /* Try to set negotiated format, on success replace acquired format */
if (gst_v4l2_object_set_format (self->v4l2capture, caps, &error)) if (gst_v4l2_object_set_format (self->v4l2capture, caps, &error))
gst_video_info_from_caps (&info, caps); info = self->v4l2capture->info;
else else
gst_v4l2_clear_error (&error); gst_v4l2_clear_error (&error);
use_acquired_caps: use_acquired_caps:
gst_caps_unref (acquired_caps);
gst_caps_unref (caps); gst_caps_unref (caps);
/* catch possible bogus driver that don't enumerate the format it actually /* catch possible bogus driver that don't enumerate the format it actually
@ -488,12 +513,13 @@ use_acquired_caps:
if (!self->v4l2capture->fmtdesc) if (!self->v4l2capture->fmtdesc)
goto not_negotiated; goto not_negotiated;
output_state = gst_video_decoder_set_output_state (decoder, output_state = gst_video_decoder_set_interlaced_output_state (decoder,
info.finfo->format, info.width, info.height, self->input_state); info.vinfo.finfo->format, info.vinfo.interlace_mode, info.vinfo.width,
info.vinfo.height, self->input_state);
/* Copy the rest of the information, there might be more in the future */ /* Copy the rest of the information, there might be more in the future */
output_state->info.interlace_mode = info.interlace_mode; output_state->info.colorimetry = info.vinfo.colorimetry;
output_state->info.colorimetry = info.colorimetry; output_state->caps = acquired_caps;
gst_video_codec_state_unref (output_state); gst_video_codec_state_unref (output_state);
ret = GST_VIDEO_DECODER_CLASS (parent_class)->negotiate (decoder); ret = GST_VIDEO_DECODER_CLASS (parent_class)->negotiate (decoder);
@ -945,14 +971,15 @@ gst_v4l2_video_dec_handle_frame (GstVideoDecoder * decoder,
/* Ensure input internal pool is active */ /* Ensure input internal pool is active */
gst_buffer_pool_config_set_params (config, self->input_state->caps, gst_buffer_pool_config_set_params (config, self->input_state->caps,
self->v4l2output->info.size, min, max); self->v4l2output->info.vinfo.size, min, max);
/* There is no reason to refuse this config */ /* There is no reason to refuse this config */
if (!gst_buffer_pool_set_config (pool, config)) { if (!gst_buffer_pool_set_config (pool, config)) {
config = gst_buffer_pool_get_config (pool); config = gst_buffer_pool_get_config (pool);
if (!gst_buffer_pool_config_validate_params (config, if (!gst_buffer_pool_config_validate_params (config,
self->input_state->caps, self->v4l2output->info.size, min, max)) { self->input_state->caps,
self->v4l2output->info.vinfo.size, min, max)) {
gst_structure_free (config); gst_structure_free (config);
goto activate_failed; goto activate_failed;
} }

View file

@ -779,14 +779,14 @@ gst_v4l2_video_enc_handle_frame (GstVideoEncoder * encoder,
GST_V4L2_MIN_BUFFERS (self->v4l2output)); GST_V4L2_MIN_BUFFERS (self->v4l2output));
gst_buffer_pool_config_set_params (config, self->input_state->caps, gst_buffer_pool_config_set_params (config, self->input_state->caps,
self->v4l2output->info.size, min, min); self->v4l2output->info.vinfo.size, min, min);
/* There is no reason to refuse this config */ /* There is no reason to refuse this config */
if (!gst_buffer_pool_set_config (opool, config)) { if (!gst_buffer_pool_set_config (opool, config)) {
config = gst_buffer_pool_get_config (opool); config = gst_buffer_pool_get_config (opool);
if (gst_buffer_pool_config_validate_params (config, if (gst_buffer_pool_config_validate_params (config,
self->input_state->caps, self->v4l2output->info.size, min, self->input_state->caps, self->v4l2output->info.vinfo.size, min,
min)) { min)) {
gst_structure_free (config); gst_structure_free (config);
if (opool) if (opool)