Commit 4db3b62d authored by Rémi Denis-Courmont's avatar Rémi Denis-Courmont

DxVA2: remove vlc_object_t back pointer

parent f1457ea3
......@@ -240,7 +240,6 @@ typedef struct {
#define VA_DXVA2_MAX_SURFACE_COUNT (64)
struct vlc_va_sys_t
{
vlc_object_t *log;
int codec_id;
int width;
int height;
......@@ -288,48 +287,39 @@ struct vlc_va_sys_t
vlc_va_surface_t surface[VA_DXVA2_MAX_SURFACE_COUNT];
LPDIRECT3DSURFACE9 hw_surface[VA_DXVA2_MAX_SURFACE_COUNT];
};
typedef struct vlc_va_sys_t vlc_va_dxva2_t;
/* */
static vlc_va_dxva2_t *vlc_va_dxva2_Get(vlc_va_t *external)
{
vlc_va_dxva2_t *va = external->sys;
assert(VLC_OBJECT(external) == va->log);
return va;
}
static int D3dCreateDevice(vlc_va_t *);
static void D3dDestroyDevice(vlc_va_sys_t *);
static char *DxDescribe(vlc_va_sys_t *);
/* */
static int D3dCreateDevice(vlc_va_dxva2_t *);
static void D3dDestroyDevice(vlc_va_dxva2_t *);
static char *DxDescribe(vlc_va_dxva2_t *);
static int D3dCreateDeviceManager(vlc_va_t *);
static void D3dDestroyDeviceManager(vlc_va_sys_t *);
static int D3dCreateDeviceManager(vlc_va_dxva2_t *);
static void D3dDestroyDeviceManager(vlc_va_dxva2_t *);
static int DxCreateVideoService(vlc_va_t *);
static void DxDestroyVideoService(vlc_va_sys_t *);
static int DxFindVideoServiceConversion(vlc_va_t *, GUID *input, D3DFORMAT *output);
static int DxCreateVideoService(vlc_va_dxva2_t *);
static void DxDestroyVideoService(vlc_va_dxva2_t *);
static int DxFindVideoServiceConversion(vlc_va_dxva2_t *, GUID *input, D3DFORMAT *output);
static int DxCreateVideoDecoder(vlc_va_dxva2_t *,
static int DxCreateVideoDecoder(vlc_va_t *,
int codec_id, const video_format_t *);
static void DxDestroyVideoDecoder(vlc_va_dxva2_t *);
static int DxResetVideoDecoder(vlc_va_dxva2_t *);
static void DxDestroyVideoDecoder(vlc_va_sys_t *);
static int DxResetVideoDecoder(vlc_va_t *);
static void DxCreateVideoConversion(vlc_va_dxva2_t *);
static void DxDestroyVideoConversion(vlc_va_dxva2_t *);
static void DxCreateVideoConversion(vlc_va_sys_t *);
static void DxDestroyVideoConversion(vlc_va_sys_t *);
/* */
static int Setup(vlc_va_t *external, void **hw, vlc_fourcc_t *chroma,
static int Setup(vlc_va_t *va, void **hw, vlc_fourcc_t *chroma,
int width, int height)
{
vlc_va_dxva2_t *va = vlc_va_dxva2_Get(external);
vlc_va_sys_t *sys = va->sys;
if (va->width == width && va->height == height && va->decoder)
if (sys->width == width && sys->height == height && sys->decoder)
goto ok;
/* */
DxDestroyVideoConversion(va);
DxDestroyVideoDecoder(va);
DxDestroyVideoConversion(sys);
DxDestroyVideoDecoder(sys);
*hw = NULL;
*chroma = 0;
......@@ -342,48 +332,48 @@ static int Setup(vlc_va_t *external, void **hw, vlc_fourcc_t *chroma,
fmt.i_width = width;
fmt.i_height = height;
if (DxCreateVideoDecoder(va, va->codec_id, &fmt))
if (DxCreateVideoDecoder(va, sys->codec_id, &fmt))
return VLC_EGENERIC;
/* */
va->hw.decoder = va->decoder;
va->hw.cfg = &va->cfg;
va->hw.surface_count = va->surface_count;
va->hw.surface = va->hw_surface;
sys->hw.decoder = sys->decoder;
sys->hw.cfg = &sys->cfg;
sys->hw.surface_count = sys->surface_count;
sys->hw.surface = sys->hw_surface;
/* */
DxCreateVideoConversion(va);
DxCreateVideoConversion(sys);
/* */
ok:
*hw = &va->hw;
const d3d_format_t *output = D3dFindFormat(va->output);
*hw = &sys->hw;
const d3d_format_t *output = D3dFindFormat(sys->output);
*chroma = output->codec;
return VLC_SUCCESS;
}
static int Extract(vlc_va_t *external, picture_t *picture, void *opaque,
static int Extract(vlc_va_t *va, picture_t *picture, void *opaque,
uint8_t *data)
{
vlc_va_dxva2_t *va = vlc_va_dxva2_Get(external);
vlc_va_sys_t *sys = va->sys;
LPDIRECT3DSURFACE9 d3d = (LPDIRECT3DSURFACE9)(uintptr_t)data;
if (!va->surface_cache.buffer)
if (!sys->surface_cache.buffer)
return VLC_EGENERIC;
/* */
assert(va->output == MAKEFOURCC('Y','V','1','2'));
assert(sys->output == MAKEFOURCC('Y','V','1','2'));
/* */
D3DLOCKED_RECT lock;
if (FAILED(IDirect3DSurface9_LockRect(d3d, &lock, NULL, D3DLOCK_READONLY))) {
msg_Err(va->log, "Failed to lock surface");
msg_Err(va, "Failed to lock surface");
return VLC_EGENERIC;
}
if (va->render == MAKEFOURCC('Y','V','1','2') ||
va->render == MAKEFOURCC('I','M','C','3')) {
bool imc3 = va->render == MAKEFOURCC('I','M','C','3');
if (sys->render == MAKEFOURCC('Y','V','1','2') ||
sys->render == MAKEFOURCC('I','M','C','3')) {
bool imc3 = sys->render == MAKEFOURCC('I','M','C','3');
size_t chroma_pitch = imc3 ? lock.Pitch : (lock.Pitch / 2);
size_t pitch[3] = {
......@@ -394,9 +384,9 @@ static int Extract(vlc_va_t *external, picture_t *picture, void *opaque,
uint8_t *plane[3] = {
(uint8_t*)lock.pBits,
(uint8_t*)lock.pBits + pitch[0] * va->surface_height,
(uint8_t*)lock.pBits + pitch[0] * va->surface_height
+ pitch[1] * va->surface_height / 2,
(uint8_t*)lock.pBits + pitch[0] * sys->surface_height,
(uint8_t*)lock.pBits + pitch[0] * sys->surface_height
+ pitch[1] * sys->surface_height / 2,
};
if (imc3) {
......@@ -404,22 +394,20 @@ static int Extract(vlc_va_t *external, picture_t *picture, void *opaque,
plane[1] = plane[2];
plane[2] = V;
}
CopyFromYv12(picture, plane, pitch,
va->width, va->height,
&va->surface_cache);
CopyFromYv12(picture, plane, pitch, sys->width, sys->height,
&sys->surface_cache);
} else {
assert(va->render == MAKEFOURCC('N','V','1','2'));
assert(sys->render == MAKEFOURCC('N','V','1','2'));
uint8_t *plane[2] = {
lock.pBits,
(uint8_t*)lock.pBits + lock.Pitch * va->surface_height
(uint8_t*)lock.pBits + lock.Pitch * sys->surface_height
};
size_t pitch[2] = {
lock.Pitch,
lock.Pitch,
};
CopyFromNv12(picture, plane, pitch,
va->width, va->height,
&va->surface_cache);
CopyFromNv12(picture, plane, pitch, sys->width, sys->height,
&sys->surface_cache);
}
/* */
......@@ -429,39 +417,39 @@ static int Extract(vlc_va_t *external, picture_t *picture, void *opaque,
}
/* FIXME it is nearly common with VAAPI */
static int Get(vlc_va_t *external, void **opaque, uint8_t **data)
static int Get(vlc_va_t *va, void **opaque, uint8_t **data)
{
vlc_va_dxva2_t *va = vlc_va_dxva2_Get(external);
vlc_va_sys_t *sys = va->sys;
/* Check the device */
HRESULT hr = IDirect3DDeviceManager9_TestDevice(va->devmng, va->device);
HRESULT hr = IDirect3DDeviceManager9_TestDevice(sys->devmng, sys->device);
if (hr == DXVA2_E_NEW_VIDEO_DEVICE) {
if (DxResetVideoDecoder(va))
return VLC_EGENERIC;
} else if (FAILED(hr)) {
msg_Err(va->log, "IDirect3DDeviceManager9_TestDevice %u", (unsigned)hr);
msg_Err(va, "IDirect3DDeviceManager9_TestDevice %u", (unsigned)hr);
return VLC_EGENERIC;
}
/* Grab an unused surface, in case none are, try the oldest
* XXX using the oldest is a workaround in case a problem happens with libavcodec */
unsigned i, old;
for (i = 0, old = 0; i < va->surface_count; i++) {
vlc_va_surface_t *surface = &va->surface[i];
for (i = 0, old = 0; i < sys->surface_count; i++) {
vlc_va_surface_t *surface = &sys->surface[i];
if (!surface->refcount)
break;
if (surface->order < va->surface[old].order)
if (surface->order < sys->surface[old].order)
old = i;
}
if (i >= va->surface_count)
if (i >= sys->surface_count)
i = old;
vlc_va_surface_t *surface = &va->surface[i];
vlc_va_surface_t *surface = &sys->surface[i];
surface->refcount = 1;
surface->order = va->surface_order++;
surface->order = sys->surface_order++;
*data = (void *)surface->d3d;
*opaque = surface;
return VLC_SUCCESS;
......@@ -475,87 +463,84 @@ static void Release(void *opaque, uint8_t *data)
(void) data;
}
static void Close(vlc_va_t *external)
static void Close(vlc_va_t *va)
{
vlc_va_dxva2_t *va = vlc_va_dxva2_Get(external);
vlc_va_sys_t *sys = va->sys;
DxDestroyVideoConversion(va);
DxDestroyVideoDecoder(va);
DxDestroyVideoService(va);
D3dDestroyDeviceManager(va);
D3dDestroyDevice(va);
DxDestroyVideoConversion(sys);
DxDestroyVideoDecoder(sys);
DxDestroyVideoService(sys);
D3dDestroyDeviceManager(sys);
D3dDestroyDevice(sys);
if (va->hdxva2_dll)
FreeLibrary(va->hdxva2_dll);
if (va->hd3d9_dll)
FreeLibrary(va->hd3d9_dll);
if (sys->hdxva2_dll)
FreeLibrary(sys->hdxva2_dll);
if (sys->hd3d9_dll)
FreeLibrary(sys->hd3d9_dll);
free(external->description);
free(va);
free(va->description);
free(sys);
}
static int Open(vlc_va_t *external, AVCodecContext *ctx,
const es_format_t *fmt)
static int Open(vlc_va_t *va, AVCodecContext *ctx, const es_format_t *fmt)
{
vlc_va_dxva2_t *va = calloc(1, sizeof(*va));
if (!va)
return VLC_EGENERIC;
vlc_va_sys_t *sys = calloc(1, sizeof (*sys));
if (unlikely(sys == NULL))
return VLC_ENOMEM;
external->sys = va;
/* */
va->log = VLC_OBJECT(external);
va->codec_id = ctx->codec_id;
va->sys = sys;
sys->codec_id = ctx->codec_id;
(void) fmt;
/* Load dll*/
va->hd3d9_dll = LoadLibrary(TEXT("D3D9.DLL"));
if (!va->hd3d9_dll) {
msg_Warn(va->log, "cannot load d3d9.dll");
sys->hd3d9_dll = LoadLibrary(TEXT("D3D9.DLL"));
if (!sys->hd3d9_dll) {
msg_Warn(va, "cannot load d3d9.dll");
goto error;
}
va->hdxva2_dll = LoadLibrary(TEXT("DXVA2.DLL"));
if (!va->hdxva2_dll) {
msg_Warn(va->log, "cannot load dxva2.dll");
sys->hdxva2_dll = LoadLibrary(TEXT("DXVA2.DLL"));
if (!sys->hdxva2_dll) {
msg_Warn(va, "cannot load dxva2.dll");
goto error;
}
msg_Dbg(va->log, "DLLs loaded");
msg_Dbg(va, "DLLs loaded");
/* */
if (D3dCreateDevice(va)) {
msg_Err(va->log, "Failed to create Direct3D device");
msg_Err(va, "Failed to create Direct3D device");
goto error;
}
msg_Dbg(va->log, "D3dCreateDevice succeed");
msg_Dbg(va, "D3dCreateDevice succeed");
if (D3dCreateDeviceManager(va)) {
msg_Err(va->log, "D3dCreateDeviceManager failed");
msg_Err(va, "D3dCreateDeviceManager failed");
goto error;
}
if (DxCreateVideoService(va)) {
msg_Err(va->log, "DxCreateVideoService failed");
msg_Err(va, "DxCreateVideoService failed");
goto error;
}
/* */
if (DxFindVideoServiceConversion(va, &va->input, &va->render)) {
msg_Err(va->log, "DxFindVideoServiceConversion failed");
if (DxFindVideoServiceConversion(va, &sys->input, &sys->render)) {
msg_Err(va, "DxFindVideoServiceConversion failed");
goto error;
}
va->thread_count = ctx->thread_count;
sys->thread_count = ctx->thread_count;
/* TODO print the hardware name/vendor for debugging purposes */
external->description = DxDescribe(va);
external->pix_fmt = PIX_FMT_DXVA2_VLD;
external->setup = Setup;
external->get = Get;
external->release = Release;
external->extract = Extract;
va->description = DxDescribe(sys);
va->pix_fmt = PIX_FMT_DXVA2_VLD;
va->setup = Setup;
va->get = Get;
va->release = Release;
va->extract = Extract;
return VLC_SUCCESS;
error:
Close(external);
Close(va);
return VLC_EGENERIC;
}
/* */
......@@ -563,14 +548,15 @@ error:
/**
* It creates a Direct3D device usable for DXVA 2
*/
static int D3dCreateDevice(vlc_va_dxva2_t *va)
static int D3dCreateDevice(vlc_va_t *va)
{
vlc_va_sys_t *sys = va->sys;
/* */
LPDIRECT3D9 (WINAPI *Create9)(UINT SDKVersion);
Create9 = (void *)GetProcAddress(va->hd3d9_dll,
"Direct3DCreate9");
Create9 = (void *)GetProcAddress(sys->hd3d9_dll, "Direct3DCreate9");
if (!Create9) {
msg_Err(va->log, "Cannot locate reference to Direct3DCreate9 ABI in DLL");
msg_Err(va, "Cannot locate reference to Direct3DCreate9 ABI in DLL");
return VLC_EGENERIC;
}
......@@ -578,21 +564,21 @@ static int D3dCreateDevice(vlc_va_dxva2_t *va)
LPDIRECT3D9 d3dobj;
d3dobj = Create9(D3D_SDK_VERSION);
if (!d3dobj) {
msg_Err(va->log, "Direct3DCreate9 failed");
msg_Err(va, "Direct3DCreate9 failed");
return VLC_EGENERIC;
}
va->d3dobj = d3dobj;
sys->d3dobj = d3dobj;
/* */
D3DADAPTER_IDENTIFIER9 *d3dai = &va->d3dai;
if (FAILED(IDirect3D9_GetAdapterIdentifier(va->d3dobj,
D3DADAPTER_IDENTIFIER9 *d3dai = &sys->d3dai;
if (FAILED(IDirect3D9_GetAdapterIdentifier(sys->d3dobj,
D3DADAPTER_DEFAULT, 0, d3dai))) {
msg_Warn(va->log, "IDirect3D9_GetAdapterIdentifier failed");
msg_Warn(va, "IDirect3D9_GetAdapterIdentifier failed");
ZeroMemory(d3dai, sizeof(*d3dai));
}
/* */
D3DPRESENT_PARAMETERS *d3dpp = &va->d3dpp;
D3DPRESENT_PARAMETERS *d3dpp = &sys->d3dpp;
ZeroMemory(d3dpp, sizeof(*d3dpp));
d3dpp->Flags = D3DPRESENTFLAG_VIDEO;
d3dpp->Windowed = TRUE;
......@@ -615,17 +601,18 @@ static int D3dCreateDevice(vlc_va_dxva2_t *va)
D3DCREATE_SOFTWARE_VERTEXPROCESSING |
D3DCREATE_MULTITHREADED,
d3dpp, &d3ddev))) {
msg_Err(va->log, "IDirect3D9_CreateDevice failed");
msg_Err(va, "IDirect3D9_CreateDevice failed");
return VLC_EGENERIC;
}
va->d3ddev = d3ddev;
sys->d3ddev = d3ddev;
return VLC_SUCCESS;
}
/**
* It releases a Direct3D device and its resources.
*/
static void D3dDestroyDevice(vlc_va_dxva2_t *va)
static void D3dDestroyDevice(vlc_va_sys_t *va)
{
if (va->d3ddev)
IDirect3DDevice9_Release(va->d3ddev);
......@@ -635,7 +622,7 @@ static void D3dDestroyDevice(vlc_va_dxva2_t *va)
/**
* It describes our Direct3D object
*/
static char *DxDescribe(vlc_va_dxva2_t *va)
static char *DxDescribe(vlc_va_sys_t *va)
{
static const struct {
unsigned id;
......@@ -669,33 +656,35 @@ static char *DxDescribe(vlc_va_dxva2_t *va)
/**
* It creates a Direct3D device manager
*/
static int D3dCreateDeviceManager(vlc_va_dxva2_t *va)
static int D3dCreateDeviceManager(vlc_va_t *va)
{
vlc_va_sys_t *sys = va->sys;
HRESULT (WINAPI *CreateDeviceManager9)(UINT *pResetToken,
IDirect3DDeviceManager9 **);
CreateDeviceManager9 =
(void *)GetProcAddress(va->hdxva2_dll,
(void *)GetProcAddress(sys->hdxva2_dll,
"DXVA2CreateDirect3DDeviceManager9");
if (!CreateDeviceManager9) {
msg_Err(va->log, "cannot load function");
msg_Err(va, "cannot load function");
return VLC_EGENERIC;
}
msg_Dbg(va->log, "OurDirect3DCreateDeviceManager9 Success!");
msg_Dbg(va, "OurDirect3DCreateDeviceManager9 Success!");
UINT token;
IDirect3DDeviceManager9 *devmng;
if (FAILED(CreateDeviceManager9(&token, &devmng))) {
msg_Err(va->log, " OurDirect3DCreateDeviceManager9 failed");
msg_Err(va, " OurDirect3DCreateDeviceManager9 failed");
return VLC_EGENERIC;
}
va->token = token;
va->devmng = devmng;
msg_Info(va->log, "obtained IDirect3DDeviceManager9");
sys->token = token;
sys->devmng = devmng;
msg_Info(va, "obtained IDirect3DDeviceManager9");
HRESULT hr = IDirect3DDeviceManager9_ResetDevice(devmng, va->d3ddev, token);
HRESULT hr = IDirect3DDeviceManager9_ResetDevice(devmng, sys->d3ddev, token);
if (FAILED(hr)) {
msg_Err(va->log, "IDirect3DDeviceManager9_ResetDevice failed: %08x", (unsigned)hr);
msg_Err(va, "IDirect3DDeviceManager9_ResetDevice failed: %08x", (unsigned)hr);
return VLC_EGENERIC;
}
return VLC_SUCCESS;
......@@ -703,7 +692,7 @@ static int D3dCreateDeviceManager(vlc_va_dxva2_t *va)
/**
* It destroys a Direct3D device manager
*/
static void D3dDestroyDeviceManager(vlc_va_dxva2_t *va)
static void D3dDestroyDeviceManager(vlc_va_sys_t *va)
{
if (va->devmng)
IDirect3DDeviceManager9_Release(va->devmng);
......@@ -712,47 +701,48 @@ static void D3dDestroyDeviceManager(vlc_va_dxva2_t *va)
/**
* It creates a DirectX video service
*/
static int DxCreateVideoService(vlc_va_dxva2_t *va)
static int DxCreateVideoService(vlc_va_t *va)
{
vlc_va_sys_t *sys = va->sys;
HRESULT (WINAPI *CreateVideoService)(IDirect3DDevice9 *,
REFIID riid,
void **ppService);
CreateVideoService =
(void *)GetProcAddress(va->hdxva2_dll,
"DXVA2CreateVideoService");
(void *)GetProcAddress(sys->hdxva2_dll, "DXVA2CreateVideoService");
if (!CreateVideoService) {
msg_Err(va->log, "cannot load function");
msg_Err(va, "cannot load function");
return 4;
}
msg_Info(va->log, "DXVA2CreateVideoService Success!");
msg_Info(va, "DXVA2CreateVideoService Success!");
HRESULT hr;
HANDLE device;
hr = IDirect3DDeviceManager9_OpenDeviceHandle(va->devmng, &device);
hr = IDirect3DDeviceManager9_OpenDeviceHandle(sys->devmng, &device);
if (FAILED(hr)) {
msg_Err(va->log, "OpenDeviceHandle failed");
msg_Err(va, "OpenDeviceHandle failed");
return VLC_EGENERIC;
}
va->device = device;
sys->device = device;
IDirectXVideoDecoderService *vs;
hr = IDirect3DDeviceManager9_GetVideoService(va->devmng, device,
&IID_IDirectXVideoDecoderService,
(void**)&vs);
void *pv;
hr = IDirect3DDeviceManager9_GetVideoService(sys->devmng, device,
&IID_IDirectXVideoDecoderService, &pv);
if (FAILED(hr)) {
msg_Err(va->log, "GetVideoService failed");
msg_Err(va, "GetVideoService failed");
return VLC_EGENERIC;
}
va->vs = vs;
sys->vs = pv;
return VLC_SUCCESS;
}
/**
* It destroys a DirectX video service
*/
static void DxDestroyVideoService(vlc_va_dxva2_t *va)
static void DxDestroyVideoService(vlc_va_sys_t *va)
{
if (va->device)
IDirect3DDeviceManager9_CloseDeviceHandle(va->devmng, va->device);
......@@ -762,24 +752,26 @@ static void DxDestroyVideoService(vlc_va_dxva2_t *va)
/**
* Find the best suited decoder mode GUID and render format.
*/
static int DxFindVideoServiceConversion(vlc_va_dxva2_t *va, GUID *input, D3DFORMAT *output)
static int DxFindVideoServiceConversion(vlc_va_t *va, GUID *input, D3DFORMAT *output)
{
vlc_va_sys_t *sys = va->sys;
/* Retreive supported modes from the decoder service */
UINT input_count = 0;
GUID *input_list = NULL;
if (FAILED(IDirectXVideoDecoderService_GetDecoderDeviceGuids(va->vs,
if (FAILED(IDirectXVideoDecoderService_GetDecoderDeviceGuids(sys->vs,
&input_count,
&input_list))) {
msg_Err(va->log, "IDirectXVideoDecoderService_GetDecoderDeviceGuids failed");
msg_Err(va, "IDirectXVideoDecoderService_GetDecoderDeviceGuids failed");
return VLC_EGENERIC;
}
for (unsigned i = 0; i < input_count; i++) {
const GUID *g = &input_list[i];
const dxva2_mode_t *mode = Dxva2FindMode(g);
if (mode) {
msg_Dbg(va->log, "- '%s' is supported by hardware", mode->name);
msg_Dbg(va, "- '%s' is supported by hardware", mode->name);
} else {
msg_Warn(va->log, "- Unknown GUID = %08X-%04x-%04x-XXXX",
msg_Warn(va, "- Unknown GUID = %08X-%04x-%04x-XXXX",
(unsigned)g->Data1, g->Data2, g->Data3);
}
}
......@@ -787,7 +779,7 @@ static int DxFindVideoServiceConversion(vlc_va_dxva2_t *va, GUID *input, D3DFORM
/* Try all supported mode by our priority */
for (unsigned i = 0; dxva2_modes[i].name; i++) {
const dxva2_mode_t *mode = &dxva2_modes[i];
if (!mode->codec || mode->codec != va->codec_id)
if (!mode->codec || mode->codec != sys->codec_id)
continue;
/* */
......@@ -799,22 +791,22 @@ static int DxFindVideoServiceConversion(vlc_va_dxva2_t *va, GUID *input, D3DFORM
continue;
/* */
msg_Dbg(va->log, "Trying to use '%s' as input", mode->name);
msg_Dbg(va, "Trying to use '%s' as input", mode->name);
UINT output_count = 0;
D3DFORMAT *output_list = NULL;
if (FAILED(IDirectXVideoDecoderService_GetDecoderRenderTargets(va->vs, mode->guid,
if (FAILED(IDirectXVideoDecoderService_GetDecoderRenderTargets(sys->vs, mode->guid,
&output_count,
&output_list))) {
msg_Err(va->log, "IDirectXVideoDecoderService_GetDecoderRenderTargets failed");
msg_Err(va, "IDirectXVideoDecoderService_GetDecoderRenderTargets failed");
continue;
}
for (unsigned j = 0; j < output_count; j++) {
const D3DFORMAT f = output_list[j];
const d3d_format_t *format = D3dFindFormat(f);
if (format) {
msg_Dbg(va->log, "%s is supported for output", format->name);
msg_Dbg(va, "%s is supported for output", format->name);
} else {
msg_Dbg(va->log, "%d is supported for output (%4.4s)", f, (const char*)&f);
msg_Dbg(va, "%d is supported for output (%4.4s)", f, (const char*)&f);
}
}
......@@ -831,7 +823,7 @@ static int DxFindVideoServiceConversion(vlc_va_dxva2_t *va, GUID *input, D3DFORM
continue;
/* We have our solution */
msg_Dbg(va->log, "Using '%s' to decode to '%s'", mode->name, format->name);
msg_Dbg(va, "Using '%s' to decode to '%s'", mode->name, format->name);
*input = *mode->guid;
*output = format->format;
CoTaskMemFree(output_list);
......@@ -847,23 +839,25 @@ static int DxFindVideoServiceConversion(vlc_va_dxva2_t *va, GUID *input, D3DFORM
/**
* It creates a DXVA2 decoder using the given video format
*/
static int DxCreateVideoDecoder(vlc_va_dxva2_t *va,
static int DxCreateVideoDecoder(vlc_va_t *va,
int codec_id, const video_format_t *fmt)
{
vlc_va_sys_t *sys = va->sys;
/* */
msg_Dbg(va->log, "DxCreateVideoDecoder id %d %dx%d",
msg_Dbg(va, "DxCreateVideoDecoder id %d %dx%d",
codec_id, fmt->i_width, fmt->i_height);
va->width = fmt->i_width;
va->height = fmt->i_height;
sys->width = fmt->i_width;
sys->height = fmt->i_height;
/* Allocates all surfaces needed for the decoder */
va->surface_width = (fmt->i_width + 15) & ~15;
va->surface_height = (fmt->i_height + 15) & ~15;
sys->surface_width = (fmt->i_width + 15) & ~15;
sys->surface_height = (fmt->i_height + 15) & ~15;
int surface_count;
switch (codec_id) {
case AV_CODEC_ID_H264:
surface_count = 16 + va->thread_count + 2;
surface_count = 16 + sys->thread_count + 2;
break;
case AV_CODEC_ID_MPEG1VIDEO:
case AV_CODEC_ID_MPEG2VIDEO:
......@@ -875,36 +869,36 @@ static int DxCreateVideoDecoder(vlc_va_dxva2_t *va,
}
if (surface_count > VA_DXVA2_MAX_SURFACE_COUNT)
return VLC_EGENERIC;
va->surface_count = surface_count;
if (FAILED(IDirectXVideoDecoderService_CreateSurface(va->vs,
va->surface_width,
va->surface_height,
va->surface_count - 1,
va->render,
sys->surface_count = surface_count;
if (FAILED(IDirectXVideoDecoderService_CreateSurface(sys->vs,
sys->surface_width,
sys->surface_height,
sys->surface_count - 1,
sys->render,
D3DPOOL_DEFAULT,
0,
DXVA2_VideoDecoderRenderTarget,
va->hw_surface,
sys->hw_surface,
NULL))) {
msg_Err(va->log, "IDirectXVideoAccelerationService_CreateSurface failed");
va->surface_count = 0;
msg_Err(va, "IDirectXVideoAccelerationService_CreateSurface failed");
sys->surface_count = 0;
return VLC_EGENERIC;
}
for (unsigned i = 0; i < va->surface_count; i++) {
vlc_va_surface_t *surface = &va->surface[i];
surface->d3d = va->hw_surface[i];
for (unsigned i = 0; i < sys->surface_count; i++) {
vlc_va_surface_t *surface = &sys->surface[i];
surface->d3d = sys->hw_surface[i];
surface->refcount = 0;
surface->order = 0;
}
msg_Dbg(va->log, "IDirectXVideoAccelerationService_CreateSurface succeed with %d surfaces (%dx%d)",
va->surface_count, fmt->i_width, fmt->i_height);
msg_Dbg(va, "IDirectXVideoAccelerationService_CreateSurface succeed with %d surfaces (%dx%d)",
sys->surface_count, fmt->i_width, fmt->i_height);
/* */
DXVA2_VideoDesc dsc;
ZeroMemory(&dsc, sizeof(dsc));
dsc.SampleWidth = fmt->i_width;
dsc.SampleHeight = fmt->i_height;
dsc.Format = va->render;
dsc.Format = sys->render;
if (fmt->i_frame_rate > 0 && fmt->i_frame_rate_base > 0) {
dsc.InputSampleFreq.Numerator = fmt->i_frame_rate;
dsc.InputSampleFreq.Denominator = fmt->i_frame_rate_base;
......@@ -929,16 +923,16 @@ static int DxCreateVideoDecoder(vlc_va_dxva2_t *va,
/* List all configurations available for the decoder */
UINT cfg_count = 0;
DXVA2_ConfigPictureDecode *cfg_list = NULL;
if (FAILED(IDirectXVideoDecoderService_GetDecoderConfigurations(va->vs,
&va->input,
if (FAILED(IDirectXVideoDecoderService_GetDecoderConfigurations(sys->vs,
&sys->input,
&dsc,
NULL,
&cfg_count,
&cfg_list))) {
msg_Err(va->log, "IDirectXVideoDecoderService_GetDecoderConfigurations failed");
msg_Err(va, "IDirectXVideoDecoderService_GetDecoderConfigurations failed");
return VLC_EGENERIC;
}
msg_Dbg(va->log, "we got %d decoder configurations", cfg_count);
msg_Dbg(va, "we got %d decoder configurations", cfg_count);
/* Select the best decoder configuration */
int cfg_score = 0;
......@@ -946,7 +940,7 @@ static int DxCreateVideoDecoder(vlc_va_dxva2_t *va,
const DXVA2_ConfigPictureDecode *cfg = &cfg_list[i];
/* */
msg_Dbg(va->log, "configuration[%d] ConfigBitstreamRaw %d",
msg_Dbg(va, "configuration[%d] ConfigBitstreamRaw %d",
i, cfg->ConfigBitstreamRaw);
/* */
......@@ -961,33 +955,34 @@ static int DxCreateVideoDecoder(vlc_va_dxva2_t *va,
score += 16;
if (cfg_score < score) {
va->cfg = *cfg;
sys->cfg = *cfg;
cfg_score = score;
}
}
CoTaskMemFree(cfg_list);
if (cfg_score <= 0) {
msg_Err(va->log, "Failed to find a supported decoder configuration");
msg_Err(va, "Failed to find a supported decoder configuration");
return VLC_EGENERIC;
}
/* Create the decoder */
IDirectXVideoDecoder *decoder;
if (FAILED(IDirectXVideoDecoderService_CreateVideoDecoder(va->vs,
&va->input,
if (FAILED(IDirectXVideoDecoderService_CreateVideoDecoder(sys->vs,
&sys->input,
&dsc,
&va->cfg,
va->hw_surface,
va->surface_count,
&sys->cfg,
sys->hw_surface,
sys->surface_count,
&decoder))) {
msg_Err(va->log, "IDirectXVideoDecoderService_CreateVideoDecoder failed");
msg_Err(va, "IDirectXVideoDecoderService_CreateVideoDecoder failed");
return VLC_EGENERIC;
}
va->decoder = decoder;
msg_Dbg(va->log, "IDirectXVideoDecoderService_CreateVideoDecoder succeed");
sys->decoder = decoder;
msg_Dbg(va, "IDirectXVideoDecoderService_CreateVideoDecoder succeed");
return VLC_SUCCESS;
}
static void DxDestroyVideoDecoder(vlc_va_dxva2_t *va)
static void DxDestroyVideoDecoder(vlc_va_sys_t *va)
{
if (va->decoder)
IDirectXVideoDecoder_Release(va->decoder);
......@@ -997,13 +992,14 @@ static void DxDestroyVideoDecoder(vlc_va_dxva2_t *va)
IDirect3DSurface9_Release(va->surface[i].d3d);
va->surface_count = 0;
}
static int DxResetVideoDecoder(vlc_va_dxva2_t *va)
static int DxResetVideoDecoder(vlc_va_t *va)
{
msg_Err(va->log, "DxResetVideoDecoder unimplemented");
msg_Err(va, "DxResetVideoDecoder unimplemented");
return VLC_EGENERIC;
}
static void DxCreateVideoConversion(vlc_va_dxva2_t *va)
static void DxCreateVideoConversion(vlc_va_sys_t *va)
{
switch (va->render) {
case MAKEFOURCC('N','V','1','2'):
......@@ -1016,7 +1012,8 @@ static void DxCreateVideoConversion(vlc_va_dxva2_t *va)
}
CopyInitCache(&va->surface_cache, va->surface_width);
}
static void DxDestroyVideoConversion(vlc_va_dxva2_t *va)
static void DxDestroyVideoConversion(vlc_va_sys_t *va)
{
CopyCleanCache(&va->surface_cache);
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment