v4l2codecs: decoder: Clean up select_src_format()

Most importantly rely on video info helpers instead of manual parsing
of caps, which will allow us to use additional helpers in the future.

While on it, tighen the check for supported formats - failing that
indicates a bug in caps negotiation - and make some style changes.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/6376>
This commit is contained in:
Robert Mader 2024-02-17 05:43:23 +01:00 committed by GStreamer Marge Bot
parent b5fe2319f3
commit 84d015cabb
2 changed files with 26 additions and 15 deletions

View file

@ -491,16 +491,15 @@ gst_v4l2_decoder_enum_src_formats (GstV4l2Decoder * self,
gboolean gboolean
gst_v4l2_decoder_select_src_format (GstV4l2Decoder * self, GstCaps * caps, gst_v4l2_decoder_select_src_format (GstV4l2Decoder * self, GstCaps * caps,
GstVideoInfo * info) GstVideoInfo * vinfo)
{ {
gint ret; gint ret;
struct v4l2_format fmt = { struct v4l2_format fmt = {
.type = self->src_buf_type, .type = self->src_buf_type,
}; };
GstStructure *str;
const gchar *format_str;
GstVideoFormat format; GstVideoFormat format;
guint32 pix_fmt; guint32 pix_fmt;
GstVideoInfo tmp_vinfo;
if (gst_caps_is_empty (caps)) if (gst_caps_is_empty (caps))
return FALSE; return FALSE;
@ -511,16 +510,28 @@ gst_v4l2_decoder_select_src_format (GstV4l2Decoder * self, GstCaps * caps,
return FALSE; return FALSE;
} }
caps = gst_caps_make_writable (caps); gst_video_info_init (&tmp_vinfo);
str = gst_caps_get_structure (caps, 0);
gst_structure_fixate_field (str, "format");
format_str = gst_structure_get_string (str, "format"); GST_DEBUG_OBJECT (self, "Original caps: %" GST_PTR_FORMAT, caps);
format = gst_video_format_from_string (format_str); caps = gst_caps_fixate (caps);
GST_DEBUG_OBJECT (self, "Fixated caps: %" GST_PTR_FORMAT, caps);
if (gst_v4l2_format_from_video_format (format, &pix_fmt) && if (gst_video_info_from_caps (&tmp_vinfo, caps)) {
pix_fmt != fmt.fmt.pix_mp.pixelformat) { format = tmp_vinfo.finfo->format;
GST_DEBUG_OBJECT (self, "Trying to use peer format: %s ", format_str); } else {
GST_WARNING_OBJECT (self, "Can't transform caps into video info!");
return FALSE;
}
if (!gst_v4l2_format_from_video_format (format, &pix_fmt)) {
GST_ERROR_OBJECT (self, "Unsupported V4L2 pixelformat %" GST_FOURCC_FORMAT,
GST_FOURCC_ARGS (fmt.fmt.pix_mp.pixelformat));
return FALSE;
}
if (pix_fmt != fmt.fmt.pix_mp.pixelformat) {
GST_WARNING_OBJECT (self, "Trying to use peer format: %s",
gst_video_format_to_string (format));
fmt.fmt.pix_mp.pixelformat = pix_fmt; fmt.fmt.pix_mp.pixelformat = pix_fmt;
ret = ioctl (self->video_fd, VIDIOC_S_FMT, &fmt); ret = ioctl (self->video_fd, VIDIOC_S_FMT, &fmt);
@ -530,15 +541,15 @@ gst_v4l2_decoder_select_src_format (GstV4l2Decoder * self, GstCaps * caps,
} }
} }
if (!gst_v4l2_format_to_video_info (&fmt, info)) { if (!gst_v4l2_format_to_video_info (&fmt, vinfo)) {
GST_ERROR_OBJECT (self, "Unsupported V4L2 pixelformat %" GST_FOURCC_FORMAT, GST_ERROR_OBJECT (self, "Unsupported V4L2 pixelformat %" GST_FOURCC_FORMAT,
GST_FOURCC_ARGS (fmt.fmt.pix_mp.pixelformat)); GST_FOURCC_ARGS (fmt.fmt.pix_mp.pixelformat));
return FALSE; return FALSE;
} }
GST_INFO_OBJECT (self, "Selected format %s %ix%i", GST_INFO_OBJECT (self, "Selected format %s %ix%i",
gst_video_format_to_string (info->finfo->format), gst_video_format_to_string (vinfo->finfo->format),
info->width, info->height); vinfo->width, vinfo->height);
return TRUE; return TRUE;
} }

View file

@ -72,7 +72,7 @@ GstCaps * gst_v4l2_decoder_enum_src_formats (GstV4l2Decoder * self,
gboolean gst_v4l2_decoder_select_src_format (GstV4l2Decoder * self, gboolean gst_v4l2_decoder_select_src_format (GstV4l2Decoder * self,
GstCaps * caps, GstCaps * caps,
GstVideoInfo * info); GstVideoInfo * vinfo);
gint gst_v4l2_decoder_request_buffers (GstV4l2Decoder * self, gint gst_v4l2_decoder_request_buffers (GstV4l2Decoder * self,
GstPadDirection direction, GstPadDirection direction,