From e0915ce982d20460f6ab1ea3cb347b7fd0539d74 Mon Sep 17 00:00:00 2001 From: He Junyan Date: Thu, 6 May 2021 18:23:23 +0800 Subject: [PATCH] libs: va: Move the VA common logic as a lib. The VA acceleration now has more usages in linux-like platforms, such as the MSDK. The different plugins based on the VA acceleration need to share some common logic and types. We now move the display related functions and types into a common va lib. Part-of: --- gst-libs/gst/meson.build | 1 + {sys => gst-libs/gst}/va/gstvadisplay.c | 159 +++++------------- gst-libs/gst/va/gstvadisplay.h | 134 +++++++++++++++ {sys => gst-libs/gst}/va/gstvadisplay_drm.c | 8 + gst-libs/gst/va/gstvadisplay_drm.h | 39 +++++ .../gst}/va/gstvadisplay_wrapped.c | 8 + gst-libs/gst/va/gstvadisplay_wrapped.h | 39 +++++ gst-libs/gst/va/meson.build | 60 +++++++ gst-libs/gst/va/va-prelude.h | 30 ++++ .../gst/va/va_fwd.h | 16 +- sys/va/gstvaallocator.h | 4 +- sys/va/gstvacaps.c | 6 +- sys/va/gstvacaps.h | 3 +- sys/va/gstvadecoder.c | 3 +- sys/va/gstvadecoder.h | 3 +- sys/va/gstvadevice.c | 1 - sys/va/gstvadevice.h | 2 +- sys/va/gstvadisplay.h | 68 -------- sys/va/gstvadisplay_priv.c | 137 +++++++++++++++ ...gstvadisplay_drm.h => gstvadisplay_priv.h} | 13 +- sys/va/gstvafilter.c | 1 + sys/va/gstvafilter.h | 4 +- sys/va/gstvautils.c | 15 +- sys/va/gstvautils.h | 2 +- sys/va/gstvavpp.c | 2 +- sys/va/meson.build | 28 +-- 26 files changed, 548 insertions(+), 238 deletions(-) rename {sys => gst-libs/gst}/va/gstvadisplay.c (75%) create mode 100644 gst-libs/gst/va/gstvadisplay.h rename {sys => gst-libs/gst}/va/gstvadisplay_drm.c (97%) create mode 100644 gst-libs/gst/va/gstvadisplay_drm.h rename {sys => gst-libs/gst}/va/gstvadisplay_wrapped.c (94%) create mode 100644 gst-libs/gst/va/gstvadisplay_wrapped.h create mode 100644 gst-libs/gst/va/meson.build create mode 100644 gst-libs/gst/va/va-prelude.h rename sys/va/gstvadisplay_wrapped.h => gst-libs/gst/va/va_fwd.h (67%) delete mode 100644 sys/va/gstvadisplay.h create mode 100644 sys/va/gstvadisplay_priv.c rename sys/va/{gstvadisplay_drm.h => gstvadisplay_priv.h} (70%) diff --git a/gst-libs/gst/meson.build b/gst-libs/gst/meson.build index 809ab4ac0f..a2862a3d86 100644 --- a/gst-libs/gst/meson.build +++ b/gst-libs/gst/meson.build @@ -18,3 +18,4 @@ subdir('transcoder') subdir('vulkan') subdir('wayland') subdir('webrtc') +subdir('va') diff --git a/sys/va/gstvadisplay.c b/gst-libs/gst/va/gstvadisplay.c similarity index 75% rename from sys/va/gstvadisplay.c rename to gst-libs/gst/va/gstvadisplay.c index a5139b1721..65a0511aae 100644 --- a/sys/va/gstvadisplay.c +++ b/gst-libs/gst/va/gstvadisplay.c @@ -23,8 +23,7 @@ #endif #include "gstvadisplay.h" -#include "gstvaprofile.h" -#include "gstvavideoformat.h" +#include GST_DEBUG_CATEGORY (gst_va_display_debug); #define GST_CAT_DEFAULT gst_va_display_debug @@ -208,6 +207,15 @@ gst_va_display_init (GstVaDisplay * self) priv->impl = GST_VA_IMPLEMENTATION_INVALID; } +/** + * gst_va_display_lock: + * @self: a #GstVaDisplay + * + * Lock the display. It will be used before we call the + * VA API functions to serialize the VA commands. + * + * Since: 1.20 + **/ void gst_va_display_lock (GstVaDisplay * self) { @@ -220,6 +228,15 @@ gst_va_display_lock (GstVaDisplay * self) g_rec_mutex_lock (&priv->lock); } +/** + * gst_va_display_unlock: + * @self: a #GstVaDisplay + * + * Unlock the display. It will be used after we call the + * VA API functions. + * + * Since: 1.20 + **/ void gst_va_display_unlock (GstVaDisplay * self) { @@ -282,6 +299,8 @@ _va_info (gpointer object, const char *message) * * Returns: %TRUE if the VA driver can be initialized; %FALSE * otherwise + * + * Since: 1.20 **/ gboolean gst_va_display_initialize (GstVaDisplay * self) @@ -321,127 +340,37 @@ gst_va_display_initialize (GstVaDisplay * self) return TRUE; } -VADisplay +/** + * gst_va_display_get_va_dpy: + * @self: a #GstVaDisplay type display. + * + * Get the VA display handle of the @self. + * + * Returns: the VA display handle. + * + * Since: 1.20 + */ +gpointer gst_va_display_get_va_dpy (GstVaDisplay * self) { - VADisplay dpy = 0; + VADisplay dpy; - g_return_val_if_fail (GST_IS_VA_DISPLAY (self), 0); + g_return_val_if_fail (GST_IS_VA_DISPLAY (self), NULL); g_object_get (self, "va-display", &dpy, NULL); return dpy; } -GArray * -gst_va_display_get_profiles (GstVaDisplay * self, guint32 codec, - VAEntrypoint entrypoint) -{ - GArray *ret = NULL; - VADisplay dpy; - VAEntrypoint *entrypoints; - VAProfile *profiles; - VAStatus status; - gint i, j, num_entrypoints = 0, num_profiles = 0; - - g_return_val_if_fail (GST_IS_VA_DISPLAY (self), NULL); - - dpy = gst_va_display_get_va_dpy (self); - - gst_va_display_lock (self); - num_profiles = vaMaxNumProfiles (dpy); - num_entrypoints = vaMaxNumEntrypoints (dpy); - gst_va_display_unlock (self); - - profiles = g_new (VAProfile, num_profiles); - entrypoints = g_new (VAEntrypoint, num_entrypoints); - - gst_va_display_lock (self); - status = vaQueryConfigProfiles (dpy, profiles, &num_profiles); - gst_va_display_unlock (self); - if (status != VA_STATUS_SUCCESS) { - GST_ERROR ("vaQueryConfigProfile: %s", vaErrorStr (status)); - goto bail; - } - - for (i = 0; i < num_profiles; i++) { - if (codec != gst_va_profile_codec (profiles[i])) - continue; - - gst_va_display_lock (self); - status = vaQueryConfigEntrypoints (dpy, profiles[i], entrypoints, - &num_entrypoints); - gst_va_display_unlock (self); - if (status != VA_STATUS_SUCCESS) { - GST_ERROR ("vaQueryConfigEntrypoints: %s", vaErrorStr (status)); - goto bail; - } - - for (j = 0; j < num_entrypoints; j++) { - if (entrypoints[j] == entrypoint) { - if (!ret) - ret = g_array_new (FALSE, FALSE, sizeof (VAProfile)); - g_array_append_val (ret, profiles[i]); - break; - } - } - } - -bail: - g_free (entrypoints); - g_free (profiles); - return ret; -} - -GArray * -gst_va_display_get_image_formats (GstVaDisplay * self) -{ - GArray *ret = NULL; - GstVideoFormat format; - VADisplay dpy; - VAImageFormat *va_formats; - VAStatus status; - int i, max, num = 0; - - g_return_val_if_fail (GST_IS_VA_DISPLAY (self), NULL); - - dpy = gst_va_display_get_va_dpy (self); - - gst_va_display_lock (self); - max = vaMaxNumImageFormats (dpy); - gst_va_display_unlock (self); - if (max == 0) - return NULL; - - va_formats = g_new (VAImageFormat, max); - - gst_va_display_lock (self); - status = vaQueryImageFormats (dpy, va_formats, &num); - gst_va_display_unlock (self); - - gst_va_video_format_fix_map (va_formats, num); - - if (status != VA_STATUS_SUCCESS) { - GST_ERROR ("vaQueryImageFormats: %s", vaErrorStr (status)); - goto bail; - } - - ret = g_array_sized_new (FALSE, FALSE, sizeof (GstVideoFormat), num); - for (i = 0; i < num; i++) { - format = gst_va_video_format_from_va_image_format (&va_formats[i]); - if (format != GST_VIDEO_FORMAT_UNKNOWN) - g_array_append_val (ret, format); - } - - if (ret->len == 0) { - g_array_unref (ret); - ret = NULL; - } - -bail: - g_free (va_formats); - return ret; -} - +/** + * gst_va_display_get_implementation: + * @self: a #GstVaDisplay type display. + * + * Get the the #GstVaImplementation type of @self. + * + * Returns: #GstVaImplementation. + * + * Since: 1.20 + */ GstVaImplementation gst_va_display_get_implementation (GstVaDisplay * self) { diff --git a/gst-libs/gst/va/gstvadisplay.h b/gst-libs/gst/va/gstvadisplay.h new file mode 100644 index 0000000000..09def14daa --- /dev/null +++ b/gst-libs/gst/va/gstvadisplay.h @@ -0,0 +1,134 @@ +/* GStreamer + * Copyright (C) 2020 Igalia, S.L. + * Author: Víctor Jáquez + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#pragma once + +#include +#include +#include + +G_BEGIN_DECLS + +/** + * GstVaImplementation: + * @GST_VA_IMPLEMENTATION_MESA_GALLIUM: The mesa gallium implementation. + * @GST_VA_IMPLEMENTATION_INTEL_I965: The legacy i965 intel implementation. + * @GST_VA_IMPLEMENTATION_INTEL_IHD: The iHD intel implementation. + * @GST_VA_IMPLEMENTATION_OTHER: Other implementation. + * @GST_VA_IMPLEMENTATION_INVALID: Invalid implementation. + * + * Types of different VA API implemented drivers. These are the typical and + * the most widely used VA drivers. + * + * Since: 1.20 + */ +typedef enum +{ + GST_VA_IMPLEMENTATION_MESA_GALLIUM, + GST_VA_IMPLEMENTATION_INTEL_I965, + GST_VA_IMPLEMENTATION_INTEL_IHD, + GST_VA_IMPLEMENTATION_OTHER, + GST_VA_IMPLEMENTATION_INVALID, +} GstVaImplementation; + +/** + * GST_VA_DISPLAY_HANDLE_CONTEXT_TYPE_STR: + * + * Since: 1.20 + */ +#define GST_VA_DISPLAY_HANDLE_CONTEXT_TYPE_STR "gst.va.display.handle" + +/** + * GST_VA_DISPLAY_IS_IMPLEMENTATION: (skip) + * + * Check whether the display is the implementation of the specified + * #GstVaImplementation type. + */ +#define GST_VA_DISPLAY_IS_IMPLEMENTATION(display, impl) \ + (gst_va_display_is_implementation (display, G_PASTE (GST_VA_IMPLEMENTATION_, impl))) + +#define GST_TYPE_VA_DISPLAY (gst_va_display_get_type()) +#define GST_VA_DISPLAY(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_VA_DISPLAY, GstVaDisplay)) +#define GST_VA_DISPLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_VA_DISPLAY, GstVaDisplayClass)) +#define GST_IS_VA_DISPLAY(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_VA_DISPLAY)) +#define GST_IS_VA_DISPLAY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_VA_DISPLAY)) +#define GST_VA_DISPLAY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GST_TYPE_VA_DISPLAY, GstVaDisplayClass)) + +/** + * GstVaDisplay: + * + * The common VA display object structure. + * + * Since: 1.20 + */ +struct _GstVaDisplay +{ + /*< private > */ + GstObject parent; +}; + +/** + * GstVaDisplayClass: + * + * The common VA display object class structure. + * @create_va_display: The function to create the real VA display. + * + * Since: 1.20 + */ +struct _GstVaDisplayClass +{ + /*< private > */ + GstObjectClass parent_class; + + /*< public > */ + gpointer (*create_va_display) (GstVaDisplay * self); +}; + +GST_VA_API +GType gst_va_display_get_type (void); +GST_VA_API +void gst_va_display_lock (GstVaDisplay * self); +GST_VA_API +void gst_va_display_unlock (GstVaDisplay * self); +GST_VA_API +gboolean gst_va_display_initialize (GstVaDisplay * self); +GST_VA_API +gpointer gst_va_display_get_va_dpy (GstVaDisplay * self); +GST_VA_API +GstVaImplementation gst_va_display_get_implementation (GstVaDisplay * self); + +/** + * gst_va_display_is_implementation: + * @display: the #GstVaDisplay to check. + * @impl: the specified #GstVaImplementation. + * + * Check whether the @display is the implementation of the @impl type. + * + * Returns: %TRUE if the @display is the implementation of the @impl type. + * + * Since: 1.20 + */ +static inline gboolean +gst_va_display_is_implementation (GstVaDisplay * display, GstVaImplementation impl) +{ + return (gst_va_display_get_implementation (display) == impl); +} + +G_END_DECLS diff --git a/sys/va/gstvadisplay_drm.c b/gst-libs/gst/va/gstvadisplay_drm.c similarity index 97% rename from sys/va/gstvadisplay_drm.c rename to gst-libs/gst/va/gstvadisplay_drm.c index 93625ea436..092bab58b3 100644 --- a/sys/va/gstvadisplay_drm.c +++ b/gst-libs/gst/va/gstvadisplay_drm.c @@ -41,6 +41,12 @@ struct _GstVaDisplayDrm gint fd; }; +struct _GstVaDisplayDrmClass +{ + /*< private > */ + GstVaDisplayClass parent_class; +}; + GST_DEBUG_CATEGORY_EXTERN (gst_va_display_debug); #define GST_CAT_DEFAULT gst_va_display_debug @@ -170,6 +176,8 @@ gst_va_display_drm_init (GstVaDisplayDrm * self) * Returns: a newly allocated #GstVaDisplay if the specified DRM * render device could be opened and initialized; otherwise %NULL * is returned. + * + * Since: 1.20 **/ GstVaDisplay * gst_va_display_drm_new_from_path (const gchar * path) diff --git a/gst-libs/gst/va/gstvadisplay_drm.h b/gst-libs/gst/va/gstvadisplay_drm.h new file mode 100644 index 0000000000..6cf9326c40 --- /dev/null +++ b/gst-libs/gst/va/gstvadisplay_drm.h @@ -0,0 +1,39 @@ +/* GStreamer + * Copyright (C) 2020 Igalia, S.L. + * Author: Víctor Jáquez + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#pragma once + +#include "gstvadisplay.h" + +G_BEGIN_DECLS + +#define GST_TYPE_VA_DISPLAY_DRM (gst_va_display_drm_get_type()) +#define GST_VA_DISPLAY_DRM(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_VA_DISPLAY_DRM, GstVaDisplayDrm)) +#define GST_VA_DISPLAY_DRM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_VA_DISPLAY_DRM, GstVaDisplayDrmClass)) +#define GST_IS_VA_DISPLAY_DRM(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_VA_DISPLAY_DRM)) +#define GST_IS_VA_DISPLAY_DRM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_VA_DISPLAY_DRM)) +#define GST_VA_DISPLAY_DRM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GST_TYPE_VA_DISPLAY_DRM, GstVaDisplayDrmClass)) + +GST_VA_API +GType gst_va_display_drm_get_type (void); +GST_VA_API +GstVaDisplay * gst_va_display_drm_new_from_path (const gchar * path); + +G_END_DECLS diff --git a/sys/va/gstvadisplay_wrapped.c b/gst-libs/gst/va/gstvadisplay_wrapped.c similarity index 94% rename from sys/va/gstvadisplay_wrapped.c rename to gst-libs/gst/va/gstvadisplay_wrapped.c index dd98251107..9a3fea1127 100644 --- a/sys/va/gstvadisplay_wrapped.c +++ b/gst-libs/gst/va/gstvadisplay_wrapped.c @@ -29,6 +29,12 @@ struct _GstVaDisplayWrapped GstVaDisplay parent; }; +struct _GstVaDisplayWrappedClass +{ + /*< private > */ + GstVaDisplayClass parent_class; +}; + #define gst_va_display_wrapped_parent_class parent_class G_DEFINE_TYPE (GstVaDisplayWrapped, gst_va_display_wrapped, GST_TYPE_VA_DISPLAY); @@ -51,6 +57,8 @@ gst_va_display_wrapped_init (GstVaDisplayWrapped * self) * VADisplay. * * Returns: a new #GstVaDisplay if @handle is valid, Otherwise %NULL. + * + * Since: 1.20 **/ GstVaDisplay * gst_va_display_wrapped_new (guintptr handle) diff --git a/gst-libs/gst/va/gstvadisplay_wrapped.h b/gst-libs/gst/va/gstvadisplay_wrapped.h new file mode 100644 index 0000000000..93f36c969c --- /dev/null +++ b/gst-libs/gst/va/gstvadisplay_wrapped.h @@ -0,0 +1,39 @@ +/* GStreamer + * Copyright (C) 2020 Igalia, S.L. + * Author: Víctor Jáquez + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#pragma once + +#include "gstvadisplay.h" + +G_BEGIN_DECLS + +#define GST_TYPE_VA_DISPLAY_WRAPPED (gst_va_display_wrapped_get_type()) +#define GST_VA_DISPLAY_WRAPPED(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_VA_DISPLAY_WRAPPED, GstVaDisplayWrapped)) +#define GST_VA_DISPLAY_WRAPPED_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_VA_DISPLAY_WRAPPED, GstVaDisplayWrappedClass)) +#define GST_IS_VA_DISPLAY_WRAPPED(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_VA_DISPLAY_WRAPPED)) +#define GST_IS_VA_DISPLAY_WRAPPED_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_VA_DISPLAY_WRAPPED)) +#define GST_VA_DISPLAY_WRAPPED_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GST_TYPE_VA_DISPLAY_WRAPPED, GstVaDisplayWrappedClass)) + +GST_VA_API +GType gst_va_display_wrapped_get_type (void); +GST_VA_API +GstVaDisplay * gst_va_display_wrapped_new (guintptr handle); + +G_END_DECLS diff --git a/gst-libs/gst/va/meson.build b/gst-libs/gst/va/meson.build new file mode 100644 index 0000000000..9999fbd92c --- /dev/null +++ b/gst-libs/gst/va/meson.build @@ -0,0 +1,60 @@ +va_sources = [ + 'gstvadisplay.c', + 'gstvadisplay_drm.c', + 'gstvadisplay_wrapped.c', +] + +va_headers = [ + 'gstvadisplay.h', + 'gstvadisplay_drm.h', + 'gstvadisplay_wrapped.h', + 'va_fwd.h', + 'va-prelude.h', +] + +gstva_dep = dependency('', required : false) + +have_va = false +va_option = get_option('va') +if va_option.disabled() or host_system != 'linux' + subdir_done() +endif + +libva_req = ['>= 1.6'] + +libva_dep = dependency('libva', version: libva_req, required: va_option) +libva_drm_dep = dependency('libva-drm', version: libva_req, required: va_option) +libgudev_dep = dependency('gudev-1.0', required: va_option) +libdrm_dep = dependency('libdrm', required: false, fallback: ['libdrm', 'ext_libdrm']) + +have_va = libva_dep.found() and libva_drm_dep.found() +if not (have_va and libgudev_dep.found()) + if va_option.enabled() + error('The va lib was enabled explicity, but required dependencies were not found.') + endif + subdir_done() +endif + + +gstva = library('gstva-' + api_version, + va_sources, + c_args : gst_plugins_bad_args + ['-DGST_USE_UNSTABLE_API', '-DBUILDING_GST_VA'], + include_directories : [configinc, libsinc], + version : libversion, + soversion : soversion, + install : true, + dependencies : [gst_dep, libva_dep, libva_drm_dep, libgudev_dep, libdrm_dep], +) + +pkgconfig.generate(gstva, + libraries : gst_dep, + variables : pkgconfig_variables, + subdirs : pkgconfig_subdirs, + name : 'gstreamer-va-1.0', + description : 'GStreamer VA support', +) + +gstva_dep = declare_dependency(link_with : gstva, + include_directories : [libsinc], + dependencies : [gst_dep, libva_dep, libva_drm_dep, libgudev_dep, libdrm_dep]) +meson.override_dependency('gstreamer-va-1.0', gstva_dep) diff --git a/gst-libs/gst/va/va-prelude.h b/gst-libs/gst/va/va-prelude.h new file mode 100644 index 0000000000..3c901b2a8e --- /dev/null +++ b/gst-libs/gst/va/va-prelude.h @@ -0,0 +1,30 @@ +/* GStreamer + * Copyright (C) 2021 GStreamer developers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#pragma once + +#include + +#ifndef GST_VA_API +# ifdef BUILDING_GST_VA +# define GST_VA_API GST_API_EXPORT /* from config.h */ +# else +# define GST_VA_API GST_API_IMPORT +# endif +#endif diff --git a/sys/va/gstvadisplay_wrapped.h b/gst-libs/gst/va/va_fwd.h similarity index 67% rename from sys/va/gstvadisplay_wrapped.h rename to gst-libs/gst/va/va_fwd.h index 752ecb5031..0b1b8cb339 100644 --- a/sys/va/gstvadisplay_wrapped.h +++ b/gst-libs/gst/va/va_fwd.h @@ -1,6 +1,5 @@ /* GStreamer - * Copyright (C) 2020 Igalia, S.L. - * Author: Víctor Jáquez + * Copyright (C) 2021 GStreamer developers * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -20,14 +19,17 @@ #pragma once -#include "gstvadisplay.h" +#include G_BEGIN_DECLS -#define GST_TYPE_VA_DISPLAY_WRAPPED gst_va_display_wrapped_get_type() -G_DECLARE_FINAL_TYPE (GstVaDisplayWrapped, gst_va_display_wrapped, GST, - VA_DISPLAY_WRAPPED, GstVaDisplay) +typedef struct _GstVaDisplay GstVaDisplay; +typedef struct _GstVaDisplayClass GstVaDisplayClass; -GstVaDisplay * gst_va_display_wrapped_new (guintptr handle); +typedef struct _GstVaDisplayDrm GstVaDisplayDrm; +typedef struct _GstVaDisplayDrmClass GstVaDisplayDrmClass; + +typedef struct _GstVaDisplayWrapped GstVaDisplayWrapped; +typedef struct _GstVaDisplayWrappedClass GstVaDisplayWrappedClass; G_END_DECLS diff --git a/sys/va/gstvaallocator.h b/sys/va/gstvaallocator.h index e4123c2515..de97fd685f 100644 --- a/sys/va/gstvaallocator.h +++ b/sys/va/gstvaallocator.h @@ -21,9 +21,9 @@ #pragma once #include +#include #include - -#include "gstvadisplay.h" +#include G_BEGIN_DECLS diff --git a/sys/va/gstvacaps.c b/sys/va/gstvacaps.c index e421c812bb..1b0dd651c4 100644 --- a/sys/va/gstvacaps.c +++ b/sys/va/gstvacaps.c @@ -28,12 +28,12 @@ #include -#include "gstvadisplay.h" +#include "gstvadisplay_priv.h" #include "gstvaprofile.h" #include "gstvavideoformat.h" -GST_DEBUG_CATEGORY_EXTERN (gst_va_display_debug); -#define GST_CAT_DEFAULT gst_va_display_debug +GST_DEBUG_CATEGORY_EXTERN (gstva_debug); +#define GST_CAT_DEFAULT gstva_debug static const guint va_rt_format_list[] = { #define R(name) G_PASTE (VA_RT_FORMAT_, name) diff --git a/sys/va/gstvacaps.h b/sys/va/gstvacaps.h index c36ef05019..096e656e49 100644 --- a/sys/va/gstvacaps.h +++ b/sys/va/gstvacaps.h @@ -20,7 +20,8 @@ #pragma once -#include "gstvadisplay.h" +#include +#include G_BEGIN_DECLS diff --git a/sys/va/gstvadecoder.c b/sys/va/gstvadecoder.c index f47728258a..17c814a076 100644 --- a/sys/va/gstvadecoder.c +++ b/sys/va/gstvadecoder.c @@ -26,8 +26,9 @@ #include "gstvaallocator.h" #include "gstvacaps.h" -#include "gstvadisplay_wrapped.h" +#include "gstvadisplay_priv.h" #include "gstvavideoformat.h" +#include struct _GstVaDecoder { diff --git a/sys/va/gstvadecoder.h b/sys/va/gstvadecoder.h index c3a16a3542..c6e31e26d4 100644 --- a/sys/va/gstvadecoder.h +++ b/sys/va/gstvadecoder.h @@ -20,7 +20,8 @@ #pragma once -#include "gstvadisplay.h" +#include +#include G_BEGIN_DECLS diff --git a/sys/va/gstvadevice.c b/sys/va/gstvadevice.c index 0e251e158c..1faa61fa8f 100644 --- a/sys/va/gstvadevice.c +++ b/sys/va/gstvadevice.c @@ -25,7 +25,6 @@ #include "gstvadevice.h" #include -#include "gstvadisplay_drm.h" #define GST_CAT_DEFAULT gstva_debug GST_DEBUG_CATEGORY_EXTERN (gstva_debug); diff --git a/sys/va/gstvadevice.h b/sys/va/gstvadevice.h index f5bc7df3a2..774741a849 100644 --- a/sys/va/gstvadevice.h +++ b/sys/va/gstvadevice.h @@ -24,7 +24,7 @@ G_BEGIN_DECLS -#include "gstvadisplay.h" +#include #define GST_TYPE_VA_DEVICE (gst_va_device_get_type()) #define GST_IS_VA_DEVICE(obj) (GST_IS_MINI_OBJECT_TYPE((obj), GST_TYPE_VA_DEVICE)) diff --git a/sys/va/gstvadisplay.h b/sys/va/gstvadisplay.h deleted file mode 100644 index a30c4bba09..0000000000 --- a/sys/va/gstvadisplay.h +++ /dev/null @@ -1,68 +0,0 @@ -/* GStreamer - * Copyright (C) 2020 Igalia, S.L. - * Author: Víctor Jáquez - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#pragma once - -#include -#include - -G_BEGIN_DECLS - -typedef enum -{ - GST_VA_IMPLEMENTATION_MESA_GALLIUM, - GST_VA_IMPLEMENTATION_INTEL_I965, - GST_VA_IMPLEMENTATION_INTEL_IHD, - GST_VA_IMPLEMENTATION_OTHER, - GST_VA_IMPLEMENTATION_INVALID, -} GstVaImplementation; - -#define GST_VA_DISPLAY_IS_IMPLEMENTATION(display, impl) \ - (gst_va_display_is_implementation (display, G_PASTE (GST_VA_IMPLEMENTATION_, impl))) - -#define GST_TYPE_VA_DISPLAY (gst_va_display_get_type()) -G_DECLARE_DERIVABLE_TYPE (GstVaDisplay, gst_va_display, GST, VA_DISPLAY, GstObject) - -struct _GstVaDisplayClass -{ - /*< private > */ - GstObjectClass parent_class; - - /*< public > */ - gpointer (*create_va_display) (GstVaDisplay * self); -}; - -void gst_va_display_lock (GstVaDisplay * self); -void gst_va_display_unlock (GstVaDisplay * self); -gboolean gst_va_display_initialize (GstVaDisplay * self); -VADisplay gst_va_display_get_va_dpy (GstVaDisplay * self); -GArray * gst_va_display_get_profiles (GstVaDisplay * self, - guint32 codec, - VAEntrypoint entrypoint); -GArray * gst_va_display_get_image_formats (GstVaDisplay * self); -GstVaImplementation gst_va_display_get_implementation (GstVaDisplay * self); - -static inline gboolean -gst_va_display_is_implementation (GstVaDisplay * self, GstVaImplementation impl) -{ - return (gst_va_display_get_implementation (self) == impl); -} - -G_END_DECLS diff --git a/sys/va/gstvadisplay_priv.c b/sys/va/gstvadisplay_priv.c new file mode 100644 index 0000000000..b9f970f9ad --- /dev/null +++ b/sys/va/gstvadisplay_priv.c @@ -0,0 +1,137 @@ +/* GStreamer + * Copyright (C) 2020 Igalia, S.L. + * Author: Víctor Jáquez + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "gstvadisplay_priv.h" +#include "gstvaprofile.h" +#include "gstvavideoformat.h" + +GArray * +gst_va_display_get_profiles (GstVaDisplay * self, guint32 codec, + VAEntrypoint entrypoint) +{ + GArray *ret = NULL; + VADisplay dpy; + VAEntrypoint *entrypoints; + VAProfile *profiles; + VAStatus status; + gint i, j, num_entrypoints = 0, num_profiles = 0; + + g_return_val_if_fail (GST_IS_VA_DISPLAY (self), NULL); + + dpy = gst_va_display_get_va_dpy (self); + + gst_va_display_lock (self); + num_profiles = vaMaxNumProfiles (dpy); + num_entrypoints = vaMaxNumEntrypoints (dpy); + gst_va_display_unlock (self); + + profiles = g_new (VAProfile, num_profiles); + entrypoints = g_new (VAEntrypoint, num_entrypoints); + + gst_va_display_lock (self); + status = vaQueryConfigProfiles (dpy, profiles, &num_profiles); + gst_va_display_unlock (self); + if (status != VA_STATUS_SUCCESS) { + GST_ERROR ("vaQueryConfigProfile: %s", vaErrorStr (status)); + goto bail; + } + + for (i = 0; i < num_profiles; i++) { + if (codec != gst_va_profile_codec (profiles[i])) + continue; + + gst_va_display_lock (self); + status = vaQueryConfigEntrypoints (dpy, profiles[i], entrypoints, + &num_entrypoints); + gst_va_display_unlock (self); + if (status != VA_STATUS_SUCCESS) { + GST_ERROR ("vaQueryConfigEntrypoints: %s", vaErrorStr (status)); + goto bail; + } + + for (j = 0; j < num_entrypoints; j++) { + if (entrypoints[j] == entrypoint) { + if (!ret) + ret = g_array_new (FALSE, FALSE, sizeof (VAProfile)); + g_array_append_val (ret, profiles[i]); + break; + } + } + } + +bail: + g_free (entrypoints); + g_free (profiles); + return ret; +} + +GArray * +gst_va_display_get_image_formats (GstVaDisplay * self) +{ + GArray *ret = NULL; + GstVideoFormat format; + VADisplay dpy; + VAImageFormat *va_formats; + VAStatus status; + int i, max, num = 0; + + g_return_val_if_fail (GST_IS_VA_DISPLAY (self), NULL); + + dpy = gst_va_display_get_va_dpy (self); + + gst_va_display_lock (self); + max = vaMaxNumImageFormats (dpy); + gst_va_display_unlock (self); + if (max == 0) + return NULL; + + va_formats = g_new (VAImageFormat, max); + + gst_va_display_lock (self); + status = vaQueryImageFormats (dpy, va_formats, &num); + gst_va_display_unlock (self); + + gst_va_video_format_fix_map (va_formats, num); + + if (status != VA_STATUS_SUCCESS) { + GST_ERROR ("vaQueryImageFormats: %s", vaErrorStr (status)); + goto bail; + } + + ret = g_array_sized_new (FALSE, FALSE, sizeof (GstVideoFormat), num); + for (i = 0; i < num; i++) { + format = gst_va_video_format_from_va_image_format (&va_formats[i]); + if (format != GST_VIDEO_FORMAT_UNKNOWN) + g_array_append_val (ret, format); + } + + if (ret->len == 0) { + g_array_unref (ret); + ret = NULL; + } + +bail: + g_free (va_formats); + return ret; +} diff --git a/sys/va/gstvadisplay_drm.h b/sys/va/gstvadisplay_priv.h similarity index 70% rename from sys/va/gstvadisplay_drm.h rename to sys/va/gstvadisplay_priv.h index 1b3121a258..86e5a6d514 100644 --- a/sys/va/gstvadisplay_drm.h +++ b/sys/va/gstvadisplay_priv.h @@ -20,14 +20,13 @@ #pragma once -#include "gstvadisplay.h" +#include +#include G_BEGIN_DECLS - -#define GST_TYPE_VA_DISPLAY_DRM (gst_va_display_drm_get_type()) -G_DECLARE_FINAL_TYPE (GstVaDisplayDrm, gst_va_display_drm, GST, VA_DISPLAY_DRM, - GstVaDisplay) - -GstVaDisplay * gst_va_display_drm_new_from_path (const gchar * path); +GArray * gst_va_display_get_profiles (GstVaDisplay * self, + guint32 codec, + VAEntrypoint entrypoint); +GArray * gst_va_display_get_image_formats (GstVaDisplay * self); G_END_DECLS diff --git a/sys/va/gstvafilter.c b/sys/va/gstvafilter.c index afd1f58468..35e946a16a 100644 --- a/sys/va/gstvafilter.c +++ b/sys/va/gstvafilter.c @@ -30,6 +30,7 @@ #include "gstvaallocator.h" #include "gstvacaps.h" +#include "gstvadisplay_priv.h" #include "gstvavideoformat.h" struct _GstVaFilter diff --git a/sys/va/gstvafilter.h b/sys/va/gstvafilter.h index 896694b74e..d6dbfb3d4c 100644 --- a/sys/va/gstvafilter.h +++ b/sys/va/gstvafilter.h @@ -20,10 +20,10 @@ #pragma once -#include "gstvadisplay.h" - +#include #include +#include #include G_BEGIN_DECLS diff --git a/sys/va/gstvautils.c b/sys/va/gstvautils.c index 6014f321a1..b11f501661 100644 --- a/sys/va/gstvautils.c +++ b/sys/va/gstvautils.c @@ -22,9 +22,9 @@ #include "config.h" #endif -#include "gstvadisplay_drm.h" -#include "gstvadisplay_wrapped.h" #include "gstvautils.h" +#include +#include GST_DEBUG_CATEGORY_STATIC (GST_CAT_CONTEXT); @@ -164,7 +164,7 @@ gst_va_element_propagate_display_context (GstElement * element, _init_context_debug (); - ctxt = gst_context_new ("gst.va.display.handle", TRUE); + ctxt = gst_context_new (GST_VA_DISPLAY_HANDLE_CONTEXT_TYPE_STR, TRUE); gst_context_set_va_display (ctxt, display); GST_CAT_INFO_OBJECT (GST_CAT_CONTEXT, element, @@ -189,7 +189,7 @@ gst_va_ensure_element_data (gpointer element, const gchar * render_device_path, if (gst_va_display_found (element, g_atomic_pointer_get (display_ptr))) goto done; - _gst_context_query (element, "gst.va.display.handle"); + _gst_context_query (element, GST_VA_DISPLAY_HANDLE_CONTEXT_TYPE_STR); /* Neighbour found and it updated the display */ if (gst_va_display_found (element, g_atomic_pointer_get (display_ptr))) @@ -222,7 +222,7 @@ gst_va_handle_set_context (GstElement * element, GstContext * context, context_type = gst_context_get_context_type (context); - if (g_strcmp0 (context_type, "gst.va.display.handle") == 0) { + if (g_strcmp0 (context_type, GST_VA_DISPLAY_HANDLE_CONTEXT_TYPE_STR) == 0) { type_name = G_OBJECT_TYPE_NAME (element); if (!gst_context_get_va_display (context, type_name, render_device_path, &display_replacement)) { @@ -258,7 +258,8 @@ gst_va_handle_context_query (GstElement * element, GstQuery * query, "handle context query %" GST_PTR_FORMAT, query); gst_query_parse_context_type (query, &context_type); - if (!display || g_strcmp0 (context_type, "gst.va.display.handle") != 0) + if (!display + || g_strcmp0 (context_type, GST_VA_DISPLAY_HANDLE_CONTEXT_TYPE_STR) != 0) return FALSE; gst_query_parse_context (query, &old_ctxt); @@ -266,7 +267,7 @@ gst_va_handle_context_query (GstElement * element, GstQuery * query, if (old_ctxt) ctxt = gst_context_copy (old_ctxt); else - ctxt = gst_context_new ("gst.va.display.handle", TRUE); + ctxt = gst_context_new (GST_VA_DISPLAY_HANDLE_CONTEXT_TYPE_STR, TRUE); gst_context_set_va_display (ctxt, display); gst_query_set_context (query, ctxt); diff --git a/sys/va/gstvautils.h b/sys/va/gstvautils.h index 44ef7a9adf..3bca0b82f6 100644 --- a/sys/va/gstvautils.h +++ b/sys/va/gstvautils.h @@ -20,7 +20,7 @@ #pragma once -#include "gstvadisplay.h" +#include G_BEGIN_DECLS diff --git a/sys/va/gstvavpp.c b/sys/va/gstvavpp.c index a7ce71b04e..70642c5137 100644 --- a/sys/va/gstvavpp.c +++ b/sys/va/gstvavpp.c @@ -77,7 +77,7 @@ #include "gstvaallocator.h" #include "gstvacaps.h" -#include "gstvadisplay_drm.h" +#include "gstvadisplay_priv.h" #include "gstvafilter.h" #include "gstvapool.h" #include "gstvautils.h" diff --git a/sys/va/meson.build b/sys/va/meson.build index 803b7e2df2..55b664beba 100644 --- a/sys/va/meson.build +++ b/sys/va/meson.build @@ -4,10 +4,8 @@ va_sources = [ 'gstvabasedec.c', 'gstvacaps.c', 'gstvadecoder.c', - 'gstvadisplay.c', - 'gstvadisplay_drm.c', - 'gstvadisplay_wrapped.c', 'gstvadevice.c', + 'gstvadisplay_priv.c', 'gstvafilter.c', 'gstvah264dec.c', 'gstvah265dec.c', @@ -21,19 +19,17 @@ va_sources = [ 'gstvavpp.c' ] -have_va = false va_option = get_option('va') if va_option.disabled() or host_system != 'linux' subdir_done() endif -libva_req = ['>= 1.6'] - -libva_dep = dependency('libva', version: libva_req, required: va_option) -libva_drm_dep = dependency('libva-drm', version: libva_req, required: va_option) -libgudev_dep = dependency('gudev-1.0', required: va_option) -libdrm_dep = dependency('libdrm', required: false, - fallback: ['libdrm', 'ext_libdrm']) +if not gstva_dep.found() + if va_option.enabled() + error('The va plugin was enabled explicity, but required dependencies were not found.') + endif + subdir_done() +endif libva_av1_req = ['>= 1.8'] libva_av1_dep = dependency('libva', version: libva_av1_req, required: va_option) @@ -41,14 +37,6 @@ if libva_av1_dep.found() va_sources += 'gstvaav1dec.c' endif -have_va = libva_dep.found() and libva_drm_dep.found() -if not (have_va and libgudev_dep.found()) - if va_option.enabled() - error('The va plugin was enabled explicity, but required dependencies were not found.') - endif - subdir_done() -endif - cdata.set10('HAVE_LIBDRM', libdrm_dep.found()) driverdir = libva_dep.get_pkgconfig_variable('driverdir') @@ -61,7 +49,7 @@ gstva = library('gstva', va_sources, c_args : gst_plugins_bad_args + extra_c_args + gstva_cargs + ['-std=c99'], include_directories : [configinc], - dependencies : [gstbase_dep, gstvideo_dep, gstcodecs_dep, libva_dep, gstallocators_dep, libva_drm_dep, libgudev_dep, libdrm_dep] + extra_dep, + dependencies : [libva_dep, gstvideo_dep, gstcodecs_dep, gstallocators_dep, gstva_dep] + extra_dep, install : true, install_dir : plugins_install_dir, )