Commit f7d5f497 authored by Steve Lhomme's avatar Steve Lhomme Committed by Jean-Baptiste Kempf

dxva: split the directx related parts from the pool/va parts

Signed-off-by: Jean-Baptiste Kempf's avatarJean-Baptiste Kempf <jb@videolan.org>
parent dd3b5b8e
...@@ -404,6 +404,7 @@ endif ...@@ -404,6 +404,7 @@ endif
libdxva2_plugin_la_SOURCES = \ libdxva2_plugin_la_SOURCES = \
codec/avcodec/dxva2.c codec/avcodec/directx_va.c codec/avcodec/directx_va.h \ codec/avcodec/dxva2.c codec/avcodec/directx_va.c codec/avcodec/directx_va.h \
codec/avcodec/va_surface.c codec/avcodec/va_surface.h codec/avcodec/va_surface_internal.h \
packetizer/h264_nal.c packetizer/h264_nal.h \ packetizer/h264_nal.c packetizer/h264_nal.h \
packetizer/hevc_nal.c packetizer/hevc_nal.h \ packetizer/hevc_nal.c packetizer/hevc_nal.h \
video_chroma/d3d9_fmt.h video_chroma/d3d9_fmt.h
...@@ -414,6 +415,7 @@ endif ...@@ -414,6 +415,7 @@ endif
libd3d11va_plugin_la_SOURCES = \ libd3d11va_plugin_la_SOURCES = \
codec/avcodec/d3d11va.c codec/avcodec/directx_va.c codec/avcodec/directx_va.h \ codec/avcodec/d3d11va.c codec/avcodec/directx_va.c codec/avcodec/directx_va.h \
codec/avcodec/va_surface.c codec/avcodec/va_surface.h codec/avcodec/va_surface_internal.h \
video_chroma/d3d11_fmt.h video_chroma/dxgi_fmt.c video_chroma/dxgi_fmt.h \ video_chroma/d3d11_fmt.h video_chroma/dxgi_fmt.c video_chroma/dxgi_fmt.h \
packetizer/h264_nal.c packetizer/h264_nal.h \ packetizer/h264_nal.c packetizer/h264_nal.h \
packetizer/hevc_nal.c packetizer/hevc_nal.h packetizer/hevc_nal.c packetizer/hevc_nal.h
......
...@@ -165,8 +165,8 @@ void SetupAVCodecContext(vlc_va_t *va) ...@@ -165,8 +165,8 @@ void SetupAVCodecContext(vlc_va_t *va)
sys->hw.video_context = sys->d3dvidctx; sys->hw.video_context = sys->d3dvidctx;
sys->hw.decoder = dx_sys->decoder; sys->hw.decoder = dx_sys->decoder;
sys->hw.cfg = &sys->cfg; sys->hw.cfg = &sys->cfg;
sys->hw.surface_count = dx_sys->surface_count; sys->hw.surface_count = dx_sys->va_pool.surface_count;
sys->hw.surface = dx_sys->hw_surface; sys->hw.surface = dx_sys->va_pool.hw_surface;
sys->hw.context_mutex = sys->context_mutex; sys->hw.context_mutex = sys->context_mutex;
if (IsEqualGUID(&dx_sys->input, &DXVA_Intel_H264_NoFGT_ClearVideo)) if (IsEqualGUID(&dx_sys->input, &DXVA_Intel_H264_NoFGT_ClearVideo))
...@@ -178,7 +178,7 @@ static int Extract(vlc_va_t *va, picture_t *output, uint8_t *data) ...@@ -178,7 +178,7 @@ static int Extract(vlc_va_t *va, picture_t *output, uint8_t *data)
VLC_UNUSED(va); VLC_UNUSED(data); VLC_UNUSED(va); VLC_UNUSED(data);
struct va_pic_context *pic_ctx = (struct va_pic_context*)output->context; struct va_pic_context *pic_ctx = (struct va_pic_context*)output->context;
if (!va->sys->b_extern_pool) if (!va->sys->b_extern_pool)
directx_va_AddRef(pic_ctx->va_surface); va_surface_AddRef(pic_ctx->va_surface);
assert(data == (void*)pic_ctx->picsys.decoder); assert(data == (void*)pic_ctx->picsys.decoder);
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -205,7 +205,7 @@ static void d3d11_pic_context_destroy(struct picture_context_t *opaque) ...@@ -205,7 +205,7 @@ static void d3d11_pic_context_destroy(struct picture_context_t *opaque)
{ {
struct va_pic_context *pic_ctx = (struct va_pic_context*)opaque; struct va_pic_context *pic_ctx = (struct va_pic_context*)opaque;
if (pic_ctx->va_surface) if (pic_ctx->va_surface)
directx_va_Release(pic_ctx->va_surface); va_surface_Release(pic_ctx->va_surface);
ReleasePictureSys(&pic_ctx->picsys); ReleasePictureSys(&pic_ctx->picsys);
free(pic_ctx); free(pic_ctx);
} }
...@@ -295,7 +295,7 @@ static int Get(vlc_va_t *va, picture_t *pic, uint8_t **data) ...@@ -295,7 +295,7 @@ static int Get(vlc_va_t *va, picture_t *pic, uint8_t **data)
#endif #endif
{ {
ID3D11ShaderResourceView *resourceView[D3D11_MAX_SHADER_VIEW]; ID3D11ShaderResourceView *resourceView[D3D11_MAX_SHADER_VIEW];
vlc_va_surface_t *va_surface = directx_va_Get(va, &va->sys->dx_sys); vlc_va_surface_t *va_surface = va_pool_Get(va, &va->sys->dx_sys.va_pool);
if (unlikely(va_surface==NULL)) if (unlikely(va_surface==NULL))
return VLC_EGENERIC; return VLC_EGENERIC;
...@@ -318,7 +318,7 @@ static int Get(vlc_va_t *va, picture_t *pic, uint8_t **data) ...@@ -318,7 +318,7 @@ static int Get(vlc_va_t *va, picture_t *pic, uint8_t **data)
ID3D11Resource_Release(p_resource); ID3D11Resource_Release(p_resource);
if (unlikely(pic_ctx==NULL)) if (unlikely(pic_ctx==NULL))
{ {
directx_va_Release(va_surface); va_surface_Release(va_surface);
return VLC_ENOMEM; return VLC_ENOMEM;
} }
pic->context = &pic_ctx->s; pic->context = &pic_ctx->s;
...@@ -360,7 +360,7 @@ static void ReleasePic(void *opaque, uint8_t *data) ...@@ -360,7 +360,7 @@ static void ReleasePic(void *opaque, uint8_t *data)
(void)data; (void)data;
picture_t *pic = opaque; picture_t *pic = opaque;
struct va_pic_context *pic_ctx = (struct va_pic_context*)pic->context; struct va_pic_context *pic_ctx = (struct va_pic_context*)pic->context;
directx_va_Release(pic_ctx->va_surface); va_surface_Release(pic_ctx->va_surface);
picture_Release(pic); picture_Release(pic);
} }
...@@ -383,14 +383,14 @@ static int Open(vlc_va_t *va, AVCodecContext *ctx, enum PixelFormat pix_fmt, ...@@ -383,14 +383,14 @@ static int Open(vlc_va_t *va, AVCodecContext *ctx, enum PixelFormat pix_fmt,
dx_sys = &sys->dx_sys; dx_sys = &sys->dx_sys;
dx_sys->pf_check_device = CheckDevice; dx_sys->va_pool.pf_check_device = CheckDevice;
dx_sys->pf_create_device = D3dCreateDevice; dx_sys->va_pool.pf_create_device = D3dCreateDevice;
dx_sys->pf_destroy_device = D3dDestroyDevice; dx_sys->va_pool.pf_destroy_device = D3dDestroyDevice;
dx_sys->pf_create_video_service = DxCreateVideoService; dx_sys->va_pool.pf_create_video_service = DxCreateVideoService;
dx_sys->pf_destroy_video_service = DxDestroyVideoService; dx_sys->va_pool.pf_destroy_video_service = DxDestroyVideoService;
dx_sys->pf_create_decoder_surfaces = DxCreateDecoderSurfaces; dx_sys->va_pool.pf_create_decoder_surfaces = DxCreateDecoderSurfaces;
dx_sys->pf_destroy_surfaces = DxDestroySurfaces; dx_sys->va_pool.pf_destroy_surfaces = DxDestroySurfaces;
dx_sys->pf_setup_avcodec_ctx = SetupAVCodecContext; dx_sys->va_pool.pf_setup_avcodec_ctx = SetupAVCodecContext;
dx_sys->pf_get_input_list = DxGetInputList; dx_sys->pf_get_input_list = DxGetInputList;
dx_sys->pf_setup_output = DxSetupOutput; dx_sys->pf_setup_output = DxSetupOutput;
dx_sys->psz_decoder_dll = TEXT("D3D11.DLL"); dx_sys->psz_decoder_dll = TEXT("D3D11.DLL");
...@@ -803,7 +803,7 @@ static int DxCreateDecoderSurfaces(vlc_va_t *va, int codec_id, ...@@ -803,7 +803,7 @@ static int DxCreateDecoderSurfaces(vlc_va_t *va, int codec_id,
for (surface_idx = 0; surface_idx < surface_count; surface_idx++) { for (surface_idx = 0; surface_idx < surface_count; surface_idx++) {
picture_t *pic = decoder_NewPicture( (decoder_t*) va->obj.parent ); picture_t *pic = decoder_NewPicture( (decoder_t*) va->obj.parent );
sys->extern_pics[surface_idx] = pic; sys->extern_pics[surface_idx] = pic;
dx_sys->hw_surface[surface_idx] = NULL; dx_sys->va_pool.hw_surface[surface_idx] = NULL;
if (pic==NULL) if (pic==NULL)
{ {
msg_Warn(va, "not enough decoder pictures %d out of %d", surface_idx, surface_count); msg_Warn(va, "not enough decoder pictures %d out of %d", surface_idx, surface_count);
...@@ -846,17 +846,17 @@ static int DxCreateDecoderSurfaces(vlc_va_t *va, int codec_id, ...@@ -846,17 +846,17 @@ static int DxCreateDecoderSurfaces(vlc_va_t *va, int codec_id,
AllocateShaderView(VLC_OBJECT(va), dx_sys->d3ddev, textureFmt, pic->p_sys->texture, pic->p_sys->slice_index, pic->p_sys->resourceView); AllocateShaderView(VLC_OBJECT(va), dx_sys->d3ddev, textureFmt, pic->p_sys->texture, pic->p_sys->slice_index, pic->p_sys->resourceView);
dx_sys->hw_surface[surface_idx] = pic->p_sys->decoder; dx_sys->va_pool.hw_surface[surface_idx] = pic->p_sys->decoder;
} }
if (!sys->b_extern_pool) if (!sys->b_extern_pool)
{ {
for (size_t i = 0; i < surface_idx; ++i) for (size_t i = 0; i < surface_idx; ++i)
{ {
if (dx_sys->hw_surface[i]) if (dx_sys->va_pool.hw_surface[i])
{ {
ID3D11VideoDecoderOutputView_Release(dx_sys->hw_surface[i]); ID3D11VideoDecoderOutputView_Release(dx_sys->va_pool.hw_surface[i]);
dx_sys->hw_surface[i] = NULL; dx_sys->va_pool.hw_surface[i] = NULL;
} }
if (sys->extern_pics[i]) if (sys->extern_pics[i])
{ {
...@@ -875,8 +875,8 @@ static int DxCreateDecoderSurfaces(vlc_va_t *va, int codec_id, ...@@ -875,8 +875,8 @@ static int DxCreateDecoderSurfaces(vlc_va_t *va, int codec_id,
{ {
D3D11_TEXTURE2D_DESC texDesc; D3D11_TEXTURE2D_DESC texDesc;
ZeroMemory(&texDesc, sizeof(texDesc)); ZeroMemory(&texDesc, sizeof(texDesc));
texDesc.Width = dx_sys->surface_width; texDesc.Width = dx_sys->va_pool.surface_width;
texDesc.Height = dx_sys->surface_height; texDesc.Height = dx_sys->va_pool.surface_height;
texDesc.MipLevels = 1; texDesc.MipLevels = 1;
texDesc.Format = sys->render; texDesc.Format = sys->render;
texDesc.SampleDesc.Count = 1; texDesc.SampleDesc.Count = 1;
...@@ -896,17 +896,17 @@ static int DxCreateDecoderSurfaces(vlc_va_t *va, int codec_id, ...@@ -896,17 +896,17 @@ static int DxCreateDecoderSurfaces(vlc_va_t *va, int codec_id,
return VLC_EGENERIC; return VLC_EGENERIC;
} }
unsigned i; unsigned surface_idx;
for (i = 0; i < surface_count; i++) { for (surface_idx = 0; surface_idx < surface_count; surface_idx++) {
sys->extern_pics[i] = NULL; sys->extern_pics[surface_idx] = NULL;
viewDesc.Texture2D.ArraySlice = i; viewDesc.Texture2D.ArraySlice = surface_idx;
hr = ID3D11VideoDevice_CreateVideoDecoderOutputView( dx_sys->d3ddec, hr = ID3D11VideoDevice_CreateVideoDecoderOutputView( dx_sys->d3ddec,
(ID3D11Resource*) p_texture, (ID3D11Resource*) p_texture,
&viewDesc, &viewDesc,
&dx_sys->hw_surface[i] ); &dx_sys->va_pool.hw_surface[surface_idx] );
if (FAILED(hr)) { if (FAILED(hr)) {
msg_Err(va, "CreateVideoDecoderOutputView %d failed. (hr=0x%0lx)", i, hr); msg_Err(va, "CreateVideoDecoderOutputView %d failed. (hr=0x%0lx)", surface_idx, hr);
ID3D11Texture2D_Release(p_texture); ID3D11Texture2D_Release(p_texture);
return VLC_EGENERIC; return VLC_EGENERIC;
} }
...@@ -914,12 +914,13 @@ static int DxCreateDecoderSurfaces(vlc_va_t *va, int codec_id, ...@@ -914,12 +914,13 @@ static int DxCreateDecoderSurfaces(vlc_va_t *va, int codec_id,
if (texDesc.BindFlags & D3D11_BIND_SHADER_RESOURCE) if (texDesc.BindFlags & D3D11_BIND_SHADER_RESOURCE)
{ {
ID3D11Texture2D *textures[D3D11_MAX_SHADER_VIEW] = {p_texture, p_texture}; ID3D11Texture2D *textures[D3D11_MAX_SHADER_VIEW] = {p_texture, p_texture};
AllocateShaderView(VLC_OBJECT(va), dx_sys->d3ddev, textureFmt, textures, i, &sys->resourceView[i * D3D11_MAX_SHADER_VIEW]); AllocateShaderView(VLC_OBJECT(va), dx_sys->d3ddev, textureFmt, textures, surface_idx,
&sys->resourceView[surface_idx * D3D11_MAX_SHADER_VIEW]);
} }
} }
} }
msg_Dbg(va, "ID3D11VideoDecoderOutputView succeed with %d surfaces (%dx%d)", msg_Dbg(va, "ID3D11VideoDecoderOutputView succeed with %d surfaces (%dx%d)",
surface_count, dx_sys->surface_width, dx_sys->surface_height); surface_count, dx_sys->va_pool.surface_width, dx_sys->va_pool.surface_height);
D3D11_VIDEO_DECODER_DESC decoderDesc; D3D11_VIDEO_DECODER_DESC decoderDesc;
ZeroMemory(&decoderDesc, sizeof(decoderDesc)); ZeroMemory(&decoderDesc, sizeof(decoderDesc));
...@@ -994,15 +995,15 @@ static int DxCreateDecoderSurfaces(vlc_va_t *va, int codec_id, ...@@ -994,15 +995,15 @@ static int DxCreateDecoderSurfaces(vlc_va_t *va, int codec_id,
static void DxDestroySurfaces(vlc_va_t *va) static void DxDestroySurfaces(vlc_va_t *va)
{ {
directx_sys_t *dx_sys = &va->sys->dx_sys; directx_sys_t *dx_sys = &va->sys->dx_sys;
if (dx_sys->surface_count && !va->sys->b_extern_pool) { if (dx_sys->va_pool.surface_count && !va->sys->b_extern_pool) {
ID3D11Resource *p_texture; ID3D11Resource *p_texture;
ID3D11VideoDecoderOutputView_GetResource( dx_sys->hw_surface[0], &p_texture ); ID3D11VideoDecoderOutputView_GetResource( dx_sys->va_pool.hw_surface[0], &p_texture );
ID3D11Resource_Release(p_texture); ID3D11Resource_Release(p_texture);
ID3D11Resource_Release(p_texture); ID3D11Resource_Release(p_texture);
} }
for (unsigned i = 0; i < dx_sys->surface_count; i++) for (unsigned i = 0; i < dx_sys->va_pool.surface_count; i++)
{ {
ID3D11VideoDecoderOutputView_Release( dx_sys->hw_surface[i] ); ID3D11VideoDecoderOutputView_Release( dx_sys->va_pool.hw_surface[i] );
for (int j = 0; j < D3D11_MAX_SHADER_VIEW; j++) for (int j = 0; j < D3D11_MAX_SHADER_VIEW; j++)
{ {
if (va->sys->resourceView[i*D3D11_MAX_SHADER_VIEW + j]) if (va->sys->resourceView[i*D3D11_MAX_SHADER_VIEW + j])
......
...@@ -262,7 +262,6 @@ static const directx_va_mode_t DXVA_MODES[] = { ...@@ -262,7 +262,6 @@ static const directx_va_mode_t DXVA_MODES[] = {
}; };
static int FindVideoServiceConversion(vlc_va_t *, directx_sys_t *, const es_format_t *fmt); static int FindVideoServiceConversion(vlc_va_t *, directx_sys_t *, const es_format_t *fmt);
static void DestroyVideoDecoder(vlc_va_t *, directx_sys_t *);
char *directx_va_GetDecoderName(const GUID *guid) char *directx_va_GetDecoderName(const GUID *guid)
{ {
...@@ -282,24 +281,8 @@ int directx_va_Setup(vlc_va_t *va, directx_sys_t *dx_sys, AVCodecContext *avctx) ...@@ -282,24 +281,8 @@ int directx_va_Setup(vlc_va_t *va, directx_sys_t *dx_sys, AVCodecContext *avctx)
{ {
int surface_alignment = 16; int surface_alignment = 16;
unsigned surface_count = 2; unsigned surface_count = 2;
unsigned i = dx_sys->surface_count;
int err = VLC_EGENERIC;
if (dx_sys->width == avctx->coded_width && dx_sys->height == avctx->coded_height switch ( dx_sys->va_pool.codec_id )
&& dx_sys->decoder != NULL)
goto done;
/* */
DestroyVideoDecoder(va, dx_sys);
avctx->hwaccel_context = NULL;
if (avctx->coded_width <= 0 || avctx->coded_height <= 0)
return VLC_EGENERIC;
/* */
msg_Dbg(va, "directx_va_Setup id %d %dx%d", dx_sys->codec_id, avctx->coded_width, avctx->coded_height);
switch ( dx_sys->codec_id )
{ {
case AV_CODEC_ID_MPEG2VIDEO: case AV_CODEC_ID_MPEG2VIDEO:
/* decoding MPEG-2 requires additional alignment on some Intel GPUs, /* decoding MPEG-2 requires additional alignment on some Intel GPUs,
...@@ -323,120 +306,13 @@ int directx_va_Setup(vlc_va_t *va, directx_sys_t *dx_sys, AVCodecContext *avctx) ...@@ -323,120 +306,13 @@ int directx_va_Setup(vlc_va_t *va, directx_sys_t *dx_sys, AVCodecContext *avctx)
if ( avctx->active_thread_type & FF_THREAD_FRAME ) if ( avctx->active_thread_type & FF_THREAD_FRAME )
surface_count += avctx->thread_count; surface_count += avctx->thread_count;
if (surface_count > MAX_SURFACE_COUNT) return va_pool_Setup(va, &dx_sys->va_pool, avctx,
return VLC_EGENERIC; surface_count, surface_alignment);
#define ALIGN(x, y) (((x) + ((y) - 1)) & ~((y) - 1))
dx_sys->width = avctx->coded_width;
dx_sys->height = avctx->coded_height;
dx_sys->surface_width = ALIGN(dx_sys->width, surface_alignment);
dx_sys->surface_height = ALIGN(dx_sys->height, surface_alignment);
/* FIXME transmit a video_format_t by VaSetup directly */
video_format_t fmt;
memset(&fmt, 0, sizeof(fmt));
fmt.i_width = dx_sys->width;
fmt.i_height = dx_sys->height;
fmt.i_frame_rate = avctx->framerate.num;
fmt.i_frame_rate_base = avctx->framerate.den;
if (dx_sys->pf_create_decoder_surfaces(va, dx_sys->codec_id, &fmt, surface_count))
return VLC_EGENERIC;
if (avctx->coded_width != dx_sys->surface_width ||
avctx->coded_height != dx_sys->surface_height)
msg_Warn( va, "surface dimensions (%dx%d) differ from avcodec dimensions (%dx%d)",
dx_sys->surface_width, dx_sys->surface_height,
avctx->coded_width, avctx->coded_height);
for (i = 0; i < surface_count; i++) {
vlc_va_surface_t *surface = malloc(sizeof(*surface));
if (unlikely(surface==NULL))
{
err = VLC_ENOMEM;
goto done;
}
atomic_init(&surface->refcount, 1);
dx_sys->surface[i] = surface;
}
dx_sys->pf_setup_avcodec_ctx(va);
err = VLC_SUCCESS;
done:
dx_sys->surface_count = i;
return err;
}
void DestroyVideoDecoder(vlc_va_t *va, directx_sys_t *dx_sys)
{
dx_sys->pf_destroy_surfaces(va);
for (unsigned i = 0; i < dx_sys->surface_count; i++)
{
IUnknown_Release( dx_sys->hw_surface[i] );
directx_va_Release(dx_sys->surface[i]);
}
dx_sys->surface_count = 0;
}
static vlc_va_surface_t *GetSurface(directx_sys_t *dx_sys)
{
for (unsigned i = 0; i < dx_sys->surface_count; i++) {
vlc_va_surface_t *surface = dx_sys->surface[i];
uintptr_t expected = 1;
if (atomic_compare_exchange_strong(&surface->refcount, &expected, 2))
{
/* TODO do a copy to allow releasing locally and keep forward alive atomic_fetch_sub(&surface->refs, 1);*/
surface->decoderSurface = dx_sys->hw_surface[i];
return surface;
}
}
return NULL;
}
vlc_va_surface_t *directx_va_Get(vlc_va_t *va, directx_sys_t *dx_sys)
{
/* Check the device */
if (dx_sys->pf_check_device(va)!=VLC_SUCCESS)
return NULL;
unsigned tries = (CLOCK_FREQ + VOUT_OUTMEM_SLEEP) / VOUT_OUTMEM_SLEEP;
vlc_va_surface_t *field;
while ((field = GetSurface(dx_sys)) == NULL)
{
if (--tries == 0)
return NULL;
/* Pool empty. Wait for some time as in src/input/decoder.c.
* XXX: Both this and the core should use a semaphore or a CV. */
msleep(VOUT_OUTMEM_SLEEP);
}
return field;
}
void directx_va_AddRef(vlc_va_surface_t *surface)
{
atomic_fetch_add(&surface->refcount, 1);
}
void directx_va_Release(vlc_va_surface_t *surface)
{
if (atomic_fetch_sub(&surface->refcount, 1) != 1)
return;
free(surface);
} }
void directx_va_Close(vlc_va_t *va, directx_sys_t *dx_sys) void directx_va_Close(vlc_va_t *va, directx_sys_t *dx_sys)
{ {
DestroyVideoDecoder(va, dx_sys); va_pool_Close(va, &dx_sys->va_pool);
dx_sys->pf_destroy_video_service(va);
if (dx_sys->pf_destroy_device_manager)
dx_sys->pf_destroy_device_manager(va);
dx_sys->pf_destroy_device(va);
if (dx_sys->hdecoder_dll) if (dx_sys->hdecoder_dll)
FreeLibrary(dx_sys->hdecoder_dll); FreeLibrary(dx_sys->hdecoder_dll);
} }
...@@ -444,8 +320,6 @@ void directx_va_Close(vlc_va_t *va, directx_sys_t *dx_sys) ...@@ -444,8 +320,6 @@ void directx_va_Close(vlc_va_t *va, directx_sys_t *dx_sys)
int directx_va_Open(vlc_va_t *va, directx_sys_t *dx_sys, int directx_va_Open(vlc_va_t *va, directx_sys_t *dx_sys,
AVCodecContext *ctx, const es_format_t *fmt, bool b_dll) AVCodecContext *ctx, const es_format_t *fmt, bool b_dll)
{ {
dx_sys->codec_id = ctx->codec_id;
if (b_dll) { if (b_dll) {
/* Load dll*/ /* Load dll*/
dx_sys->hdecoder_dll = LoadLibrary(dx_sys->psz_decoder_dll); dx_sys->hdecoder_dll = LoadLibrary(dx_sys->psz_decoder_dll);
...@@ -456,23 +330,8 @@ int directx_va_Open(vlc_va_t *va, directx_sys_t *dx_sys, ...@@ -456,23 +330,8 @@ int directx_va_Open(vlc_va_t *va, directx_sys_t *dx_sys,
msg_Dbg(va, "DLLs loaded"); msg_Dbg(va, "DLLs loaded");
} }
/* */ if (va_pool_Open(va, &dx_sys->va_pool, ctx, fmt) != VLC_SUCCESS)
if (dx_sys->pf_create_device(va)) {
msg_Err(va, "Failed to create DirectX device");
goto error; goto error;
}
msg_Dbg(va, "CreateDevice succeed");
if (dx_sys->pf_create_device_manager &&
dx_sys->pf_create_device_manager(va) != VLC_SUCCESS) {
msg_Err(va, "CreateDeviceManager failed");
goto error;
}
if (dx_sys->pf_create_video_service(va)) {
msg_Err(va, "CreateVideoService failed");
goto error;
}
/* */ /* */
if (FindVideoServiceConversion(va, dx_sys, fmt)) { if (FindVideoServiceConversion(va, dx_sys, fmt)) {
...@@ -545,7 +404,7 @@ static int FindVideoServiceConversion(vlc_va_t *va, directx_sys_t *dx_sys, const ...@@ -545,7 +404,7 @@ static int FindVideoServiceConversion(vlc_va_t *va, directx_sys_t *dx_sys, const
/* Try all supported mode by our priority */ /* Try all supported mode by our priority */
const directx_va_mode_t *mode = DXVA_MODES; const directx_va_mode_t *mode = DXVA_MODES;
for (; mode->name; ++mode) { for (; mode->name; ++mode) {
if (!mode->codec || mode->codec != dx_sys->codec_id) if (!mode->codec || mode->codec != dx_sys->va_pool.codec_id)
continue; continue;
/* */ /* */
......
...@@ -42,11 +42,7 @@ ...@@ -42,11 +42,7 @@
#include <unknwn.h> #include <unknwn.h>
#include <stdatomic.h> #include <stdatomic.h>
/* */ #include "va_surface_internal.h"
struct vlc_va_surface_t {
atomic_uintptr_t refcount;
D3D_DecoderSurface *decoderSurface;
};
typedef struct input_list_t { typedef struct input_list_t {
void (*pf_release)(struct input_list_t *); void (*pf_release)(struct input_list_t *);
...@@ -57,9 +53,7 @@ typedef struct input_list_t { ...@@ -57,9 +53,7 @@ typedef struct input_list_t {
#define MAX_SURFACE_COUNT (64) #define MAX_SURFACE_COUNT (64)
typedef struct typedef struct
{ {
int codec_id; va_pool_t va_pool;
int width;
int height;
/* DLL */ /* DLL */
HINSTANCE hdecoder_dll; HINSTANCE hdecoder_dll;
...@@ -75,28 +69,6 @@ typedef struct ...@@ -75,28 +69,6 @@ typedef struct
/* Video decoder */ /* Video decoder */
D3D_DecoderType *decoder; D3D_DecoderType *decoder;
/* */
unsigned surface_count;
int surface_width;
int surface_height;
vlc_va_surface_t *surface[MAX_SURFACE_COUNT];
D3D_DecoderSurface *hw_surface[MAX_SURFACE_COUNT];
/**
* Check that the decoder device is still available
*/
int (*pf_check_device)(vlc_va_t *);
int (*pf_create_device)(vlc_va_t *);
void (*pf_destroy_device)(vlc_va_t *);
int (*pf_create_device_manager)(vlc_va_t *);
void (*pf_destroy_device_manager)(vlc_va_t *);
int (*pf_create_video_service)(vlc_va_t *);
void (*pf_destroy_video_service)(vlc_va_t *);
/** /**
* Read the list of possible input GUIDs * Read the list of possible input GUIDs
*/ */
...@@ -107,29 +79,11 @@ typedef struct ...@@ -107,29 +79,11 @@ typedef struct
*/ */
int (*pf_setup_output)(vlc_va_t *, const GUID *input, const video_format_t *fmt); int (*pf_setup_output)(vlc_va_t *, const GUID *input, const video_format_t *fmt);
/**
* Create the DirectX surfaces in hw_surface and the decoder in decoder
*/
int (*pf_create_decoder_surfaces)(vlc_va_t *, int codec_id,
const video_format_t *fmt,
unsigned surface_count);
/**
* Destroy resources allocated with the surfaces and the associated decoder
*/
void (*pf_destroy_surfaces)(vlc_va_t *);
/**
* Set the avcodec hw context after the decoder is created
*/
void (*pf_setup_avcodec_ctx)(vlc_va_t *);
} directx_sys_t; } directx_sys_t;
int directx_va_Open(vlc_va_t *, directx_sys_t *, AVCodecContext *ctx, const es_format_t *fmt, bool b_dll); int directx_va_Open(vlc_va_t *, directx_sys_t *, AVCodecContext *ctx, const es_format_t *fmt, bool b_dll);
void directx_va_Close(vlc_va_t *, directx_sys_t *); void directx_va_Close(vlc_va_t *, directx_sys_t *);
int directx_va_Setup(vlc_va_t *, directx_sys_t *, AVCodecContext *avctx); int directx_va_Setup(vlc_va_t *, directx_sys_t *, AVCodecContext *avctx);
vlc_va_surface_t *directx_va_Get(vlc_va_t *, directx_sys_t *);
void directx_va_AddRef(vlc_va_surface_t *surface);
void directx_va_Release(vlc_va_surface_t *surface);
char *directx_va_GetDecoderName(const GUID *guid); char *directx_va_GetDecoderName(const GUID *guid);
#endif /* AVCODEC_DIRECTX_VA_H */ #endif /* AVCODEC_DIRECTX_VA_H */
...@@ -167,8 +167,8 @@ void SetupAVCodecContext(vlc_va_t *va) ...@@ -167,8 +167,8 @@ void SetupAVCodecContext(vlc_va_t *va)
sys->hw.decoder = dx_sys->decoder; sys->hw.decoder = dx_sys->decoder;
sys->hw.cfg = &sys->cfg; sys->hw.cfg = &sys->cfg;
sys->hw.surface_count = dx_sys->surface_count; sys->hw.surface_count = dx_sys->va_pool.surface_count;
sys->hw.surface = dx_sys->hw_surface; sys->hw.surface = dx_sys->va_pool.hw_surface;
if (IsEqualGUID(&dx_sys->input, &DXVA_Intel_H264_NoFGT_ClearVideo)) if (IsEqualGUID(&dx_sys->input, &DXVA_Intel_H264_NoFGT_ClearVideo))
sys->hw.workaround |= FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO; sys->hw.workaround |= FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO;
...@@ -178,7 +178,7 @@ static int Extract(vlc_va_t *va, picture_t *picture, uint8_t *data) ...@@ -178,7 +178,7 @@ static int Extract(vlc_va_t *va, picture_t *picture, uint8_t *data)