Skip to content

Commit

Permalink
[WIN] Fix zoom with separated convolution scaler and refactor/improve…
Browse files Browse the repository at this point in the history
… the coordinates cropping function
  • Loading branch information
CrystalP authored and CrystalP committed Oct 5, 2011
2 parents 5ca608b + a1c9d92 commit 80fb239
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 65 deletions.
23 changes: 18 additions & 5 deletions xbmc/cores/VideoRenderers/VideoShaders/WinVideoFilter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
#include <map>
#include "ConvolutionKernels.h"
#include "YUV2RGBShader.h"

#include "win32/WIN32Util.h"

CYUV2RGBMatrix::CYUV2RGBMatrix()
{
Expand Down Expand Up @@ -733,8 +733,19 @@ void CConvolutionShaderSeparable::PrepareParameters(unsigned int sourceWidth, un
CUSTOMVERTEX* v;
CWinShader::LockVertexBuffer((void**)&v);

// Alter rectangles the destination rectangle exceeds the intermediate target width when zooming and causes artifacts.
// Work on the parameters rather than the members to avoid disturbing the parameter change detection the next time the function is called
CRect tgtRect(0, 0, destWidth, destHeight);
CWIN32Util::CropSource(sourceRect, destRect, tgtRect);

// Manipulate the coordinates to work only on the active parts of the textures,
// and therefore avoid the need to clear surfaces/render targets

// Pass 1:
// Horizontal dimension: crop/zoom, so that it is completely done with the convolution shader. Scaling to display width in pass1 and
// cropping/zooming in pass 2 would use bilinear in pass2, which we don't want.
// Vertical dimension: crop using sourceRect to save memory bandwidth for high zoom values, but don't stretch/shrink in any way in this pass.

v[0].x = 0;
v[0].y = 0;
v[0].tu = sourceRect.x1 / sourceWidth;
Expand All @@ -755,25 +766,27 @@ void CConvolutionShaderSeparable::PrepareParameters(unsigned int sourceWidth, un
v[3].tu = sourceRect.x1 / sourceWidth;
v[3].tv = sourceRect.y2 / sourceHeight;

// Pass 2: pass the horizontal data untouched, resize vertical dimension for final result.

v[4].x = destRect.x1;
v[4].y = destRect.y1;
v[4].tu = 0;
v[4].tv = 0;

v[5].x = destRect.x2;
v[5].y = destRect.y1;
v[5].tu = (destRect.x2 - destRect.x1) / m_destWidth;
v[5].tu = (destRect.x2 - destRect.x1) / destWidth;
v[5].tv = 0;

v[6].x = destRect.x2;
v[6].y = destRect.y2;
v[6].tu = (destRect.x2 - destRect.x1) / m_destWidth;
v[6].tv = (sourceRect.y2 - sourceRect.y1) / m_sourceHeight;
v[6].tu = (destRect.x2 - destRect.x1) / destWidth;
v[6].tv = (sourceRect.y2 - sourceRect.y1) / sourceHeight;

v[7].x = destRect.x1;
v[7].y = destRect.y2;
v[7].tu = 0;
v[7].tv = (sourceRect.y2 - sourceRect.y1) / m_sourceHeight;
v[7].tv = (sourceRect.y2 - sourceRect.y1) / sourceHeight;

// -0.5 offset to compensate for D3D rasterization
// set z and rhw
Expand Down
67 changes: 15 additions & 52 deletions xbmc/cores/VideoRenderers/WinRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "DllSwScale.h"
#include "guilib/LocalizeStrings.h"
#include "dialogs/GUIDialogKaiToast.h"
#include "win32/WIN32Util.h"

typedef struct {
RenderMethod method;
Expand Down Expand Up @@ -634,38 +635,6 @@ void CWinRenderer::UpdateVideoFilter()
}
}

void CWinRenderer::CropSource(RECT& src, RECT& dst, const D3DSURFACE_DESC& desc)
{
if(dst.left < 0)
{
src.left -= dst.left
* (src.right - src.left)
/ (dst.right - dst.left);
dst.left = 0;
}
if(dst.top < 0)
{
src.top -= dst.top
* (src.bottom - src.top)
/ (dst.bottom - dst.top);
dst.top = 0;
}
if(dst.right > (LONG)desc.Width)
{
src.right -= (dst.right - desc.Width)
* (src.right - src.left)
/ (dst.right - dst.left);
dst.right = desc.Width;
}
if(dst.bottom > (LONG)desc.Height)
{
src.bottom -= (dst.bottom - desc.Height)
* (src.bottom - src.top)
/ (dst.bottom - dst.top);
dst.bottom = desc.Height;
}
}

void CWinRenderer::Render(DWORD flags)
{
if (m_renderMethod == RENDER_DXVA)
Expand Down Expand Up @@ -769,23 +738,27 @@ void CWinRenderer::ScaleStretchRect()
// m_StretchRectSupported = true;
//}
RECT srcRect = { m_sourceRect.x1, m_sourceRect.y1, m_sourceRect.x2, m_sourceRect.y2 };
CRect sourceRect = m_sourceRect;
CRect destRect = m_destRect;
D3DSURFACE_DESC desc;
if (FAILED(target->GetDesc(&desc)))
CLog::Log(LOGERROR, "CWinRenderer::Render - failed to get back buffer description");
CRect tgtRect(0, 0, desc.Width, desc.Height);
// Need to manipulate the coordinates since StretchRect doesn't accept off-screen coordinates.
CWIN32Util::CropSource(sourceRect, destRect, tgtRect);
RECT srcRect = { sourceRect.x1, sourceRect.y1, sourceRect.x2, sourceRect.y2 };
IDirect3DSurface9* source;
if(!m_SWTarget.GetSurfaceLevel(0, &source))
CLog::Log(LOGERROR, "CWinRenderer::Render - failed to get source");
RECT dstRect = { m_destRect.x1, m_destRect.y1, m_destRect.x2, m_destRect.y2 };
RECT dstRect = { destRect.x1, destRect.y1, destRect.x2, destRect.y2 };
IDirect3DSurface9* target;
if(FAILED(g_Windowing.Get3DDevice()->GetRenderTarget(0, &target)))
CLog::Log(LOGERROR, "CWinRenderer::Render - failed to get back buffer");
D3DSURFACE_DESC desc;
if (FAILED(target->GetDesc(&desc)))
CLog::Log(LOGERROR, "CWinRenderer::Render - failed to get back buffer description");
// Need to manipulate the coordinates since StretchRect doesn't accept off-screen coordinates.
CropSource(srcRect, dstRect, desc);
HRESULT hr;
LPDIRECT3DDEVICE9 pD3DDevice = g_Windowing.Get3DDevice();
Expand Down Expand Up @@ -947,16 +920,6 @@ void CWinRenderer::RenderProcessor(DWORD flags)
{
CSingleLock lock(g_graphicsContext);
HRESULT hr;
RECT sourceRect;
sourceRect.top = m_sourceRect.y1;
sourceRect.bottom = m_sourceRect.y2;
sourceRect.left = m_sourceRect.x1;
sourceRect.right = m_sourceRect.x2;
RECT destRect;
destRect.top = m_destRect.y1;
destRect.bottom = m_destRect.y2;
destRect.left = m_destRect.x1;
destRect.right = m_destRect.x2;

DXVABuffer *image = (DXVABuffer*)m_VideoBuffers[m_iYV12RenderBuffer];

Expand All @@ -967,7 +930,7 @@ void CWinRenderer::RenderProcessor(DWORD flags)
return;
}

m_processor.Render(sourceRect, destRect, target, image->id, flags);
m_processor.Render(m_sourceRect, m_destRect, target, image->id, flags);

target->Release();
}
Expand Down
2 changes: 0 additions & 2 deletions xbmc/cores/VideoRenderers/WinRenderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,6 @@ class CWinRenderer : public CBaseRenderer

virtual unsigned int GetProcessorSize() { return m_processor.Size(); }

static void CropSource(RECT& src, RECT& dst, const D3DSURFACE_DESC& desc);

protected:
virtual void Render(DWORD flags);
void RenderSW();
Expand Down
14 changes: 9 additions & 5 deletions xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#include "utils/AutoPtrHandle.h"
#include "settings/AdvancedSettings.h"
#include "cores/VideoRenderers/RenderManager.h"
#include "win32/WIN32Util.h"

#define ALLOW_ADDING_SURFACES 0

Expand Down Expand Up @@ -1395,7 +1396,7 @@ static DXVA2_Fixed32 ConvertRange(const DXVA2_ValueRange& range, int value, int
return range.DefaultValue;
}

bool CProcessor::Render(RECT src, RECT dst, IDirect3DSurface9* target, REFERENCE_TIME time, DWORD flags)
bool CProcessor::Render(CRect src, CRect dst, IDirect3DSurface9* target, REFERENCE_TIME time, DWORD flags)
{
CSingleLock lock(m_section);

Expand Down Expand Up @@ -1439,8 +1440,11 @@ bool CProcessor::Render(RECT src, RECT dst, IDirect3DSurface9* target, REFERENCE

D3DSURFACE_DESC desc;
CHECK(target->GetDesc(&desc));
CRect rectTarget(0, 0, desc.Width, desc.Height);
CWIN32Util::CropSource(src, dst, rectTarget);
RECT sourceRECT = { src.x1, src.y1, src.x2, src.y2 };
RECT dstRECT = { dst.x1, dst.y1, dst.x2, dst.y2 };

CWinRenderer::CropSource(src, dst, desc);

// How to prepare the samples array for VideoProcessBlt
// - always provide current picture + the number of forward and backward references required by the current processor.
Expand All @@ -1460,8 +1464,8 @@ bool CProcessor::Render(RECT src, RECT dst, IDirect3DSurface9* target, REFERENCE
{
DXVA2_VideoSample& vs = samp[(it->sample.Start - MinTime) / 2];
vs = it->sample;
vs.SrcRect = src;
vs.DstRect = dst;
vs.SrcRect = sourceRECT;
vs.DstRect = dstRECT;
if(vs.End == 0)
vs.End = vs.Start + 2;

Expand Down Expand Up @@ -1500,7 +1504,7 @@ bool CProcessor::Render(RECT src, RECT dst, IDirect3DSurface9* target, REFERENCE
blt.TargetFrame = time;
if (flags & RENDER_FLAG_FIELD1)
blt.TargetFrame += 1;
blt.TargetRect = dst;
blt.TargetRect = dstRECT;
blt.ConstrictionSize.cx = 0;
blt.ConstrictionSize.cy = 0;

Expand Down
3 changes: 2 additions & 1 deletion xbmc/cores/dvdplayer/DVDCodecs/Video/DXVA.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <deque>
#include <vector>
#include "settings/VideoSettings.h"
#include "guilib/Geometry.h"

namespace DXVA {

Expand Down Expand Up @@ -123,7 +124,7 @@ class CProcessor
bool Open(UINT width, UINT height, unsigned int flags, unsigned int format);
void Close();
REFERENCE_TIME Add(DVDVideoPicture* picture);
bool Render(RECT src, RECT dst, IDirect3DSurface9* target, const REFERENCE_TIME time, DWORD flags);
bool Render(CRect src, CRect dst, IDirect3DSurface9* target, const REFERENCE_TIME time, DWORD flags);
unsigned Size() { if (m_service) return m_size; return 0; }

virtual void OnCreateDevice() {}
Expand Down
33 changes: 33 additions & 0 deletions xbmc/win32/WIN32Util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1421,6 +1421,39 @@ bool CWIN32Util::GetFocussedProcess(CStdString &strProcessFile)
return true;
}

// Adjust the src rectangle so that the dst is always contained in the target rectangle.
void CWIN32Util::CropSource(CRect& src, CRect& dst, CRect target)
{
if(dst.x1 < target.x1)
{
src.x1 -= (dst.x1 - target.x1)
* (src.x2 - src.x1)
/ (dst.x2 - dst.x1);
dst.x1 = target.x1;
}
if(dst.y1 < target.y1)
{
src.y1 -= (dst.y1 - target.y1)
* (src.y2 - src.y1)
/ (dst.y2 - dst.y1);
dst.y1 = target.y1;
}
if(dst.x2 > target.x2)
{
src.x2 -= (dst.x2 - target.x2)
* (src.x2 - src.x1)
/ (dst.x2 - dst.x1);
dst.x2 = target.x2;
}
if(dst.y2 > target.y2)
{
src.y2 -= (dst.y2 - target.y2)
* (src.y2 - src.y1)
/ (dst.y2 - dst.y1);
dst.y2 = target.y2;
}
}

void CWinIdleTimer::StartZero()
{
SetThreadExecutionState(ES_SYSTEM_REQUIRED);
Expand Down
2 changes: 2 additions & 0 deletions xbmc/win32/WIN32Util.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#endif
#include "MediaSource.h"
#include "utils/Stopwatch.h"
#include "guilib/Geometry.h"

enum Drive_Types
{
Expand Down Expand Up @@ -80,6 +81,7 @@ class CWIN32Util
static bool GetCrystalHDLibraryPath(CStdString &strPath);

static bool GetFocussedProcess(CStdString &strProcessFile);
static void CropSource(CRect& src, CRect& dst, CRect target);

private:
#if _MSC_VER > 1400
Expand Down

0 comments on commit 80fb239

Please sign in to comment.