mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-29 21:21:12 +00:00
va: Apply the new DMA format:modifier pair negotiation in vpp
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/4044>
This commit is contained in:
parent
5df0bfa7cb
commit
d0587cda74
2 changed files with 128 additions and 25 deletions
|
@ -25,6 +25,7 @@
|
||||||
#include "gstvabasetransform.h"
|
#include "gstvabasetransform.h"
|
||||||
|
|
||||||
#include <gst/va/gstva.h>
|
#include <gst/va/gstva.h>
|
||||||
|
#include <gst/va/gstvavideoformat.h>
|
||||||
|
|
||||||
#include "gstvacaps.h"
|
#include "gstvacaps.h"
|
||||||
#include "gstvapluginutils.h"
|
#include "gstvapluginutils.h"
|
||||||
|
@ -177,11 +178,11 @@ gst_va_base_transform_set_caps (GstBaseTransform * trans, GstCaps * incaps,
|
||||||
gboolean res;
|
gboolean res;
|
||||||
|
|
||||||
/* input caps */
|
/* input caps */
|
||||||
if (!gst_video_info_from_caps (&in_info, incaps))
|
if (!gst_va_video_info_from_caps (&in_info, NULL, incaps))
|
||||||
goto invalid_caps;
|
goto invalid_caps;
|
||||||
|
|
||||||
/* output caps */
|
/* output caps */
|
||||||
if (!gst_video_info_from_caps (&out_info, outcaps))
|
if (!gst_va_video_info_from_caps (&out_info, NULL, outcaps))
|
||||||
goto invalid_caps;
|
goto invalid_caps;
|
||||||
|
|
||||||
fclass = GST_VA_BASE_TRANSFORM_GET_CLASS (self);
|
fclass = GST_VA_BASE_TRANSFORM_GET_CLASS (self);
|
||||||
|
@ -253,7 +254,7 @@ gst_va_base_transform_propose_allocation (GstBaseTransform * trans,
|
||||||
gst_query_parse_allocation (query, &caps, NULL);
|
gst_query_parse_allocation (query, &caps, NULL);
|
||||||
if (!caps)
|
if (!caps)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if (!gst_video_info_from_caps (&info, caps)) {
|
if (!gst_va_video_info_from_caps (&info, NULL, caps)) {
|
||||||
GST_ERROR_OBJECT (self, "Cannot parse caps %" GST_PTR_FORMAT, caps);
|
GST_ERROR_OBJECT (self, "Cannot parse caps %" GST_PTR_FORMAT, caps);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -353,7 +354,7 @@ gst_va_base_transform_decide_allocation (GstBaseTransform * trans,
|
||||||
gst_allocation_params_init (&other_params);
|
gst_allocation_params_init (&other_params);
|
||||||
gst_allocation_params_init (¶ms);
|
gst_allocation_params_init (¶ms);
|
||||||
|
|
||||||
if (!gst_video_info_from_caps (&vinfo, outcaps)) {
|
if (!gst_va_video_info_from_caps (&vinfo, NULL, outcaps)) {
|
||||||
GST_ERROR_OBJECT (self, "Cannot parse caps %" GST_PTR_FORMAT, outcaps);
|
GST_ERROR_OBJECT (self, "Cannot parse caps %" GST_PTR_FORMAT, outcaps);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -848,6 +849,35 @@ _get_sinkpad_pool (GstVaBaseTransform * self, GstBuffer * inbuf)
|
||||||
else
|
else
|
||||||
caps = gst_caps_copy (self->in_caps);
|
caps = gst_caps_copy (self->in_caps);
|
||||||
|
|
||||||
|
g_assert (gst_caps_is_fixed (caps));
|
||||||
|
/* For DMA buffer, we can only import linear buffers.
|
||||||
|
Replace the drm-format into format field. */
|
||||||
|
if (gst_video_is_dma_drm_caps (caps)) {
|
||||||
|
GstVideoInfoDmaDrm dma_info;
|
||||||
|
GstVideoInfo info;
|
||||||
|
|
||||||
|
if (!gst_video_info_dma_drm_from_caps (&dma_info, caps)) {
|
||||||
|
GST_ERROR_OBJECT (self, "Cannot parse caps %" GST_PTR_FORMAT, caps);
|
||||||
|
gst_caps_unref (caps);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dma_info.drm_modifier != DRM_FORMAT_MOD_LINEAR) {
|
||||||
|
GST_ERROR_OBJECT (self, "Cannot import non-linear DMA buffer");
|
||||||
|
gst_caps_unref (caps);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gst_va_dma_drm_info_to_video_info (&dma_info, &info)) {
|
||||||
|
GST_ERROR_OBJECT (self, "Cannot get va video info");
|
||||||
|
gst_caps_unref (caps);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
gst_caps_set_simple (caps, "format", G_TYPE_STRING,
|
||||||
|
gst_video_format_to_string (GST_VIDEO_INFO_FORMAT (&info)), NULL);
|
||||||
|
gst_structure_remove_field (gst_caps_get_structure (caps, 0), "drm-format");
|
||||||
|
}
|
||||||
gst_caps_set_features_simple (caps,
|
gst_caps_set_features_simple (caps,
|
||||||
gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_VA));
|
gst_caps_features_from_string (GST_CAPS_FEATURE_MEMORY_VA));
|
||||||
|
|
||||||
|
|
|
@ -65,6 +65,7 @@
|
||||||
#include <gst/va/gstva.h>
|
#include <gst/va/gstva.h>
|
||||||
#include <gst/video/video.h>
|
#include <gst/video/video.h>
|
||||||
#include <va/va_drmcommon.h>
|
#include <va/va_drmcommon.h>
|
||||||
|
#include <gst/va/gstvavideoformat.h>
|
||||||
|
|
||||||
#include "gstvabasetransform.h"
|
#include "gstvabasetransform.h"
|
||||||
#include "gstvacaps.h"
|
#include "gstvacaps.h"
|
||||||
|
@ -942,8 +943,8 @@ gst_va_vpp_caps_remove_fields (GstCaps * caps)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* remove format-related fields */
|
/* remove format-related fields */
|
||||||
gst_structure_remove_fields (structure, "format", "colorimetry",
|
gst_structure_remove_fields (structure, "format", "drm-format",
|
||||||
"chroma-site", NULL);
|
"colorimetry", "chroma-site", NULL);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1190,34 +1191,63 @@ gst_va_vpp_fixate_format (GstVaVpp * self, GstCaps * caps, GstCaps * result)
|
||||||
GstVideoFormat fmt;
|
GstVideoFormat fmt;
|
||||||
gint min_loss = G_MAXINT;
|
gint min_loss = G_MAXINT;
|
||||||
guint i, best_i, capslen;
|
guint i, best_i, capslen;
|
||||||
|
guint64 best_modifier;
|
||||||
|
|
||||||
ins = gst_caps_get_structure (caps, 0);
|
ins = gst_caps_get_structure (caps, 0);
|
||||||
|
|
||||||
|
if (gst_video_is_dma_drm_caps (caps)) {
|
||||||
|
guint32 fourcc;
|
||||||
|
GstVideoFormat video_format;
|
||||||
|
|
||||||
|
in_format = gst_structure_get_string (ins, "drm-format");
|
||||||
|
if (!in_format)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
fourcc = gst_video_dma_drm_fourcc_from_string (in_format, NULL);
|
||||||
|
video_format = gst_va_video_format_from_drm_fourcc (fourcc);
|
||||||
|
if (video_format == GST_VIDEO_FORMAT_UNKNOWN)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
in_info = gst_video_format_get_info (video_format);
|
||||||
|
} else {
|
||||||
in_format = gst_structure_get_string (ins, "format");
|
in_format = gst_structure_get_string (ins, "format");
|
||||||
if (!in_format)
|
if (!in_format)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
GST_DEBUG_OBJECT (self, "source format %s", in_format);
|
|
||||||
|
|
||||||
in_info =
|
in_info =
|
||||||
gst_video_format_get_info (gst_video_format_from_string (in_format));
|
gst_video_format_get_info (gst_video_format_from_string (in_format));
|
||||||
|
}
|
||||||
|
|
||||||
if (!in_info)
|
if (!in_info)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
GST_DEBUG_OBJECT (self, "source format %s", in_format);
|
||||||
|
|
||||||
best_i = 0;
|
best_i = 0;
|
||||||
|
best_modifier = DRM_FORMAT_MOD_INVALID;
|
||||||
capslen = gst_caps_get_size (result);
|
capslen = gst_caps_get_size (result);
|
||||||
GST_DEBUG_OBJECT (self, "iterate %d structures", capslen);
|
GST_DEBUG_OBJECT (self, "iterate %d structures", capslen);
|
||||||
for (i = 0; i < capslen; i++) {
|
for (i = 0; i < capslen; i++) {
|
||||||
|
gboolean is_dma;
|
||||||
GstStructure *tests;
|
GstStructure *tests;
|
||||||
const GValue *format;
|
const GValue *format;
|
||||||
|
guint64 modifier;
|
||||||
|
guint32 fourcc;
|
||||||
|
|
||||||
|
features = gst_caps_get_features (result, i);
|
||||||
tests = gst_caps_get_structure (result, i);
|
tests = gst_caps_get_structure (result, i);
|
||||||
|
|
||||||
|
if (gst_caps_features_contains (features, GST_CAPS_FEATURE_MEMORY_DMABUF)) {
|
||||||
|
format = gst_structure_get_value (tests, "drm-format");
|
||||||
|
is_dma = TRUE;
|
||||||
|
} else {
|
||||||
format = gst_structure_get_value (tests, "format");
|
format = gst_structure_get_value (tests, "format");
|
||||||
|
is_dma = FALSE;
|
||||||
|
}
|
||||||
/* should not happen */
|
/* should not happen */
|
||||||
if (format == NULL)
|
if (format == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
features = gst_caps_get_features (result, i);
|
|
||||||
|
|
||||||
if (GST_VALUE_HOLDS_LIST (format)) {
|
if (GST_VALUE_HOLDS_LIST (format)) {
|
||||||
gint j, len;
|
gint j, len;
|
||||||
|
|
||||||
|
@ -1226,23 +1256,52 @@ gst_va_vpp_fixate_format (GstVaVpp * self, GstCaps * caps, GstCaps * result)
|
||||||
for (j = 0; j < len; j++) {
|
for (j = 0; j < len; j++) {
|
||||||
const GValue *val;
|
const GValue *val;
|
||||||
|
|
||||||
|
modifier = DRM_FORMAT_MOD_INVALID;
|
||||||
|
|
||||||
val = gst_value_list_get_value (format, j);
|
val = gst_value_list_get_value (format, j);
|
||||||
if (G_VALUE_HOLDS_STRING (val)) {
|
if (G_VALUE_HOLDS_STRING (val)) {
|
||||||
|
if (is_dma) {
|
||||||
|
fourcc = gst_video_dma_drm_fourcc_from_string
|
||||||
|
(g_value_get_string (val), &modifier);
|
||||||
|
fmt = gst_va_video_format_from_drm_fourcc (fourcc);
|
||||||
|
} else {
|
||||||
fmt = gst_video_format_from_string (g_value_get_string (val));
|
fmt = gst_video_format_from_string (g_value_get_string (val));
|
||||||
|
}
|
||||||
|
if (fmt == GST_VIDEO_FORMAT_UNKNOWN)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (!gst_va_filter_has_video_format (btrans->filter, fmt, features))
|
if (!gst_va_filter_has_video_format (btrans->filter, fmt, features))
|
||||||
continue;
|
continue;
|
||||||
if (score_value (self, in_info, fmt, &min_loss, &out_info))
|
|
||||||
|
if (score_value (self, in_info, fmt, &min_loss, &out_info)) {
|
||||||
best_i = i;
|
best_i = i;
|
||||||
|
best_modifier = modifier;
|
||||||
|
}
|
||||||
|
|
||||||
if (min_loss == 0)
|
if (min_loss == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (G_VALUE_HOLDS_STRING (format)) {
|
} else if (G_VALUE_HOLDS_STRING (format)) {
|
||||||
|
modifier = DRM_FORMAT_MOD_INVALID;
|
||||||
|
|
||||||
|
if (is_dma) {
|
||||||
|
fourcc = gst_video_dma_drm_fourcc_from_string
|
||||||
|
(g_value_get_string (format), &modifier);
|
||||||
|
fmt = gst_va_video_format_from_drm_fourcc (fourcc);
|
||||||
|
} else {
|
||||||
fmt = gst_video_format_from_string (g_value_get_string (format));
|
fmt = gst_video_format_from_string (g_value_get_string (format));
|
||||||
|
}
|
||||||
|
if (fmt == GST_VIDEO_FORMAT_UNKNOWN)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (!gst_va_filter_has_video_format (btrans->filter, fmt, features))
|
if (!gst_va_filter_has_video_format (btrans->filter, fmt, features))
|
||||||
continue;
|
continue;
|
||||||
if (score_value (self, in_info, fmt, &min_loss, &out_info))
|
|
||||||
|
if (score_value (self, in_info, fmt, &min_loss, &out_info)) {
|
||||||
best_i = i;
|
best_i = i;
|
||||||
|
best_modifier = modifier;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (min_loss == 0)
|
if (min_loss == 0)
|
||||||
|
@ -1255,8 +1314,21 @@ gst_va_vpp_fixate_format (GstVaVpp * self, GstCaps * caps, GstCaps * result)
|
||||||
|
|
||||||
features = gst_caps_features_copy (gst_caps_get_features (result, best_i));
|
features = gst_caps_features_copy (gst_caps_get_features (result, best_i));
|
||||||
out = gst_structure_copy (gst_caps_get_structure (result, best_i));
|
out = gst_structure_copy (gst_caps_get_structure (result, best_i));
|
||||||
|
|
||||||
|
if (gst_caps_features_contains (features, GST_CAPS_FEATURE_MEMORY_DMABUF)) {
|
||||||
|
gchar *drm_fmt_name;
|
||||||
|
|
||||||
|
g_assert (best_modifier != DRM_FORMAT_MOD_INVALID);
|
||||||
|
|
||||||
|
drm_fmt_name = gst_video_dma_drm_fourcc_to_string
|
||||||
|
(gst_va_drm_fourcc_from_video_format (out_info->format),
|
||||||
|
best_modifier);
|
||||||
|
gst_structure_set (out, "drm-format", G_TYPE_STRING, drm_fmt_name, NULL);
|
||||||
|
g_free (drm_fmt_name);
|
||||||
|
} else {
|
||||||
gst_structure_set (out, "format", G_TYPE_STRING,
|
gst_structure_set (out, "format", G_TYPE_STRING,
|
||||||
GST_VIDEO_FORMAT_INFO_NAME (out_info), NULL);
|
GST_VIDEO_FORMAT_INFO_NAME (out_info), NULL);
|
||||||
|
}
|
||||||
ret = gst_caps_new_full (out, NULL);
|
ret = gst_caps_new_full (out, NULL);
|
||||||
gst_caps_set_features_simple (ret, features);
|
gst_caps_set_features_simple (ret, features);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1757,12 +1829,13 @@ transfer_colorimetry_from_input (GstVaVpp * self, GstCaps * in_caps,
|
||||||
const GValue *in_colorimetry =
|
const GValue *in_colorimetry =
|
||||||
gst_structure_get_value (in_caps_s, "colorimetry");
|
gst_structure_get_value (in_caps_s, "colorimetry");
|
||||||
|
|
||||||
if (!gst_video_info_from_caps (&in_info, in_caps)) {
|
if (!gst_va_video_info_from_caps (&in_info, NULL, in_caps)) {
|
||||||
GST_WARNING_OBJECT (self,
|
GST_WARNING_OBJECT (self,
|
||||||
"Failed to convert sink pad caps to video info");
|
"Failed to convert sink pad caps to video info");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!gst_video_info_from_caps (&out_info, out_caps)) {
|
|
||||||
|
if (!gst_va_video_info_from_caps (&out_info, NULL, out_caps)) {
|
||||||
GST_WARNING_OBJECT (self, "Failed to convert src pad caps to video info");
|
GST_WARNING_OBJECT (self, "Failed to convert src pad caps to video info");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1844,7 +1917,7 @@ update_hdr_fields (GstVaVpp * self, GstCaps * result)
|
||||||
|
|
||||||
have_colorimetry = gst_structure_has_field (s, "colorimetry");
|
have_colorimetry = gst_structure_has_field (s, "colorimetry");
|
||||||
if (!have_colorimetry) {
|
if (!have_colorimetry) {
|
||||||
if (gst_video_info_from_caps (&out_info, result)) {
|
if (gst_va_video_info_from_caps (&out_info, NULL, result)) {
|
||||||
gchar *colorimetry_str =
|
gchar *colorimetry_str =
|
||||||
gst_video_colorimetry_to_string (&out_info.colorimetry);
|
gst_video_colorimetry_to_string (&out_info.colorimetry);
|
||||||
gst_caps_set_simple (result, "colorimetry", G_TYPE_STRING,
|
gst_caps_set_simple (result, "colorimetry", G_TYPE_STRING,
|
||||||
|
|
Loading…
Reference in a new issue