v4l2codecs: decoder: Reorder caps to prefer DMA_DRM ones

Certain V4L2 fourccs don't (yet) have DRM counter parts, in which case
we can't create DMA_DRM caps for them. This is usually the case for
specific tilings, which are represented as modifiers for DMA formats.

While using these tilings is generally preferable - because of e.g.
lower memory usage - it can result in additional conversion steps when
interacting with DMA based APIs such as GL, Vulkan or KMS. In such cases
using a DMA compatible format usually ends up being the better option.

Before the addition of DMA_DRM caps, this was what playbin3 ended up
requesting in various cases - e.g. prefering NV12 over NV12_4L4 - but
the addition of DMA_DRM caps seems to confuse the selection logic.

As a simple and quite robust solution, assume that peers supporting
DMA_DRM caps always prefer these and reorder the caps accordingly.

In the future we plan to have a translation layer for cases where
there is a matching fourcc+modifier pair for a V4L2 fourcc, ensuring
optimal results.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/6824>
This commit is contained in:
Robert Mader 2024-04-15 13:38:15 +02:00 committed by Backport Bot
parent fb8e2c60a2
commit e869185287

View file

@ -463,6 +463,20 @@ gst_v4l2_decoder_probe_caps_for_format (GstV4l2Decoder * self,
return caps; return caps;
} }
static gboolean
filter_only_dmabuf_caps (GstCapsFeatures * features,
GstStructure * structure, gpointer user_data)
{
return gst_caps_features_contains (features, GST_CAPS_FEATURE_MEMORY_DMABUF);
}
static gboolean
filter_non_dmabuf_caps (GstCapsFeatures * features,
GstStructure * structure, gpointer user_data)
{
return !gst_caps_features_contains (features, GST_CAPS_FEATURE_MEMORY_DMABUF);
}
GstCaps * GstCaps *
gst_v4l2_decoder_enum_src_formats (GstV4l2Decoder * self, gst_v4l2_decoder_enum_src_formats (GstV4l2Decoder * self,
GstStaticCaps * static_filter) GstStaticCaps * static_filter)
@ -510,6 +524,11 @@ gst_v4l2_decoder_enum_src_formats (GstV4l2Decoder * self,
gst_caps_unref (tmp); gst_caps_unref (tmp);
gst_caps_unref (filter); gst_caps_unref (filter);
tmp = gst_caps_copy (caps);
gst_caps_filter_and_map_in_place (caps, filter_only_dmabuf_caps, NULL);
gst_caps_filter_and_map_in_place (tmp, filter_non_dmabuf_caps, NULL);
gst_caps_append (caps, tmp);
GST_DEBUG_OBJECT (self, "Probed caps: %" GST_PTR_FORMAT, caps); GST_DEBUG_OBJECT (self, "Probed caps: %" GST_PTR_FORMAT, caps);
return caps; return caps;