From: gunsoo83.kim Date: Fri, 26 Sep 2014 05:52:44 +0000 (+0900) Subject: brillcodec: apply context management to DXVA X-Git-Tag: Tizen_Studio_1.3_Release_p2.3.2~620^2~3 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F99%2F28099%2F1;p=sdk%2Femulator%2Fqemu.git brillcodec: apply context management to DXVA - implement plug-in context management in DXVA. Change-Id: Iaa8642806483b9503d15cb5d6d2a300b04f1fe7d Signed-off-by: gunsoo83.kim --- diff --git a/tizen/src/hw/pci/maru_dxva2_plugin.c b/tizen/src/hw/pci/maru_dxva2_plugin.c index 83b63b0c93..fca00646ae 100644 --- a/tizen/src/hw/pci/maru_dxva2_plugin.c +++ b/tizen/src/hw/pci/maru_dxva2_plugin.c @@ -205,26 +205,13 @@ static const d3d_format_t d3d_formats[] = { { NULL, 0 } }; -/* */ -typedef struct { - LPDIRECT3DSURFACE9 d3d; - bool is_occupied; -} DXVAPluginSurface; +struct DXVAPluginSurface; +typedef struct DXVAPluginSurface DXVAPluginSurface; #define VA_DXVA2_MAX_SURFACE_COUNT (64) typedef struct DXVAPluginContext { - /* Direct3D */ - D3DPRESENT_PARAMETERS d3dpp; - LPDIRECT3D9 d3dobj; - LPDIRECT3DDEVICE9 d3ddev; - - /* Device manager */ - IDirect3DDeviceManager9 *devmng; - HANDLE hd3ddev; - /* Video service */ - IDirectXVideoDecoderService *vs; GUID guid_decdev; D3DFORMAT render_fmt; @@ -235,26 +222,42 @@ typedef struct DXVAPluginContext /* Option conversion */ D3DFORMAT output; - /* */ + /* Surfaces */ unsigned surface_count; int surface_width; int surface_height; + DXVAPluginSurface *surface; + LPDIRECT3DSURFACE9 hw_surface[VA_DXVA2_MAX_SURFACE_COUNT]; int thread_count; - DXVAPluginSurface surface[VA_DXVA2_MAX_SURFACE_COUNT]; - LPDIRECT3DSURFACE9 hw_surface[VA_DXVA2_MAX_SURFACE_COUNT]; - struct dxva_context *hw_context; } DXVAPluginContext; -// FIXME : modify dxva_ctx to multi instance for multi-thread decoding. -static DXVAPluginContext *dxva_ctx = &(DXVAPluginContext) {}; +struct DXVAPluginSurface { + LPDIRECT3DSURFACE9 d3d; + bool is_occupied; + DXVAPluginContext *dxva_ctx; +}; -/* DLL */ -static HINSTANCE hd3d9_dll; -static HINSTANCE hdxva2_dll; +typedef struct DXVADeviceHandle +{ + /* DLL */ + HINSTANCE hd3d9_dll; + HINSTANCE hdxva2_dll; + /* Direct3D */ + LPDIRECT3D9 d3dobj; + LPDIRECT3DDEVICE9 d3ddev; + + /* Device manager */ + IDirect3DDeviceManager9 *devmng; + HANDLE hd3ddev; + + /* Video service */ + IDirectXVideoDecoderService *vs; +} DXVADeviceHandle; +static DXVADeviceHandle *dxva_dev = &(DXVADeviceHandle) {}; static const dxva2_mode_t *Dxva2FindMode(const GUID *guid) { @@ -285,7 +288,7 @@ static int D3dCreateDevice(void) { /* */ LPDIRECT3D9 (WINAPI *Create9)(UINT SDKVersion); - Create9 = (void *)GetProcAddress(hd3d9_dll, "Direct3DCreate9"); + Create9 = (void *)GetProcAddress(dxva_dev->hd3d9_dll, "Direct3DCreate9"); if (!Create9) { ERR("Cannot locate reference to Direct3DCreate9 ABI in DLL\n"); return -1; @@ -298,22 +301,22 @@ static int D3dCreateDevice(void) ERR("Direct3DCreate9 failed\n"); return -1; } - dxva_ctx->d3dobj = d3dobj; + dxva_dev->d3dobj = d3dobj; /* */ - D3DPRESENT_PARAMETERS *d3dpp = &dxva_ctx->d3dpp; - ZeroMemory(d3dpp, sizeof(*d3dpp)); - d3dpp->Flags = D3DPRESENTFLAG_VIDEO; - d3dpp->Windowed = TRUE; - d3dpp->hDeviceWindow = NULL; - d3dpp->SwapEffect = D3DSWAPEFFECT_DISCARD; - d3dpp->MultiSampleType = D3DMULTISAMPLE_NONE; - d3dpp->PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; - d3dpp->BackBufferCount = 0; /* FIXME what to put here */ - d3dpp->BackBufferFormat = D3DFMT_X8R8G8B8; /* FIXME what to put here */ - d3dpp->BackBufferWidth = 0; - d3dpp->BackBufferHeight = 0; - d3dpp->EnableAutoDepthStencil = FALSE; + D3DPRESENT_PARAMETERS d3dpp; + ZeroMemory(&d3dpp, sizeof(d3dpp)); + d3dpp.Flags = D3DPRESENTFLAG_VIDEO; + d3dpp.Windowed = TRUE; + d3dpp.hDeviceWindow = NULL; + d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; + d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE; + d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; + d3dpp.BackBufferCount = 0; /* FIXME what to put here */ + d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8; /* FIXME what to put here */ + d3dpp.BackBufferWidth = 0; + d3dpp.BackBufferHeight = 0; + d3dpp.EnableAutoDepthStencil = FALSE; /* Direct3D needs a HWND to create a device, even without using ::Present this HWND is used to alert Direct3D when there's a change of focus window. @@ -323,11 +326,11 @@ static int D3dCreateDevice(void) D3DDEVTYPE_HAL, GetDesktopWindow(), D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED, - d3dpp, &d3ddev))) { + &d3dpp, &d3ddev))) { ERR("IDirect3D9_CreateDevice failed\n"); return -1; } - dxva_ctx->d3ddev = d3ddev; + dxva_dev->d3ddev = d3ddev; return 0; } @@ -340,7 +343,7 @@ static int D3dCreateDeviceManager(void) HRESULT (WINAPI *CreateDeviceManager9)(UINT *pResetToken, IDirect3DDeviceManager9 **); CreateDeviceManager9 = - (void *)GetProcAddress(hdxva2_dll, + (void *)GetProcAddress(dxva_dev->hdxva2_dll, "DXVA2CreateDirect3DDeviceManager9"); if (!CreateDeviceManager9) { @@ -356,10 +359,10 @@ static int D3dCreateDeviceManager(void) } TRACE("OurDirect3DCreateDeviceManager9 Success!\n"); - dxva_ctx->devmng = devmng; + dxva_dev->devmng = devmng; TRACE("obtained IDirect3DDeviceManager9\n"); - HRESULT hr = IDirect3DDeviceManager9_ResetDevice(devmng, dxva_ctx->d3ddev, token); + HRESULT hr = IDirect3DDeviceManager9_ResetDevice(devmng, dxva_dev->d3ddev, token); if (FAILED(hr)) { ERR("IDirect3DDeviceManager9_ResetDevice failed: %08x\n", (unsigned)hr); return -1; @@ -377,7 +380,7 @@ static int DxCreateVideoService(void) REFIID riid, void **ppService); CreateVideoService = - (void *)GetProcAddress(hdxva2_dll, "DXVA2CreateVideoService"); + (void *)GetProcAddress(dxva_dev->hdxva2_dll, "DXVA2CreateVideoService"); if (!CreateVideoService) { ERR("cannot load function\n"); @@ -388,21 +391,21 @@ static int DxCreateVideoService(void) HRESULT hr; HANDLE hd3ddev; - hr = IDirect3DDeviceManager9_OpenDeviceHandle(dxva_ctx->devmng, &hd3ddev); + hr = IDirect3DDeviceManager9_OpenDeviceHandle(dxva_dev->devmng, &hd3ddev); if (FAILED(hr)) { ERR("OpenDeviceHandle failed\n"); return -1; } - dxva_ctx->hd3ddev = hd3ddev; + dxva_dev->hd3ddev = hd3ddev; void *pv; - hr = IDirect3DDeviceManager9_GetVideoService(dxva_ctx->devmng, hd3ddev, + hr = IDirect3DDeviceManager9_GetVideoService(dxva_dev->devmng, hd3ddev, &IID_IDirectXVideoDecoderService, &pv); if (FAILED(hr)) { ERR("GetVideoService failed\n"); return -1; } - dxva_ctx->vs = pv; + dxva_dev->vs = pv; return 0; } @@ -410,7 +413,7 @@ static int DxCreateVideoService(void) /** * Find the best suited decoder mode GUID and render format. */ -static int DxFindVideoServiceConversion(int codec_id) +static int DxFindVideoServiceConversion(DXVAPluginContext *dxva_ctx, int codec_id) { unsigned i = 0; GUID *guid_decdev = &dxva_ctx->guid_decdev; @@ -419,7 +422,7 @@ static int DxFindVideoServiceConversion(int codec_id) /* Retreive supported modes from the decoder service */ UINT decdev_count = 0; GUID *guid_decdev_list = NULL; - if (FAILED(IDirectXVideoDecoderService_GetDecoderDeviceGuids(dxva_ctx->vs, + if (FAILED(IDirectXVideoDecoderService_GetDecoderDeviceGuids(dxva_dev->vs, &decdev_count, &guid_decdev_list))) { ERR("IDirectXVideoDecoderService_GetDecoderDeviceGuids failed\n"); @@ -459,7 +462,7 @@ static int DxFindVideoServiceConversion(int codec_id) INFO("Trying to use '%s' as input\n", mode->name); UINT render_fmt_count = 0; D3DFORMAT *render_fmt_list = NULL; - if (FAILED(IDirectXVideoDecoderService_GetDecoderRenderTargets(dxva_ctx->vs, mode->guid, + if (FAILED(IDirectXVideoDecoderService_GetDecoderRenderTargets(dxva_dev->vs, mode->guid, &render_fmt_count, &render_fmt_list))) { ERR("IDirectXVideoDecoderService_GetDecoderRenderTargets failed\n"); @@ -504,7 +507,7 @@ static int DxFindVideoServiceConversion(int codec_id) return -1; } -static void DxDestroyVideoDecoder(void) +static void DxDestroyVideoDecoder(DXVAPluginContext *dxva_ctx) { unsigned i = 0; @@ -522,7 +525,7 @@ static void DxDestroyVideoDecoder(void) /** * It creates a DXVA2 decoder using the given video format */ -static int DxCreateVideoDecoder(AVCodecContext *dec_ctx) +static int DxCreateVideoDecoder(DXVAPluginContext *dxva_ctx, AVCodecContext *dec_ctx) { int surface_count = 0; unsigned i = 0; @@ -556,7 +559,7 @@ static int DxCreateVideoDecoder(AVCodecContext *dec_ctx) if (surface_count > VA_DXVA2_MAX_SURFACE_COUNT) return -1; dxva_ctx->surface_count = surface_count; - if (FAILED(IDirectXVideoDecoderService_CreateSurface(dxva_ctx->vs, + if (FAILED(IDirectXVideoDecoderService_CreateSurface(dxva_dev->vs, dxva_ctx->surface_width, dxva_ctx->surface_height, dxva_ctx->surface_count - 1, @@ -570,10 +573,12 @@ static int DxCreateVideoDecoder(AVCodecContext *dec_ctx) dxva_ctx->surface_count = 0; return -1; } + + dxva_ctx->surface = g_malloc_n(dxva_ctx->surface_count, sizeof(DXVAPluginSurface)); for (i = 0; i < dxva_ctx->surface_count; i++) { - DXVAPluginSurface *surface = &dxva_ctx->surface[i]; - surface->d3d = dxva_ctx->hw_surface[i]; - surface->is_occupied = false; + dxva_ctx->surface[i].d3d = dxva_ctx->hw_surface[i]; + dxva_ctx->surface[i].is_occupied = false; + dxva_ctx->surface[i].dxva_ctx = dxva_ctx; } TRACE("IDirectXVideoAccelerationService_CreateSurface succeed with %d surfaces (%dx%d)\n", dxva_ctx->surface_count, width, height); @@ -603,7 +608,7 @@ static int DxCreateVideoDecoder(AVCodecContext *dec_ctx) /* List all configurations available for the decoder */ UINT cfg_count = 0; DXVA2_ConfigPictureDecode *cfg_list = NULL; - if (FAILED(IDirectXVideoDecoderService_GetDecoderConfigurations(dxva_ctx->vs, + if (FAILED(IDirectXVideoDecoderService_GetDecoderConfigurations(dxva_dev->vs, &dxva_ctx->guid_decdev, &dsc, NULL, @@ -647,7 +652,7 @@ static int DxCreateVideoDecoder(AVCodecContext *dec_ctx) /* Create the decoder */ IDirectXVideoDecoder *decoder; - if (FAILED(IDirectXVideoDecoderService_CreateVideoDecoder(dxva_ctx->vs, + if (FAILED(IDirectXVideoDecoderService_CreateVideoDecoder(dxva_dev->vs, &dxva_ctx->guid_decdev, &dsc, &dxva_ctx->cfg, @@ -662,7 +667,7 @@ static int DxCreateVideoDecoder(AVCodecContext *dec_ctx) return 0; } -static void DxCreateVideoConversion(void) +static void DxCreateVideoConversion(DXVAPluginContext *dxva_ctx) { unsigned int output = dxva_ctx->render_fmt; @@ -682,10 +687,10 @@ static void DxCreateVideoConversion(void) */ static void DxDestroyVideoService(void) { - if (dxva_ctx->hd3ddev) - IDirect3DDeviceManager9_CloseDeviceHandle(dxva_ctx->devmng, dxva_ctx->hd3ddev); - if (dxva_ctx->vs) - IDirectXVideoDecoderService_Release(dxva_ctx->vs); + if (dxva_dev->hd3ddev) + IDirect3DDeviceManager9_CloseDeviceHandle(dxva_dev->devmng, dxva_dev->hd3ddev); + if (dxva_dev->vs) + IDirectXVideoDecoderService_Release(dxva_dev->vs); } /** @@ -693,8 +698,8 @@ static void DxDestroyVideoService(void) */ static void D3dDestroyDeviceManager(void) { - if (dxva_ctx->devmng) - IDirect3DDeviceManager9_Release(dxva_ctx->devmng); + if (dxva_dev->devmng) + IDirect3DDeviceManager9_Release(dxva_dev->devmng); } /** @@ -702,10 +707,10 @@ static void D3dDestroyDeviceManager(void) */ static void D3dDestroyDevice(void) { - if (dxva_ctx->d3ddev) - IDirect3DDevice9_Release(dxva_ctx->d3ddev); - if (dxva_ctx->d3dobj) - IDirect3D9_Release(dxva_ctx->d3dobj); + if (dxva_dev->d3ddev) + IDirect3DDevice9_Release(dxva_dev->d3ddev); + if (dxva_dev->d3dobj) + IDirect3D9_Release(dxva_dev->d3dobj); } #if 0 @@ -776,38 +781,30 @@ static void copy_nv12(uint8_t *dst[3], int linesizes[4], static void maru_dxva2_close(void) { - DxDestroyVideoDecoder(); DxDestroyVideoService(); D3dDestroyDeviceManager(); D3dDestroyDevice(); - if (hdxva2_dll) { - FreeLibrary(hdxva2_dll); - hdxva2_dll = NULL; - } - if (hd3d9_dll) { - FreeLibrary(hd3d9_dll); - hd3d9_dll = NULL; + if (dxva_dev->hdxva2_dll) { + FreeLibrary(dxva_dev->hdxva2_dll); + dxva_dev->hdxva2_dll = NULL; } - - if (dxva_ctx->hw_context) { - free(dxva_ctx->hw_context); - dxva_ctx->hw_context = NULL; + if (dxva_dev->hd3d9_dll) { + FreeLibrary(dxva_dev->hd3d9_dll); + dxva_dev->hd3d9_dll = NULL; } - - //free(dxva_ctx); } static bool probe(void) { - if (hd3d9_dll == NULL || hdxva2_dll == NULL) { - hd3d9_dll = LoadLibrary(TEXT("D3D9.DLL")); - if (!hd3d9_dll) { + if (dxva_dev->hd3d9_dll == NULL || dxva_dev->hdxva2_dll == NULL) { + dxva_dev->hd3d9_dll = LoadLibrary(TEXT("D3D9.DLL")); + if (!dxva_dev->hd3d9_dll) { ERR("cannot load d3d9.dll\n"); goto error; } - hdxva2_dll = LoadLibrary(TEXT("DXVA2.DLL")); - if (!hdxva2_dll) { + dxva_dev->hdxva2_dll = LoadLibrary(TEXT("DXVA2.DLL")); + if (!dxva_dev->hdxva2_dll) { ERR("cannot load dxva2.dll\n"); goto error; } @@ -837,19 +834,32 @@ error: return false; } +static void cleanup(void *opaque) +{ + DXVAPluginContext *dxva_ctx = (DXVAPluginContext *)opaque; + + DxDestroyVideoDecoder(dxva_ctx); + + if (dxva_ctx->hw_context) { + g_free(dxva_ctx->hw_context); + } + + g_free(dxva_ctx); + +} + static void *dxva_setup(AVCodecContext *dec_ctx, int width, int height) { - if (DxFindVideoServiceConversion(dec_ctx->codec_id)) { + DXVAPluginContext *dxva_ctx = g_malloc0(sizeof(DXVAPluginContext)); + + if (DxFindVideoServiceConversion(dxva_ctx, dec_ctx->codec_id)) { ERR("DxFindVideoServiceConversion failed\n"); return NULL; } dxva_ctx->thread_count = dec_ctx->thread_count; - //TODO: destroy surface and decoder at avcontext deinit() - DxDestroyVideoDecoder(); - - if (DxCreateVideoDecoder(dec_ctx) < -1) { + if (DxCreateVideoDecoder(dxva_ctx, dec_ctx) < -1) { ERR("DxCreateVideoDecoder failed\n"); return NULL; } @@ -865,7 +875,7 @@ static void *dxva_setup(AVCodecContext *dec_ctx, int width, int height) dxva_ctx->hw_context->surface_count = dxva_ctx->surface_count; dxva_ctx->hw_context->surface = dxva_ctx->hw_surface; - DxCreateVideoConversion(); + DxCreateVideoConversion(dxva_ctx); return dxva_ctx; } @@ -874,10 +884,11 @@ static int dxva_get_surface(AVCodecContext *dec_ctx, AVFrame *frame) { unsigned i = 0; DXVAPluginSurface *surface = NULL; + DXVAPluginContext *dxva_ctx = (DXVAPluginContext *)get_plugin_context(dec_ctx); /* Check the device */ #if 0 - HRESULT hr = IDirect3DDeviceManager9_TestDevice(dxva_ctx->devmng, dxva_ctx->hd3ddev); + HRESULT hr = IDirect3DDeviceManager9_TestDevice(dxva_dev->devmng, dxva_dev->hd3ddev); if (hr == DXVA2_E_NEW_VIDEO_DEVICE) { if (DxResetVideoDecoder()) return -1; @@ -921,6 +932,7 @@ static void extract(void *dst, void *src) { AVFrame *frame = (AVFrame *)src; LPDIRECT3DSURFACE9 d3d = (LPDIRECT3DSURFACE9)(uintptr_t)frame->data[3]; + DXVAPluginContext *dxva_ctx = (DXVAPluginContext *)((DXVAPluginSurface *)frame->opaque)->dxva_ctx; /* */ assert(dxva_ctx->output == MAKEFOURCC('Y','V','1','2')); @@ -990,6 +1002,7 @@ CodecPlugin dxva_plugin = { .output_pix_fmt = PIX_FMT_YUV420P, .probe = probe, .setup = dxva_setup, + .cleanup = cleanup, .get_buffer = dxva_get_surface, .release_buffer = dxva_release_surface, .get_picture = extract,