diff options
Diffstat (limited to 'video/decode')
-rw-r--r-- | video/decode/d3d.c | 18 | ||||
-rw-r--r-- | video/decode/d3d.h | 6 | ||||
-rw-r--r-- | video/decode/d3d11va.c | 21 | ||||
-rw-r--r-- | video/decode/dxva2.c | 38 |
4 files changed, 34 insertions, 49 deletions
diff --git a/video/decode/d3d.c b/video/decode/d3d.c index df10c9fe19..b978472723 100644 --- a/video/decode/d3d.c +++ b/video/decode/d3d.c @@ -15,6 +15,8 @@ * License along with mpv. If not, see <http://www.gnu.org/licenses/>. */ +#include <pthread.h> + #include <libavcodec/avcodec.h> #include "lavc.h" @@ -96,6 +98,22 @@ static const struct d3dva_mode d3dva_modes[] = { #undef MODE #undef MODE2 +HMODULE d3d11_dll, d3d9_dll, dxva2_dll; + +static pthread_once_t d3d_load_once = PTHREAD_ONCE_INIT; + +static void d3d_do_load(void) +{ + d3d11_dll = LoadLibrary(L"d3d11.dll"); + d3d9_dll = LoadLibrary(L"d3d9.dll"); + dxva2_dll = LoadLibrary(L"dxva2.dll"); +} + +void d3d_load_dlls(void) +{ + pthread_once(&d3d_load_once, d3d_do_load); +} + int d3d_probe_codec(const char *codec) { enum AVCodecID codecid = mp_codec_to_av_codec_id(codec); diff --git a/video/decode/d3d.h b/video/decode/d3d.h index 3f5b8aebe7..15c423ab8c 100644 --- a/video/decode/d3d.h +++ b/video/decode/d3d.h @@ -36,6 +36,12 @@ struct d3d_decoder_fmt { const struct d3d_decoded_format *format; }; +// Must call d3d_load_dlls() before accessing. Once this is done, the DLLs +// remain loaded forever. +extern HMODULE d3d11_dll, d3d9_dll, dxva2_dll; + +void d3d_load_dlls(void); + int d3d_probe_codec(const char *codec); struct d3d_decoder_fmt d3d_select_decoder_mode( diff --git a/video/decode/d3d11va.c b/video/decode/d3d11va.c index d631fff479..dd4535bdd7 100644 --- a/video/decode/d3d11va.c +++ b/video/decode/d3d11va.c @@ -40,7 +40,6 @@ struct d3d11va_decoder { struct priv { struct mp_log *log; - HMODULE d3d11_dll; ID3D11Device *device; ID3D11DeviceContext *device_ctx; ID3D11VideoDevice *video_dev; @@ -51,7 +50,6 @@ struct priv { }; struct d3d11va_surface { - HMODULE d3d11_dll; ID3D11Texture2D *texture; int subindex; ID3D11VideoDecoderOutputView *surface; @@ -66,9 +64,6 @@ static void d3d11va_release_img(void *arg) if (surface->texture) ID3D11Texture2D_Release(surface->texture); - if (surface->d3d11_dll) - FreeLibrary(surface->d3d11_dll); - talloc_free(surface); } @@ -79,10 +74,6 @@ static struct mp_image *d3d11va_new_ref(ID3D11VideoDecoderOutputView *view, return NULL; struct d3d11va_surface *surface = talloc_zero(NULL, struct d3d11va_surface); - surface->d3d11_dll = LoadLibrary(L"d3d11.dll"); - if (!surface->d3d11_dll) - goto fail; - surface->surface = view; ID3D11VideoDecoderOutputView_AddRef(surface->surface); ID3D11VideoDecoderOutputView_GetResource( @@ -105,9 +96,6 @@ static struct mp_image *d3d11va_new_ref(ID3D11VideoDecoderOutputView *view, mpi->planes[3] = (void *)surface->surface; return mpi; -fail: - d3d11va_release_img(surface); - return NULL; } static struct mp_image *d3d11va_allocate_image(struct lavc_ctx *s, int w, int h) @@ -434,9 +422,6 @@ static void destroy_device(struct lavc_ctx *s) if (p->device_ctx) ID3D11DeviceContext_Release(p->device_ctx); - - if (p->d3d11_dll) - FreeLibrary(p->d3d11_dll); } static bool create_device(struct lavc_ctx *s, BOOL thread_safe) @@ -444,14 +429,14 @@ static bool create_device(struct lavc_ctx *s, BOOL thread_safe) HRESULT hr; struct priv *p = s->hwdec_priv; - p->d3d11_dll = LoadLibrary(L"d3d11.dll"); - if (!p->d3d11_dll) { + d3d_load_dlls(); + if (!d3d11_dll) { MP_ERR(p, "Failed to load D3D11 library\n"); return false; } PFN_D3D11_CREATE_DEVICE CreateDevice = - (void *)GetProcAddress(p->d3d11_dll, "D3D11CreateDevice"); + (void *)GetProcAddress(d3d11_dll, "D3D11CreateDevice"); if (!CreateDevice) { MP_ERR(p, "Failed to get D3D11CreateDevice symbol from DLL: %s\n", mp_LastError_to_str()); diff --git a/video/decode/dxva2.c b/video/decode/dxva2.c index 829d77ccbf..489f580fc0 100644 --- a/video/decode/dxva2.c +++ b/video/decode/dxva2.c @@ -39,8 +39,6 @@ struct priv { struct mp_log *log; - HMODULE d3d9_dll; - HMODULE dxva2_dll; IDirect3D9 *d3d9; IDirect3DDevice9 *device; HANDLE device_handle; @@ -53,9 +51,6 @@ struct priv { }; struct dxva2_surface { - HMODULE d3dlib; - HMODULE dxva2lib; - IDirectXVideoDecoder *decoder; IDirect3DSurface9 *surface; }; @@ -69,12 +64,6 @@ static void dxva2_release_img(void *arg) if (surface->decoder) IDirectXVideoDecoder_Release(surface->decoder); - if (surface->dxva2lib) - FreeLibrary(surface->dxva2lib); - - if (surface->d3dlib) - FreeLibrary(surface->d3dlib); - talloc_free(surface); } @@ -86,13 +75,6 @@ static struct mp_image *dxva2_new_ref(IDirectXVideoDecoder *decoder, return NULL; struct dxva2_surface *surface = talloc_zero(NULL, struct dxva2_surface); - // Add additional references to the libraries which might otherwise be freed - // before the surface, which is observed to lead to bad behaviour - surface->d3dlib = LoadLibrary(L"d3d9.dll"); - surface->dxva2lib = LoadLibrary(L"dxva2.dll"); - if (!surface->d3dlib || !surface->dxva2lib) - goto fail; - surface->surface = d3d9_surface; IDirect3DSurface9_AddRef(surface->surface); surface->decoder = decoder; @@ -368,25 +350,20 @@ static void destroy_device(struct lavc_ctx *s) if (p->d3d9) IDirect3D9_Release(p->d3d9); - - if (p->d3d9_dll) - FreeLibrary(p->d3d9_dll); - - if (p->dxva2_dll) - FreeLibrary(p->dxva2_dll); } static bool create_device(struct lavc_ctx *s) { struct priv *p = s->hwdec_priv; - p->d3d9_dll = LoadLibrary(L"d3d9.dll"); - if (!p->d3d9_dll) { + + d3d_load_dlls(); + if (!d3d9_dll) { MP_ERR(p, "Failed to load D3D9 library\n"); return false; } IDirect3D9* (WINAPI *Direct3DCreate9)(UINT) = - (void *)GetProcAddress(p->d3d9_dll, "Direct3DCreate9"); + (void *)GetProcAddress(d3d9_dll, "Direct3DCreate9"); if (!Direct3DCreate9) { MP_ERR(p, "Failed to locate Direct3DCreate9\n"); return false; @@ -477,15 +454,14 @@ static int dxva2_init(struct lavc_ctx *s) goto fail; } - p->dxva2_dll = LoadLibrary(L"dxva2.dll"); - if (!p->dxva2_dll) { + d3d_load_dlls(); + if (!dxva2_dll) { MP_ERR(p, "Failed to load DXVA2 library\n"); goto fail; } HRESULT (WINAPI *CreateDeviceManager9)(UINT *, IDirect3DDeviceManager9 **) = - (void *)GetProcAddress(p->dxva2_dll, - "DXVA2CreateDirect3DDeviceManager9"); + (void *)GetProcAddress(dxva2_dll, "DXVA2CreateDirect3DDeviceManager9"); if (!CreateDeviceManager9) { MP_ERR(p, "Failed to locate DXVA2CreateDirect3DDeviceManager9\n"); goto fail; |