1 /*****************************************************************************
2  * vlc_vdpau.h: 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 #ifndef VLC_VDPAU_H
22 # include <stdint.h>
23 # include <vdpau/vdpau.h>
24 
25 typedef struct vdp_s vdp_t;
26 
27 const char *vdp_get_error_string(const vdp_t *, VdpStatus);
28 VdpStatus vdp_get_proc_address(const vdp_t *, VdpDevice, VdpFuncId, void **);
29 VdpStatus vdp_get_api_version(const vdp_t *, uint32_t *);
30 VdpStatus vdp_get_information_string(const vdp_t *, const char **);
31 VdpStatus vdp_device_destroy(const vdp_t *, VdpDevice);
32 VdpStatus vdp_generate_csc_matrix(const vdp_t *, const VdpProcamp *,
33                                   VdpColorStandard, VdpCSCMatrix *);
34 VdpStatus vdp_video_surface_query_capabilities(const vdp_t *, VdpDevice,
35                              VdpChromaType, VdpBool *, uint32_t *, uint32_t *);
36 VdpStatus vdp_video_surface_query_get_put_bits_y_cb_cr_capabilities(
37     const vdp_t *, VdpDevice, VdpChromaType, VdpYCbCrFormat, VdpBool *);
38 VdpStatus vdp_video_surface_create(const vdp_t *, VdpDevice, VdpChromaType,
39                                    uint32_t, uint32_t, VdpVideoSurface *);
40 VdpStatus vdp_video_surface_destroy(const vdp_t *, VdpVideoSurface);
41 VdpStatus vdp_video_surface_get_parameters(const vdp_t *, VdpVideoSurface,
42                                       VdpChromaType *, uint32_t *, uint32_t *);
43 VdpStatus vdp_video_surface_get_bits_y_cb_cr(const vdp_t *, VdpVideoSurface,
44                               VdpYCbCrFormat, void *const *, uint32_t const *);
45 VdpStatus vdp_video_surface_put_bits_y_cb_cr(const vdp_t *, VdpVideoSurface,
46                         VdpYCbCrFormat, const void *const *, uint32_t const *);
47 VdpStatus vdp_output_surface_query_capabilities(const vdp_t *, VdpDevice,
48     VdpRGBAFormat, VdpBool *, uint32_t *, uint32_t *);
49 VdpStatus vdp_output_surface_query_get_put_bits_native_capabilities(
50     const vdp_t *, VdpDevice, VdpRGBAFormat, VdpBool *);
51 VdpStatus vdp_output_surface_query_put_bits_indexed_capabilities(const vdp_t *,
52     VdpDevice, VdpRGBAFormat, VdpIndexedFormat, VdpColorTableFormat,
53     VdpBool *);
54 VdpStatus vdp_output_surface_query_put_bits_y_cb_cr_capabilities(const vdp_t *,
55     VdpDevice, VdpRGBAFormat, VdpYCbCrFormat, VdpBool *);
56 VdpStatus vdp_output_surface_create(const vdp_t *, VdpDevice, VdpRGBAFormat,
57     uint32_t, uint32_t, VdpOutputSurface *);
58 VdpStatus vdp_output_surface_destroy(const vdp_t *, VdpOutputSurface);
59 VdpStatus vdp_output_surface_get_parameters(const vdp_t *, VdpOutputSurface,
60     VdpRGBAFormat *, uint32_t *, uint32_t *);
61 VdpStatus vdp_output_surface_get_bits_native(const vdp_t *, VdpOutputSurface,
62     const VdpRect *, void *const *, uint32_t const *);
63 VdpStatus vdp_output_surface_put_bits_native(const vdp_t *, VdpOutputSurface,
64     const void *const *, uint32_t const *, const VdpRect *);
65 VdpStatus vdp_output_surface_put_bits_indexed(const vdp_t *, VdpOutputSurface,
66     VdpIndexedFormat, const void *const *, const uint32_t *, const VdpRect *,
67     VdpColorTableFormat, const void *);
68 VdpStatus vdp_output_surface_put_bits_y_cb_cr(const vdp_t *, VdpOutputSurface,
69     VdpYCbCrFormat, const void *const *, const uint32_t *, const VdpRect *,
70     const VdpCSCMatrix *);
71 VdpStatus vdp_bitmap_surface_query_capabilities(const vdp_t *, VdpDevice,
72     VdpRGBAFormat, VdpBool *, uint32_t *, uint32_t *);
73 VdpStatus vdp_bitmap_surface_create(const vdp_t *, VdpDevice, VdpRGBAFormat,
74     uint32_t, uint32_t, VdpBool, VdpBitmapSurface *);
75 VdpStatus vdp_bitmap_surface_destroy(const vdp_t *, VdpBitmapSurface);
76 VdpStatus vdp_bitmap_surface_get_parameters(const vdp_t *, VdpBitmapSurface,
77     VdpRGBAFormat *, uint32_t *, uint32_t *, VdpBool *);
78 VdpStatus vdp_bitmap_surface_put_bits_native(const vdp_t *, VdpBitmapSurface,
79     const void *const *, const uint32_t *, const VdpRect *);
80 VdpStatus vdp_output_surface_render_output_surface(const vdp_t *,
81     VdpOutputSurface, const VdpRect *, VdpOutputSurface, const VdpRect *,
82     const VdpColor *, const VdpOutputSurfaceRenderBlendState *const,
83     uint32_t);
84 VdpStatus vdp_output_surface_render_bitmap_surface(const vdp_t *,
85     VdpOutputSurface, const VdpRect *, VdpBitmapSurface, const VdpRect *,
86     const VdpColor *, const VdpOutputSurfaceRenderBlendState *, uint32_t);
87 VdpStatus vdp_decoder_query_capabilities(const vdp_t *, VdpDevice,
88     VdpDecoderProfile, VdpBool *,
89     uint32_t *, uint32_t *, uint32_t *, uint32_t *);
90 VdpStatus vdp_decoder_create(const vdp_t *, VdpDevice, VdpDecoderProfile,
91     uint32_t, uint32_t, uint32_t, VdpDecoder *);
92 VdpStatus vdp_decoder_destroy(const vdp_t *, VdpDecoder);
93 VdpStatus vdp_decoder_get_parameters(const vdp_t *, VdpDecoder,
94     VdpDecoderProfile *, uint32_t *, uint32_t *);
95 VdpStatus vdp_decoder_render(const vdp_t *, VdpDecoder, VdpVideoSurface,
96     const VdpPictureInfo *, uint32_t, const VdpBitstreamBuffer *);
97 VdpStatus vdp_video_mixer_query_feature_support(const vdp_t *, VdpDevice,
98     VdpVideoMixerFeature, VdpBool *);
99 VdpStatus vdp_video_mixer_query_parameter_support(const vdp_t *, VdpDevice,
100     VdpVideoMixerParameter, VdpBool *);
101 VdpStatus vdp_video_mixer_query_attribute_support(const vdp_t *, VdpDevice,
102     VdpVideoMixerAttribute, VdpBool *);
103 VdpStatus vdp_video_mixer_query_parameter_value_range(const vdp_t *, VdpDevice,
104     VdpVideoMixerParameter, void *, void *);
105 VdpStatus vdp_video_mixer_query_attribute_value_range(const vdp_t *, VdpDevice,
106     VdpVideoMixerAttribute, void *, void *);
107 VdpStatus vdp_video_mixer_create(const vdp_t *, VdpDevice, uint32_t,
108     const VdpVideoMixerFeature *, uint32_t, const VdpVideoMixerParameter *,
109     const void *const *, VdpVideoMixer *);
110 VdpStatus vdp_video_mixer_set_feature_enables(const vdp_t *, VdpVideoMixer,
111     uint32_t, const VdpVideoMixerFeature *, const VdpBool *);
112 VdpStatus vdp_video_mixer_set_attribute_values(const vdp_t *, VdpVideoMixer,
113     uint32_t, const VdpVideoMixerAttribute *const, const void *const *);
114 VdpStatus vdp_video_mixer_get_feature_support(const vdp_t *, VdpVideoMixer,
115     uint32_t, const VdpVideoMixerFeature *, VdpBool *);
116 VdpStatus vdp_video_mixer_get_feature_enables(const vdp_t *, VdpVideoMixer,
117     uint32_t, const VdpVideoMixerFeature *, VdpBool *);
118 VdpStatus vdp_video_mixer_get_parameter_values(const vdp_t *, VdpVideoMixer,
119     uint32_t, const VdpVideoMixerParameter *, void *const *);
120 VdpStatus vdp_video_mixer_get_attribute_values(const vdp_t *, VdpVideoMixer,
121     uint32_t, const VdpVideoMixerAttribute *, void *const *);
122 VdpStatus vdp_video_mixer_destroy(const vdp_t *, VdpVideoMixer);
123 VdpStatus vdp_video_mixer_render(const vdp_t *, VdpVideoMixer,
124     VdpOutputSurface, const VdpRect *, VdpVideoMixerPictureStructure, uint32_t,
125     const VdpVideoSurface *, VdpVideoSurface, uint32_t,
126     const VdpVideoSurface *, const VdpRect *, VdpOutputSurface,
127     const VdpRect *, const VdpRect *, uint32_t, const VdpLayer *);
128 VdpStatus vdp_presentation_queue_target_destroy(const vdp_t *,
129     VdpPresentationQueueTarget);
130 VdpStatus vdp_presentation_queue_create(const vdp_t *, VdpDevice,
131     VdpPresentationQueueTarget, VdpPresentationQueue *);
132 VdpStatus vdp_presentation_queue_destroy(const vdp_t *, VdpPresentationQueue);
133 VdpStatus vdp_presentation_queue_set_background_color(const vdp_t *,
134     VdpPresentationQueue, const VdpColor *);
135 VdpStatus vdp_presentation_queue_get_background_color(const vdp_t *,
136     VdpPresentationQueue, VdpColor *);
137 VdpStatus vdp_presentation_queue_get_time(const vdp_t *,
138     VdpPresentationQueue, VdpTime *);
139 VdpStatus vdp_presentation_queue_display(const vdp_t *, VdpPresentationQueue,
140     VdpOutputSurface, uint32_t, uint32_t, VdpTime);
141 VdpStatus vdp_presentation_queue_block_until_surface_idle(const vdp_t *,
142     VdpPresentationQueue, VdpOutputSurface, VdpTime *);
143 VdpStatus vdp_presentation_queue_query_surface_status(const vdp_t *,
144     VdpPresentationQueue, VdpOutputSurface, VdpPresentationQueueStatus *,
145     VdpTime *);
146 VdpStatus vdp_preemption_callback_register(const vdp_t *vdp, VdpDevice,
147                                            VdpPreemptionCallback, void *);
148 
149 VdpStatus vdp_presentation_queue_target_create_x11(const vdp_t *,
150                             VdpDevice, uint32_t, VdpPresentationQueueTarget *);
151 
152 /**
153  * Loads a VDPAU instance and creates a VDPAU device using X11.
154  * @param dpy X11 display handle (Xlib Display pointer) [IN]
155  * @param snum X11 screen number
156  * @param vdpp memory location to hold the VDPAU instance pointer [OUT]
157  * @param devp memory location to hold the VDPAU device handle [OUT]
158  * @note The X11 display connection must remain valid until after the VDPAU
159  * device has been destroyed with vdp_device_destroy().
160  * @return VDP_STATUS_OK on success, otherwise a VDPAU error code.
161  */
162 VdpStatus vdp_create_x11(void *dpy, int snum, vdp_t **vdpp, VdpDevice *devp);
163 
164 
165 /**
166  * Destroys a VDPAU instance created with vdp_create_x11().
167  * @note The corresponding VDPAU device shall have been destroyed with
168  * vdp_device_destroy() first.
169  */
170 void vdp_destroy_x11(vdp_t *);
171 
172 /* Instance reuse */
173 
174 /**
175  * Finds an existing pair of VDPAU instance and VDPAU device matching the
176  * specified X11 display and screen number from within the process-wide list.
177  * If no existing instance corresponds, connect to the X11 server,
178  * create a new pair of instance and device, and set the reference count to 1.
179  * @param name X11 display name
180  * @param snum X11 screen number
181  * @param vdp memory location to hold the VDPAU instance pointer [OUT]
182  * @param dev memory location to hold the VDPAU device handle [OUT]
183  * @return VDP_STATUS_OK on success, otherwise a VDPAU error code.
184  *
185  * @note Use vdp_release_x11() to release the instance. <b>Do not use</b>
186  * vdp_device_destroy() and/or vdp_destroy_x11() with vdp_get_x11().
187  */
188 VdpStatus vdp_get_x11(const char *name, int num, vdp_t **vdp, VdpDevice *dev);
189 
190 /**
191  * Increases the reference count of a VDPAU instance created by vdp_get_x11().
192  * @param vdp VDPAU instance (as returned by vdp_get_x11())
193  * @param device location to store the VDPAU device corresponding to the
194  *               VDPAU instance (or NULL) [OUT]
195  * @return the first pameter, always succeeds.
196  */
197 vdp_t *vdp_hold_x11(vdp_t *vdp, VdpDevice *device);
198 
199 /**
200  * Decreases the reference count of a VDPAU instance created by vdp_get_x11().
201  * If it reaches zero, destroy the corresponding VDPAU device, then the VDPAU
202  * instance and remove the pair from the process-wide list.
203  */
204 void vdp_release_x11(vdp_t *);
205 
206 /* VLC specifics */
207 # include <stdbool.h>
208 # include <vlc_common.h>
209 # include <vlc_fourcc.h>
210 # include <vlc_atomic.h>
211 # include <vlc_picture.h>
212 
213 /** Converts VLC YUV format to VDPAU chroma type and YCbCr format */
214 static inline
vlc_fourcc_to_vdp_ycc(vlc_fourcc_t fourcc,VdpChromaType * restrict type,VdpYCbCrFormat * restrict format)215 bool vlc_fourcc_to_vdp_ycc(vlc_fourcc_t fourcc,
216                  VdpChromaType *restrict type, VdpYCbCrFormat *restrict format)
217 {
218     switch (fourcc)
219     {
220         case VLC_CODEC_I420:
221         case VLC_CODEC_YV12:
222             *type = VDP_CHROMA_TYPE_420;
223             *format = VDP_YCBCR_FORMAT_YV12;
224             break;
225         case VLC_CODEC_NV12:
226             *type = VDP_CHROMA_TYPE_420;
227             *format = VDP_YCBCR_FORMAT_NV12;
228             break;
229         case VLC_CODEC_I422:
230             *type = VDP_CHROMA_TYPE_422;
231             *format = VDP_YCBCR_FORMAT_YV12;
232             break;
233         case VLC_CODEC_NV16:
234             *type = VDP_CHROMA_TYPE_422;
235             *format = VDP_YCBCR_FORMAT_NV12;
236             break;
237         case VLC_CODEC_YUYV:
238             *type = VDP_CHROMA_TYPE_422;
239             *format = VDP_YCBCR_FORMAT_YUYV;
240             break;
241         case VLC_CODEC_UYVY:
242             *type = VDP_CHROMA_TYPE_422;
243             *format = VDP_YCBCR_FORMAT_UYVY;
244             break;
245         case VLC_CODEC_I444:
246             *type = VDP_CHROMA_TYPE_444;
247             *format = VDP_YCBCR_FORMAT_YV12;
248             break;
249         case VLC_CODEC_NV24:
250             *type = VDP_CHROMA_TYPE_444;
251             *format = VDP_YCBCR_FORMAT_NV12;
252             break;
253         default:
254             return false;
255     }
256     return true;
257 }
258 
259 struct picture_sys_t
260 {
261     VdpOutputSurface surface;
262     VdpDevice device;
263     vdp_t *vdp;
264     void *gl_nv_surface;
265 };
266 
267 typedef struct vlc_vdp_video_frame
268 {
269     VdpVideoSurface surface;
270     VdpDevice device;
271     vdp_t *vdp;
272     atomic_uintptr_t refs;
273 } vlc_vdp_video_frame_t;
274 
275 typedef struct vlc_vdp_video_field
276 {
277     picture_context_t context;
278     vlc_vdp_video_frame_t *frame;
279     VdpVideoMixerPictureStructure structure;
280     VdpProcamp procamp;
281     float sharpen;
282 } vlc_vdp_video_field_t;
283 
284 /**
285  * Attaches a VDPAU video surface as context of a VLC picture.
286  */
287 VdpStatus vlc_vdp_video_attach(vdp_t *, VdpVideoSurface, picture_t *);
288 
289 /**
290  * Wraps a VDPAU video surface into a VLC picture context.
291  */
292 vlc_vdp_video_field_t *vlc_vdp_video_create(vdp_t *, VdpVideoSurface);
293 
vlc_vdp_video_destroy(vlc_vdp_video_field_t * f)294 static inline void vlc_vdp_video_destroy(vlc_vdp_video_field_t *f)
295 {
296     return f->context.destroy(&f->context);
297 }
298 
299 /**
300  * Performs a shallow copy of a VDPAU video surface context
301  * (the underlying VDPAU video surface is shared).
302  */
vlc_vdp_video_copy(vlc_vdp_video_field_t * fold)303 static inline vlc_vdp_video_field_t *vlc_vdp_video_copy(
304     vlc_vdp_video_field_t *fold)
305 {
306     return (vlc_vdp_video_field_t *)fold->context.copy(&fold->context);
307 }
308 #endif
309