mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-26 03:31:05 +00:00
va: Improve the template caps for DMA, use new drm-format kind caps
We should add the modifier information for each surface format when we report the template caps. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4044>
This commit is contained in:
parent
93d763b85c
commit
b1909949cb
3 changed files with 160 additions and 28 deletions
|
@ -145,6 +145,38 @@ gst_caps_set_format_array (GstCaps * caps, GArray * formats)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_caps_set_drm_format_array (GstCaps * caps, GPtrArray * formats)
|
||||
{
|
||||
GValue v_formats = G_VALUE_INIT;
|
||||
const gchar *format;
|
||||
guint i;
|
||||
|
||||
g_return_val_if_fail (GST_IS_CAPS (caps), FALSE);
|
||||
g_return_val_if_fail (formats, FALSE);
|
||||
|
||||
if (formats->len == 1) {
|
||||
format = g_ptr_array_index (formats, 0);
|
||||
g_value_init (&v_formats, G_TYPE_STRING);
|
||||
g_value_set_string (&v_formats, format);
|
||||
} else if (formats->len > 1) {
|
||||
|
||||
gst_value_list_init (&v_formats, formats->len);
|
||||
|
||||
for (i = 0; i < formats->len; i++) {
|
||||
format = g_ptr_array_index (formats, i);
|
||||
_value_list_append_string (&v_formats, format);
|
||||
}
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gst_caps_set_value (caps, "drm-format", &v_formats);
|
||||
g_value_unset (&v_formats);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Fix raw frames ill reported by drivers.
|
||||
*
|
||||
* Mesa Gallium reports P010 and P016 for H264 encoder:
|
||||
|
@ -154,32 +186,15 @@ gst_caps_set_format_array (GstCaps * caps, GArray * formats)
|
|||
* XXX: add issue or pr
|
||||
*/
|
||||
static gboolean
|
||||
fix_raw_formats (GstVaDisplay * display, VAConfigID config, GArray * formats)
|
||||
fix_raw_formats (GstVaDisplay * display, VAProfile profile,
|
||||
VAEntrypoint entrypoint, GArray * formats)
|
||||
{
|
||||
VADisplay dpy;
|
||||
VAStatus status;
|
||||
VAProfile profile;
|
||||
VAEntrypoint entrypoint;
|
||||
VAConfigAttrib *attribs;
|
||||
GstVideoFormat format;
|
||||
int num;
|
||||
|
||||
if (!(GST_VA_DISPLAY_IS_IMPLEMENTATION (display, INTEL_I965) ||
|
||||
GST_VA_DISPLAY_IS_IMPLEMENTATION (display, MESA_GALLIUM)))
|
||||
return TRUE;
|
||||
|
||||
dpy = gst_va_display_get_va_dpy (display);
|
||||
attribs = g_new (VAConfigAttrib, vaMaxNumConfigAttributes (dpy));
|
||||
status = vaQueryConfigAttributes (dpy, config, &profile, &entrypoint, attribs,
|
||||
&num);
|
||||
g_free (attribs);
|
||||
|
||||
if (status != VA_STATUS_SUCCESS) {
|
||||
GST_ERROR_OBJECT (display, "vaQueryConfigAttributes: %s",
|
||||
vaErrorStr (status));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (gst_va_profile_codec (profile) != H264
|
||||
|| entrypoint != VAEntrypointEncSlice)
|
||||
return TRUE;
|
||||
|
@ -190,6 +205,110 @@ fix_raw_formats (GstVaDisplay * display, VAConfigID config, GArray * formats)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
GstCaps *
|
||||
gst_va_create_dma_caps (GstVaDisplay * display, VAEntrypoint entrypoint,
|
||||
GArray * formats, gint min_width, gint max_width,
|
||||
gint min_height, gint max_height)
|
||||
{
|
||||
guint usage_hint;
|
||||
guint64 modifier;
|
||||
guint32 fourcc;
|
||||
GstVideoFormat fmt;
|
||||
gchar *drm_fmt_str;
|
||||
GPtrArray *drm_formats_str;
|
||||
GstCaps *caps = NULL;
|
||||
guint i;
|
||||
|
||||
switch (entrypoint) {
|
||||
case VAEntrypointVLD:
|
||||
usage_hint = VA_SURFACE_ATTRIB_USAGE_HINT_DECODER;
|
||||
break;
|
||||
case VAEntrypointEncSlice:
|
||||
case VAEntrypointEncSliceLP:
|
||||
case VAEntrypointEncPicture:
|
||||
usage_hint = VA_SURFACE_ATTRIB_USAGE_HINT_ENCODER;
|
||||
break;
|
||||
case VAEntrypointVideoProc:
|
||||
usage_hint = VA_SURFACE_ATTRIB_USAGE_HINT_VPP_READ |
|
||||
VA_SURFACE_ATTRIB_USAGE_HINT_VPP_WRITE;
|
||||
break;
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
break;
|
||||
}
|
||||
|
||||
drm_formats_str = g_ptr_array_new_with_free_func (g_free);
|
||||
|
||||
for (i = 0; i < formats->len; i++) {
|
||||
fmt = g_array_index (formats, GstVideoFormat, i);
|
||||
|
||||
fourcc = gst_va_drm_fourcc_from_video_format (fmt);
|
||||
if (fourcc == DRM_FORMAT_INVALID)
|
||||
continue;
|
||||
|
||||
modifier = gst_va_dmabuf_get_modifier_for_format (display, fmt, usage_hint);
|
||||
if (modifier == DRM_FORMAT_MOD_INVALID)
|
||||
continue;
|
||||
|
||||
drm_fmt_str = gst_video_dma_drm_fourcc_to_string (fourcc, modifier);
|
||||
|
||||
g_ptr_array_add (drm_formats_str, drm_fmt_str);
|
||||
}
|
||||
|
||||
if (drm_formats_str->len == 0)
|
||||
goto out;
|
||||
|
||||
caps = gst_caps_new_simple ("video/x-raw", "width", GST_TYPE_INT_RANGE,
|
||||
min_width, max_width, "height", GST_TYPE_INT_RANGE, min_height,
|
||||
max_height, NULL);
|
||||
|
||||
gst_caps_set_features_simple (caps,
|
||||
gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_DMABUF));
|
||||
|
||||
gst_caps_set_simple (caps, "format", G_TYPE_STRING, "DMA_DRM", NULL);
|
||||
|
||||
if (!gst_caps_set_drm_format_array (caps, drm_formats_str)) {
|
||||
gst_clear_caps (&caps);
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
g_ptr_array_unref (drm_formats_str);
|
||||
return caps;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_get_entrypoint_from_config (GstVaDisplay * display, VAConfigID config,
|
||||
VAProfile * profile_out, VAEntrypoint * entrypoint_out)
|
||||
{
|
||||
VADisplay dpy;
|
||||
VAStatus status;
|
||||
VAProfile profile;
|
||||
VAEntrypoint entrypoint;
|
||||
VAConfigAttrib *attribs;
|
||||
int num_attribs = 0;
|
||||
|
||||
dpy = gst_va_display_get_va_dpy (display);
|
||||
|
||||
attribs = g_new (VAConfigAttrib, vaMaxNumConfigAttributes (dpy));
|
||||
status = vaQueryConfigAttributes (dpy, config, &profile, &entrypoint, attribs,
|
||||
&num_attribs);
|
||||
g_free (attribs);
|
||||
|
||||
if (status != VA_STATUS_SUCCESS) {
|
||||
GST_ERROR_OBJECT (display, "vaQueryConfigAttributes: %s",
|
||||
vaErrorStr (status));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (profile_out)
|
||||
*profile_out = profile;
|
||||
if (entrypoint_out)
|
||||
*entrypoint_out = entrypoint;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GstCaps *
|
||||
gst_va_create_raw_caps_from_config (GstVaDisplay * display, VAConfigID config)
|
||||
{
|
||||
|
@ -198,10 +317,15 @@ gst_va_create_raw_caps_from_config (GstVaDisplay * display, VAConfigID config)
|
|||
GstCapsFeatures *features;
|
||||
GstVideoFormat format;
|
||||
VASurfaceAttrib *attribs;
|
||||
VAEntrypoint entrypoint;
|
||||
VAProfile profile;
|
||||
guint i, attrib_count, mem_type = 0;
|
||||
gint min_width = 1, max_width = G_MAXINT;
|
||||
gint min_height = 1, max_height = G_MAXINT;
|
||||
|
||||
if (!_get_entrypoint_from_config (display, config, &profile, &entrypoint))
|
||||
return NULL;
|
||||
|
||||
attribs = gst_va_get_surface_attribs (display, config, &attrib_count);
|
||||
if (!attribs)
|
||||
return NULL;
|
||||
|
@ -241,7 +365,7 @@ gst_va_create_raw_caps_from_config (GstVaDisplay * display, VAConfigID config)
|
|||
if (formats->len == 0)
|
||||
goto bail;
|
||||
|
||||
if (!fix_raw_formats (display, config, formats))
|
||||
if (!fix_raw_formats (display, profile, entrypoint, formats))
|
||||
goto bail;
|
||||
|
||||
base_caps = gst_caps_new_simple ("video/x-raw", "width", GST_TYPE_INT_RANGE,
|
||||
|
@ -263,10 +387,10 @@ gst_va_create_raw_caps_from_config (GstVaDisplay * display, VAConfigID config)
|
|||
}
|
||||
if (mem_type & VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME
|
||||
|| mem_type & VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2) {
|
||||
feature_caps = gst_caps_copy (base_caps);
|
||||
features = gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_DMABUF);
|
||||
gst_caps_set_features_simple (feature_caps, features);
|
||||
caps = gst_caps_merge (caps, feature_caps);
|
||||
feature_caps = gst_va_create_dma_caps (display, entrypoint, formats,
|
||||
min_width, max_width, min_height, max_height);
|
||||
if (feature_caps)
|
||||
caps = gst_caps_merge (caps, feature_caps);
|
||||
}
|
||||
|
||||
/* raw caps */
|
||||
|
|
|
@ -35,6 +35,13 @@ VASurfaceAttrib * gst_va_get_surface_attribs (GstVaDisplay * displa
|
|||
VAConfigID config,
|
||||
guint * attrib_count);
|
||||
|
||||
GstCaps * gst_va_create_dma_caps (GstVaDisplay * display,
|
||||
VAEntrypoint entrypoint,
|
||||
GArray * formats,
|
||||
gint min_width,
|
||||
gint max_width,
|
||||
gint min_height,
|
||||
gint max_height);
|
||||
GstCaps * gst_va_create_raw_caps_from_config (GstVaDisplay * display,
|
||||
VAConfigID config);
|
||||
GstCaps * gst_va_create_coded_caps (GstVaDisplay * display,
|
||||
|
|
|
@ -1071,10 +1071,11 @@ gst_va_filter_get_caps (GstVaFilter * self)
|
|||
}
|
||||
if (mem_types & VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME
|
||||
|| mem_types & VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2) {
|
||||
feature_caps = gst_caps_copy (base_caps);
|
||||
features = gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_DMABUF);
|
||||
gst_caps_set_features_simple (feature_caps, features);
|
||||
caps = gst_caps_merge (caps, feature_caps);
|
||||
feature_caps = gst_va_create_dma_caps (self->display,
|
||||
VAEntrypointVideoProc, surface_formats,
|
||||
self->min_width, self->max_width, self->min_height, self->max_height);
|
||||
if (feature_caps)
|
||||
caps = gst_caps_merge (caps, feature_caps);
|
||||
}
|
||||
|
||||
gst_caps_unref (base_caps);
|
||||
|
|
Loading…
Reference in a new issue