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: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5890>
This commit is contained in:
Robert Mader 2024-02-16 22:48:17 +01:00 committed by GStreamer Marge Bot
parent 55136c30c4
commit 65896dab75
8 changed files with 61 additions and 22 deletions

View file

@ -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 "

View file

@ -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 "

View file

@ -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 "

View file

@ -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 "

View file

@ -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 "

View file

@ -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 "

View file

@ -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;
}

View file

@ -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,