1 /*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19 #include "config.h"
20
21 #include <stdint.h>
22 #include <string.h>
23
24 #include <vdpau/vdpau.h>
25
34
39
43 #ifdef VDP_YCBCR_FORMAT_P016
46 #endif
48 };
49
56 };
57
59 #ifdef VDP_YCBCR_FORMAT_Y_U_V_444
61 #endif
62 #ifdef VDP_YCBCR_FORMAT_P016
64 #endif
66 };
67
68 static const struct {
76 #ifdef VDP_YCBCR_FORMAT_P016
82 #endif
83 };
84
91
95
101
105
107 {
108 int count = 0;
111 count++;
112 }
113 return count;
114 }
115
117 {
121
124 int nb_pix_fmts;
125
130
131 nb_pix_fmts = 0;
133 VdpBool supported;
136 if (err == VDP_STATUS_OK && supported)
139 }
142 }
143
144 return 0;
145 }
146
147 #define GET_CALLBACK(id, result) \
148 do { \
149 void *tmp; \
150 err = hwctx->get_proc_address(hwctx->device, id, &tmp); \
151 if (err != VDP_STATUS_OK) { \
152 av_log(ctx, AV_LOG_ERROR, "Error getting the " #id " callback.\n"); \
153 return AVERROR_UNKNOWN; \
154 } \
155 result = tmp; \
156 } while (0)
157
159 {
162 VdpStatus err;
164
165 GET_CALLBACK(VDP_FUNC_ID_VIDEO_SURFACE_QUERY_GET_PUT_BITS_Y_CB_CR_CAPABILITIES,
171
176 }
177
178 return 0;
179 }
180
182 {
185
188 }
189
191 const void *hwconfig,
193 {
195 int nb_sw_formats = 0;
197
202
206 }
208
212
215
216 return 0;
217 }
218
220 {
223 VdpVideoSurface surf = (VdpVideoSurface)(uintptr_t)
data;
224
226 }
227
229 {
234
236 VdpVideoSurface surf;
237 VdpStatus err;
238
240 ctx->width,
ctx->height, &surf);
241 if (err != VDP_STATUS_OK) {
244 }
245
251 }
252
254 }
255
257 {
260
262
269 break;
270 }
271 }
276 }
277
281 if (!
ctx->internal->pool_internal)
283 }
284
287
288 return 0;
289 }
290
292 {
296
301
302 return 0;
303 }
304
308 {
310
312
315 "No target formats are supported for this chroma type\n");
317 }
318
320 if (!fmts)
322
325
326 return 0;
327 }
328
331 {
333 VdpVideoSurface surf = (VdpVideoSurface)(uintptr_t)
src->data[3];
334
336 uint32_t linesize[3];
337
339 VdpYCbCrFormat vdpau_format;
340 VdpStatus err;
342
347 "The linesize %d cannot be represented as uint32\n",
350 }
352 }
353
358 break;
359 }
360 }
363 "Unsupported target pixel format: %s\n",
366 }
367
368 if ((vdpau_format == VDP_YCBCR_FORMAT_YV12)
369 #ifdef VDP_YCBCR_FORMAT_Y_U_V_444
370 || (vdpau_format == VDP_YCBCR_FORMAT_Y_U_V_444)
371 #endif
372 #ifdef VDP_YCBCR_FORMAT_P016
373 || (vdpau_format == VDP_YCBCR_FORMAT_Y_U_V_444_16)
374 #endif
375 )
377
378 err = priv->
get_data(surf, vdpau_format,
data, linesize);
379 if (err != VDP_STATUS_OK) {
382 }
383
384 return 0;
385 }
386
389 {
391 VdpVideoSurface surf = (VdpVideoSurface)(uintptr_t)dst->
data[3];
392
394 uint32_t linesize[3];
395
397 VdpYCbCrFormat vdpau_format;
398 VdpStatus err;
400
403 if (
src->linesize[
i] < 0 ||
src->linesize[
i] > UINT32_MAX) {
405 "The linesize %d cannot be represented as uint32\n",
408 }
409 linesize[
i] =
src->linesize[
i];
410 }
411
416 break;
417 }
418 }
421 "Unsupported source pixel format: %s\n",
424 }
425
426 if ((vdpau_format == VDP_YCBCR_FORMAT_YV12)
427 #ifdef VDP_YCBCR_FORMAT_Y_U_V_444
428 || (vdpau_format == VDP_YCBCR_FORMAT_Y_U_V_444)
429 #endif
430 )
432
433 err = priv->
put_data(surf, vdpau_format,
data, linesize);
434 if (err != VDP_STATUS_OK) {
437 }
438
439 return 0;
440 }
441
442 #if HAVE_VDPAU_X11
443 #include <vdpau/vdpau_x11.h>
444 #include <X11/Xlib.h>
445
446 typedef struct VDPAUDevicePriv {
447 VdpDeviceDestroy *device_destroy;
448 Display *dpy;
449 } VDPAUDevicePriv;
450
452 {
454 VDPAUDevicePriv *priv =
ctx->user_opaque;
455
456 if (priv->device_destroy)
457 priv->device_destroy(hwctx->
device);
458 if (priv->dpy)
459 XCloseDisplay(priv->dpy);
461 }
462
465 {
467
468 VDPAUDevicePriv *priv;
469 VdpStatus err;
470 VdpGetInformationString *get_information_string;
471 const char *display, *vendor;
472
474 if (!priv)
476
477 ctx->user_opaque = priv;
478 ctx->free = vdpau_device_free;
479
480 priv->dpy = XOpenDisplay(device);
481 if (!priv->dpy) {
483 XDisplayName(device));
485 }
486 display = XDisplayString(priv->dpy);
487
488 err = vdp_device_create_x11(priv->dpy, XDefaultScreen(priv->dpy),
490 if (err != VDP_STATUS_OK) {
492 display);
494 }
495
496 GET_CALLBACK(VDP_FUNC_ID_GET_INFORMATION_STRING, get_information_string);
497 GET_CALLBACK(VDP_FUNC_ID_DEVICE_DESTROY, priv->device_destroy);
498
499 get_information_string(&vendor);
501 "X11 display %s\n", vendor, display);
502
503 return 0;
504 }
505 #endif
506
509 .name = "VDPAU",
510
514
515 #if HAVE_VDPAU_X11
516 .device_create = vdpau_device_create,
517 #endif
526
528 };