1 /*****************************************************************************
2 * vlc_vdpau.c: VDPAU helper for VLC
3 *****************************************************************************
4 * Copyright (C) 2013 Rémi Denis-Courmont
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2.1 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19 *****************************************************************************/
20
21 #ifdef HAVE_CONFIG_H
22 # include <config.h>
23 #endif
24
25 #include <stdlib.h>
26 #include <vlc_common.h>
27 #include "vlc_vdpau.h"
28
29 #pragma GCC visibility push(default)
30
31 typedef struct
32 {
33 VdpGetErrorString *get_error_string;
34 VdpGetProcAddress *get_proc_address;
35 VdpGetApiVersion *get_api_version;
36 void *dummy3;
37 VdpGetInformationString *get_information_string;
38 VdpDeviceDestroy *device_destroy;
39 VdpGenerateCSCMatrix *generate_csc_matrix;
40 VdpVideoSurfaceQueryCapabilities *video_surface_query_capabilities;
41 VdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities *video_surface_query_get_put_bits_y_cb_cr_capabilities;
42 VdpVideoSurfaceCreate *video_surface_create;
43 VdpVideoSurfaceDestroy *video_surface_destroy;
44 VdpVideoSurfaceGetParameters *video_surface_get_parameters;
45 VdpVideoSurfaceGetBitsYCbCr *video_surface_get_bits_y_cb_cr;
46 VdpVideoSurfacePutBitsYCbCr *video_surface_put_bits_y_cb_cr;
47 VdpOutputSurfaceQueryCapabilities *output_surface_query_capabilities;
48 VdpOutputSurfaceQueryGetPutBitsNativeCapabilities *output_surface_query_get_put_bits_native_capabilities;
49 VdpOutputSurfaceQueryPutBitsIndexedCapabilities *output_surface_query_put_bits_indexed_capabilities;
50 VdpOutputSurfaceQueryPutBitsYCbCrCapabilities *output_surface_query_put_bits_y_cb_cr_capabilities;
51 VdpOutputSurfaceCreate *output_surface_create;
52 VdpOutputSurfaceDestroy *output_surface_destroy;
53 VdpOutputSurfaceGetParameters *output_surface_get_parameters;
54 VdpOutputSurfaceGetBitsNative *output_surface_get_bits_native;
55 VdpOutputSurfacePutBitsNative *output_surface_put_bits_native;
56 VdpOutputSurfacePutBitsIndexed *output_surface_put_bits_indexed;
57 VdpOutputSurfacePutBitsYCbCr *output_surface_put_bits_y_cb_cr;
58 VdpBitmapSurfaceQueryCapabilities *bitmap_surface_query_capabilities;
59 VdpBitmapSurfaceCreate *bitmap_surface_create;
60 VdpBitmapSurfaceDestroy *bitmap_surface_destroy;
61 VdpBitmapSurfaceGetParameters *bitmap_surface_get_parameters;
62 VdpBitmapSurfacePutBitsNative *bitmap_surface_put_bits_native;
63 void *dummy30;
64 void *dummy31;
65 void *dummy32;
66 VdpOutputSurfaceRenderOutputSurface *output_surface_render_output_surface;
67 VdpOutputSurfaceRenderBitmapSurface *output_surface_render_bitmap_surface;
68 void *output_surface_render_video_surface_luma;
69 VdpDecoderQueryCapabilities *decoder_query_capabilities;
70 VdpDecoderCreate *decoder_create;
71 VdpDecoderDestroy *decoder_destroy;
72 VdpDecoderGetParameters *decoder_get_parameters;
73 VdpDecoderRender *decoder_render;
74 VdpVideoMixerQueryFeatureSupport *video_mixer_query_feature_support;
75 VdpVideoMixerQueryParameterSupport *video_mixer_query_parameter_support;
76 VdpVideoMixerQueryAttributeSupport *video_mixer_query_attribute_support;
77 VdpVideoMixerQueryParameterValueRange *video_mixer_query_parameter_value_range;
78 VdpVideoMixerQueryAttributeValueRange *video_mixer_query_attribute_value_range;
79 VdpVideoMixerCreate *video_mixer_create;
80 VdpVideoMixerSetFeatureEnables *video_mixer_set_feature_enables;
81 VdpVideoMixerSetAttributeValues *video_mixer_set_attribute_values;
82 VdpVideoMixerGetFeatureSupport *video_mixer_get_feature_support;
83 VdpVideoMixerGetFeatureEnables *video_mixer_get_feature_enables;
84 VdpVideoMixerGetParameterValues *video_mixer_get_parameter_values;
85 VdpVideoMixerGetAttributeValues *video_mixer_get_attribute_values;
86 VdpVideoMixerDestroy *video_mixer_destroy;
87 VdpVideoMixerRender *video_mixer_render;
88 VdpPresentationQueueTargetDestroy *presentation_queue_target_destroy;
89 VdpPresentationQueueCreate *presentation_queue_create;
90 VdpPresentationQueueDestroy *presentation_queue_destroy;
91 VdpPresentationQueueSetBackgroundColor *presentation_queue_set_background_color;
92 VdpPresentationQueueGetBackgroundColor *presentation_queue_get_background_color;
93 void *dummy60;
94 void *dummy61;
95 VdpPresentationQueueGetTime *presentation_queue_get_time;
96 VdpPresentationQueueDisplay *presentation_queue_display;
97 VdpPresentationQueueBlockUntilSurfaceIdle *presentation_queue_block_until_surface_idle;
98 VdpPresentationQueueQuerySurfaceStatus *presentation_queue_query_surface_status;
99 VdpPreemptionCallbackRegister *preemption_callback_register;
100 } vdp_vtable_t;
101
102 struct vdp_s
103 {
104 union
105 {
106 vdp_vtable_t vt;
107 void *funcs[sizeof (vdp_vtable_t) / sizeof (void *)];
108 }; /**< VDPAU function pointers table */
109 void *handle; /**< Shared library handle */
110 };
111
112 #define CHECK_FUNC(id) \
113 if (unlikely(vdp->funcs[VDP_FUNC_ID_##id] == NULL)) \
114 return VDP_STATUS_NO_IMPLEMENTATION
115
vdp_get_error_string(const vdp_t * vdp,VdpStatus status)116 const char *vdp_get_error_string(const vdp_t *vdp, VdpStatus status)
117 {
118 if (unlikely(vdp->funcs[VDP_FUNC_ID_GET_ERROR_STRING] == NULL))
119 return (status != VDP_STATUS_OK) ? "Unknown error" : "No error";
120 return vdp->vt.get_error_string(status);
121 }
122
vdp_get_proc_address(const vdp_t * vdp,VdpDevice device,VdpFuncId func_id,void ** func_ptr)123 VdpStatus vdp_get_proc_address(const vdp_t *vdp, VdpDevice device,
124 VdpFuncId func_id, void **func_ptr)
125 {
126 CHECK_FUNC(GET_PROC_ADDRESS);
127 return vdp->vt.get_proc_address(device, func_id, func_ptr);
128 }
129
vdp_get_api_version(const vdp_t * vdp,uint32_t * ver)130 VdpStatus vdp_get_api_version(const vdp_t *vdp, uint32_t *ver)
131 {
132 CHECK_FUNC(GET_API_VERSION);
133 return vdp->vt.get_api_version(ver);
134 }
135
vdp_get_information_string(const vdp_t * vdp,const char ** str)136 VdpStatus vdp_get_information_string(const vdp_t *vdp, const char **str)
137 {
138 CHECK_FUNC(GET_INFORMATION_STRING);
139 return vdp->vt.get_information_string(str);
140 }
141
142 /*** Device ***/
vdp_device_destroy(const vdp_t * vdp,VdpDevice device)143 VdpStatus vdp_device_destroy(const vdp_t *vdp, VdpDevice device)
144 {
145 CHECK_FUNC(DEVICE_DESTROY);
146 return vdp->vt.device_destroy(device);
147 }
148
vdp_generate_csc_matrix(const vdp_t * vdp,const VdpProcamp * procamp,VdpColorStandard standard,VdpCSCMatrix * csc_matrix)149 VdpStatus vdp_generate_csc_matrix(const vdp_t *vdp, const VdpProcamp *procamp,
150 VdpColorStandard standard, VdpCSCMatrix *csc_matrix)
151 {
152 VdpProcamp buf, *copy = NULL;
153
154 if (procamp != NULL)
155 {
156 buf = *procamp;
157 copy = &buf;
158 }
159 CHECK_FUNC(GENERATE_CSC_MATRIX);
160 return vdp->vt.generate_csc_matrix(copy, standard, csc_matrix);
161 }
162
163 /*** Video surface ***/
vdp_video_surface_query_capabilities(const vdp_t * vdp,VdpDevice dev,VdpChromaType type,VdpBool * ok,uint32_t * mw,uint32_t * mh)164 VdpStatus vdp_video_surface_query_capabilities(const vdp_t *vdp, VdpDevice dev,
165 VdpChromaType type, VdpBool *ok, uint32_t *mw, uint32_t *mh)
166 {
167 CHECK_FUNC(VIDEO_SURFACE_QUERY_CAPABILITIES);
168 return vdp->vt.video_surface_query_capabilities(dev, type, ok, mw, mh);
169 }
170
vdp_video_surface_query_get_put_bits_y_cb_cr_capabilities(const vdp_t * vdp,VdpDevice device,VdpChromaType type,VdpYCbCrFormat fmt,VdpBool * ok)171 VdpStatus vdp_video_surface_query_get_put_bits_y_cb_cr_capabilities(
172 const vdp_t *vdp, VdpDevice device, VdpChromaType type, VdpYCbCrFormat fmt,
173 VdpBool *ok)
174 {
175 CHECK_FUNC(VIDEO_SURFACE_QUERY_GET_PUT_BITS_Y_CB_CR_CAPABILITIES);
176 return vdp->vt.video_surface_query_get_put_bits_y_cb_cr_capabilities(
177 device, type, fmt, ok);
178 }
179
vdp_video_surface_create(const vdp_t * vdp,VdpDevice device,VdpChromaType chroma,uint32_t w,uint32_t h,VdpVideoSurface * surface)180 VdpStatus vdp_video_surface_create(const vdp_t *vdp, VdpDevice device,
181 VdpChromaType chroma, uint32_t w, uint32_t h, VdpVideoSurface *surface)
182 {
183 CHECK_FUNC(VIDEO_SURFACE_CREATE);
184 return vdp->vt.video_surface_create(device, chroma, w, h, surface);
185 }
186
vdp_video_surface_destroy(const vdp_t * vdp,VdpVideoSurface surface)187 VdpStatus vdp_video_surface_destroy(const vdp_t *vdp, VdpVideoSurface surface)
188 {
189 CHECK_FUNC(VIDEO_SURFACE_DESTROY);
190 return vdp->vt.video_surface_destroy(surface);
191 }
192
vdp_video_surface_get_parameters(const vdp_t * vdp,VdpVideoSurface surface,VdpChromaType * type,uint32_t * w,uint32_t * h)193 VdpStatus vdp_video_surface_get_parameters(const vdp_t *vdp,
194 VdpVideoSurface surface, VdpChromaType *type, uint32_t *w, uint32_t *h)
195 {
196 CHECK_FUNC(VIDEO_SURFACE_GET_PARAMETERS);
197 return vdp->vt.video_surface_get_parameters(surface, type, w, h);
198 }
199
vdp_video_surface_get_bits_y_cb_cr(const vdp_t * vdp,VdpVideoSurface surface,VdpYCbCrFormat fmt,void * const * data,uint32_t const * pitches)200 VdpStatus vdp_video_surface_get_bits_y_cb_cr(const vdp_t *vdp,
201 VdpVideoSurface surface, VdpYCbCrFormat fmt,
202 void *const *data, uint32_t const *pitches)
203 {
204 CHECK_FUNC(VIDEO_SURFACE_GET_BITS_Y_CB_CR);
205 return vdp->vt.video_surface_get_bits_y_cb_cr(surface, fmt, data, pitches);
206 }
207
vdp_video_surface_put_bits_y_cb_cr(const vdp_t * vdp,VdpVideoSurface surface,VdpYCbCrFormat fmt,const void * const * data,uint32_t const * pitches)208 VdpStatus vdp_video_surface_put_bits_y_cb_cr(const vdp_t *vdp,
209 VdpVideoSurface surface, VdpYCbCrFormat fmt,
210 const void *const *data, uint32_t const *pitches)
211 {
212 CHECK_FUNC(VIDEO_SURFACE_PUT_BITS_Y_CB_CR);
213 return vdp->vt.video_surface_put_bits_y_cb_cr(surface, fmt, data, pitches);
214 }
215
216 /*** Output surface ***/
vdp_output_surface_query_capabilities(const vdp_t * vdp,VdpDevice device,VdpRGBAFormat fmt,VdpBool * ok,uint32_t * max_width,uint32_t * max_height)217 VdpStatus vdp_output_surface_query_capabilities(const vdp_t *vdp,
218 VdpDevice device, VdpRGBAFormat fmt, VdpBool *ok,
219 uint32_t *max_width, uint32_t *max_height)
220 {
221 CHECK_FUNC(OUTPUT_SURFACE_QUERY_CAPABILITIES);
222 return vdp->vt.output_surface_query_capabilities(device, fmt, ok,
223 max_width, max_height);
224 }
225
vdp_output_surface_query_get_put_bits_native_capabilities(const vdp_t * vdp,VdpDevice device,VdpRGBAFormat fmt,VdpBool * ok)226 VdpStatus vdp_output_surface_query_get_put_bits_native_capabilities(
227 const vdp_t *vdp, VdpDevice device, VdpRGBAFormat fmt, VdpBool *ok)
228 {
229 CHECK_FUNC(OUTPUT_SURFACE_QUERY_GET_PUT_BITS_NATIVE_CAPABILITIES);
230 return vdp->vt.output_surface_query_get_put_bits_native_capabilities(
231 device, fmt, ok);
232 }
233
vdp_output_surface_query_put_bits_indexed_capabilities(const vdp_t * vdp,VdpDevice device,VdpRGBAFormat fmt,VdpIndexedFormat idxfmt,VdpColorTableFormat colfmt,VdpBool * ok)234 VdpStatus vdp_output_surface_query_put_bits_indexed_capabilities(
235 const vdp_t *vdp, VdpDevice device, VdpRGBAFormat fmt,
236 VdpIndexedFormat idxfmt, VdpColorTableFormat colfmt, VdpBool *ok)
237 {
238 CHECK_FUNC(OUTPUT_SURFACE_QUERY_PUT_BITS_INDEXED_CAPABILITIES);
239 return vdp->vt.output_surface_query_put_bits_indexed_capabilities(device,
240 fmt, idxfmt, colfmt, ok);
241 }
242
vdp_output_surface_query_put_bits_y_cb_cr_capabilities(const vdp_t * vdp,VdpDevice device,VdpRGBAFormat fmt,VdpYCbCrFormat yccfmt,VdpBool * ok)243 VdpStatus vdp_output_surface_query_put_bits_y_cb_cr_capabilities(
244 const vdp_t *vdp, VdpDevice device,
245 VdpRGBAFormat fmt, VdpYCbCrFormat yccfmt, VdpBool *ok)
246 {
247 CHECK_FUNC(OUTPUT_SURFACE_QUERY_PUT_BITS_Y_CB_CR_CAPABILITIES);
248 return vdp->vt.output_surface_query_put_bits_y_cb_cr_capabilities(device,
249 fmt, yccfmt, ok);
250 }
251
vdp_output_surface_create(const vdp_t * vdp,VdpDevice device,VdpRGBAFormat fmt,uint32_t w,uint32_t h,VdpOutputSurface * surface)252 VdpStatus vdp_output_surface_create(const vdp_t *vdp, VdpDevice device,
253 VdpRGBAFormat fmt, uint32_t w, uint32_t h, VdpOutputSurface *surface)
254 {
255 CHECK_FUNC(OUTPUT_SURFACE_CREATE);
256 return vdp->vt.output_surface_create(device, fmt, w, h, surface);
257 }
258
vdp_output_surface_destroy(const vdp_t * vdp,VdpOutputSurface surface)259 VdpStatus vdp_output_surface_destroy(const vdp_t *vdp,
260 VdpOutputSurface surface)
261 {
262 CHECK_FUNC(OUTPUT_SURFACE_DESTROY);
263 return vdp->vt.output_surface_destroy(surface);
264 }
265
vdp_output_surface_get_parameters(const vdp_t * vdp,VdpOutputSurface surface,VdpRGBAFormat * fmt,uint32_t * w,uint32_t * h)266 VdpStatus vdp_output_surface_get_parameters(const vdp_t *vdp,
267 VdpOutputSurface surface, VdpRGBAFormat *fmt, uint32_t *w, uint32_t *h)
268 {
269 CHECK_FUNC(OUTPUT_SURFACE_GET_PARAMETERS);
270 return vdp->vt.output_surface_get_parameters(surface, fmt, w, h);
271 }
272
vdp_output_surface_get_bits_native(const vdp_t * vdp,VdpOutputSurface surface,const VdpRect * src,void * const * data,uint32_t const * pitches)273 VdpStatus vdp_output_surface_get_bits_native(const vdp_t *vdp,
274 VdpOutputSurface surface, const VdpRect *src,
275 void *const *data, uint32_t const *pitches)
276 {
277 CHECK_FUNC(OUTPUT_SURFACE_GET_BITS_NATIVE);
278 return vdp->vt.output_surface_get_bits_native(surface, src, data, pitches);
279 }
280
vdp_output_surface_put_bits_native(const vdp_t * vdp,VdpOutputSurface surface,const void * const * data,uint32_t const * pitches,const VdpRect * dst)281 VdpStatus vdp_output_surface_put_bits_native(const vdp_t *vdp,
282 VdpOutputSurface surface, const void *const *data, uint32_t const *pitches,
283 const VdpRect *dst)
284 {
285 CHECK_FUNC(OUTPUT_SURFACE_PUT_BITS_NATIVE);
286 return vdp->vt.output_surface_put_bits_native(surface, data, pitches, dst);
287 }
288
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)289 VdpStatus vdp_output_surface_put_bits_indexed(const vdp_t *vdp,
290 VdpOutputSurface surface, VdpIndexedFormat fmt, const void *const *data,
291 const uint32_t *pitch, const VdpRect *dst,
292 VdpColorTableFormat tabfmt, const void *tab)
293 {
294 CHECK_FUNC(OUTPUT_SURFACE_PUT_BITS_INDEXED);
295 return vdp->vt.output_surface_put_bits_indexed(surface, fmt, data, pitch,
296 dst, tabfmt, tab);
297 }
298
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)299 VdpStatus vdp_output_surface_put_bits_y_cb_cr(const vdp_t *vdp,
300 VdpOutputSurface surface, VdpYCbCrFormat fmt, const void *const *data,
301 const uint32_t *pitches, const VdpRect *dst, const VdpCSCMatrix *mtx)
302 {
303 CHECK_FUNC(OUTPUT_SURFACE_PUT_BITS_Y_CB_CR);
304 return vdp->vt.output_surface_put_bits_y_cb_cr(surface, fmt, data,
305 pitches, dst, mtx);
306 }
307
308 /*** Bitmap surface ***/
vdp_bitmap_surface_query_capabilities(const vdp_t * vdp,VdpDevice device,VdpRGBAFormat fmt,VdpBool * ok,uint32_t * w,uint32_t * h)309 VdpStatus vdp_bitmap_surface_query_capabilities(const vdp_t *vdp,
310 VdpDevice device, VdpRGBAFormat fmt, VdpBool *ok, uint32_t *w, uint32_t *h)
311 {
312 CHECK_FUNC(BITMAP_SURFACE_QUERY_CAPABILITIES);
313 return vdp->vt.bitmap_surface_query_capabilities(device, fmt, ok, w, h);
314 }
315
vdp_bitmap_surface_create(const vdp_t * vdp,VdpDevice device,VdpRGBAFormat fmt,uint32_t w,uint32_t h,VdpBool fq,VdpBitmapSurface * surface)316 VdpStatus vdp_bitmap_surface_create(const vdp_t *vdp, VdpDevice device,
317 VdpRGBAFormat fmt, uint32_t w, uint32_t h, VdpBool fq,
318 VdpBitmapSurface *surface)
319 {
320 CHECK_FUNC(BITMAP_SURFACE_CREATE);
321 return vdp->vt.bitmap_surface_create(device, fmt, w, h, fq, surface);
322 }
323
vdp_bitmap_surface_destroy(const vdp_t * vdp,VdpBitmapSurface surface)324 VdpStatus vdp_bitmap_surface_destroy(const vdp_t *vdp,
325 VdpBitmapSurface surface)
326 {
327 CHECK_FUNC(BITMAP_SURFACE_DESTROY);
328 return vdp->vt.bitmap_surface_destroy(surface);
329 }
330
vdp_bitmap_surface_get_parameters(const vdp_t * vdp,VdpBitmapSurface surface,VdpRGBAFormat * fmt,uint32_t * w,uint32_t * h,VdpBool * fq)331 VdpStatus vdp_bitmap_surface_get_parameters(const vdp_t *vdp,
332 VdpBitmapSurface surface, VdpRGBAFormat *fmt, uint32_t *w, uint32_t *h,
333 VdpBool *fq)
334 {
335 CHECK_FUNC(BITMAP_SURFACE_GET_PARAMETERS);
336 return vdp->vt.bitmap_surface_get_parameters(surface, fmt, w, h, fq);
337 }
338
vdp_bitmap_surface_put_bits_native(const vdp_t * vdp,VdpBitmapSurface surface,const void * const * data,const uint32_t * pitch,const VdpRect * rect)339 VdpStatus vdp_bitmap_surface_put_bits_native(const vdp_t *vdp,
340 VdpBitmapSurface surface, const void *const *data, const uint32_t *pitch,
341 const VdpRect *rect)
342 {
343 CHECK_FUNC(BITMAP_SURFACE_PUT_BITS_NATIVE);
344 return vdp->vt.bitmap_surface_put_bits_native(surface, data, pitch, rect);
345 }
346
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)347 VdpStatus vdp_output_surface_render_output_surface(const vdp_t *vdp,
348 VdpOutputSurface dst_surface, const VdpRect *dst_rect,
349 VdpOutputSurface src_surface, const VdpRect *src_rect,
350 const VdpColor *colors,
351 const VdpOutputSurfaceRenderBlendState *const state, uint32_t flags)
352 {
353 CHECK_FUNC(OUTPUT_SURFACE_RENDER_OUTPUT_SURFACE);
354 return vdp->vt.output_surface_render_output_surface(dst_surface, dst_rect,
355 src_surface, src_rect, colors, state, flags);
356 }
357
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)358 VdpStatus vdp_output_surface_render_bitmap_surface(const vdp_t *vdp,
359 VdpOutputSurface dst_surface, const VdpRect *dst_rect,
360 VdpBitmapSurface src_surface, const VdpRect *src_rect,
361 const VdpColor *colors,
362 const VdpOutputSurfaceRenderBlendState *state, uint32_t flags)
363 {
364 CHECK_FUNC(OUTPUT_SURFACE_RENDER_BITMAP_SURFACE);
365 return vdp->vt.output_surface_render_bitmap_surface(dst_surface, dst_rect,
366 src_surface, src_rect, colors, state, flags);
367 }
368
369 /*** Decoder ***/
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)370 VdpStatus vdp_decoder_query_capabilities(const vdp_t *vdp, VdpDevice device,
371 VdpDecoderProfile profile, VdpBool *ok, uint32_t *l, uint32_t *m,
372 uint32_t *w, uint32_t *h)
373 {
374 CHECK_FUNC(DECODER_QUERY_CAPABILITIES);
375 return vdp->vt.decoder_query_capabilities(device, profile, ok, l, m, w, h);
376 }
377
vdp_decoder_create(const vdp_t * vdp,VdpDevice device,VdpDecoderProfile profile,uint32_t w,uint32_t h,uint32_t refs,VdpDecoder * decoder)378 VdpStatus vdp_decoder_create(const vdp_t *vdp, VdpDevice device,
379 VdpDecoderProfile profile, uint32_t w, uint32_t h, uint32_t refs,
380 VdpDecoder *decoder)
381 {
382 CHECK_FUNC(DECODER_CREATE);
383 return vdp->vt.decoder_create(device, profile, w, h, refs, decoder);
384 }
385
vdp_decoder_destroy(const vdp_t * vdp,VdpDecoder decoder)386 VdpStatus vdp_decoder_destroy(const vdp_t *vdp, VdpDecoder decoder)
387 {
388 CHECK_FUNC(DECODER_DESTROY);
389 return vdp->vt.decoder_destroy(decoder);
390 }
391
vdp_decoder_get_parameters(const vdp_t * vdp,VdpDecoder decoder,VdpDecoderProfile * profile,uint32_t * w,uint32_t * h)392 VdpStatus vdp_decoder_get_parameters(const vdp_t *vdp, VdpDecoder decoder,
393 VdpDecoderProfile *profile, uint32_t *w, uint32_t *h)
394 {
395 CHECK_FUNC(DECODER_GET_PARAMETERS);
396 return vdp->vt.decoder_get_parameters(decoder, profile, w, h);
397 }
398
vdp_decoder_render(const vdp_t * vdp,VdpDecoder decoder,VdpVideoSurface target,const VdpPictureInfo * info,uint32_t bufv,const VdpBitstreamBuffer * bufc)399 VdpStatus vdp_decoder_render(const vdp_t *vdp, VdpDecoder decoder,
400 VdpVideoSurface target, const VdpPictureInfo *info,
401 uint32_t bufv, const VdpBitstreamBuffer *bufc)
402 {
403 CHECK_FUNC(DECODER_RENDER);
404 return vdp->vt.decoder_render(decoder, target, info, bufv, bufc);
405 }
406
407 /*** Video mixer ***/
vdp_video_mixer_query_feature_support(const vdp_t * vdp,VdpDevice device,VdpVideoMixerFeature feature,VdpBool * ok)408 VdpStatus vdp_video_mixer_query_feature_support(const vdp_t *vdp,
409 VdpDevice device, VdpVideoMixerFeature feature, VdpBool *ok)
410 {
411 CHECK_FUNC(VIDEO_MIXER_QUERY_FEATURE_SUPPORT);
412 return vdp->vt.video_mixer_query_feature_support(device, feature, ok);
413 }
414
vdp_video_mixer_query_parameter_support(const vdp_t * vdp,VdpDevice device,VdpVideoMixerParameter parameter,VdpBool * ok)415 VdpStatus vdp_video_mixer_query_parameter_support(const vdp_t *vdp,
416 VdpDevice device, VdpVideoMixerParameter parameter, VdpBool *ok)
417 {
418 CHECK_FUNC(VIDEO_MIXER_QUERY_PARAMETER_SUPPORT);
419 return vdp->vt.video_mixer_query_parameter_support(device, parameter, ok);
420 }
421
vdp_video_mixer_query_attribute_support(const vdp_t * vdp,VdpDevice device,VdpVideoMixerAttribute attribute,VdpBool * ok)422 VdpStatus vdp_video_mixer_query_attribute_support(const vdp_t *vdp,
423 VdpDevice device, VdpVideoMixerAttribute attribute, VdpBool *ok)
424 {
425 CHECK_FUNC(VIDEO_MIXER_QUERY_ATTRIBUTE_SUPPORT);
426 return vdp->vt.video_mixer_query_attribute_support(device, attribute, ok);
427 }
428
vdp_video_mixer_query_parameter_value_range(const vdp_t * vdp,VdpDevice device,VdpVideoMixerParameter parameter,void * min,void * max)429 VdpStatus vdp_video_mixer_query_parameter_value_range(const vdp_t *vdp,
430 VdpDevice device, VdpVideoMixerParameter parameter, void *min, void *max)
431 {
432 CHECK_FUNC(VIDEO_MIXER_QUERY_PARAMETER_VALUE_RANGE);
433 return vdp->vt.video_mixer_query_parameter_value_range(device, parameter,
434 min, max);
435 }
436
vdp_video_mixer_query_attribute_value_range(const vdp_t * vdp,VdpDevice device,VdpVideoMixerAttribute attribute,void * min,void * max)437 VdpStatus vdp_video_mixer_query_attribute_value_range(const vdp_t *vdp,
438 VdpDevice device, VdpVideoMixerAttribute attribute, void *min, void *max)
439 {
440 CHECK_FUNC(VIDEO_MIXER_QUERY_ATTRIBUTE_VALUE_RANGE);
441 return vdp->vt.video_mixer_query_attribute_value_range(device, attribute,
442 min, max);
443 }
444
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)445 VdpStatus vdp_video_mixer_create(const vdp_t *vdp, VdpDevice device,
446 uint32_t featc, const VdpVideoMixerFeature *featv,
447 uint32_t parmc, const VdpVideoMixerParameter *parmv,
448 const void *const *parmvalv, VdpVideoMixer *mixer)
449 {
450 CHECK_FUNC(VIDEO_MIXER_CREATE);
451 return vdp->vt.video_mixer_create(device, featc, featv, parmc, parmv,
452 parmvalv, mixer);
453 }
454
vdp_video_mixer_set_feature_enables(const vdp_t * vdp,VdpVideoMixer mixer,uint32_t count,const VdpVideoMixerFeature * ids,const VdpBool * values)455 VdpStatus vdp_video_mixer_set_feature_enables(const vdp_t *vdp,
456 VdpVideoMixer mixer, uint32_t count, const VdpVideoMixerFeature *ids,
457 const VdpBool *values)
458 {
459 CHECK_FUNC(VIDEO_MIXER_SET_FEATURE_ENABLES);
460 return vdp->vt.video_mixer_set_feature_enables(mixer, count, ids, values);
461 }
462
vdp_video_mixer_set_attribute_values(const vdp_t * vdp,VdpVideoMixer mixer,uint32_t count,const VdpVideoMixerAttribute * const ids,const void * const * values)463 VdpStatus vdp_video_mixer_set_attribute_values(const vdp_t *vdp,
464 VdpVideoMixer mixer, uint32_t count,
465 const VdpVideoMixerAttribute *const ids, const void *const *values)
466 {
467 CHECK_FUNC(VIDEO_MIXER_SET_ATTRIBUTE_VALUES);
468 return vdp->vt.video_mixer_set_attribute_values(mixer, count, ids, values);
469 }
470
vdp_video_mixer_get_feature_support(const vdp_t * vdp,VdpVideoMixer mixer,uint32_t count,const VdpVideoMixerFeature * ids,VdpBool * values)471 VdpStatus vdp_video_mixer_get_feature_support(const vdp_t *vdp,
472 VdpVideoMixer mixer, uint32_t count, const VdpVideoMixerFeature *ids,
473 VdpBool *values)
474 {
475 CHECK_FUNC(VIDEO_MIXER_GET_FEATURE_SUPPORT);
476 return vdp->vt.video_mixer_get_feature_support(mixer, count, ids, values);
477 }
478
vdp_video_mixer_get_feature_enables(const vdp_t * vdp,VdpVideoMixer mixer,uint32_t count,const VdpVideoMixerFeature * ids,VdpBool * values)479 VdpStatus vdp_video_mixer_get_feature_enables(const vdp_t *vdp,
480 VdpVideoMixer mixer, uint32_t count, const VdpVideoMixerFeature *ids,
481 VdpBool *values)
482 {
483 CHECK_FUNC(VIDEO_MIXER_GET_FEATURE_ENABLES);
484 return vdp->vt.video_mixer_get_feature_enables(mixer, count, ids, values);
485 }
486
vdp_video_mixer_get_parameter_values(const vdp_t * vdp,VdpVideoMixer mixer,uint32_t count,const VdpVideoMixerParameter * ids,void * const * values)487 VdpStatus vdp_video_mixer_get_parameter_values(const vdp_t *vdp,
488 VdpVideoMixer mixer, uint32_t count, const VdpVideoMixerParameter *ids,
489 void *const *values)
490 {
491 CHECK_FUNC(VIDEO_MIXER_GET_PARAMETER_VALUES);
492 return vdp->vt.video_mixer_get_parameter_values(mixer, count, ids, values);
493 }
494
vdp_video_mixer_get_attribute_values(const vdp_t * vdp,VdpVideoMixer mixer,uint32_t count,const VdpVideoMixerAttribute * ids,void * const * values)495 VdpStatus vdp_video_mixer_get_attribute_values(const vdp_t *vdp,
496 VdpVideoMixer mixer, uint32_t count, const VdpVideoMixerAttribute *ids,
497 void *const *values)
498 {
499 CHECK_FUNC(VIDEO_MIXER_GET_ATTRIBUTE_VALUES);
500 return vdp->vt.video_mixer_get_attribute_values(mixer, count, ids, values);
501 }
502
vdp_video_mixer_destroy(const vdp_t * vdp,VdpVideoMixer mixer)503 VdpStatus vdp_video_mixer_destroy(const vdp_t *vdp, VdpVideoMixer mixer)
504 {
505 CHECK_FUNC(VIDEO_MIXER_DESTROY);
506 return vdp->vt.video_mixer_destroy(mixer);
507 }
508
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)509 VdpStatus vdp_video_mixer_render(const vdp_t *vdp, VdpVideoMixer mixer,
510 VdpOutputSurface bgsurface, const VdpRect *bgrect,
511 VdpVideoMixerPictureStructure pic_struct, uint32_t prev_count,
512 const VdpVideoSurface *prev, VdpVideoSurface cur, uint32_t next_count,
513 const VdpVideoSurface *next, const VdpRect *src_rect,
514 VdpOutputSurface dst, const VdpRect *dst_rect, const VdpRect *dst_v_rect,
515 uint32_t layerc, const VdpLayer *layerv)
516 {
517 CHECK_FUNC(VIDEO_MIXER_RENDER);
518 return vdp->vt.video_mixer_render(mixer, bgsurface, bgrect, pic_struct,
519 prev_count, prev, cur, next_count, next, src_rect, dst, dst_rect,
520 dst_v_rect, layerc, layerv);
521 }
522
523 /*** Presentation queue ***/
vdp_presentation_queue_target_destroy(const vdp_t * vdp,VdpPresentationQueueTarget target)524 VdpStatus vdp_presentation_queue_target_destroy(const vdp_t *vdp,
525 VdpPresentationQueueTarget target)
526 {
527 CHECK_FUNC(PRESENTATION_QUEUE_TARGET_DESTROY);
528 return vdp->vt.presentation_queue_target_destroy(target);
529 }
530
vdp_presentation_queue_create(const vdp_t * vdp,VdpDevice device,VdpPresentationQueueTarget target,VdpPresentationQueue * queue)531 VdpStatus vdp_presentation_queue_create(const vdp_t *vdp, VdpDevice device,
532 VdpPresentationQueueTarget target, VdpPresentationQueue *queue)
533 {
534 CHECK_FUNC(PRESENTATION_QUEUE_CREATE);
535 return vdp->vt.presentation_queue_create(device, target, queue);
536 }
537
vdp_presentation_queue_destroy(const vdp_t * vdp,VdpPresentationQueue queue)538 VdpStatus vdp_presentation_queue_destroy(const vdp_t *vdp,
539 VdpPresentationQueue queue)
540 {
541 CHECK_FUNC(PRESENTATION_QUEUE_DESTROY);
542 return vdp->vt.presentation_queue_destroy(queue);
543 }
544
vdp_presentation_queue_set_background_color(const vdp_t * vdp,VdpPresentationQueue queue,const VdpColor * color)545 VdpStatus vdp_presentation_queue_set_background_color(const vdp_t *vdp,
546 VdpPresentationQueue queue, const VdpColor *color)
547 {
548 VdpColor bak = *color;
549 CHECK_FUNC(PRESENTATION_QUEUE_SET_BACKGROUND_COLOR);
550 return vdp->vt.presentation_queue_set_background_color(queue, &bak);
551 }
552
vdp_presentation_queue_get_background_color(const vdp_t * vdp,VdpPresentationQueue queue,VdpColor * color)553 VdpStatus vdp_presentation_queue_get_background_color(const vdp_t *vdp,
554 VdpPresentationQueue queue, VdpColor *color)
555 {
556 CHECK_FUNC(PRESENTATION_QUEUE_GET_BACKGROUND_COLOR);
557 return vdp->vt.presentation_queue_get_background_color(queue, color);
558 }
559
vdp_presentation_queue_get_time(const vdp_t * vdp,VdpPresentationQueue queue,VdpTime * current_time)560 VdpStatus vdp_presentation_queue_get_time(const vdp_t *vdp,
561 VdpPresentationQueue queue, VdpTime *current_time)
562 {
563 CHECK_FUNC(PRESENTATION_QUEUE_GET_TIME);
564 return vdp->vt.presentation_queue_get_time(queue, current_time);
565 }
566
vdp_presentation_queue_display(const vdp_t * vdp,VdpPresentationQueue queue,VdpOutputSurface surface,uint32_t clip_width,uint32_t clip_height,VdpTime pts)567 VdpStatus vdp_presentation_queue_display(const vdp_t *vdp,
568 VdpPresentationQueue queue, VdpOutputSurface surface, uint32_t clip_width,
569 uint32_t clip_height, VdpTime pts)
570 {
571 CHECK_FUNC(PRESENTATION_QUEUE_DISPLAY);
572 return vdp->vt.presentation_queue_display(queue, surface, clip_width,
573 clip_height, pts);
574 }
575
vdp_presentation_queue_block_until_surface_idle(const vdp_t * vdp,VdpPresentationQueue queue,VdpOutputSurface surface,VdpTime * pts)576 VdpStatus vdp_presentation_queue_block_until_surface_idle(const vdp_t *vdp,
577 VdpPresentationQueue queue, VdpOutputSurface surface, VdpTime *pts)
578 {
579 CHECK_FUNC(PRESENTATION_QUEUE_BLOCK_UNTIL_SURFACE_IDLE);
580 return vdp->vt.presentation_queue_block_until_surface_idle(queue, surface,
581 pts);
582 }
583
vdp_presentation_queue_query_surface_status(const vdp_t * vdp,VdpPresentationQueue queue,VdpOutputSurface surface,VdpPresentationQueueStatus * status,VdpTime * pts)584 VdpStatus vdp_presentation_queue_query_surface_status(const vdp_t *vdp,
585 VdpPresentationQueue queue, VdpOutputSurface surface,
586 VdpPresentationQueueStatus *status, VdpTime *pts)
587 {
588 CHECK_FUNC(PRESENTATION_QUEUE_QUERY_SURFACE_STATUS);
589 return vdp->vt.presentation_queue_query_surface_status(queue, surface,
590 status, pts);
591 }
592
593 /*** Preemption ***/
vdp_preemption_callback_register(const vdp_t * vdp,VdpDevice device,VdpPreemptionCallback cb,void * ctx)594 VdpStatus vdp_preemption_callback_register(const vdp_t *vdp, VdpDevice device,
595 VdpPreemptionCallback cb, void *ctx)
596 {
597 CHECK_FUNC(PREEMPTION_CALLBACK_REGISTER);
598 return vdp->vt.preemption_callback_register(device, cb, ctx);
599 }
600
601 /*** X11 & VLC ***/
602 #include <dlfcn.h>
603 #include <vdpau/vdpau_x11.h>
604
vdp_presentation_queue_target_create_x11(const vdp_t * vdp,VdpDevice device,uint32_t drawable,VdpPresentationQueueTarget * target)605 VdpStatus vdp_presentation_queue_target_create_x11(const vdp_t *vdp,
606 VdpDevice device, uint32_t drawable, VdpPresentationQueueTarget *target)
607 {
608 void *ptr;
609 VdpStatus err = vdp_get_proc_address(vdp, device,
610 VDP_FUNC_ID_PRESENTATION_QUEUE_TARGET_CREATE_X11, &ptr);
611 if (err != VDP_STATUS_OK)
612 return err;
613
614 VdpPresentationQueueTargetCreateX11 *f = ptr;
615 return f(device, drawable, target);
616 }
617
vdp_create_x11(void * dpy,int snum,vdp_t ** restrict vdpp,VdpDevice * restrict devp)618 VdpStatus vdp_create_x11(void *dpy, int snum,
619 vdp_t **restrict vdpp, VdpDevice *restrict devp)
620 {
621 vdp_t *vdp = malloc(sizeof (*vdp));
622 if (unlikely(vdp == NULL))
623 return VDP_STATUS_RESOURCES;
624 *vdpp = vdp;
625
626 VdpStatus err = VDP_STATUS_NO_IMPLEMENTATION;
627
628 vdp->handle = dlopen("libvdpau.so.1", RTLD_LAZY|RTLD_LOCAL);
629 if (vdp->handle == NULL)
630 {
631 free(vdp);
632 return err;
633 }
634
635 VdpDeviceCreateX11 *create = dlsym(vdp->handle, "vdp_device_create_x11");
636 if (create == NULL)
637 goto error;
638
639 VdpGetProcAddress *gpa;
640 err = create(dpy, snum, devp, &gpa);
641 if (err != VDP_STATUS_OK)
642 goto error;
643
644 for (VdpFuncId i = 0; i < sizeof (vdp->vt) / sizeof (void *); i++)
645 if (gpa(*devp, i, vdp->funcs + i) != VDP_STATUS_OK)
646 vdp->funcs[i] = NULL;
647
648 return VDP_STATUS_OK;
649 error:
650 vdp_destroy_x11(vdp);
651 return err;
652 }
653
vdp_destroy_x11(vdp_t * vdp)654 void vdp_destroy_x11(vdp_t *vdp)
655 {
656 dlclose(vdp->handle);
657 free(vdp);
658 }
659