From 65896dab75ea0a1e07a9792ae2cf53410ad970f8 Mon Sep 17 00:00:00 2001 From: Robert Mader Date: Fri, 16 Feb 2024 22:48:17 +0100 Subject: [PATCH] v4l2codecs: decoders: Use src template for negotiation filter This ensures we don't create filter caps that are not supported by the individual codec implementations, as well as that the resulting caps have the required fields so they can be turned into a GstVideoFormat. Part-of: --- .../sys/v4l2codecs/gstv4l2codecav1dec.c | 11 ++++++++--- .../sys/v4l2codecs/gstv4l2codech264dec.c | 11 ++++++++--- .../sys/v4l2codecs/gstv4l2codech265dec.c | 11 ++++++++--- .../sys/v4l2codecs/gstv4l2codecmpeg2dec.c | 11 ++++++++--- .../sys/v4l2codecs/gstv4l2codecvp8dec.c | 11 ++++++++--- .../sys/v4l2codecs/gstv4l2codecvp9dec.c | 11 ++++++++--- .../sys/v4l2codecs/gstv4l2decoder.c | 14 +++++++++++--- .../sys/v4l2codecs/gstv4l2decoder.h | 3 ++- 8 files changed, 61 insertions(+), 22 deletions(-) diff --git a/subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2codecav1dec.c b/subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2codecav1dec.c index eed22839e3..f0f2573d90 100644 --- a/subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2codecav1dec.c +++ b/subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2codecav1dec.c @@ -52,10 +52,15 @@ GST_STATIC_PAD_TEMPLATE (GST_VIDEO_DECODER_SINK_NAME, GST_PAD_SINK, GST_PAD_ALWAYS, GST_STATIC_CAPS ("video/x-av1, alignment=frame")); +#define SRC_CAPS \ + GST_VIDEO_CAPS_MAKE (GST_V4L2_DEFAULT_VIDEO_FORMATS) + +static GstStaticCaps static_src_caps = GST_STATIC_CAPS (SRC_CAPS); + static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE (GST_VIDEO_DECODER_SRC_NAME, GST_PAD_SRC, GST_PAD_ALWAYS, - GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE (GST_V4L2_DEFAULT_VIDEO_FORMATS))); + GST_STATIC_CAPS (SRC_CAPS)); struct _GstV4l2CodecAV1Dec { @@ -303,7 +308,7 @@ gst_v4l2_codec_av1_dec_negotiate (GstVideoDecoder * decoder) return FALSE; } - filter = gst_v4l2_decoder_enum_src_formats (self->decoder); + filter = gst_v4l2_decoder_enum_src_formats (self->decoder, &static_src_caps); if (!filter) { GST_ELEMENT_ERROR (self, CORE, NEGOTIATION, ("No supported decoder output formats"), (NULL)); @@ -1576,7 +1581,7 @@ gst_v4l2_codec_av1_dec_register (GstPlugin * plugin, GstV4l2Decoder * decoder, 320, 240, 8)) return; - src_caps = gst_v4l2_decoder_enum_src_formats (decoder); + src_caps = gst_v4l2_decoder_enum_src_formats (decoder, &static_src_caps); if (gst_caps_is_empty (src_caps)) { GST_WARNING ("Not registering AV1 decoder since it produces no " diff --git a/subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2codech264dec.c b/subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2codech264dec.c index 41b1f843bd..7327e76ba6 100644 --- a/subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2codech264dec.c +++ b/subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2codech264dec.c @@ -50,10 +50,15 @@ GST_STATIC_PAD_TEMPLATE (GST_VIDEO_DECODER_SINK_NAME, "alignment=(string) au") ); +#define SRC_CAPS \ + GST_VIDEO_CAPS_MAKE (GST_V4L2_DEFAULT_VIDEO_FORMATS) + +static GstStaticCaps static_src_caps = GST_STATIC_CAPS (SRC_CAPS); + static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE (GST_VIDEO_DECODER_SRC_NAME, GST_PAD_SRC, GST_PAD_ALWAYS, - GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE (GST_V4L2_DEFAULT_VIDEO_FORMATS))); + GST_STATIC_CAPS (SRC_CAPS)); struct _GstV4l2CodecH264Dec { @@ -345,7 +350,7 @@ gst_v4l2_codec_h264_dec_negotiate (GstVideoDecoder * decoder) return FALSE; } - filter = gst_v4l2_decoder_enum_src_formats (self->decoder); + filter = gst_v4l2_decoder_enum_src_formats (self->decoder, &static_src_caps); if (!filter) { GST_ELEMENT_ERROR (self, CORE, NEGOTIATION, ("No supported decoder output formats"), (NULL)); @@ -1570,7 +1575,7 @@ gst_v4l2_codec_h264_dec_register (GstPlugin * plugin, GstV4l2Decoder * decoder, if (!gst_v4l2_decoder_set_sink_fmt (decoder, V4L2_PIX_FMT_H264_SLICE, 320, 240, 8)) return; - src_caps = gst_v4l2_decoder_enum_src_formats (decoder); + src_caps = gst_v4l2_decoder_enum_src_formats (decoder, &static_src_caps); if (gst_caps_is_empty (src_caps)) { GST_WARNING ("Not registering H264 decoder since it produces no " diff --git a/subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2codech265dec.c b/subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2codech265dec.c index 43dc16a3ab..13f0cd6214 100644 --- a/subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2codech265dec.c +++ b/subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2codech265dec.c @@ -51,10 +51,15 @@ GST_STATIC_PAD_TEMPLATE (GST_VIDEO_DECODER_SINK_NAME, "alignment=(string) au") ); +#define SRC_CAPS \ + GST_VIDEO_CAPS_MAKE (GST_V4L2_DEFAULT_VIDEO_FORMATS) + +static GstStaticCaps static_src_caps = GST_STATIC_CAPS (SRC_CAPS); + static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE (GST_VIDEO_DECODER_SRC_NAME, GST_PAD_SRC, GST_PAD_ALWAYS, - GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE (GST_V4L2_DEFAULT_VIDEO_FORMATS))); + GST_STATIC_CAPS (SRC_CAPS)); struct _GstV4l2CodecH265Dec { @@ -379,7 +384,7 @@ gst_v4l2_codec_h265_dec_negotiate (GstVideoDecoder * decoder) return FALSE; } - filter = gst_v4l2_decoder_enum_src_formats (self->decoder); + filter = gst_v4l2_decoder_enum_src_formats (self->decoder, &static_src_caps); if (!filter) { GST_ELEMENT_ERROR (self, CORE, NEGOTIATION, ("No supported decoder output formats"), (NULL)); @@ -1685,7 +1690,7 @@ gst_v4l2_codec_h265_dec_register (GstPlugin * plugin, GstV4l2Decoder * decoder, if (!gst_v4l2_decoder_set_sink_fmt (decoder, V4L2_PIX_FMT_HEVC_SLICE, 320, 240, 8)) return; - src_caps = gst_v4l2_decoder_enum_src_formats (decoder); + src_caps = gst_v4l2_decoder_enum_src_formats (decoder, &static_src_caps); if (gst_caps_is_empty (src_caps)) { GST_WARNING ("Not registering H265 decoder since it produces no " diff --git a/subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2codecmpeg2dec.c b/subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2codecmpeg2dec.c index 37eb7a9a8b..2c08379450 100644 --- a/subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2codecmpeg2dec.c +++ b/subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2codecmpeg2dec.c @@ -53,10 +53,15 @@ GST_STATIC_PAD_TEMPLATE (GST_VIDEO_DECODER_SINK_NAME, "systemstream=(boolean) false, " "mpegversion=(int) 2, " "profile=(string) {main, simple} ")); +#define SRC_CAPS \ + GST_VIDEO_CAPS_MAKE (GST_V4L2_DEFAULT_VIDEO_FORMATS) + +static GstStaticCaps static_src_caps = GST_STATIC_CAPS (SRC_CAPS); + static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE (GST_VIDEO_DECODER_SRC_NAME, GST_PAD_SRC, GST_PAD_ALWAYS, - GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE (GST_V4L2_DEFAULT_VIDEO_FORMATS))); + GST_STATIC_CAPS (SRC_CAPS)); struct _GstV4l2CodecMpeg2Dec { @@ -267,7 +272,7 @@ gst_v4l2_codec_mpeg2_dec_negotiate (GstVideoDecoder * decoder) return FALSE; } - filter = gst_v4l2_decoder_enum_src_formats (self->decoder); + filter = gst_v4l2_decoder_enum_src_formats (self->decoder, &static_src_caps); if (!filter) { GST_ELEMENT_ERROR (self, CORE, NEGOTIATION, ("No supported decoder output formats"), (NULL)); @@ -1088,7 +1093,7 @@ gst_v4l2_codec_mpeg2_dec_register (GstPlugin * plugin, GstV4l2Decoder * decoder, if (!gst_v4l2_decoder_set_sink_fmt (decoder, V4L2_PIX_FMT_MPEG2_SLICE, 320, 240, 8)) return; - src_caps = gst_v4l2_decoder_enum_src_formats (decoder); + src_caps = gst_v4l2_decoder_enum_src_formats (decoder, &static_src_caps); if (gst_caps_is_empty (src_caps)) { GST_WARNING ("Not registering MPEG2 decoder since it produces no " diff --git a/subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2codecvp8dec.c b/subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2codecvp8dec.c index da6efe54f9..38d9e71121 100644 --- a/subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2codecvp8dec.c +++ b/subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2codecvp8dec.c @@ -54,10 +54,15 @@ GST_STATIC_PAD_TEMPLATE (GST_VIDEO_DECODER_SINK_NAME, GST_STATIC_CAPS ("video/x-vp8, codec-alpha = (boolean) true") ); +#define SRC_CAPS \ + GST_VIDEO_CAPS_MAKE (GST_V4L2_DEFAULT_VIDEO_FORMATS) + +static GstStaticCaps static_src_caps = GST_STATIC_CAPS (SRC_CAPS); + static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE (GST_VIDEO_DECODER_SRC_NAME, GST_PAD_SRC, GST_PAD_ALWAYS, - GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE (GST_V4L2_DEFAULT_VIDEO_FORMATS))); + GST_STATIC_CAPS (SRC_CAPS)); struct _GstV4l2CodecVp8Dec { @@ -216,7 +221,7 @@ gst_v4l2_codec_vp8_dec_negotiate (GstVideoDecoder * decoder) return FALSE; } - filter = gst_v4l2_decoder_enum_src_formats (self->decoder); + filter = gst_v4l2_decoder_enum_src_formats (self->decoder, &static_src_caps); if (!filter) { GST_ELEMENT_ERROR (self, CORE, NEGOTIATION, ("No supported decoder output formats"), (NULL)); @@ -965,7 +970,7 @@ gst_v4l2_codec_vp8_dec_register (GstPlugin * plugin, GstV4l2Decoder * decoder, if (!gst_v4l2_decoder_set_sink_fmt (decoder, V4L2_PIX_FMT_VP8_FRAME, 320, 240, 8)) return; - src_caps = gst_v4l2_decoder_enum_src_formats (decoder); + src_caps = gst_v4l2_decoder_enum_src_formats (decoder, &static_src_caps); if (gst_caps_is_empty (src_caps)) { GST_WARNING ("Not registering VP8 decoder since it produces no " diff --git a/subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2codecvp9dec.c b/subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2codecvp9dec.c index a5c5bd5c0f..5ba3890bdf 100644 --- a/subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2codecvp9dec.c +++ b/subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2codecvp9dec.c @@ -55,10 +55,15 @@ GST_STATIC_PAD_TEMPLATE (GST_VIDEO_DECODER_SINK_NAME, "alignment = frame") ); +#define SRC_CAPS \ + GST_VIDEO_CAPS_MAKE (GST_V4L2_DEFAULT_VIDEO_FORMATS) + +static GstStaticCaps static_src_caps = GST_STATIC_CAPS (SRC_CAPS); + static GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE (GST_VIDEO_DECODER_SRC_NAME, GST_PAD_SRC, GST_PAD_ALWAYS, - GST_STATIC_CAPS (GST_VIDEO_CAPS_MAKE (GST_V4L2_DEFAULT_VIDEO_FORMATS))); + GST_STATIC_CAPS (SRC_CAPS)); struct _GstV4l2CodecVp9Dec { @@ -486,7 +491,7 @@ gst_v4l2_codec_vp9_dec_negotiate (GstVideoDecoder * decoder) return FALSE; } - filter = gst_v4l2_decoder_enum_src_formats (self->decoder); + filter = gst_v4l2_decoder_enum_src_formats (self->decoder, &static_src_caps); if (!filter) { GST_ELEMENT_ERROR (self, CORE, NEGOTIATION, ("No supported decoder output formats"), (NULL)); @@ -1209,7 +1214,7 @@ gst_v4l2_codec_vp9_dec_register (GstPlugin * plugin, GstV4l2Decoder * decoder, if (!gst_v4l2_decoder_set_sink_fmt (decoder, V4L2_PIX_FMT_VP9_FRAME, 320, 240, 8)) return; - src_caps = gst_v4l2_decoder_enum_src_formats (decoder); + src_caps = gst_v4l2_decoder_enum_src_formats (decoder, &static_src_caps); if (gst_caps_is_empty (src_caps)) { GST_WARNING ("Not registering VP9 decoder since it produces no " diff --git a/subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2decoder.c b/subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2decoder.c index a11cbdaf24..5c44c45b93 100644 --- a/subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2decoder.c +++ b/subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2decoder.c @@ -430,13 +430,14 @@ gst_v4l2_decoder_probe_caps_for_format (GstV4l2Decoder * self, } GstCaps * -gst_v4l2_decoder_enum_src_formats (GstV4l2Decoder * self) +gst_v4l2_decoder_enum_src_formats (GstV4l2Decoder * self, + GstStaticCaps * static_filter) { gint ret; struct v4l2_format fmt = { .type = self->src_buf_type, }; - GstCaps *caps; + GstCaps *caps, *filter, *tmp; gint i; g_return_val_if_fail (self->opened, FALSE); @@ -455,7 +456,6 @@ gst_v4l2_decoder_enum_src_formats (GstV4l2Decoder * self) * structure in the caps */ for (i = 0; ret >= 0; i++) { struct v4l2_fmtdesc fmtdesc = { i, self->src_buf_type, }; - GstCaps *tmp; ret = ioctl (self->video_fd, VIDIOC_ENUM_FMT, &fmtdesc); if (ret < 0) { @@ -470,6 +470,14 @@ gst_v4l2_decoder_enum_src_formats (GstV4l2Decoder * self) caps = gst_caps_merge (caps, tmp); } + filter = gst_static_caps_get (static_filter); + tmp = caps; + caps = gst_caps_intersect_full (tmp, filter, GST_CAPS_INTERSECT_FIRST); + gst_caps_unref (tmp); + gst_caps_unref (filter); + + GST_DEBUG_OBJECT (self, "Probed caps: %" GST_PTR_FORMAT, caps); + return caps; } diff --git a/subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2decoder.h b/subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2decoder.h index 1abadfa615..146b8c26e0 100644 --- a/subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2decoder.h +++ b/subprojects/gst-plugins-bad/sys/v4l2codecs/gstv4l2decoder.h @@ -67,7 +67,8 @@ gboolean gst_v4l2_decoder_set_sink_fmt (GstV4l2Decoder * self, guint32 gint width, gint height, gint pixel_bitdepth); -GstCaps * gst_v4l2_decoder_enum_src_formats (GstV4l2Decoder * self); +GstCaps * gst_v4l2_decoder_enum_src_formats (GstV4l2Decoder * self, + GstStaticCaps * static_filter); gboolean gst_v4l2_decoder_select_src_format (GstV4l2Decoder * self, GstCaps * caps,