forked from Mirrors/wine-wine
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
parent
16ac83bcbf
commit
717784efc9
|
@ -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);
|
return CONTAINING_RECORD(iface, struct quartz_vmr, renderer.filter.IBaseFilter_iface);
|
||||||
}
|
}
|
||||||
|
|
||||||
static DWORD VMR9_SendSampleData(struct quartz_vmr *This, VMR9PresentationInfo *info, LPBYTE data,
|
static HRESULT WINAPI VMR9_DoRenderSample(struct strmbase_renderer *iface, IMediaSample *sample)
|
||||||
DWORD size)
|
|
||||||
{
|
{
|
||||||
const BITMAPINFOHEADER *bmiHeader = get_bitmap_header(&This->renderer.sink.pin.mt);
|
struct quartz_vmr *filter = impl_from_IBaseFilter(&iface->filter.IBaseFilter_iface);
|
||||||
HRESULT hr = S_OK;
|
const HANDLE events[2] = {filter->run_event, filter->renderer.flush_event};
|
||||||
int width;
|
const BITMAPINFOHEADER *bitmap_header;
|
||||||
int height;
|
unsigned int data_size, width, depth;
|
||||||
D3DLOCKED_RECT lock;
|
REFERENCE_TIME start_time, end_time;
|
||||||
|
|
||||||
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};
|
|
||||||
VMR9PresentationInfo info = {};
|
VMR9PresentationInfo info = {};
|
||||||
LPBYTE pbSrcStream = NULL;
|
D3DLOCKED_RECT locked_rect;
|
||||||
long cbSrcStream = 0;
|
BYTE *data = NULL;
|
||||||
REFERENCE_TIME tStart, tStop;
|
|
||||||
HRESULT hr;
|
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 */
|
/* 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");
|
ERR("NO PRESENTER!!\n");
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = IMediaSample_GetTime(pSample, &tStart, &tStop);
|
info.dwFlags = VMR9Sample_SrcDstRectsValid;
|
||||||
if (FAILED(hr))
|
|
||||||
info.dwFlags = VMR9Sample_SrcDstRectsValid;
|
|
||||||
else
|
|
||||||
info.dwFlags = VMR9Sample_SrcDstRectsValid | VMR9Sample_TimeValid;
|
|
||||||
|
|
||||||
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;
|
info.dwFlags |= VMR9Sample_Discontinuity;
|
||||||
|
|
||||||
if (IMediaSample_IsPreroll(pSample) == S_OK)
|
if (IMediaSample_IsPreroll(sample) == S_OK)
|
||||||
info.dwFlags |= VMR9Sample_Preroll;
|
info.dwFlags |= VMR9Sample_Preroll;
|
||||||
|
|
||||||
if (IMediaSample_IsSyncPoint(pSample) == S_OK)
|
if (IMediaSample_IsSyncPoint(sample) == S_OK)
|
||||||
info.dwFlags |= VMR9Sample_SyncPoint;
|
info.dwFlags |= VMR9Sample_SyncPoint;
|
||||||
|
|
||||||
/* If we render ourselves, and this is a preroll sample, discard it */
|
/* 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;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
hr = IMediaSample_GetPointer(pSample, &pbSrcStream);
|
if (FAILED(hr = IMediaSample_GetPointer(sample, &data)))
|
||||||
if (FAILED(hr))
|
|
||||||
{
|
{
|
||||||
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;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
cbSrcStream = IMediaSample_GetActualDataLength(pSample);
|
if (height > 0)
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
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);
|
WaitForMultipleObjects(2, events, FALSE, INFINITE);
|
||||||
EnterCriticalSection(&This->renderer.csRenderLock);
|
EnterCriticalSection(&filter->renderer.csRenderLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
return hr;
|
return hr;
|
||||||
|
|
Loading…
Reference in New Issue