quartz/vmr9: Cache surfaces on connection.
How to Survive does not reference the IDirect3DSurface9 in IVMRSurfaceAllocator9::GetSurface(), nor does it dereference it in IVMRSurfaceAllocator9::TerminateDevice(). Native quartz only asks for each surface once, when connecting, and releases those surfaces when disconnecting, which lets these two application bugs cancel each other out. Signed-off-by: Zebediah Figura <zfigura@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
01f83593ed
commit
d6a70366e1
|
@ -75,6 +75,7 @@ struct quartz_vmr
|
||||||
/* Presentation related members */
|
/* Presentation related members */
|
||||||
IDirect3DDevice9 *allocator_d3d9_dev;
|
IDirect3DDevice9 *allocator_d3d9_dev;
|
||||||
HMONITOR allocator_mon;
|
HMONITOR allocator_mon;
|
||||||
|
IDirect3DSurface9 **surfaces;
|
||||||
DWORD num_surfaces;
|
DWORD num_surfaces;
|
||||||
DWORD cur_surface;
|
DWORD cur_surface;
|
||||||
DWORD_PTR cookie;
|
DWORD_PTR cookie;
|
||||||
|
@ -312,14 +313,9 @@ static HRESULT WINAPI VMR9_DoRenderSample(struct strmbase_renderer *iface, IMedi
|
||||||
info.rtEnd = tStop;
|
info.rtEnd = tStop;
|
||||||
info.szAspectRatio.cx = This->bmiheader.biWidth;
|
info.szAspectRatio.cx = This->bmiheader.biWidth;
|
||||||
info.szAspectRatio.cy = This->bmiheader.biHeight;
|
info.szAspectRatio.cy = This->bmiheader.biHeight;
|
||||||
|
info.lpSurf = This->surfaces[(++This->cur_surface) % This->num_surfaces];
|
||||||
hr = IVMRSurfaceAllocatorEx9_GetSurface(This->allocator, This->cookie, (++This->cur_surface)%This->num_surfaces, 0, &info.lpSurf);
|
|
||||||
|
|
||||||
if (FAILED(hr))
|
|
||||||
return hr;
|
|
||||||
|
|
||||||
VMR9_SendSampleData(This, &info, pbSrcStream, cbSrcStream);
|
VMR9_SendSampleData(This, &info, pbSrcStream, cbSrcStream);
|
||||||
IDirect3DSurface9_Release(info.lpSurf);
|
|
||||||
|
|
||||||
if (This->renderer.filter.state == State_Paused)
|
if (This->renderer.filter.state == State_Paused)
|
||||||
{
|
{
|
||||||
|
@ -351,7 +347,7 @@ static HRESULT WINAPI VMR9_CheckMediaType(struct strmbase_renderer *iface, const
|
||||||
|
|
||||||
static HRESULT initialize_device(struct quartz_vmr *filter, VMR9AllocationInfo *info)
|
static HRESULT initialize_device(struct quartz_vmr *filter, VMR9AllocationInfo *info)
|
||||||
{
|
{
|
||||||
DWORD buffer_count = 1;
|
DWORD buffer_count = 1, i;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
if (FAILED(hr = IVMRSurfaceAllocatorEx9_InitializeDevice(filter->allocator,
|
if (FAILED(hr = IVMRSurfaceAllocatorEx9_InitializeDevice(filter->allocator,
|
||||||
|
@ -361,6 +357,25 @@ static HRESULT initialize_device(struct quartz_vmr *filter, VMR9AllocationInfo *
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(filter->surfaces = calloc(buffer_count, sizeof(IDirect3DSurface9 *))))
|
||||||
|
{
|
||||||
|
IVMRSurfaceAllocatorEx9_TerminateDevice(filter->allocator, filter->cookie);
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < buffer_count; ++i)
|
||||||
|
{
|
||||||
|
if (FAILED(hr = IVMRSurfaceAllocatorEx9_GetSurface(filter->allocator,
|
||||||
|
filter->cookie, i, 0, &filter->surfaces[i])))
|
||||||
|
{
|
||||||
|
ERR("Failed to get surface %u, hr %#x.\n", i, hr);
|
||||||
|
while (i--)
|
||||||
|
IDirect3DSurface9_Release(filter->surfaces[i]);
|
||||||
|
IVMRSurfaceAllocatorEx9_TerminateDevice(filter->allocator, filter->cookie);
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SetRect(&filter->source_rect, 0, 0, filter->bmiheader.biWidth, filter->bmiheader.biHeight);
|
SetRect(&filter->source_rect, 0, 0, filter->bmiheader.biWidth, filter->bmiheader.biHeight);
|
||||||
filter->num_surfaces = buffer_count;
|
filter->num_surfaces = buffer_count;
|
||||||
|
|
||||||
|
@ -538,6 +553,7 @@ static HRESULT WINAPI VMR9_BreakConnect(struct strmbase_renderer *This)
|
||||||
{
|
{
|
||||||
struct quartz_vmr *pVMR9 = impl_from_IBaseFilter(&This->filter.IBaseFilter_iface);
|
struct quartz_vmr *pVMR9 = impl_from_IBaseFilter(&This->filter.IBaseFilter_iface);
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr = S_OK;
|
||||||
|
DWORD i;
|
||||||
|
|
||||||
if (!pVMR9->mode)
|
if (!pVMR9->mode)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
|
@ -549,6 +565,10 @@ static HRESULT WINAPI VMR9_BreakConnect(struct strmbase_renderer *This)
|
||||||
}
|
}
|
||||||
if (pVMR9->renderer.filter.state == State_Running)
|
if (pVMR9->renderer.filter.state == State_Running)
|
||||||
hr = IVMRImagePresenter9_StopPresenting(pVMR9->presenter, pVMR9->cookie);
|
hr = IVMRImagePresenter9_StopPresenting(pVMR9->presenter, pVMR9->cookie);
|
||||||
|
|
||||||
|
for (i = 0; i < pVMR9->num_surfaces; ++i)
|
||||||
|
IDirect3DSurface9_Release(pVMR9->surfaces[i]);
|
||||||
|
free(pVMR9->surfaces);
|
||||||
IVMRSurfaceAllocatorEx9_TerminateDevice(pVMR9->allocator, pVMR9->cookie);
|
IVMRSurfaceAllocatorEx9_TerminateDevice(pVMR9->allocator, pVMR9->cookie);
|
||||||
pVMR9->num_surfaces = 0;
|
pVMR9->num_surfaces = 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue