summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHe Junyan <junyan.he@hotmail.com>2020-04-10 21:44:05 +0800
committerVíctor Manuel Jáquez Leal <vjaquez@igalia.com>2020-05-16 19:58:15 +0000
commit0e4c7509187c43661474e52f8013816bb5e235cd (patch)
treef9e7e7a8742a28426d2ee3d404d3042704420ed5
parent3583a4b86cc8a9398939ec84fbee8ca370a54ed1 (diff)
plugins: util: Add a helper function to detect supported caps.
This helper function iterate all profiles and entrypoints belong to the specified codec, query the VAConfigAttribRTFormat and list all possible video formats. This function is used by each codec to get the template sink caps (for encode) or src caps(for decode) at register time, when just all possible formats are listed and no need to be very accurate. So there is no context created for the performance reason. Most codecs just use YUV kinds of formats as the input/output, so we do not include RGB kinds of formats. User can specified more formats in extra_fmts(For example, jpeg may need BGRA) if needed. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer-vaapi/-/merge_requests/315>
-rw-r--r--gst/vaapi/gstvaapipluginutil.c105
-rw-r--r--gst/vaapi/gstvaapipluginutil.h6
2 files changed, 111 insertions, 0 deletions
diff --git a/gst/vaapi/gstvaapipluginutil.c b/gst/vaapi/gstvaapipluginutil.c
index ce3179d5..0e55640f 100644
--- a/gst/vaapi/gstvaapipluginutil.c
+++ b/gst/vaapi/gstvaapipluginutil.c
@@ -25,6 +25,7 @@
#include "gstcompat.h"
#include "gstvaapivideocontext.h"
#include <gst/vaapi/gstvaapiprofilecaps.h>
+#include <gst/vaapi/gstvaapiutils.h>
#if USE_DRM
# include <gst/vaapi/gstvaapidisplay_drm.h>
#endif
@@ -1138,3 +1139,107 @@ gst_vaapi_build_caps_from_formats (GArray * formats, gint min_width,
return out_caps;
}
+
+/**
+ * gst_vaapi_build_template_caps_by_codec:
+ * @display: a #GstVaapiDisplay
+ * @usage: used for encode, decode or postproc
+ * @codec: a #GstVaapiCodec specify the codec to detect
+ * @extra_fmts: a #GArray of extra #GstVideoFormat
+ *
+ * Called by vaapi elements to detect the all possible video formats belong to
+ * the specified codec and build the caps. Only YUV kinds of formats are detected
+ * because so far almost all codecs use YUV kinds of formats as input/output.
+ * extra_fmts can specified more formats to be included.
+ *
+ * Returns: a built #GstCaps if succeeds, or %NULL if error.
+ **/
+GstCaps *
+gst_vaapi_build_template_caps_by_codec (GstVaapiDisplay * display,
+ GstVaapiContextUsage usage, GstVaapiCodec codec, GArray * extra_fmts)
+{
+ GArray *profiles = NULL;
+ GArray *supported_fmts = NULL;
+ GstCaps *out_caps = NULL;
+ guint i, e;
+ GstVaapiProfile profile;
+ guint value;
+ guint chroma;
+ GstVaapiChromaType gst_chroma;
+ GstVaapiEntrypoint entrypoint_start, entrypoint_end;
+
+ if (usage == GST_VAAPI_CONTEXT_USAGE_ENCODE) {
+ profiles = gst_vaapi_display_get_encode_profiles (display);
+ entrypoint_start = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE;
+ entrypoint_end = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE_LP;
+ } else if (usage == GST_VAAPI_CONTEXT_USAGE_DECODE) {
+ profiles = gst_vaapi_display_get_decode_profiles (display);
+ entrypoint_start = GST_VAAPI_ENTRYPOINT_VLD;
+ entrypoint_end = GST_VAAPI_ENTRYPOINT_MOCO;
+ }
+ /* TODO: VPP */
+
+ if (!profiles)
+ goto out;
+
+ chroma = 0;
+ for (i = 0; i < profiles->len; i++) {
+ profile = g_array_index (profiles, GstVaapiProfile, i);
+ if (gst_vaapi_profile_get_codec (profile) != codec)
+ continue;
+
+ for (e = entrypoint_start; e <= entrypoint_end; e++) {
+ if (!gst_vaapi_get_config_attribute (display,
+ gst_vaapi_profile_get_va_profile (profile),
+ gst_vaapi_entrypoint_get_va_entrypoint (e),
+ VAConfigAttribRTFormat, &value))
+ continue;
+
+ chroma |= value;
+ }
+ }
+
+ if (!chroma)
+ goto out;
+
+ for (gst_chroma = GST_VAAPI_CHROMA_TYPE_YUV420;
+ gst_chroma <= GST_VAAPI_CHROMA_TYPE_YUV444_12BPP; gst_chroma++) {
+ GArray *fmts;
+ if (!(chroma & from_GstVaapiChromaType (gst_chroma)))
+ continue;
+
+ fmts = gst_vaapi_video_format_get_formats_by_chroma (gst_chroma);
+ if (!fmts)
+ continue;
+
+ /* One format can not belong to different chroma, no need to merge */
+ if (supported_fmts == NULL) {
+ supported_fmts = fmts;
+ } else {
+ for (i = 0; i < fmts->len; i++)
+ g_array_append_val (supported_fmts,
+ g_array_index (fmts, GstVideoFormat, i));
+ g_array_unref (fmts);
+ }
+ }
+
+ if (!supported_fmts)
+ goto out;
+
+ if (extra_fmts) {
+ for (i = 0; i < extra_fmts->len; i++)
+ g_array_append_val (supported_fmts,
+ g_array_index (extra_fmts, GstVideoFormat, i));
+ }
+
+ out_caps = gst_vaapi_build_caps_from_formats (supported_fmts, 1, 1,
+ G_MAXINT, G_MAXINT, TRUE);
+
+out:
+ if (profiles)
+ g_array_unref (profiles);
+ if (supported_fmts)
+ g_array_unref (supported_fmts);
+
+ return out_caps;
+}
diff --git a/gst/vaapi/gstvaapipluginutil.h b/gst/vaapi/gstvaapipluginutil.h
index 99b6e133..abdaf1e9 100644
--- a/gst/vaapi/gstvaapipluginutil.h
+++ b/gst/vaapi/gstvaapipluginutil.h
@@ -27,6 +27,7 @@
#include <gst/vaapi/gstvaapidisplay.h>
#include <gst/vaapi/gstvaapisurface.h>
+#include <gst/vaapi/gstvaapicontext.h>
#include "gstvaapivideomemory.h"
typedef GstVaapiProfile (*GstVaapiStrToProfileFunc) (const gchar * str);
@@ -165,4 +166,9 @@ GstCaps *
gst_vaapi_build_caps_from_formats (GArray * formats, gint min_width,
gint min_height, gint max_width, gint max_height, guint mem_type);
+G_GNUC_INTERNAL
+GstCaps *
+gst_vaapi_build_template_caps_by_codec (GstVaapiDisplay * display,
+ GstVaapiContextUsage usage, GstVaapiCodec codec, GArray * extra_fmts);
+
#endif /* GST_VAAPI_PLUGIN_UTIL_H */