quartz/vmr9: Merge VMR9_SendSampleData() into VMR9_DoRenderSample().

Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
master
Zebediah Figura 2020-06-19 19:50:12 -05:00 committed by Alexandre Julliard
parent 16ac83bcbf
commit 717784efc9
1 changed files with 79 additions and 82 deletions

View File

@ -207,89 +207,41 @@ static inline struct quartz_vmr *impl_from_IBaseFilter(IBaseFilter *iface)
return CONTAINING_RECORD(iface, struct quartz_vmr, renderer.filter.IBaseFilter_iface);
}
static DWORD VMR9_SendSampleData(struct quartz_vmr *This, VMR9PresentationInfo *info, LPBYTE data,
DWORD size)
static HRESULT WINAPI VMR9_DoRenderSample(struct strmbase_renderer *iface, IMediaSample *sample)
{
const BITMAPINFOHEADER *bmiHeader = get_bitmap_header(&This->renderer.sink.pin.mt);
HRESULT hr = S_OK;
int width;
int height;
D3DLOCKED_RECT lock;
TRACE("%p %p %d\n", This, data, size);
width = bmiHeader->biWidth;
height = bmiHeader->biHeight;
hr = IDirect3DSurface9_LockRect(info->lpSurf, &lock, NULL, D3DLOCK_DISCARD);
if (FAILED(hr))
{
ERR("IDirect3DSurface9_LockRect failed (%x)\n",hr);
return hr;
}
if (height > 0) {
/* Bottom up image needs inverting */
lock.pBits = (char *)lock.pBits + (height * lock.Pitch);
while (height--)
{
lock.pBits = (char *)lock.pBits - lock.Pitch;
memcpy(lock.pBits, data, width * bmiHeader->biBitCount / 8);
data = data + width * bmiHeader->biBitCount / 8;
}
}
else if (lock.Pitch != width * bmiHeader->biBitCount / 8)
{
WARN("Slow path! %u/%u\n", lock.Pitch, width * bmiHeader->biBitCount/8);
while (height--)
{
memcpy(lock.pBits, data, width * bmiHeader->biBitCount / 8);
data = data + width * bmiHeader->biBitCount / 8;
lock.pBits = (char *)lock.pBits + lock.Pitch;
}
}
else memcpy(lock.pBits, data, size);
IDirect3DSurface9_UnlockRect(info->lpSurf);
hr = IVMRImagePresenter9_PresentImage(This->presenter, This->cookie, info);
return hr;
}
static HRESULT WINAPI VMR9_DoRenderSample(struct strmbase_renderer *iface, IMediaSample *pSample)
{
struct quartz_vmr *This = impl_from_IBaseFilter(&iface->filter.IBaseFilter_iface);
const HANDLE events[2] = {This->run_event, This->renderer.flush_event};
struct quartz_vmr *filter = impl_from_IBaseFilter(&iface->filter.IBaseFilter_iface);
const HANDLE events[2] = {filter->run_event, filter->renderer.flush_event};
const BITMAPINFOHEADER *bitmap_header;
unsigned int data_size, width, depth;
REFERENCE_TIME start_time, end_time;
VMR9PresentationInfo info = {};
LPBYTE pbSrcStream = NULL;
long cbSrcStream = 0;
REFERENCE_TIME tStart, tStop;
D3DLOCKED_RECT locked_rect;
BYTE *data = NULL;
HRESULT hr;
int height;
TRACE("%p %p\n", iface, pSample);
TRACE("filter %p, sample %p.\n", filter, sample);
/* It is possible that there is no device at this point */
if (!This->allocator || !This->presenter)
if (!filter->allocator || !filter->presenter)
{
ERR("NO PRESENTER!!\n");
return S_FALSE;
}
hr = IMediaSample_GetTime(pSample, &tStart, &tStop);
if (FAILED(hr))
info.dwFlags = VMR9Sample_SrcDstRectsValid;
else
info.dwFlags = VMR9Sample_SrcDstRectsValid | VMR9Sample_TimeValid;
info.dwFlags = VMR9Sample_SrcDstRectsValid;
if (IMediaSample_IsDiscontinuity(pSample) == S_OK)
if (SUCCEEDED(hr = IMediaSample_GetTime(sample, &start_time, &end_time)))
info.dwFlags |= VMR9Sample_TimeValid;
if (IMediaSample_IsDiscontinuity(sample) == S_OK)
info.dwFlags |= VMR9Sample_Discontinuity;
if (IMediaSample_IsPreroll(pSample) == S_OK)
if (IMediaSample_IsPreroll(sample) == S_OK)
info.dwFlags |= VMR9Sample_Preroll;
if (IMediaSample_IsSyncPoint(pSample) == S_OK)
if (IMediaSample_IsSyncPoint(sample) == S_OK)
info.dwFlags |= VMR9Sample_SyncPoint;
/* If we render ourselves, and this is a preroll sample, discard it */
@ -298,28 +250,73 @@ static HRESULT WINAPI VMR9_DoRenderSample(struct strmbase_renderer *iface, IMedi
return S_OK;
}
hr = IMediaSample_GetPointer(pSample, &pbSrcStream);
if (FAILED(hr))
if (FAILED(hr = IMediaSample_GetPointer(sample, &data)))
{
ERR("Cannot get pointer to sample data (%x)\n", hr);
ERR("Failed to get pointer to sample data, hr %#x.\n", hr);
return hr;
}
data_size = IMediaSample_GetActualDataLength(sample);
bitmap_header = get_bitmap_header(&filter->renderer.sink.pin.mt);
width = bitmap_header->biWidth;
height = bitmap_header->biHeight;
depth = bitmap_header->biBitCount;
info.rtStart = start_time;
info.rtEnd = end_time;
info.szAspectRatio.cx = width;
info.szAspectRatio.cy = height;
info.lpSurf = filter->surfaces[(++filter->cur_surface) % filter->num_surfaces];
if (FAILED(hr = IDirect3DSurface9_LockRect(info.lpSurf, &locked_rect, NULL, D3DLOCK_DISCARD)))
{
ERR("Failed to lock surface, hr %#x.\n", hr);
return hr;
}
cbSrcStream = IMediaSample_GetActualDataLength(pSample);
info.rtStart = tStart;
info.rtEnd = tStop;
info.szAspectRatio.cx = This->bmiheader.biWidth;
info.szAspectRatio.cy = This->bmiheader.biHeight;
info.lpSurf = This->surfaces[(++This->cur_surface) % This->num_surfaces];
VMR9_SendSampleData(This, &info, pbSrcStream, cbSrcStream);
if (This->renderer.filter.state == State_Paused)
if (height > 0)
{
LeaveCriticalSection(&This->renderer.csRenderLock);
BYTE *dst = (BYTE *)locked_rect.pBits + (height * locked_rect.Pitch);
const BYTE *src = data;
TRACE("Inverting image.\n");
while (height--)
{
dst -= locked_rect.Pitch;
memcpy(dst, src, width * depth / 8);
src += width * depth / 8;
}
}
else if (locked_rect.Pitch != width * depth / 8)
{
BYTE *dst = locked_rect.pBits;
const BYTE *src = data;
TRACE("Source pitch %u does not match dest pitch %u; copying manually.\n",
width * depth / 8, locked_rect.Pitch);
while (height--)
{
memcpy(dst, src, width * depth / 8);
src += width * depth / 8;
dst += locked_rect.Pitch;
}
}
else
{
memcpy(locked_rect.pBits, data, data_size);
}
IDirect3DSurface9_UnlockRect(info.lpSurf);
hr = IVMRImagePresenter9_PresentImage(filter->presenter, filter->cookie, &info);
if (filter->renderer.filter.state == State_Paused)
{
LeaveCriticalSection(&filter->renderer.csRenderLock);
WaitForMultipleObjects(2, events, FALSE, INFINITE);
EnterCriticalSection(&This->renderer.csRenderLock);
EnterCriticalSection(&filter->renderer.csRenderLock);
}
return hr;