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
86 /**
87 * The public AVVDPAUDeviceContext. See hwcontext_vdpau.h for it.
88 */
90
96
100
106
110
112 {
113 int count = 0;
116 count++;
117 }
118 return count;
119 }
120
122 {
126
129 int nb_pix_fmts;
130
135
136 nb_pix_fmts = 0;
138 VdpBool supported;
141 if (err == VDP_STATUS_OK && supported)
144 }
147 }
148
149 return 0;
150 }
151
152 #define GET_CALLBACK(id, result) \
153 do { \
154 void *tmp; \
155 err = hwctx->get_proc_address(hwctx->device, id, &tmp); \
156 if (err != VDP_STATUS_OK) { \
157 av_log(ctx, AV_LOG_ERROR, "Error getting the " #id " callback.\n"); \
158 return AVERROR_UNKNOWN; \
159 } \
160 result = tmp; \
161 } while (0)
162
164 {
167 VdpStatus err;
169
170 GET_CALLBACK(VDP_FUNC_ID_VIDEO_SURFACE_QUERY_GET_PUT_BITS_Y_CB_CR_CAPABILITIES,
176
181 }
182
183 return 0;
184 }
185
187 {
190
193 }
194
196 const void *hwconfig,
198 {
200 int nb_sw_formats = 0;
202
207
211 }
213
217
220
221 return 0;
222 }
223
225 {
228 VdpVideoSurface surf = (VdpVideoSurface)(uintptr_t)
data;
229
231 }
232
234 {
239
241 VdpVideoSurface surf;
242 VdpStatus err;
243
245 ctx->width,
ctx->height, &surf);
246 if (err != VDP_STATUS_OK) {
249 }
250
256 }
257
259 }
260
262 {
265
267
274 break;
275 }
276 }
281 }
282
289 }
290
293
294 return 0;
295 }
296
298 {
302
307
308 return 0;
309 }
310
314 {
316
318
321 "No target formats are supported for this chroma type\n");
323 }
324
326 if (!fmts)
328
331
332 return 0;
333 }
334
337 {
339 VdpVideoSurface surf = (VdpVideoSurface)(uintptr_t)
src->data[3];
340
342 uint32_t linesize[3];
343
345 VdpYCbCrFormat vdpau_format;
346 VdpStatus err;
348
351 if (
dst->linesize[
i] < 0 ||
dst->linesize[
i] > UINT32_MAX) {
353 "The linesize %d cannot be represented as uint32\n",
356 }
357 linesize[
i] =
dst->linesize[
i];
358 }
359
364 break;
365 }
366 }
369 "Unsupported target pixel format: %s\n",
372 }
373
374 if ((vdpau_format == VDP_YCBCR_FORMAT_YV12)
375 #ifdef VDP_YCBCR_FORMAT_Y_U_V_444
376 || (vdpau_format == VDP_YCBCR_FORMAT_Y_U_V_444)
377 #endif
378 #ifdef VDP_YCBCR_FORMAT_P016
379 || (vdpau_format == VDP_YCBCR_FORMAT_Y_U_V_444_16)
380 #endif
381 )
383
384 err = priv->
get_data(surf, vdpau_format,
data, linesize);
385 if (err != VDP_STATUS_OK) {
388 }
389
390 return 0;
391 }
392
395 {
397 VdpVideoSurface surf = (VdpVideoSurface)(uintptr_t)
dst->data[3];
398
400 uint32_t linesize[3];
401
403 VdpYCbCrFormat vdpau_format;
404 VdpStatus err;
406
409 if (
src->linesize[
i] < 0 ||
src->linesize[
i] > UINT32_MAX) {
411 "The linesize %d cannot be represented as uint32\n",
414 }
415 linesize[
i] =
src->linesize[
i];
416 }
417
422 break;
423 }
424 }
427 "Unsupported source pixel format: %s\n",
430 }
431
432 if ((vdpau_format == VDP_YCBCR_FORMAT_YV12)
433 #ifdef VDP_YCBCR_FORMAT_Y_U_V_444
434 || (vdpau_format == VDP_YCBCR_FORMAT_Y_U_V_444)
435 #endif
436 )
438
439 err = priv->
put_data(surf, vdpau_format,
data, linesize);
440 if (err != VDP_STATUS_OK) {
443 }
444
445 return 0;
446 }
447
448 #if HAVE_VDPAU_X11
449 #include <vdpau/vdpau_x11.h>
450 #include <X11/Xlib.h>
451
452 typedef struct VDPAUDevicePriv {
453 VdpDeviceDestroy *device_destroy;
454 Display *dpy;
455 } VDPAUDevicePriv;
456
458 {
460 VDPAUDevicePriv *priv =
ctx->user_opaque;
461
462 if (priv->device_destroy)
463 priv->device_destroy(hwctx->
device);
464 if (priv->dpy)
465 XCloseDisplay(priv->dpy);
467 }
468
471 {
473
474 VDPAUDevicePriv *priv;
475 VdpStatus err;
476 VdpGetInformationString *get_information_string;
477 const char *display, *vendor;
478
480 if (!priv)
482
483 ctx->user_opaque = priv;
484 ctx->free = vdpau_device_free;
485
486 priv->dpy = XOpenDisplay(device);
487 if (!priv->dpy) {
489 XDisplayName(device));
491 }
492 display = XDisplayString(priv->dpy);
493
494 err = vdp_device_create_x11(priv->dpy, XDefaultScreen(priv->dpy),
496 if (err != VDP_STATUS_OK) {
498 display);
500 }
501
502 GET_CALLBACK(VDP_FUNC_ID_GET_INFORMATION_STRING, get_information_string);
503 GET_CALLBACK(VDP_FUNC_ID_DEVICE_DESTROY, priv->device_destroy);
504
505 get_information_string(&vendor);
507 "X11 display %s\n", vendor, display);
508
509 return 0;
510 }
511 #endif
512
515 .name = "VDPAU",
516
519
520 #if HAVE_VDPAU_X11
521 .device_create = vdpau_device_create,
522 #endif
531
533 };