[vlc-devel] [PATCH 03/48] vdpau: helper library for VDPAU and VDPAU-X11 function calls

Rémi Denis-Courmont remi at remlab.net
Tue Jul 2 19:51:29 CEST 2013


This provides a more traditional set of library function calls than the
VDPAU specification defines. Furthermore, this has libvdpau.so as a
conditional run-time linking dependency.

Note that this requires libvdpau 0.6 or later (0.4.1-8 on Debian) at
run-time due to a bug in libvdpau versions 0.4 through 0.5.
---
 configure.ac                 |   1 +
 modules/Makefile.am          |   4 +
 modules/hw/.gitignore        |   1 +
 modules/hw/vdpau/Makefile.am |  14 +
 modules/hw/vdpau/vlc_vdpau.c | 611 +++++++++++++++++++++++++++++++++++++++++++
 modules/hw/vdpau/vlc_vdpau.h | 171 ++++++++++++
 6 files changed, 802 insertions(+)
 create mode 100644 modules/hw/.gitignore
 create mode 100644 modules/hw/vdpau/Makefile.am
 create mode 100644 modules/hw/vdpau/vlc_vdpau.c
 create mode 100644 modules/hw/vdpau/vlc_vdpau.h

diff --git a/configure.ac b/configure.ac
index 89d8102..9e6ee11 100644
--- a/configure.ac
+++ b/configure.ac
@@ -4223,6 +4223,7 @@ AC_CONFIG_FILES([
   modules/sse2/Makefile
   modules/altivec/Makefile
   modules/arm_neon/Makefile
+  modules/hw/vdpau/Makefile
 ])
 
 AM_COND_IF([HAVE_WIN32], [
diff --git a/modules/Makefile.am b/modules/Makefile.am
index 31c6d83..3091f11 100644
--- a/modules/Makefile.am
+++ b/modules/Makefile.am
@@ -27,6 +27,7 @@ EXTRA_SUBDIRS = \
 	sse2 \
 	altivec \
 	arm_neon \
+	hw/vdpau \
 	lua \
 	$(NULL)
 
@@ -47,6 +48,9 @@ endif
 if HAVE_NEON
 SUBDIRS += arm_neon
 endif
+if HAVE_VDPAU
+SUBDIRS += hw/vdpau
+endif
 if BUILD_LUA
 SUBDIRS += lua
 endif
diff --git a/modules/hw/.gitignore b/modules/hw/.gitignore
new file mode 100644
index 0000000..08a6d72
--- /dev/null
+++ b/modules/hw/.gitignore
@@ -0,0 +1 @@
+Makefile.am
diff --git a/modules/hw/vdpau/Makefile.am b/modules/hw/vdpau/Makefile.am
new file mode 100644
index 0000000..f210018
--- /dev/null
+++ b/modules/hw/vdpau/Makefile.am
@@ -0,0 +1,14 @@
+basedir = vdpau
+include $(top_srcdir)/modules/common.am
+
+AM_CFLAGS += $(VDPAU_CFLAGS)
+
+libvlc_vdpau_la_SOURCES = vlc_vdpau.c vlc_vdpau.h
+libvlc_vdpau_la_CPPFLAGS =
+libvlc_vdpau_la_LIBADD = $(X_LIBS) $(X_PRE_LIBS) -lX11 \
+	$(LIBDL) $(LIBPTHREAD)
+libvlc_vdpau_la_LDFLAGS = \
+	-no-undefined \
+	-export-symbols-regex ^vdp_ \
+	-version-info 0:0:0
+pkglib_LTLIBRARIES = libvlc_vdpau.la
diff --git a/modules/hw/vdpau/vlc_vdpau.c b/modules/hw/vdpau/vlc_vdpau.c
new file mode 100644
index 0000000..8e0a76d
--- /dev/null
+++ b/modules/hw/vdpau/vlc_vdpau.c
@@ -0,0 +1,611 @@
+/*****************************************************************************
+ * vlc_vdpau.c: VDPAU helper for VLC
+ *****************************************************************************
+ * Copyright (C) 2013 Rémi Denis-Courmont
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <vlc_common.h>
+#include "vlc_vdpau.h"
+
+#pragma GCC visibility push(default)
+
+typedef struct
+{
+    VdpGetErrorString *get_error_string;
+    VdpGetProcAddress *get_proc_address;
+    VdpGetApiVersion *get_api_version;
+    void *dummy3;
+    VdpGetInformationString *get_information_string;
+    VdpDeviceDestroy *device_destroy;
+    VdpGenerateCSCMatrix *generate_csc_matrix;
+    VdpVideoSurfaceQueryCapabilities *video_surface_query_capabilities;
+    VdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities *video_surface_query_get_put_bits_y_cb_cr_capabilities;
+    VdpVideoSurfaceCreate *video_surface_create;
+    VdpVideoSurfaceDestroy *video_surface_destroy;
+    VdpVideoSurfaceGetParameters *video_surface_get_parameters;
+    VdpVideoSurfaceGetBitsYCbCr *video_surface_get_bits_y_cb_cr;
+    VdpVideoSurfacePutBitsYCbCr *video_surface_put_bits_y_cb_cr;
+    VdpOutputSurfaceQueryCapabilities *output_surface_query_capabilities;
+    VdpOutputSurfaceQueryGetPutBitsNativeCapabilities *output_surface_query_get_put_bits_native_capabilities;
+    VdpOutputSurfaceQueryPutBitsIndexedCapabilities *output_surface_query_put_bits_indexed_capabilities;
+    VdpOutputSurfaceQueryPutBitsYCbCrCapabilities *output_surface_query_put_bits_y_cb_cr_capabilities;
+    VdpOutputSurfaceCreate *output_surface_create;
+    VdpOutputSurfaceDestroy *output_surface_destroy;
+    VdpOutputSurfaceGetParameters *output_surface_get_parameters;
+    VdpOutputSurfaceGetBitsNative *output_surface_get_bits_native;
+    VdpOutputSurfacePutBitsNative *output_surface_put_bits_native;
+    VdpOutputSurfacePutBitsIndexed *output_surface_put_bits_indexed;
+    VdpOutputSurfacePutBitsYCbCr *output_surface_put_bits_y_cb_cr;
+    VdpBitmapSurfaceQueryCapabilities *bitmap_surface_query_capabilities;
+    VdpBitmapSurfaceCreate *bitmap_surface_create;
+    VdpBitmapSurfaceDestroy *bitmap_surface_destroy;
+    VdpBitmapSurfaceGetParameters *bitmap_surface_get_parameters;
+    VdpBitmapSurfacePutBitsNative *bitmap_surface_put_bits_native;
+    void *dummy30;
+    void *dummy31;
+    void *dummy32;
+    VdpOutputSurfaceRenderOutputSurface *output_surface_render_output_surface;
+    VdpOutputSurfaceRenderBitmapSurface *output_surface_render_bitmap_surface;
+    void *output_surface_render_video_surface_luma;
+    VdpDecoderQueryCapabilities *decoder_query_capabilities;
+    VdpDecoderCreate *decoder_create;
+    VdpDecoderDestroy *decoder_destroy;
+    VdpDecoderGetParameters *decoder_get_parameters;
+    VdpDecoderRender *decoder_render;
+    VdpVideoMixerQueryFeatureSupport *video_mixer_query_feature_support;
+    VdpVideoMixerQueryParameterSupport *video_mixer_query_parameter_support;
+    VdpVideoMixerQueryAttributeSupport *video_mixer_query_attribute_support;
+    VdpVideoMixerQueryParameterValueRange *video_mixer_query_parameter_value_range;
+    VdpVideoMixerQueryAttributeValueRange *video_mixer_query_attribute_value_range;
+    VdpVideoMixerCreate *video_mixer_create;
+    VdpVideoMixerSetFeatureEnables *video_mixer_set_feature_enables;
+    VdpVideoMixerSetAttributeValues *video_mixer_set_attribute_values;
+    VdpVideoMixerGetFeatureSupport *video_mixer_get_feature_support;
+    VdpVideoMixerGetFeatureEnables *video_mixer_get_feature_enables;
+    VdpVideoMixerGetParameterValues *video_mixer_get_parameter_values;
+    VdpVideoMixerGetAttributeValues *video_mixer_get_attribute_values;
+    VdpVideoMixerDestroy *video_mixer_destroy;
+    VdpVideoMixerRender *video_mixer_render;
+    VdpPresentationQueueTargetDestroy *presentation_queue_target_destroy;
+    VdpPresentationQueueCreate *presentation_queue_create;
+    VdpPresentationQueueDestroy *presentation_queue_destroy;
+    VdpPresentationQueueSetBackgroundColor *presentation_queue_set_background_color;
+    VdpPresentationQueueGetBackgroundColor *presentation_queue_get_background_color;
+    void *dummy60;
+    void *dummy61;
+    VdpPresentationQueueGetTime *presentation_queue_get_time;
+    VdpPresentationQueueDisplay *presentation_queue_display;
+    VdpPresentationQueueBlockUntilSurfaceIdle *presentation_queue_block_until_surface_idle;
+    VdpPresentationQueueQuerySurfaceStatus *presentation_queue_query_surface_status;
+    VdpPreemptionCallbackRegister *preemption_callback_register;
+} vdp_vtable_t;
+
+struct vdp_s
+{
+    union
+    {
+        vdp_vtable_t vt;
+        void *funcs[1];
+    }; /**< VDPAU function pointers table */
+    void *handle; /**< Shared library handle */
+};
+
+const char *vdp_get_error_string(const vdp_t *vdp, VdpStatus status)
+{
+    return vdp->vt.get_error_string(status);
+}
+
+static const char *vdp_get_error_string_fallback(const vdp_t *vdp,
+                                                 VdpStatus status)
+{
+    (void) vdp;
+    return (status != VDP_STATUS_OK) ? "Unknown error" : "No error";
+}
+
+VdpStatus vdp_get_proc_address(const vdp_t *vdp, VdpDevice device,
+    VdpFuncId func_id, void **func_ptr)
+{
+    return vdp->vt.get_proc_address(device, func_id, func_ptr);
+}
+
+VdpStatus vdp_get_api_version(const vdp_t *vdp, uint32_t *ver)
+{
+    return vdp->vt.get_api_version(ver);
+}
+
+VdpStatus vdp_get_information_string(const vdp_t *vdp, const char **str)
+{
+    return vdp->vt.get_information_string(str);
+}
+
+/*** Device ***/
+VdpStatus vdp_device_destroy(const vdp_t *vdp, VdpDevice device)
+{
+    return vdp->vt.device_destroy(device);
+}
+
+VdpStatus vdp_generate_csc_matrix(const vdp_t *vdp, const VdpProcamp *procamp,
+    VdpColorStandard standard, VdpCSCMatrix *csc_matrix)
+{
+    VdpProcamp buf, *copy = NULL;
+
+    if (procamp != NULL)
+    {
+        buf = *procamp;
+        copy = &buf;
+    }
+    return vdp->vt.generate_csc_matrix(copy, standard, csc_matrix);
+}
+
+/*** Video surface ***/
+VdpStatus vdp_video_surface_query_capabilities(const vdp_t *vdp, VdpDevice dev,
+    VdpChromaType type, VdpBool *ok, uint32_t *mw, uint32_t *mh)
+{
+    return vdp->vt.video_surface_query_capabilities(dev, type, ok, mw, mh);
+}
+
+VdpStatus vdp_video_surface_query_get_put_bits_y_cb_cr_capabilities(
+    const vdp_t *vdp, VdpDevice device, VdpChromaType type, VdpYCbCrFormat fmt,
+    VdpBool *ok)
+{
+    return vdp->vt.video_surface_query_get_put_bits_y_cb_cr_capabilities(
+        device, type, fmt, ok);
+}
+
+VdpStatus vdp_video_surface_create(const vdp_t *vdp, VdpDevice device,
+    VdpChromaType chroma, uint32_t w, uint32_t h, VdpVideoSurface *surface)
+{
+    return vdp->vt.video_surface_create(device, chroma, w, h, surface);
+}
+
+VdpStatus vdp_video_surface_destroy(const vdp_t *vdp, VdpVideoSurface surface)
+{
+    return vdp->vt.video_surface_destroy(surface);
+}
+
+VdpStatus vdp_video_surface_get_parameters(const vdp_t *vdp,
+    VdpVideoSurface surface, VdpChromaType *type, uint32_t *w, uint32_t *h)
+{
+    return vdp->vt.video_surface_get_parameters(surface, type, w, h);
+}
+
+VdpStatus vdp_video_surface_get_bits_y_cb_cr(const vdp_t *vdp,
+    VdpVideoSurface surface, VdpYCbCrFormat fmt,
+    void *const *data, uint32_t const *pitches)
+{
+    return vdp->vt.video_surface_get_bits_y_cb_cr(surface, fmt, data, pitches);
+}
+
+VdpStatus vdp_video_surface_put_bits_y_cb_cr(const vdp_t *vdp,
+    VdpVideoSurface surface, VdpYCbCrFormat fmt,
+    const void *const *data, uint32_t const *pitches)
+{
+    return vdp->vt.video_surface_put_bits_y_cb_cr(surface, fmt, data, pitches);
+}
+
+/*** Output surface ***/
+VdpStatus vdp_output_surface_query_capabilities(const vdp_t *vdp,
+    VdpDevice device, VdpRGBAFormat fmt, VdpBool *ok,
+    uint32_t *max_width, uint32_t *max_height)
+{
+    return vdp->vt.output_surface_query_capabilities(device, fmt, ok,
+                                                     max_width, max_height);
+}
+
+VdpStatus vdp_output_surface_query_get_put_bits_native_capabilities(
+    const vdp_t *vdp, VdpDevice device, VdpRGBAFormat fmt, VdpBool *ok)
+{
+    return vdp->vt.output_surface_query_get_put_bits_native_capabilities(
+                                                              device, fmt, ok);
+}
+
+VdpStatus vdp_output_surface_query_put_bits_indexed_capabilities(
+    const vdp_t *vdp, VdpDevice device, VdpRGBAFormat fmt,
+    VdpIndexedFormat idxfmt, VdpColorTableFormat colfmt, VdpBool *ok)
+{
+    return vdp->vt.output_surface_query_put_bits_indexed_capabilities(device,
+                                                      fmt, idxfmt, colfmt, ok);
+}
+
+VdpStatus vdp_output_surface_query_put_bits_y_cb_cr_capabilities(
+    const vdp_t *vdp, VdpDevice device,
+    VdpRGBAFormat fmt, VdpYCbCrFormat yccfmt, VdpBool *ok)
+{
+    return vdp->vt.output_surface_query_put_bits_y_cb_cr_capabilities(device,
+                                                              fmt, yccfmt, ok);
+}
+
+VdpStatus vdp_output_surface_create(const vdp_t *vdp, VdpDevice device,
+    VdpRGBAFormat fmt, uint32_t w, uint32_t h, VdpOutputSurface *surface)
+{
+    return vdp->vt.output_surface_create(device, fmt, w, h, surface);
+}
+
+VdpStatus vdp_output_surface_destroy(const vdp_t *vdp,
+                                     VdpOutputSurface surface)
+{
+    return vdp->vt.output_surface_destroy(surface);
+}
+
+VdpStatus vdp_output_surface_get_parameters(const vdp_t *vdp,
+    VdpOutputSurface surface, VdpRGBAFormat *fmt, uint32_t *w, uint32_t *h)
+{
+    return vdp->vt.output_surface_get_parameters(surface, fmt, w, h);
+}
+
+VdpStatus vdp_output_surface_get_bits_native(const vdp_t *vdp,
+    VdpOutputSurface surface, const VdpRect *src,
+    void *const *data, uint32_t const *pitches)
+{
+    return vdp->vt.output_surface_get_bits_native(surface, src, data, pitches);
+}
+
+VdpStatus vdp_output_surface_put_bits_native(const vdp_t *vdp,
+    VdpOutputSurface surface, const void *const *data, uint32_t const *pitches,
+    const VdpRect *dst)
+{
+    return vdp->vt.output_surface_put_bits_native(surface, data, pitches, dst);
+}
+
+VdpStatus vdp_output_surface_put_bits_indexed(const vdp_t *vdp,
+    VdpOutputSurface surface, VdpIndexedFormat fmt, const void *const *data,
+    const uint32_t *pitch, const VdpRect *dst,
+    VdpColorTableFormat tabfmt, const void *tab)
+{
+    return vdp->vt.output_surface_put_bits_indexed(surface, fmt, data, pitch,
+                                                   dst, tabfmt, tab);
+}
+
+VdpStatus vdp_output_surface_put_bits_y_cb_cr(const vdp_t *vdp,
+    VdpOutputSurface surface, VdpYCbCrFormat fmt, const void *const *data,
+    const uint32_t *pitches, const VdpRect *dst, const VdpCSCMatrix *mtx)
+{
+    return vdp->vt.output_surface_put_bits_y_cb_cr(surface, fmt, data,
+                                                   pitches, dst, mtx);
+}
+
+/*** Bitmap surface ***/
+VdpStatus vdp_bitmap_surface_query_capabilities(const vdp_t *vdp,
+    VdpDevice device, VdpRGBAFormat fmt, VdpBool *ok, uint32_t *w, uint32_t *h)
+{
+    return vdp->vt.bitmap_surface_query_capabilities(device, fmt, ok, w, h);
+}
+
+VdpStatus vdp_bitmap_surface_create(const vdp_t *vdp, VdpDevice device,
+    VdpRGBAFormat fmt, uint32_t w, uint32_t h, VdpBool fq,
+    VdpBitmapSurface *surface)
+{
+    return vdp->vt.bitmap_surface_create(device, fmt, w, h, fq, surface);
+}
+
+VdpStatus vdp_bitmap_surface_destroy(const vdp_t *vdp,
+                                     VdpBitmapSurface surface)
+{
+    return vdp->vt.bitmap_surface_destroy(surface);
+}
+
+VdpStatus vdp_bitmap_surface_get_parameters(const vdp_t *vdp,
+    VdpBitmapSurface surface, VdpRGBAFormat *fmt, uint32_t *w, uint32_t *h,
+    VdpBool *fq)
+{
+    return vdp->vt.bitmap_surface_get_parameters(surface, fmt, w, h, fq);
+}
+
+VdpStatus vdp_bitmap_surface_put_bits_native(const vdp_t *vdp,
+    VdpBitmapSurface surface, const void *const *data, const uint32_t *pitch,
+    const VdpRect *rect)
+{
+    return vdp->vt.bitmap_surface_put_bits_native(surface, data, pitch, rect);
+}
+
+VdpStatus vdp_output_surface_render_output_surface(const vdp_t *vdp,
+    VdpOutputSurface dst_surface, const VdpRect *dst_rect,
+    VdpOutputSurface src_surface, const VdpRect *src_rect,
+    const VdpColor *colors,
+    const VdpOutputSurfaceRenderBlendState const *state, uint32_t flags)
+{
+    return vdp->vt.output_surface_render_output_surface(dst_surface, dst_rect,
+        src_surface, src_rect, colors, state, flags);
+}
+
+VdpStatus vdp_output_surface_render_bitmap_surface(const vdp_t *vdp,
+    VdpOutputSurface dst_surface, const VdpRect *dst_rect,
+    VdpBitmapSurface src_surface, const VdpRect *src_rect,
+    const VdpColor *colors,
+    const VdpOutputSurfaceRenderBlendState *state, uint32_t flags)
+{
+    return vdp->vt.output_surface_render_bitmap_surface(dst_surface, dst_rect,
+        src_surface, src_rect, colors, state, flags);
+}
+
+/*** Decoder ***/
+VdpStatus vdp_decoder_query_capabilities(const vdp_t *vdp, VdpDevice device,
+    VdpDecoderProfile profile, VdpBool *ok, uint32_t *l, uint32_t *m,
+    uint32_t *w, uint32_t *h)
+{
+    return vdp->vt.decoder_query_capabilities(device, profile, ok, l, m, w, h);
+}
+
+VdpStatus vdp_decoder_create(const vdp_t *vdp, VdpDevice device,
+    VdpDecoderProfile profile, uint32_t w, uint32_t h, uint32_t refs,
+    VdpDecoder *decoder)
+{
+    return vdp->vt.decoder_create(device, profile, w, h, refs, decoder);
+}
+
+VdpStatus vdp_decoder_destroy(const vdp_t *vdp, VdpDecoder decoder)
+{
+    return vdp->vt.decoder_destroy(decoder);
+}
+
+VdpStatus vdp_decoder_get_parameters(const vdp_t *vdp, VdpDecoder decoder,
+    VdpDecoderProfile *profile, uint32_t *w, uint32_t *h)
+{
+    return vdp->vt.decoder_get_parameters(decoder, profile, w, h);
+}
+
+VdpStatus vdp_decoder_render(const vdp_t *vdp, VdpDecoder decoder,
+    VdpVideoSurface target, const VdpPictureInfo *info,
+    uint32_t bufv, const VdpBitstreamBuffer *bufc)
+
+{
+    return vdp->vt.decoder_render(decoder, target, info, bufv, bufc);
+}
+
+/*** Video mixer ***/
+VdpStatus vdp_video_mixer_query_feature_support(const vdp_t *vdp,
+    VdpDevice device, VdpVideoMixerFeature feature, VdpBool *ok)
+{
+    return vdp->vt.video_mixer_query_feature_support(device, feature, ok);
+}
+
+VdpStatus vdp_video_mixer_query_parameter_support(const vdp_t *vdp,
+    VdpDevice device, VdpVideoMixerParameter parameter, VdpBool *ok)
+{
+    return vdp->vt.video_mixer_query_parameter_support(device, parameter, ok);
+}
+
+VdpStatus vdp_video_mixer_query_attribute_support(const vdp_t *vdp,
+    VdpDevice device, VdpVideoMixerAttribute attribute, VdpBool *ok)
+{
+    return vdp->vt.video_mixer_query_attribute_support(device, attribute, ok);
+}
+
+VdpStatus vdp_video_mixer_query_parameter_value_range(const vdp_t *vdp,
+    VdpDevice device, VdpVideoMixerParameter parameter, void *min, void *max)
+{
+    return vdp->vt.video_mixer_query_parameter_value_range(device, parameter,
+        min, max);
+}
+
+VdpStatus vdp_video_mixer_query_attribute_value_range(const vdp_t *vdp,
+    VdpDevice device, VdpVideoMixerAttribute attribute, void *min, void *max)
+{
+    return vdp->vt.video_mixer_query_attribute_value_range(device, attribute,
+        min, max);
+}
+
+VdpStatus vdp_video_mixer_create(const vdp_t *vdp, VdpDevice device,
+    uint32_t featc, const VdpVideoMixerFeature *featv,
+    uint32_t parmc, const VdpVideoMixerParameter *parmv,
+    const void *const *parmvalv, VdpVideoMixer *mixer)
+{
+    return vdp->vt.video_mixer_create(device, featc, featv, parmc, parmv,
+                                      parmvalv, mixer);
+}
+
+VdpStatus vdp_video_mixer_set_feature_enables(const vdp_t *vdp,
+    VdpVideoMixer mixer, uint32_t count, const VdpVideoMixerFeature *ids,
+    const VdpBool *values)
+{
+    return vdp->vt.video_mixer_set_feature_enables(mixer, count, ids, values);
+}
+
+VdpStatus vdp_video_mixer_set_attribute_values(const vdp_t *vdp,
+    VdpVideoMixer mixer, uint32_t count,
+    const VdpVideoMixerAttribute const *ids, const void *const *values)
+{
+    return vdp->vt.video_mixer_set_attribute_values(mixer, count, ids, values);
+}
+
+VdpStatus vdp_video_mixer_get_feature_support(const vdp_t *vdp,
+    VdpVideoMixer mixer, uint32_t count, const VdpVideoMixerFeature *ids,
+    VdpBool *values)
+{
+    return vdp->vt.video_mixer_get_feature_support(mixer, count, ids, values);
+}
+
+VdpStatus vdp_video_mixer_get_feature_enables(const vdp_t *vdp,
+    VdpVideoMixer mixer, uint32_t count, const VdpVideoMixerFeature *ids,
+    VdpBool *values)
+{
+    return vdp->vt.video_mixer_get_feature_enables(mixer, count, ids, values);
+}
+
+VdpStatus vdp_video_mixer_get_parameter_values(const vdp_t *vdp,
+    VdpVideoMixer mixer, uint32_t count, const VdpVideoMixerParameter *ids,
+    void *const *values)
+{
+    return vdp->vt.video_mixer_get_parameter_values(mixer, count, ids, values);
+}
+
+VdpStatus vdp_video_mixer_get_attribute_values(const vdp_t *vdp,
+    VdpVideoMixer mixer, uint32_t count, const VdpVideoMixerAttribute *ids,
+    void *const *values)
+{
+    return vdp->vt.video_mixer_get_attribute_values(mixer, count, ids, values);
+}
+
+VdpStatus vdp_video_mixer_destroy(const vdp_t *vdp, VdpVideoMixer mixer)
+{
+    return vdp->vt.video_mixer_destroy(mixer);
+}
+
+VdpStatus vdp_video_mixer_render(const vdp_t *vdp, VdpVideoMixer mixer,
+    VdpOutputSurface bgsurface, const VdpRect *bgrect,
+    VdpVideoMixerPictureStructure pic_struct, uint32_t prev_count,
+    const VdpVideoSurface *prev, VdpVideoSurface cur, uint32_t next_count,
+    const VdpVideoSurface *next, const VdpRect *src_rect,
+    VdpOutputSurface dst, const VdpRect *dst_rect, const VdpRect *dst_v_rect,
+    uint32_t layerc, const VdpLayer *layerv)
+{
+    return vdp->vt.video_mixer_render(mixer, bgsurface, bgrect, pic_struct,
+        prev_count, prev, cur, next_count, next, src_rect, dst, dst_rect,
+        dst_v_rect, layerc, layerv);
+}
+
+/*** Presentation queue ***/
+VdpStatus vdp_presentation_queue_target_destroy(const vdp_t *vdp,
+    VdpPresentationQueueTarget target)
+{
+    return vdp->vt.presentation_queue_target_destroy(target);
+}
+
+VdpStatus vdp_presentation_queue_create(const vdp_t *vdp, VdpDevice device,
+    VdpPresentationQueueTarget target, VdpPresentationQueue *queue)
+{
+    return vdp->vt.presentation_queue_create(device, target, queue);
+}
+
+VdpStatus vdp_presentation_queue_destroy(const vdp_t *vdp,
+    VdpPresentationQueue queue)
+{
+    return vdp->vt.presentation_queue_destroy(queue);
+}
+
+VdpStatus vdp_presentation_queue_set_background_color(const vdp_t *vdp,
+    VdpPresentationQueue queue, const VdpColor *color)
+{
+    VdpColor bak = *color;
+    return vdp->vt.presentation_queue_set_background_color(queue, &bak);
+}
+
+VdpStatus vdp_presentation_queue_get_background_color(const vdp_t *vdp,
+    VdpPresentationQueue queue, VdpColor *color)
+{
+    return vdp->vt.presentation_queue_get_background_color(queue, color);
+}
+
+VdpStatus vdp_presentation_queue_get_time(const vdp_t *vdp,
+    VdpPresentationQueue queue, VdpTime *current_time)
+{
+    return vdp->vt.presentation_queue_get_time(queue, current_time);
+}
+
+VdpStatus vdp_presentation_queue_display(const vdp_t *vdp,
+    VdpPresentationQueue queue, VdpOutputSurface surface, uint32_t clip_width,
+    uint32_t clip_height, VdpTime pts)
+{
+    return vdp->vt.presentation_queue_display(queue, surface, clip_width,
+                                              clip_height, pts);
+}
+
+VdpStatus vdp_presentation_queue_block_until_surface_idle(const vdp_t *vdp,
+    VdpPresentationQueue queue, VdpOutputSurface surface, VdpTime *pts)
+{
+    return vdp->vt.presentation_queue_block_until_surface_idle(queue, surface,
+                                                               pts);
+}
+
+VdpStatus vdp_presentation_queue_query_surface_status(const vdp_t *vdp,
+    VdpPresentationQueue queue, VdpOutputSurface surface,
+    VdpPresentationQueueStatus *status, VdpTime *pts)
+{
+    return vdp->vt.presentation_queue_query_surface_status(queue, surface,
+                                                           status, pts);
+}
+
+/*** Preemption ***/
+VdpStatus vdp_preemption_callback_register(const vdp_t *vdp, VdpDevice device,
+    VdpPreemptionCallback cb, void *ctx)
+{
+    return vdp->vt.preemption_callback_register(device, cb, ctx);
+}
+
+static VdpStatus vdp_fallback(/* UNDEFINED - LEAVE EMPTY */)
+{
+    return VDP_STATUS_NO_IMPLEMENTATION;
+}
+
+/*** X11 & VLC ***/
+#include <dlfcn.h>
+#include <vdpau/vdpau_x11.h>
+
+VdpStatus vdp_presentation_queue_target_create_x11(const vdp_t *vdp,
+    VdpDevice device, uint32_t drawable, VdpPresentationQueueTarget *target)
+{
+    void *ptr;
+    VdpStatus err = vdp_get_proc_address(vdp, device,
+                       VDP_FUNC_ID_PRESENTATION_QUEUE_TARGET_CREATE_X11, &ptr);
+    if (err != VDP_STATUS_OK)
+        return err;
+
+    VdpPresentationQueueTargetCreateX11 *f = ptr;
+    return f(device, drawable, target);
+}
+
+VdpStatus vdp_create_x11(void *dpy, int snum,
+                         vdp_t **restrict vdpp, VdpDevice *restrict devp)
+{
+    vdp_t *vdp = malloc(sizeof (*vdp));
+    if (unlikely(vdp == NULL))
+        return VDP_STATUS_RESOURCES;
+    *vdpp = vdp;
+
+    VdpStatus err = VDP_STATUS_NO_IMPLEMENTATION;
+
+    vdp->handle = dlopen("libvdpau.so.1", RTLD_LAZY|RTLD_LOCAL);
+    if (vdp->handle == NULL)
+    {
+        free(vdp);
+        return err;
+    }
+
+    VdpDeviceCreateX11 *create = dlsym(vdp->handle, "vdp_device_create_x11");
+    if (create == NULL)
+        goto error;
+
+    VdpGetProcAddress *gpa;
+    err = create(dpy, snum, devp, &gpa);
+    if (err != VDP_STATUS_OK)
+        goto error;
+
+    for (VdpFuncId i = 0; i < sizeof (vdp->vt) / sizeof (void *); i++)
+        if (gpa(*devp, i, vdp->funcs + i) != VDP_STATUS_OK)
+        {
+            void *fallback = vdp_fallback;
+            if (unlikely(i == VDP_FUNC_ID_GET_ERROR_STRING))
+                fallback = vdp_get_error_string_fallback;
+            vdp->funcs[i] = fallback;
+        }
+
+    return VDP_STATUS_OK;
+error:
+    vdp_destroy_x11(vdp);
+    return err;
+}
+
+void vdp_destroy_x11(vdp_t *vdp)
+{
+    dlclose(vdp->handle);
+    free(vdp);
+}
diff --git a/modules/hw/vdpau/vlc_vdpau.h b/modules/hw/vdpau/vlc_vdpau.h
new file mode 100644
index 0000000..69ce11f
--- /dev/null
+++ b/modules/hw/vdpau/vlc_vdpau.h
@@ -0,0 +1,171 @@
+/*****************************************************************************
+ * vlc_vdpau.h: VDPAU helper for VLC
+ *****************************************************************************
+ * Copyright (C) 2013 Rémi Denis-Courmont
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifndef VLC_VDPAU_H
+# include <stdint.h>
+# include <vdpau/vdpau.h>
+
+typedef struct vdp_s vdp_t;
+
+const char *vdp_get_error_string(const vdp_t *, VdpStatus);
+VdpStatus vdp_get_proc_address(const vdp_t *, VdpDevice, VdpFuncId, void **);
+VdpStatus vdp_get_api_version(const vdp_t *, uint32_t *);
+VdpStatus vdp_get_information_string(const vdp_t *, const char **);
+VdpStatus vdp_device_destroy(const vdp_t *, VdpDevice);
+VdpStatus vdp_generate_csc_matrix(const vdp_t *, const VdpProcamp *,
+                                  VdpColorStandard, VdpCSCMatrix *);
+VdpStatus vdp_video_surface_query_capabilities(const vdp_t *, VdpDevice,
+                             VdpChromaType, VdpBool *, uint32_t *, uint32_t *);
+VdpStatus vdp_video_surface_query_get_put_bits_y_cb_cr_capabilities(
+    const vdp_t *, VdpDevice, VdpChromaType, VdpYCbCrFormat, VdpBool *);
+VdpStatus vdp_video_surface_create(const vdp_t *, VdpDevice, VdpChromaType,
+                                   uint32_t, uint32_t, VdpVideoSurface *);
+VdpStatus vdp_video_surface_destroy(const vdp_t *, VdpVideoSurface);
+VdpStatus vdp_video_surface_get_parameters(const vdp_t *, VdpVideoSurface,
+                                      VdpChromaType *, uint32_t *, uint32_t *);
+VdpStatus vdp_video_surface_get_bits_y_cb_cr(const vdp_t *, VdpVideoSurface,
+                              VdpYCbCrFormat, void *const *, uint32_t const *);
+VdpStatus vdp_video_surface_put_bits_y_cb_cr(const vdp_t *, VdpVideoSurface,
+                        VdpYCbCrFormat, const void *const *, uint32_t const *);
+VdpStatus vdp_output_surface_query_capabilities(const vdp_t *, VdpDevice,
+    VdpRGBAFormat, VdpBool *, uint32_t *, uint32_t *);
+VdpStatus vdp_output_surface_query_get_put_bits_native_capabilities(
+    const vdp_t *, VdpDevice, VdpRGBAFormat, VdpBool *);
+VdpStatus vdp_output_surface_query_put_bits_indexed_capabilities(const vdp_t *,
+    VdpDevice, VdpRGBAFormat, VdpIndexedFormat, VdpColorTableFormat,
+    VdpBool *);
+VdpStatus vdp_output_surface_query_put_bits_y_cb_cr_capabilities(const vdp_t *,
+    VdpDevice, VdpRGBAFormat, VdpYCbCrFormat, VdpBool *);
+VdpStatus vdp_output_surface_create(const vdp_t *, VdpDevice, VdpRGBAFormat,
+    uint32_t, uint32_t, VdpOutputSurface *);
+VdpStatus vdp_output_surface_destroy(const vdp_t *, VdpOutputSurface);
+VdpStatus vdp_output_surface_get_parameters(const vdp_t *, VdpOutputSurface,
+    VdpRGBAFormat *, uint32_t *, uint32_t *);
+VdpStatus vdp_output_surface_get_bits_native(const vdp_t *, VdpOutputSurface,
+    const VdpRect *, void *const *, uint32_t const *);
+VdpStatus vdp_output_surface_put_bits_native(const vdp_t *, VdpOutputSurface,
+    const void *const *, uint32_t const *, const VdpRect *);
+VdpStatus vdp_output_surface_put_bits_indexed(const vdp_t *, VdpOutputSurface,
+    VdpIndexedFormat, const void *const *, const uint32_t *, const VdpRect *,
+    VdpColorTableFormat, const void *);
+VdpStatus vdp_output_surface_put_bits_y_cb_cr(const vdp_t *, VdpOutputSurface,
+    VdpYCbCrFormat, const void *const *, const uint32_t *, const VdpRect *,
+    const VdpCSCMatrix *);
+VdpStatus vdp_bitmap_surface_query_capabilities(const vdp_t *, VdpDevice,
+    VdpRGBAFormat, VdpBool *, uint32_t *, uint32_t *);
+VdpStatus vdp_bitmap_surface_create(const vdp_t *, VdpDevice, VdpRGBAFormat,
+    uint32_t, uint32_t, VdpBool, VdpBitmapSurface *);
+VdpStatus vdp_bitmap_surface_destroy(const vdp_t *, VdpBitmapSurface);
+VdpStatus vdp_bitmap_surface_get_parameters(const vdp_t *, VdpBitmapSurface,
+    VdpRGBAFormat *, uint32_t *, uint32_t *, VdpBool *);
+VdpStatus vdp_bitmap_surface_put_bits_native(const vdp_t *, VdpBitmapSurface,
+    const void *const *, const uint32_t *, const VdpRect *);
+VdpStatus vdp_output_surface_render_output_surface(const vdp_t *,
+    VdpOutputSurface, const VdpRect *, VdpOutputSurface, const VdpRect *,
+    const VdpColor *, const VdpOutputSurfaceRenderBlendState const *,
+    uint32_t);
+VdpStatus vdp_output_surface_render_bitmap_surface(const vdp_t *,
+    VdpOutputSurface, const VdpRect *, VdpBitmapSurface, const VdpRect *,
+    const VdpColor *, const VdpOutputSurfaceRenderBlendState *, uint32_t);
+VdpStatus vdp_decoder_query_capabilities(const vdp_t *, VdpDevice,
+    VdpDecoderProfile, VdpBool *,
+    uint32_t *, uint32_t *, uint32_t *, uint32_t *);
+VdpStatus vdp_decoder_create(const vdp_t *, VdpDevice, VdpDecoderProfile,
+    uint32_t, uint32_t, uint32_t, VdpDecoder *);
+VdpStatus vdp_decoder_destroy(const vdp_t *, VdpDecoder);
+VdpStatus vdp_decoder_get_parameters(const vdp_t *, VdpDecoder,
+    VdpDecoderProfile *, uint32_t *, uint32_t *);
+VdpStatus vdp_decoder_render(const vdp_t *, VdpDecoder, VdpVideoSurface,
+    const VdpPictureInfo *, uint32_t, const VdpBitstreamBuffer *);
+VdpStatus vdp_video_mixer_query_feature_support(const vdp_t *, VdpDevice,
+    VdpVideoMixerFeature, VdpBool *);
+VdpStatus vdp_video_mixer_query_parameter_support(const vdp_t *, VdpDevice,
+    VdpVideoMixerParameter, VdpBool *);
+VdpStatus vdp_video_mixer_query_attribute_support(const vdp_t *, VdpDevice,
+    VdpVideoMixerAttribute, VdpBool *);
+VdpStatus vdp_video_mixer_query_parameter_value_range(const vdp_t *, VdpDevice,
+    VdpVideoMixerParameter, void *, void *);
+VdpStatus vdp_video_mixer_query_attribute_value_range(const vdp_t *, VdpDevice,
+    VdpVideoMixerAttribute, void *, void *);
+VdpStatus vdp_video_mixer_create(const vdp_t *, VdpDevice, uint32_t,
+    const VdpVideoMixerFeature *, uint32_t, const VdpVideoMixerParameter *,
+    const void *const *, VdpVideoMixer *);
+VdpStatus vdp_video_mixer_set_feature_enables(const vdp_t *, VdpVideoMixer,
+    uint32_t, const VdpVideoMixerFeature *, const VdpBool *);
+VdpStatus vdp_video_mixer_set_attribute_values(const vdp_t *, VdpVideoMixer,
+    uint32_t, const VdpVideoMixerAttribute const *, const void *const *);
+VdpStatus vdp_video_mixer_get_feature_support(const vdp_t *, VdpVideoMixer,
+    uint32_t, const VdpVideoMixerFeature *, VdpBool *);
+VdpStatus vdp_video_mixer_get_feature_enables(const vdp_t *, VdpVideoMixer,
+    uint32_t, const VdpVideoMixerFeature *, VdpBool *);
+VdpStatus vdp_video_mixer_get_parameter_values(const vdp_t *, VdpVideoMixer,
+    uint32_t, const VdpVideoMixerParameter *, void *const *);
+VdpStatus vdp_video_mixer_get_attribute_values(const vdp_t *, VdpVideoMixer,
+    uint32_t, const VdpVideoMixerAttribute *, void *const *);
+VdpStatus vdp_video_mixer_destroy(const vdp_t *, VdpVideoMixer);
+VdpStatus vdp_video_mixer_render(const vdp_t *, VdpVideoMixer,
+    VdpOutputSurface, const VdpRect *, VdpVideoMixerPictureStructure, uint32_t,
+    const VdpVideoSurface *, VdpVideoSurface, uint32_t,
+    const VdpVideoSurface *, const VdpRect *, VdpOutputSurface,
+    const VdpRect *, const VdpRect *, uint32_t, const VdpLayer *);
+VdpStatus vdp_presentation_queue_target_destroy(const vdp_t *,
+    VdpPresentationQueueTarget);
+VdpStatus vdp_presentation_queue_create(const vdp_t *, VdpDevice,
+    VdpPresentationQueueTarget, VdpPresentationQueue *);
+VdpStatus vdp_presentation_queue_destroy(const vdp_t *, VdpPresentationQueue);
+VdpStatus vdp_presentation_queue_set_background_color(const vdp_t *,
+    VdpPresentationQueue, const VdpColor *);
+VdpStatus vdp_presentation_queue_get_background_color(const vdp_t *,
+    VdpPresentationQueue, VdpColor *);
+VdpStatus vdp_presentation_queue_get_time(const vdp_t *,
+    VdpPresentationQueue, VdpTime *);
+VdpStatus vdp_presentation_queue_display(const vdp_t *, VdpPresentationQueue,
+    VdpOutputSurface, uint32_t, uint32_t, VdpTime);
+VdpStatus vdp_presentation_queue_block_until_surface_idle(const vdp_t *,
+    VdpPresentationQueue, VdpOutputSurface, VdpTime *);
+VdpStatus vdp_presentation_queue_query_surface_status(const vdp_t *,
+    VdpPresentationQueue, VdpOutputSurface, VdpPresentationQueueStatus *,
+    VdpTime *);
+VdpStatus vdp_preemption_callback_register(const vdp_t *vdp, VdpDevice,
+                                           VdpPreemptionCallback, void *);
+
+VdpStatus vdp_presentation_queue_target_create_x11(const vdp_t *,
+                            VdpDevice, uint32_t, VdpPresentationQueueTarget *);
+
+/**
+ * Loads a VDPAU instance and creates a VDPAU device using X11.
+ * @param dpy X11 display handle (Xlib Display pointer) [IN]
+ * @param snum X11 screen number
+ * @param vdpp memory location to hold the VDPAU instance pointer [OUT]
+ * @param devp memory location to hold the VDPAU device handle [OUT]
+ * @note The X11 display connection must remain valid until after the VDPAU
+ * device has been destroyed with vdp_device_destroy().
+ * @return VDP_STATUS_OK on success, otherwise a VDPAU error code.
+ */
+VdpStatus vdp_create_x11(void *dpy, int snum, vdp_t **vdpp, VdpDevice *devp);
+
+
+/**
+ * Destroys a VDPAU instance created with vdp_create_x11().
+ * @note The corresponding VDPAU device shall have been destroyed with
+ * vdp_device_destroy() first.
+ */
+void vdp_destroy_x11(vdp_t *);
+#endif
-- 
1.8.3.2




More information about the vlc-devel mailing list