summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--video/decode/d3d.c18
-rw-r--r--video/decode/d3d.h6
-rw-r--r--video/decode/d3d11va.c21
-rw-r--r--video/decode/dxva2.c38
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;