Line | Count | Source (jump to first uncovered line) |
1 | | #include <assert.h> |
2 | | |
3 | | #include <libavutil/hwcontext.h> |
4 | | |
5 | | #include "config.h" |
6 | | #include "hwdec.h" |
7 | | #include "osdep/threads.h" |
8 | | |
9 | | struct mp_hwdec_devices { |
10 | | mp_mutex lock; |
11 | | |
12 | | struct mp_hwdec_ctx **hwctxs; |
13 | | int num_hwctxs; |
14 | | |
15 | | void (*load_api)(void *ctx, |
16 | | struct hwdec_imgfmt_request *params); |
17 | | void *load_api_ctx; |
18 | | }; |
19 | | |
20 | | struct mp_hwdec_devices *hwdec_devices_create(void) |
21 | 0 | { |
22 | 0 | struct mp_hwdec_devices *devs = talloc_zero(NULL, struct mp_hwdec_devices); |
23 | 0 | mp_mutex_init(&devs->lock); |
24 | 0 | return devs; |
25 | 0 | } |
26 | | |
27 | | void hwdec_devices_destroy(struct mp_hwdec_devices *devs) |
28 | 0 | { |
29 | 0 | if (!devs) |
30 | 0 | return; |
31 | 0 | mp_assert(!devs->num_hwctxs); // must have been hwdec_devices_remove()ed |
32 | 0 | mp_assert(!devs->load_api); // must have been unset |
33 | 0 | mp_mutex_destroy(&devs->lock); |
34 | 0 | talloc_free(devs); |
35 | 0 | } |
36 | | |
37 | | struct mp_hwdec_ctx *hwdec_devices_get_by_imgfmt_and_type(struct mp_hwdec_devices *devs, |
38 | | int hw_imgfmt, |
39 | | enum AVHWDeviceType device_type) |
40 | 0 | { |
41 | 0 | struct mp_hwdec_ctx *res = NULL; |
42 | 0 | mp_mutex_lock(&devs->lock); |
43 | 0 | for (int n = 0; n < devs->num_hwctxs; n++) { |
44 | 0 | struct mp_hwdec_ctx *dev = devs->hwctxs[n]; |
45 | 0 | AVHWDeviceContext *hw_device_ctx = |
46 | 0 | dev->av_device_ref ? (AVHWDeviceContext *)dev->av_device_ref->data : NULL; |
47 | 0 | if (dev->hw_imgfmt == hw_imgfmt && |
48 | 0 | (!hw_device_ctx || hw_device_ctx->type == device_type)) { |
49 | 0 | res = dev; |
50 | 0 | break; |
51 | 0 | } |
52 | 0 | } |
53 | 0 | mp_mutex_unlock(&devs->lock); |
54 | 0 | return res; |
55 | 0 | } |
56 | | |
57 | | struct mp_hwdec_ctx *hwdec_devices_get_first(struct mp_hwdec_devices *devs) |
58 | 0 | { |
59 | 0 | return hwdec_devices_get_n(devs, 0); |
60 | 0 | } |
61 | | |
62 | | struct mp_hwdec_ctx *hwdec_devices_get_n(struct mp_hwdec_devices *devs, int n) |
63 | 0 | { |
64 | 0 | mp_mutex_lock(&devs->lock); |
65 | 0 | struct mp_hwdec_ctx *res = n < devs->num_hwctxs ? devs->hwctxs[n] : NULL; |
66 | 0 | mp_mutex_unlock(&devs->lock); |
67 | 0 | return res; |
68 | 0 | } |
69 | | |
70 | | void hwdec_devices_add(struct mp_hwdec_devices *devs, struct mp_hwdec_ctx *ctx) |
71 | 0 | { |
72 | 0 | mp_mutex_lock(&devs->lock); |
73 | 0 | MP_TARRAY_APPEND(devs, devs->hwctxs, devs->num_hwctxs, ctx); |
74 | 0 | mp_mutex_unlock(&devs->lock); |
75 | 0 | } |
76 | | |
77 | | void hwdec_devices_remove(struct mp_hwdec_devices *devs, struct mp_hwdec_ctx *ctx) |
78 | 0 | { |
79 | 0 | mp_mutex_lock(&devs->lock); |
80 | 0 | for (int n = 0; n < devs->num_hwctxs; n++) { |
81 | 0 | if (devs->hwctxs[n] == ctx) { |
82 | 0 | MP_TARRAY_REMOVE_AT(devs->hwctxs, devs->num_hwctxs, n); |
83 | 0 | break; |
84 | 0 | } |
85 | 0 | } |
86 | 0 | mp_mutex_unlock(&devs->lock); |
87 | 0 | } |
88 | | |
89 | | void hwdec_devices_set_loader(struct mp_hwdec_devices *devs, |
90 | | void (*load_api)(void *ctx, struct hwdec_imgfmt_request *params), |
91 | | void *load_api_ctx) |
92 | 0 | { |
93 | 0 | devs->load_api = load_api; |
94 | 0 | devs->load_api_ctx = load_api_ctx; |
95 | 0 | } |
96 | | |
97 | | void hwdec_devices_request_for_img_fmt(struct mp_hwdec_devices *devs, |
98 | | struct hwdec_imgfmt_request *params) |
99 | 0 | { |
100 | 0 | if (devs->load_api) |
101 | 0 | devs->load_api(devs->load_api_ctx, params); |
102 | 0 | } |
103 | | |
104 | | char *hwdec_devices_get_names(struct mp_hwdec_devices *devs) |
105 | 0 | { |
106 | 0 | char *res = NULL; |
107 | 0 | for (int n = 0; n < devs->num_hwctxs; n++) { |
108 | 0 | if (res) |
109 | 0 | ta_xstrdup_append(&res, ","); |
110 | 0 | ta_xstrdup_append(&res, devs->hwctxs[n]->driver_name); |
111 | 0 | } |
112 | 0 | return res; |
113 | 0 | } |
114 | | |
115 | | static const struct hwcontext_fns *const hwcontext_fns[] = { |
116 | | #if HAVE_CUDA_HWACCEL |
117 | | &hwcontext_fns_cuda, |
118 | | #endif |
119 | | #if HAVE_D3D_HWACCEL |
120 | | &hwcontext_fns_d3d11, |
121 | | #endif |
122 | | #if HAVE_D3D9_HWACCEL |
123 | | &hwcontext_fns_dxva2, |
124 | | #endif |
125 | | #if HAVE_DRM |
126 | | &hwcontext_fns_drmprime, |
127 | | #endif |
128 | | #if HAVE_VAAPI |
129 | | &hwcontext_fns_vaapi, |
130 | | #endif |
131 | | #if HAVE_VDPAU |
132 | | &hwcontext_fns_vdpau, |
133 | | #endif |
134 | | NULL, |
135 | | }; |
136 | | |
137 | | const struct hwcontext_fns *hwdec_get_hwcontext_fns(int av_hwdevice_type) |
138 | 0 | { |
139 | 0 | for (int n = 0; hwcontext_fns[n]; n++) { |
140 | 0 | if (hwcontext_fns[n]->av_hwdevice_type == av_hwdevice_type) |
141 | 0 | return hwcontext_fns[n]; |
142 | 0 | } |
143 | 0 | return NULL; |
144 | 0 | } |