mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 06:54:49 +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;
|
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.
|
/* Fix raw frames ill reported by drivers.
|
||||||
*
|
*
|
||||||
* Mesa Gallium reports P010 and P016 for H264 encoder:
|
* 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
|
* XXX: add issue or pr
|
||||||
*/
|
*/
|
||||||
static gboolean
|
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;
|
GstVideoFormat format;
|
||||||
int num;
|
|
||||||
|
|
||||||
if (!(GST_VA_DISPLAY_IS_IMPLEMENTATION (display, INTEL_I965) ||
|
if (!(GST_VA_DISPLAY_IS_IMPLEMENTATION (display, INTEL_I965) ||
|
||||||
GST_VA_DISPLAY_IS_IMPLEMENTATION (display, MESA_GALLIUM)))
|
GST_VA_DISPLAY_IS_IMPLEMENTATION (display, MESA_GALLIUM)))
|
||||||
return TRUE;
|
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
|
if (gst_va_profile_codec (profile) != H264
|
||||||
|| entrypoint != VAEntrypointEncSlice)
|
|| entrypoint != VAEntrypointEncSlice)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -190,6 +205,110 @@ fix_raw_formats (GstVaDisplay * display, VAConfigID config, GArray * formats)
|
||||||
return TRUE;
|
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 *
|
GstCaps *
|
||||||
gst_va_create_raw_caps_from_config (GstVaDisplay * display, VAConfigID config)
|
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;
|
GstCapsFeatures *features;
|
||||||
GstVideoFormat format;
|
GstVideoFormat format;
|
||||||
VASurfaceAttrib *attribs;
|
VASurfaceAttrib *attribs;
|
||||||
|
VAEntrypoint entrypoint;
|
||||||
|
VAProfile profile;
|
||||||
guint i, attrib_count, mem_type = 0;
|
guint i, attrib_count, mem_type = 0;
|
||||||
gint min_width = 1, max_width = G_MAXINT;
|
gint min_width = 1, max_width = G_MAXINT;
|
||||||
gint min_height = 1, max_height = 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);
|
attribs = gst_va_get_surface_attribs (display, config, &attrib_count);
|
||||||
if (!attribs)
|
if (!attribs)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -241,7 +365,7 @@ gst_va_create_raw_caps_from_config (GstVaDisplay * display, VAConfigID config)
|
||||||
if (formats->len == 0)
|
if (formats->len == 0)
|
||||||
goto bail;
|
goto bail;
|
||||||
|
|
||||||
if (!fix_raw_formats (display, config, formats))
|
if (!fix_raw_formats (display, profile, entrypoint, formats))
|
||||||
goto bail;
|
goto bail;
|
||||||
|
|
||||||
base_caps = gst_caps_new_simple ("video/x-raw", "width", GST_TYPE_INT_RANGE,
|
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
|
if (mem_type & VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME
|
||||||
|| mem_type & VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2) {
|
|| mem_type & VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2) {
|
||||||
feature_caps = gst_caps_copy (base_caps);
|
feature_caps = gst_va_create_dma_caps (display, entrypoint, formats,
|
||||||
features = gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_DMABUF);
|
min_width, max_width, min_height, max_height);
|
||||||
gst_caps_set_features_simple (feature_caps, features);
|
if (feature_caps)
|
||||||
caps = gst_caps_merge (caps, feature_caps);
|
caps = gst_caps_merge (caps, feature_caps);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* raw caps */
|
/* raw caps */
|
||||||
|
|
|
@ -35,6 +35,13 @@ VASurfaceAttrib * gst_va_get_surface_attribs (GstVaDisplay * displa
|
||||||
VAConfigID config,
|
VAConfigID config,
|
||||||
guint * attrib_count);
|
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,
|
GstCaps * gst_va_create_raw_caps_from_config (GstVaDisplay * display,
|
||||||
VAConfigID config);
|
VAConfigID config);
|
||||||
GstCaps * gst_va_create_coded_caps (GstVaDisplay * display,
|
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
|
if (mem_types & VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME
|
||||||
|| mem_types & VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2) {
|
|| mem_types & VA_SURFACE_ATTRIB_MEM_TYPE_DRM_PRIME_2) {
|
||||||
feature_caps = gst_caps_copy (base_caps);
|
feature_caps = gst_va_create_dma_caps (self->display,
|
||||||
features = gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_DMABUF);
|
VAEntrypointVideoProc, surface_formats,
|
||||||
gst_caps_set_features_simple (feature_caps, features);
|
self->min_width, self->max_width, self->min_height, self->max_height);
|
||||||
caps = gst_caps_merge (caps, feature_caps);
|
if (feature_caps)
|
||||||
|
caps = gst_caps_merge (caps, feature_caps);
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_caps_unref (base_caps);
|
gst_caps_unref (base_caps);
|
||||||
|
|
Loading…
Reference in a new issue