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 <stdint.h>
20
21 #include <vdpau/vdpau.h>
22 #include <vdpau/vdpau_x11.h>
23
24 #include <X11/Xlib.h>
25
27
29
34
37
41
53
55
59
61 {
64
68
71
74
76 XCloseDisplay(ctx->
dpy);
77
79
82 }
83
85 {
86 VdpVideoSurface surface = *(VdpVideoSurface*)data;
88
91 }
92
94 {
97 VdpVideoSurface *surface;
98 VdpStatus err;
99
101
103 if (!surface)
105
109 if (!frame->
buf[0]) {
112 }
113
114 // properly we should keep a pool of surfaces instead of creating
115 // them anew for each frame, but since we don't care about speed
116 // much in this code, we don't bother
119 if (err != VDP_STATUS_OK) {
124 }
125
127
128 return 0;
129 }
130
132 {
133 VdpVideoSurface surface = (VdpVideoSurface)(uintptr_t)frame->
data[3];
136 VdpStatus err;
137 int ret, chroma_type;
138
142 if (err != VDP_STATUS_OK) {
146 }
148
150 if (ret < 0)
152
155
159 if (err != VDP_STATUS_OK) {
163 goto fail;
164 }
165
168
170 if (ret < 0)
171 goto fail;
172
175 return 0;
176
177 fail:
180 }
181
187 };
188
190 {
195 const char *display, *vendor;
196 VdpStatus err;
197 int i;
198
200 if (!ctx)
202
207
210 goto fail;
211
214 av_log(NULL, loglevel,
"Cannot open the X11 display %s.\n",
216 goto fail;
217 }
218 display = XDisplayString(ctx->
dpy);
219
220 err = vdp_device_create_x11(ctx->
dpy, XDefaultScreen(ctx->
dpy), &ctx->
device,
222 if (err != VDP_STATUS_OK) {
223 av_log(NULL, loglevel,
"VDPAU device creation on X11 display %s failed.\n",
224 display);
225 goto fail;
226 }
227
228 #define GET_CALLBACK(id, result) \
229 do { \
230 void *tmp; \
231 err = ctx->get_proc_address(ctx->device, id, &tmp); \
232 if (err != VDP_STATUS_OK) { \
233 av_log(NULL, loglevel, "Error getting the " #id " callback.\n"); \
234 goto fail; \
235 } \
236 ctx->result = tmp; \
237 } while (0)
238
239 GET_CALLBACK(VDP_FUNC_ID_GET_ERROR_STRING, get_error_string);
240 GET_CALLBACK(VDP_FUNC_ID_GET_INFORMATION_STRING, get_information_string);
241 GET_CALLBACK(VDP_FUNC_ID_DEVICE_DESTROY, device_destroy);
242 GET_CALLBACK(VDP_FUNC_ID_DECODER_CREATE, decoder_create);
243 GET_CALLBACK(VDP_FUNC_ID_DECODER_DESTROY, decoder_destroy);
244 GET_CALLBACK(VDP_FUNC_ID_DECODER_RENDER, decoder_render);
245 GET_CALLBACK(VDP_FUNC_ID_VIDEO_SURFACE_CREATE, video_surface_create);
246 GET_CALLBACK(VDP_FUNC_ID_VIDEO_SURFACE_DESTROY, video_surface_destroy);
247 GET_CALLBACK(VDP_FUNC_ID_VIDEO_SURFACE_GET_BITS_Y_CB_CR, video_surface_get_bits);
248 GET_CALLBACK(VDP_FUNC_ID_VIDEO_SURFACE_GET_PARAMETERS, video_surface_get_parameters);
249 GET_CALLBACK(VDP_FUNC_ID_VIDEO_SURFACE_QUERY_GET_PUT_BITS_Y_CB_CR_CAPABILITIES,
250 video_surface_query);
251
253 VdpBool supported;
256 if (err != VDP_STATUS_OK) {
258 "Error querying VDPAU surface capabilities: %s\n",
260 goto fail;
261 }
262 if (supported)
263 break;
264 }
267 "No supported VDPAU format for retrieving the data.\n");
269 }
272
274 if (!vdpau_ctx)
275 goto fail;
277
279
282 "to decode input stream #%d:%d.\n", vendor,
284
285 return 0;
286
287 fail:
288 av_log(NULL, loglevel,
"VDPAU init failed for stream #%d:%d.\n",
292 }
293
295 {
300 VdpStatus err;
302
305 if (ret < 0)
307 }
310
312 if (ret < 0) {
313 av_log(NULL, loglevel,
"No known VDPAU decoder profile for this stream.\n");
315 }
316
319
323 if (err != VDP_STATUS_OK) {
324 av_log(NULL, loglevel,
"Error creating the VDPAU decoder: %s\n",
327 }
328
330
333
334 return 0;
335 }