mirror of
https://github.com/mpv-player/mpv
synced 2024-08-04 14:59:58 +02:00
0780d38329
With the recent changes, mpv's internal mechanisms got synced to libavcodec's once more. Some things are still needed for filters (until the mechanism gets replaced), but there's no need to require other hwdec methods to use these fields. So remove them where they are unnecessary. Also fix some minor leaks in the dxva2 backends, and set the driver_name field in the Apple ones. Untested on Apple crap.
156 lines
4.0 KiB
C
156 lines
4.0 KiB
C
#include <pthread.h>
|
|
#include <assert.h>
|
|
|
|
#include <libavutil/hwcontext.h>
|
|
|
|
#include "config.h"
|
|
|
|
#include "hwdec.h"
|
|
|
|
struct mp_hwdec_devices {
|
|
pthread_mutex_t lock;
|
|
|
|
struct mp_hwdec_ctx **hwctxs;
|
|
int num_hwctxs;
|
|
|
|
void (*load_api)(void *ctx);
|
|
void *load_api_ctx;
|
|
};
|
|
|
|
struct mp_hwdec_devices *hwdec_devices_create(void)
|
|
{
|
|
struct mp_hwdec_devices *devs = talloc_zero(NULL, struct mp_hwdec_devices);
|
|
pthread_mutex_init(&devs->lock, NULL);
|
|
return devs;
|
|
}
|
|
|
|
void hwdec_devices_destroy(struct mp_hwdec_devices *devs)
|
|
{
|
|
if (!devs)
|
|
return;
|
|
assert(!devs->num_hwctxs); // must have been hwdec_devices_remove()ed
|
|
assert(!devs->load_api); // must have been unset
|
|
pthread_mutex_destroy(&devs->lock);
|
|
talloc_free(devs);
|
|
}
|
|
|
|
struct mp_hwdec_ctx *hwdec_devices_get(struct mp_hwdec_devices *devs,
|
|
enum hwdec_type type)
|
|
{
|
|
struct mp_hwdec_ctx *res = NULL;
|
|
pthread_mutex_lock(&devs->lock);
|
|
for (int n = 0; n < devs->num_hwctxs; n++) {
|
|
if (type && devs->hwctxs[n]->type == type) {
|
|
res = devs->hwctxs[n];
|
|
break;
|
|
}
|
|
}
|
|
pthread_mutex_unlock(&devs->lock);
|
|
return res;
|
|
}
|
|
|
|
struct AVBufferRef *hwdec_devices_get_lavc(struct mp_hwdec_devices *devs,
|
|
int av_hwdevice_type)
|
|
{
|
|
AVBufferRef *res = NULL;
|
|
pthread_mutex_lock(&devs->lock);
|
|
for (int n = 0; n < devs->num_hwctxs; n++) {
|
|
struct mp_hwdec_ctx *dev = devs->hwctxs[n];
|
|
if (dev->av_device_ref) {
|
|
AVHWDeviceContext *hwctx = (void *)dev->av_device_ref->data;
|
|
if (hwctx->type == av_hwdevice_type) {
|
|
if (dev->av_device_ref)
|
|
res = av_buffer_ref(dev->av_device_ref);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
pthread_mutex_unlock(&devs->lock);
|
|
return res;
|
|
}
|
|
|
|
struct mp_hwdec_ctx *hwdec_devices_get_first(struct mp_hwdec_devices *devs)
|
|
{
|
|
pthread_mutex_lock(&devs->lock);
|
|
struct mp_hwdec_ctx *res = devs->num_hwctxs ? devs->hwctxs[0] : NULL;
|
|
pthread_mutex_unlock(&devs->lock);
|
|
return res;
|
|
}
|
|
|
|
void hwdec_devices_add(struct mp_hwdec_devices *devs, struct mp_hwdec_ctx *ctx)
|
|
{
|
|
pthread_mutex_lock(&devs->lock);
|
|
MP_TARRAY_APPEND(devs, devs->hwctxs, devs->num_hwctxs, ctx);
|
|
pthread_mutex_unlock(&devs->lock);
|
|
}
|
|
|
|
void hwdec_devices_remove(struct mp_hwdec_devices *devs, struct mp_hwdec_ctx *ctx)
|
|
{
|
|
pthread_mutex_lock(&devs->lock);
|
|
for (int n = 0; n < devs->num_hwctxs; n++) {
|
|
if (devs->hwctxs[n] == ctx) {
|
|
MP_TARRAY_REMOVE_AT(devs->hwctxs, devs->num_hwctxs, n);
|
|
break;
|
|
}
|
|
}
|
|
pthread_mutex_unlock(&devs->lock);
|
|
}
|
|
|
|
void hwdec_devices_set_loader(struct mp_hwdec_devices *devs,
|
|
void (*load_api)(void *ctx), void *load_api_ctx)
|
|
{
|
|
devs->load_api = load_api;
|
|
devs->load_api_ctx = load_api_ctx;
|
|
}
|
|
|
|
void hwdec_devices_request_all(struct mp_hwdec_devices *devs)
|
|
{
|
|
if (devs->load_api && !hwdec_devices_get_first(devs))
|
|
devs->load_api(devs->load_api_ctx);
|
|
}
|
|
|
|
void *hwdec_devices_load(struct mp_hwdec_devices *devs, enum hwdec_type type)
|
|
{
|
|
if (!devs)
|
|
return NULL;
|
|
hwdec_devices_request_all(devs);
|
|
struct mp_hwdec_ctx *hwctx = hwdec_devices_get(devs, type);
|
|
return hwctx ? hwctx->ctx : NULL;
|
|
}
|
|
|
|
char *hwdec_devices_get_names(struct mp_hwdec_devices *devs)
|
|
{
|
|
char *res = NULL;
|
|
for (int n = 0; n < devs->num_hwctxs; n++) {
|
|
if (res)
|
|
ta_xstrdup_append(&res, ",");
|
|
ta_xstrdup_append(&res, devs->hwctxs[n]->driver_name);
|
|
}
|
|
return res;
|
|
}
|
|
|
|
static const struct hwcontext_fns *const hwcontext_fns[] = {
|
|
#if HAVE_D3D_HWACCEL
|
|
&hwcontext_fns_d3d11,
|
|
#endif
|
|
#if HAVE_D3D9_HWACCEL
|
|
&hwcontext_fns_dxva2,
|
|
#endif
|
|
#if HAVE_VAAPI
|
|
&hwcontext_fns_vaapi,
|
|
#endif
|
|
#if HAVE_VDPAU
|
|
&hwcontext_fns_vdpau,
|
|
#endif
|
|
NULL,
|
|
};
|
|
|
|
const struct hwcontext_fns *hwdec_get_hwcontext_fns(int av_hwdevice_type)
|
|
{
|
|
for (int n = 0; hwcontext_fns[n]; n++) {
|
|
if (hwcontext_fns[n]->av_hwdevice_type == av_hwdevice_type)
|
|
return hwcontext_fns[n];
|
|
}
|
|
return NULL;
|
|
}
|