+++ /dev/null
-/*
- * Copyright (C) 2005-2013 Team XBMC
- * http://xbmc.org
- *
- * This Program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This Program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with XBMC; see the file COPYING. If not, see
- * <http://www.gnu.org/licenses/>.
- *
- */
-
-#include "stdafx.h"
-#include "ComboRenderer.h"
-#include "Application.h"
-#include "settings/Settings.h"
-#include "settings/DisplaySettings.h"
-
-CComboRenderer::CComboRenderer(LPDIRECT3DDEVICE8 pDevice)
- : CXBoxRenderer(pDevice)
-{
- m_bHasDimView = false;
- m_RGBSurface[0] = NULL;
- m_RGBSurface[1] = NULL;
- m_YUY2Texture[0] = NULL;
- m_YUY2Texture[1] = NULL;
- m_hPixelShader = 0;
- m_iYUY2RenderBuffer = 0;
- m_iYUY2Buffers = 2;
- m_iScreenWidth = 0;
- m_iScreenHeight = 0;
-}
-
-void CComboRenderer::DeleteYUY2Texture(int index)
-{
- CSingleLock lock(g_graphicsContext);
- if (m_RGBSurface[index])
- SAFE_RELEASE(m_RGBSurface[index]);
-
- if (m_YUY2Texture[index])
- {
- SAFE_RELEASE(m_YUY2Texture[index]);
- CLog::Log(LOGDEBUG, "Deleted yuy2 textures (%d)", index);
- }
-}
-
-void CComboRenderer::ClearYUY2Texture(int index)
-{
- D3DLOCKED_RECT lr;
- // Clear our RGB/YUY2 texture
- m_RGBSurface[index]->LockRect(&lr, NULL, 0);
- memset(lr.pBits, 0x00800080, lr.Pitch*m_iSourceHeight);
- m_RGBSurface[index]->UnlockRect();
-}
-
-bool CComboRenderer::CreateYUY2Texture(int index)
-{
- CSingleLock lock(g_graphicsContext);
- DeleteYUY2Texture(index);
- // Create our textures...
-
- if (D3D_OK != m_pD3DDevice->CreateTexture(m_iSourceWidth, m_iSourceHeight, 1, 0, D3DFMT_YUY2, 0, &m_YUY2Texture[index]))
- return false;
-
- m_YUY2Texture[index]->GetSurfaceLevel(0, &m_RGBSurface[index]);
- m_RGBSurface[index]->Format &= ~D3DFORMAT_FORMAT_MASK;
- m_RGBSurface[index]->Format |= D3DFMT_LIN_A8R8G8B8 << D3DFORMAT_FORMAT_SHIFT;
-
- m_RGBSurface[index]->Size &= ~D3DSIZE_WIDTH_MASK;
- m_RGBSurface[index]->Size |= ((m_iSourceWidth>>1) - 1) & D3DSIZE_WIDTH_MASK;
-
- ClearYUY2Texture(index);
- CLog::Log(LOGDEBUG, "Created yuy2 textures (%d)", index);
- return true;
-}
-
-void CComboRenderer::ManageTextures()
-{
- //use 1 buffer in fullscreen mode and 0 buffers in windowed mode
- if (g_graphicsContext.IsFullScreenVideo())
- {
- m_iYUY2Buffers = 2;
-
- if (!m_RGBSurface[0] && m_iYUY2Buffers > 0)
- CreateYUY2Texture(0);
- if (!m_RGBSurface[1] && m_iYUY2Buffers > 1)
- CreateYUY2Texture(1);
-
- if(m_iYV12RenderBuffer >= m_iYUY2Buffers)
- m_iYV12RenderBuffer = 0;
- }
- else
- {
- m_iYUY2Buffers = 0;
-
- if (m_RGBSurface[0])
- DeleteYUY2Texture(0);
-
- if (m_RGBSurface[1])
- DeleteYUY2Texture(1);
- }
-
- CXBoxRenderer::ManageTextures();
-}
-
-void CComboRenderer::ManageDisplay()
-{
- const RECT& rv = g_graphicsContext.GetViewWindow();
- float fScreenWidth = (float)rv.right - rv.left;
- float fScreenHeight = (float)rv.bottom - rv.top;
- float fOffsetX1 = (float)rv.left;
- float fOffsetY1 = (float)rv.top;
- float fPixelRatio = CDisplaySettings::Get().GetPixelRatio();
- float fMaxScreenWidth = (float)CDisplaySettings::Get().GetResolutionInfo(g_graphicsContext.GetVideoResolution()).iWidth;
- float fMaxScreenHeight = (float)CDisplaySettings::Get().GetResolutionInfo(g_graphicsContext.GetVideoResolution()).iHeight;
- if (fOffsetX1 < 0) fOffsetX1 = 0;
- if (fOffsetY1 < 0) fOffsetY1 = 0;
- if (fScreenWidth + fOffsetX1 > fMaxScreenWidth) fScreenWidth = fMaxScreenWidth - fOffsetX1;
- if (fScreenHeight + fOffsetY1 > fMaxScreenHeight) fScreenHeight = fMaxScreenHeight - fOffsetY1;
-
- // Correct for HDTV_1080i -> 540p
- if (GetResolution() == HDTV_1080i)
- {
- fOffsetY1 /= 2;
- fScreenHeight /= 2;
- fPixelRatio *= 2;
- }
-
- // source rect
- rs.left = CMediaSettings::Get().GetCurrentVideoSettings().m_CropLeft;
- rs.top = CMediaSettings::Get().GetCurrentVideoSettings().m_CropTop;
- rs.right = m_iSourceWidth - CMediaSettings::Get().GetCurrentVideoSettings().m_CropRight;
- rs.bottom = m_iSourceHeight - CMediaSettings::Get().GetCurrentVideoSettings().m_CropBottom;
-
- CalcNormalDisplayRect(fOffsetX1, fOffsetY1, fScreenWidth, fScreenHeight, GetAspectRatio() * fPixelRatio, CDisplaySettings::Get().GetZoomAmount());
-
- // check whether we need to alter our source rect
- if (rd.left < fOffsetX1 || rd.right > fOffsetX1 + fScreenWidth)
- {
- // wants to be wider than we allow, so fix
- float fRequiredWidth = (float)rd.right - rd.left;
- if (rs.right <= rs.left) rs.right = rs.left+1;
- float fHorizScale = fRequiredWidth / (float)(rs.right - rs.left);
- float fNewWidth = fScreenWidth / fHorizScale;
- rs.left = (rs.right - rs.left - (int)fNewWidth) / 2;
- rs.right = rs.left + (int)fNewWidth;
- rd.left = (int)fOffsetX1;
- rd.right = (int)(fOffsetX1 + fScreenWidth);
- }
- if (rd.top < fOffsetY1 || rd.bottom > fOffsetY1 + fScreenHeight)
- {
- // wants to be wider than we allow, so fix
- float fRequiredHeight = (float)rd.bottom - rd.top;
- if (rs.bottom <= rs.top) rs.bottom = rs.top+1;
- float fVertScale = fRequiredHeight / (float)(rs.bottom - rs.top);
- float fNewHeight = fScreenHeight / fVertScale;
- rs.top = (rs.bottom - rs.top - (int)fNewHeight) / 2;
- rs.bottom = rs.top + (int)fNewHeight;
- rd.top = (int)fOffsetY1;
- rd.bottom = (int)(fOffsetY1 + fScreenHeight);
- }
-}
-
-bool CComboRenderer::Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags)
-{
- if(!CXBoxRenderer::Configure(width, height, d_width, d_height, fps, flags))
- return false;
-
- m_bConfigured = true;
- return true;
-}
-
-void CComboRenderer::Update(bool bPauseDrawing)
-{
- if(!m_bConfigured) return;
- CSingleLock lock(g_graphicsContext);
-
- if(g_graphicsContext.IsFullScreenVideo() || g_graphicsContext.IsCalibrating())
- m_pD3DDevice->EnableOverlay(!bPauseDrawing);
- else
- m_pD3DDevice->EnableOverlay(FALSE);
-
- CXBoxRenderer::Update(bPauseDrawing);
-}
-
-void CComboRenderer::FlipPage(int source)
-{
- if(m_iYUY2Buffers)
- m_iYUY2RenderBuffer = ++m_iYUY2RenderBuffer % m_iYUY2Buffers;
-
- CXBoxRenderer::FlipPage(source);
-}
-
-void CComboRenderer::YV12toYUY2()
-{
- int index = m_iYV12RenderBuffer;
- if (!m_RGBSurface[m_iYUY2RenderBuffer]) return;
-
- /* if we have dimmed our texture, don't overwrite it */
- if( g_application.IsInScreenSaver() && m_bHasDimView ) return;
-
- if( WaitForSingleObject(m_eventTexturesDone[index], 500) == WAIT_TIMEOUT )
- CLog::Log(LOGWARNING, __FUNCTION__" - Timeout waiting for texture %d", index);
-
- // Do the YV12 -> YUY2 conversion.
- // ALWAYS use buffer 0 in this case (saves 12 bits/pixel)
- m_pD3DDevice->SetTexture( 0, m_YUVTexture[index][FIELD_FULL][PLANE_Y] );
- m_pD3DDevice->SetTexture( 1, m_YUVTexture[index][FIELD_FULL][PLANE_U] );
- m_pD3DDevice->SetTexture( 2, m_YUVTexture[index][FIELD_FULL][PLANE_Y] );
- m_pD3DDevice->SetTexture( 3, m_YUVTexture[index][FIELD_FULL][PLANE_V] );
-
- for (int i = 0; i < 4; ++i)
- {
- m_pD3DDevice->SetTextureStageState( i, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP );
- m_pD3DDevice->SetTextureStageState( i, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP );
- m_pD3DDevice->SetTextureStageState( i, D3DTSS_MAGFILTER, D3DTEXF_POINT );
- m_pD3DDevice->SetTextureStageState( i, D3DTSS_MINFILTER, D3DTEXF_POINT );
- }
- // U and V need to use linear filtering, as they're being doubled vertically
- m_pD3DDevice->SetTextureStageState( 1, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
- m_pD3DDevice->SetTextureStageState( 1, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
- m_pD3DDevice->SetTextureStageState( 3, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
- m_pD3DDevice->SetTextureStageState( 3, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
-
- m_pD3DDevice->SetRenderState( D3DRS_ZENABLE, FALSE );
- m_pD3DDevice->SetRenderState( D3DRS_FOGENABLE, FALSE );
- m_pD3DDevice->SetRenderState( D3DRS_FOGTABLEMODE, D3DFOG_NONE );
- m_pD3DDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID );
- m_pD3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );
- m_pD3DDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
- m_pD3DDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE );
- m_pD3DDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ZERO );
- m_pD3DDevice->SetRenderState( D3DRS_YUVENABLE, FALSE );
- m_pD3DDevice->SetVertexShader( FVF_YUYVVERTEX );
- m_pD3DDevice->SetPixelShader( m_hPixelShader );
- // Render the image
- LPDIRECT3DSURFACE8 pOldRT;
- m_pD3DDevice->GetRenderTarget(&pOldRT);
- m_pD3DDevice->SetRenderTarget(m_RGBSurface[m_iYUY2RenderBuffer], NULL);
-
- m_pD3DDevice->Begin(D3DPT_QUADLIST);
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD0, (float)1.5f, (float)0.5f );
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD1, (float)0.5f, (float)0.5f );
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD2, (float)0.5f, (float)0.5f );
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD3, (float)0.5f, (float)0.5f);
- m_pD3DDevice->SetVertexData4f( D3DVSDE_VERTEX, (float)0.0f, (float)0.0f, 0, 1.0f );
-
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD0, (float)m_iSourceWidth + 1.5f, (float)0.5f );
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD1, (float)m_iSourceWidth / 2.0f + 0.5f, (float)0.5f );
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD2, (float)m_iSourceWidth + 0.5f, (float)0.5f );
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD3, (float)m_iSourceWidth / 2.0f + 0.5f, (float)0.5f );
- m_pD3DDevice->SetVertexData4f( D3DVSDE_VERTEX, (float)m_iSourceWidth / 2.0f, (float)0.0f, 0, 1.0f );
-
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD0, (float)m_iSourceWidth + 1.5f, (float)m_iSourceHeight + 0.5f );
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD1, (float)m_iSourceWidth / 2.0f + 0.5f, (float)m_iSourceHeight / 2.0f + 0.5f );
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD2, (float)m_iSourceWidth + 0.5f, (float)m_iSourceHeight + 0.5f);
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD3, (float)m_iSourceWidth / 2.0f + 0.5f, (float)m_iSourceHeight / 2.0f + 0.5f );
- m_pD3DDevice->SetVertexData4f( D3DVSDE_VERTEX, (float)m_iSourceWidth / 2.0f, (float)m_iSourceHeight, 0, 1.0f );
-
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD0, (float)1.5f, (float)m_iSourceHeight + 0.5f );
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD1, (float)0.5f, (float)m_iSourceHeight / 2.0f + 0.5f );
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD2, (float)0.5f, (float)m_iSourceHeight + 0.5f );
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD3, (float)0.5f, (float)m_iSourceHeight / 2.0f + 0.5f );
- m_pD3DDevice->SetVertexData4f( D3DVSDE_VERTEX, (float)0.0f, (float)m_iSourceHeight, 0, 1.0f );
- m_pD3DDevice->End();
-
- m_pD3DDevice->SetTexture(0, NULL);
- m_pD3DDevice->SetTexture(1, NULL);
- m_pD3DDevice->SetTexture(2, NULL);
- m_pD3DDevice->SetTexture(3, NULL);
-
- m_pD3DDevice->SetRenderState( D3DRS_YUVENABLE, FALSE );
- m_pD3DDevice->SetPixelShader( NULL );
- m_pD3DDevice->SetRenderTarget(pOldRT, NULL);
-
- m_pD3DDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
- m_pD3DDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
- m_pD3DDevice->SetTextureStageState( 2, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
- m_pD3DDevice->SetTextureStageState( 2, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
-
- pOldRT->Release();
-
- //Okey, when the gpu is done with the textures here, they are free to be modified again
- m_pD3DDevice->InsertCallback(D3DCALLBACK_WRITE,&TextureCallback, (DWORD)m_eventTexturesDone[index]);
-
- m_pD3DDevice->KickPushBuffer();
-
- m_bHasDimView = false;
-}
-
-void CComboRenderer::Render(DWORD flags)
-{
- if ( m_RGBSurface[m_iYUY2RenderBuffer] == NULL )
- {
- RenderLowMem(flags);
- }
- else
- {
- YV12toYUY2();
- CheckScreenSaver();
-
- /* clear target area, otherwise we won't get any picture */
- D3DRECT target;
- target.x1 = rd.left;
- target.x2 = rd.right;
- target.y1 = rd.top;
- target.y2 = rd.bottom;
- m_pD3DDevice->Clear( 1L, &target, D3DCLEAR_TARGET, m_clearColour, 1.0f, 0L );
-
- // Don't render if we are waiting an overlay event
- while (!m_pD3DDevice->GetOverlayUpdateStatus()) Sleep(1);
-
- LPDIRECT3DSURFACE8 pSurface;
- m_YUY2Texture[m_iYUY2RenderBuffer]->GetSurfaceLevel(0, &pSurface);
- m_pD3DDevice->UpdateOverlay( pSurface, &rs, &rd, TRUE, m_clearColour );
- pSurface->Release();
- }
-
- CXBoxRenderer::Render(flags | RENDER_FLAG_NOOSDALPHA);
-}
-
-unsigned int CComboRenderer::PreInit()
-{
- CXBoxRenderer::PreInit();
- // May have to set clearColour non-zero in future for HW overlays method?
-// if (!m_clearColour)
-// m_clearColour = 0x010001;
-
- m_bHasDimView = false;
- // Create the pixel shader
- if (!m_hPixelShader)
- {
- // shader to interleave separate Y U and V planes into a single YUY2 output
- const char* shader =
- "xps.1.1\n"
- "def c0,1,0,0,0\n"
- "def c1,0,1,0,0\n"
- "def c2,0,0,1,0\n"
- "def c3,0,0,0,1\n"
- "tex t0\n" // Y1 plane (Y plane)
- "tex t1\n" // U plane
- "tex t2\n" // Y2 plane (Y plane shifted 1 pixel to the left)
- "tex t3\n" // V plane
- "xmma discard,discard,r0, t0, c0, t1, c1\n"
- "xmma discard,discard,r1, t2, c2, t3.b, c3\n"
- "add r0, r0, r1\n";
- XGBuffer* pShader;
- XGAssembleShader("XBMCShader", shader, strlen(shader), 0, NULL, &pShader, NULL, NULL, NULL, NULL, NULL);
- m_pD3DDevice->CreatePixelShader((D3DPIXELSHADERDEF*)pShader->GetBufferPointer(), &m_hPixelShader);
- pShader->Release();
- }
-
- m_pD3DDevice->EnableOverlay(TRUE);
- return 0;
-}
-
-void CComboRenderer::UnInit()
-{
- CSingleLock lock(g_graphicsContext);
-
- m_pD3DDevice->EnableOverlay(FALSE);
- DeleteYUY2Texture(0);
- DeleteYUY2Texture(1);
-
- if (m_hPixelShader)
- {
- m_pD3DDevice->DeletePixelShader(m_hPixelShader);
- m_hPixelShader = 0;
- }
-
- CXBoxRenderer::UnInit();
-}
-
-void CComboRenderer::CheckScreenSaver()
-{
- if (g_application.IsInScreenSaver() && !m_bHasDimView)
- {
- D3DLOCKED_RECT lr;
- float fAmount = (float)CSettings::Get().GetInt("screensaver.dimlevel") / 100.0f;
- if ( D3D_OK == m_YUY2Texture[m_iYUY2RenderBuffer]->LockRect(0, &lr, NULL, 0 ))
- {
- // Drop brightness of current surface to 20%
- DWORD strideScreen = lr.Pitch;
- for (DWORD y = 0; y < UINT (rs.top + rs.bottom); y++)
- {
- BYTE *pDest = (BYTE*)lr.pBits + strideScreen * y;
- for (DWORD x = 0; x < UINT ((rs.left + rs.right) >> 1); x++)
- {
- pDest[0] = BYTE (pDest[0] * fAmount); // Y1
- pDest[1] = BYTE ((pDest[1] - 128) * fAmount + 128); // U (with 128 shift!)
- pDest[2] = BYTE (pDest[2] * fAmount); // Y2
- pDest[3] = BYTE ((pDest[3] - 128) * fAmount + 128); // V (with 128 shift!)
- pDest += 4;
- }
- }
- m_YUY2Texture[m_iYUY2RenderBuffer]->UnlockRect(0);
-
- }
- m_bHasDimView = true;
- }
-}
-
-void CComboRenderer::SetupScreenshot()
-{
- if (!g_graphicsContext.IsFullScreenVideo())
- return;
- CSingleLock lock(g_graphicsContext);
- // first, grab the current overlay texture and convert it to RGB
- LPDIRECT3DTEXTURE8 pRGB = NULL;
- if (D3D_OK != m_pD3DDevice->CreateTexture(m_iSourceWidth, m_iSourceHeight, 1, 0, D3DFMT_LIN_A8R8G8B8, 0, &pRGB))
- {
- return ;
- }
- D3DLOCKED_RECT lr, lr2;
- m_YUY2Texture[m_iYUY2RenderBuffer]->LockRect(0, &lr, NULL, 0);
- pRGB->LockRect(0, &lr2, NULL, 0);
- // convert to RGB via software converter
- BYTE *s = (BYTE *)lr.pBits;
- LONG *d = (LONG *)lr2.pBits;
- LONG dpitch = lr2.Pitch / 4;
- for (unsigned int y = 0; y < m_iSourceHeight; y++)
- {
- for (unsigned int x = 0; x < m_iSourceWidth; x += 2)
- {
- d[x] = YUV2RGB(s[2 * x], s[2 * x + 1], s[2 * x + 3]);
- d[x + 1] = YUV2RGB(s[2 * x + 2], s[2 * x + 1], s[2 * x + 3]);
- }
- s += lr.Pitch;
- d += dpitch;
- }
- m_YUY2Texture[m_iYUY2RenderBuffer]->UnlockRect(0);
- pRGB->UnlockRect(0);
- // ok - now lets dump the RGB texture to a file to test
- // ok, now this needs to be rendered to the screen
- m_pD3DDevice->SetTexture( 0, pRGB);
-
- m_pD3DDevice->SetTextureStageState( 0, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP );
- m_pD3DDevice->SetTextureStageState( 0, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP );
- m_pD3DDevice->SetTextureStageState( 0, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
- m_pD3DDevice->SetTextureStageState( 0, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
-
- // set scissors if we are not in fullscreen video
- if ( !(g_graphicsContext.IsFullScreenVideo() || g_graphicsContext.IsCalibrating() ))
- {
- g_graphicsContext.ClipToViewWindow();
- }
-
- m_pD3DDevice->SetRenderState( D3DRS_ZENABLE, FALSE );
- m_pD3DDevice->SetRenderState( D3DRS_FOGENABLE, FALSE );
- m_pD3DDevice->SetRenderState( D3DRS_FOGTABLEMODE, D3DFOG_NONE );
- m_pD3DDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID );
- m_pD3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );
- m_pD3DDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
- m_pD3DDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE );
- m_pD3DDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ZERO );
- m_pD3DDevice->SetRenderState( D3DRS_YUVENABLE, FALSE /*TRUE*/ );
- m_pD3DDevice->SetVertexShader( FVF_RGBVERTEX );
- // Render the image
- m_pD3DDevice->SetScreenSpaceOffset( -0.5f, -0.5f); // fix texel align
- m_pD3DDevice->Begin(D3DPT_QUADLIST);
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD0, (float)rs.left, (float)rs.top );
- m_pD3DDevice->SetVertexData4f( D3DVSDE_VERTEX, (float)rd.left, (float)rd.top, 0, 1.0f );
-
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD0, (float)rs.right, (float)rs.top );
- m_pD3DDevice->SetVertexData4f( D3DVSDE_VERTEX, (float)rd.right, (float)rd.top, 0, 1.0f );
-
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD0, (float)rs.right, (float)rs.bottom );
- m_pD3DDevice->SetVertexData4f( D3DVSDE_VERTEX, (float)rd.right, (float)rd.bottom, 0, 1.0f );
-
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD0, (float)rs.left, (float)rs.bottom );
- m_pD3DDevice->SetVertexData4f( D3DVSDE_VERTEX, (float)rd.left, (float)rd.bottom, 0, 1.0f );
- m_pD3DDevice->End();
- m_pD3DDevice->SetScreenSpaceOffset(0, 0);
-
- m_pD3DDevice->SetTexture(0, NULL);
- m_pD3DDevice->SetScissors(0, FALSE, NULL );
-
- RenderOSD();
-
- if (g_application.NeedRenderFullScreen())
- { // render our subtitles and osd
- g_application.RenderFullScreen();
- }
-
- m_pD3DDevice->Present( NULL, NULL, NULL, NULL );
-
- while (pRGB->IsBusy()) Sleep(1);
- pRGB->Release();
-
- return ;
-}
-
-LONG CComboRenderer::YUV2RGB(BYTE y, BYTE u, BYTE v)
-{
- YUVCOEF &coef = yuv_coef_bt601;
- YUVRANGE &range = yuv_range_lim;
-
- // normalize
- float Yp = (y - range.y_min) * 255.0f / (range.y_max - range.y_min);
- float Up = (u - range.u_min) * 255.0f / (range.u_max - range.u_min) - 127.5f;
- float Vp = (v - range.v_min) * 255.0f / (range.v_max - range.v_min) - 127.5f;
-
- // recalculate
- float R = Yp + coef.r_up * Up + coef.r_vp * Vp;
- float G = Yp + coef.g_up * Up + coef.g_vp * Vp;
- float B = Yp + coef.b_up * Up + coef.b_vp * Vp;
-
- // clamp
- R = CLAMP(R, 0.0f, 255.0f);
- G = CLAMP(G, 0.0f, 255.0f);
- B = CLAMP(B, 0.0f, 255.0f);
-
- return ((int)R << 16) + ((int)G << 8) + (int)B;
-}
+++ /dev/null
-#ifndef COMBO_RENDERER
-#define COMBO_RENDERER
-
-/*
- * Copyright (C) 2005-2013 Team XBMC
- * http://xbmc.org
- *
- * This Program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This Program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with XBMC; see the file COPYING. If not, see
- * <http://www.gnu.org/licenses/>.
- *
- */
-
-#include "XBoxRenderer.h"
-
-//const DWORD FVF_YV12VERTEX = D3DFVF_XYZRHW|D3DFVF_TEX3;
-
-class CComboRenderer : public CXBoxRenderer
-{
-public:
- CComboRenderer(LPDIRECT3DDEVICE8 pDevice);
- //~CComboRenderer();
-
- virtual void Update(bool bPauseDrawing);
- virtual void SetupScreenshot();
- virtual void FlipPage(int source);
-
- // Functions called from mplayer
- virtual bool Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags);
- virtual unsigned int PreInit();
- virtual void UnInit();
-
-protected:
- virtual void Render(DWORD flags);
- virtual void ManageDisplay();
- virtual void ManageTextures();
- bool CreateYUY2Texture(int index);
- void DeleteYUY2Texture(int index);
- void ClearYUY2Texture(int index);
- void YV12toYUY2();
- void CheckScreenSaver();
-
- LONG YUV2RGB(BYTE y, BYTE u, BYTE v);
-
- DWORD m_hPixelShader;
-
- // RGB/YUY2 texture target(s)
- LPDIRECT3DSURFACE8 m_RGBSurface[2];
- LPDIRECT3DTEXTURE8 m_YUY2Texture[2];
-
- static const DWORD FVF_YUYVVERTEX = D3DFVF_XYZRHW | D3DFVF_TEX4;
- static const DWORD FVF_RGBVERTEX = D3DFVF_XYZRHW | D3DFVF_TEX1;
-
- int m_iYUY2RenderBuffer;
- int m_iYUY2Buffers;
- int m_iScreenWidth;
- int m_iScreenHeight;
- // screensaver stuff
- bool m_bHasDimView;
-};
-
-#endif
+++ /dev/null
-/*
- * Copyright (C) 2005-2013 Team XBMC
- * http://xbmc.org
- *
- * This Program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This Program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with XBMC; see the file COPYING. If not, see
- * <http://www.gnu.org/licenses/>.
- *
- */
-
-#include "stdafx.h"
-#include "RGBRendererV2.h"
-
-#define SURFTOTEX(a) ((a)->Parent ? (a)->Parent : (D3DBaseTexture*)(a))
-
-//#define DBGBOB
-
-CRGBRendererV2::CRGBRendererV2(LPDIRECT3DDEVICE8 pDevice)
- : CXBoxRenderer(pDevice)
-{
- m_444PTextureFull = NULL;
- m_444PTextureField = NULL;
-
- m_hInterleavingShader = 0;
- m_hInterleavingShaderAlpha = 0;
- m_hYUVtoRGBLookup = 0;
- m_UVLookup = NULL;
- m_UVErrorLookup = NULL;
- m_motionpass = 5;
- m_444GeneratedFull = false;
- m_444RenderBuffer = 0;
- memset(&m_yuvcoef_last, 0, sizeof(YUVCOEF));
- memset(&m_yuvrange_last, 0, sizeof(YUVRANGE));
-}
-
-void CRGBRendererV2::FlipPage(int source)
-{
- m_444GeneratedFull = false;
-
- CXBoxRenderer::FlipPage(source);
-}
-
-void CRGBRendererV2::Delete444PTexture()
-{
- CSingleLock lock(g_graphicsContext);
- SAFE_RELEASE(m_444PTextureFull);
- SAFE_RELEASE(m_444PTextureField);
- CLog::Log(LOGDEBUG, "Deleted 444P video textures");
-}
-
-void CRGBRendererV2::Clear444PTexture(bool full, bool field)
-{
- CSingleLock lock(g_graphicsContext);
- if(m_444PTextureFull && full)
- {
- D3DLOCKED_RECT lr;
- m_444PTextureFull->LockRect(0, &lr, NULL, 0);
- memset(lr.pBits, 0x00, lr.Pitch*m_iSourceHeight);
- m_444PTextureFull->UnlockRect(0);
- }
-
- if(m_444PTextureField && field)
- {
- D3DLOCKED_RECT lr;
- m_444PTextureField->LockRect(0, &lr, NULL, 0);
-#ifdef DBGBOB
- memset(lr.pBits, 0xFF, lr.Pitch*m_iSourceHeight>>1);
-#else
- memset(lr.pBits, 0x00, lr.Pitch*m_iSourceHeight>>1);
-#endif
- m_444PTextureField->UnlockRect(0);
- }
- m_444GeneratedFull = false;
-}
-
-bool CRGBRendererV2::Create444PTexture(bool full, bool field)
-{
- CSingleLock lock(g_graphicsContext);
- if (!m_444PTextureFull && full)
- {
- if(D3D_OK != m_pD3DDevice->CreateTexture(m_iSourceWidth, m_iSourceHeight, 1, 0, D3DFMT_LIN_A8R8G8B8, 0, &m_444PTextureFull))
- return false;
-
- CLog::Log(LOGINFO, "Created 444P full texture");
- }
-
- if (!m_444PTextureField && field)
- {
- if(D3D_OK != m_pD3DDevice->CreateTexture(m_iSourceWidth, m_iSourceHeight>>1, 1, 0, D3DFMT_LIN_A8R8G8B8, 0, &m_444PTextureField))
- return false;
- CLog::Log(LOGINFO, "Created 444P field texture");
- }
- return true;
-}
-
-void CRGBRendererV2::ManageTextures()
-{
- //use 1 buffer in fullscreen mode and 0 buffers in windowed mode
- if (!g_graphicsContext.IsFullScreenVideo())
- {
- if (m_444PTextureFull || m_444PTextureField)
- Delete444PTexture();
- }
-
- CXBoxRenderer::ManageTextures();
-
- if (g_graphicsContext.IsFullScreenVideo())
- {
- if (!m_444PTextureFull)
- {
- Create444PTexture(true, false);
- Clear444PTexture(true, false);
- }
- }
-}
-
-bool CRGBRendererV2::Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags)
-{
- if(!CXBoxRenderer::Configure(width, height, d_width, d_height, fps, flags))
- return false;
-
- // create our lookup textures for yv12->rgb translation,
- if(!CreateLookupTextures(m_yuvcoef, m_yuvrange) )
- return false;
-
- m_bConfigured = true;
- return true;
-}
-
-void CRGBRendererV2::Render(DWORD flags)
-{
- CSingleLock lock(g_graphicsContext);
- if ( !g_graphicsContext.IsFullScreenVideo() )
- {
- RenderLowMem(flags);
- }
- else
- {
- int index = m_iYV12RenderBuffer;
-
- if( !(flags & RENDER_FLAG_NOLOCK) )
- if( WaitForSingleObject(m_eventTexturesDone[index], 500) == WAIT_TIMEOUT )
- CLog::Log(LOGWARNING, __FUNCTION__" - Timeout waiting for texture %d", index);
-
- D3DSurface* p444PSourceFull = NULL;
- D3DSurface* p444PSourceField = NULL;
-
- if( flags & (RENDER_FLAG_TOP|RENDER_FLAG_BOT) )
- {
- if(!m_444PTextureField)
- {
- Create444PTexture(false, true);
- Clear444PTexture(false, true);
- }
- if(!m_444PTextureField)
- {
- CLog::Log(LOGERROR, __FUNCTION__" - Couldn't create field texture");
- return;
- }
-
- m_444PTextureField->GetSurfaceLevel(0, &p444PSourceField);
- }
-
- if(!m_444PTextureFull)
- {
- CLog::Log(LOGERROR, __FUNCTION__" - Couldn't create full texture");
- return;
- }
-
- m_444PTextureFull->GetSurfaceLevel(0, &p444PSourceFull);
-
- //UV in interlaced video is seen as being closer to first line in first field and closer to second line in second field
- //we shift it with an offset of 1/4th pixel (1/8 in UV planes)
- //This need only be done when field scaling
- #define CHROMAOFFSET_VERT 0.125f
-
- //Each chroma sample is not said to be between the first and second sample as in the vertical case
- //first Y(1) <=> UV(1), Y(2) <=> ( UV(1)+UV(2) ) / 2, Y(3) <=> UV(2)
- //we wish to offset this by 1/2 pxiel to le left, which in the half rez of UV planes means 1/4th
- #define CHROMAOFFSET_HORIZ 0.25f
-
-
- //Example of how YUV has it's Luma and Chroma data stored
- //for progressive video
- //L L L L L L L L L L
- //C C C C C
- //L L L L L L L L L L
-
- //Example of how YUV has Chroma subsampled in interlaced displays
- //FIELD 1 FIELD 2
- //L L L L L L L L L L
- //C C C C C
- // L L L L L L L L L L
- //
- //L L L L L L L L L L
- // C C C C C
- // L L L L L L L L L L
- //
- //L L L L L L L L L L
- //C C C C C
- // L L L L L L L L L L
- //
- //.........................................
- //.........................................
-
- m_pD3DDevice->SetRenderState( D3DRS_SWATHWIDTH, 15 );
- m_pD3DDevice->SetRenderState( D3DRS_ZENABLE, FALSE );
- m_pD3DDevice->SetRenderState( D3DRS_FOGENABLE, FALSE );
- m_pD3DDevice->SetRenderState( D3DRS_FILLMODE, D3DFILL_SOLID );
- m_pD3DDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );
- m_pD3DDevice->SetRenderState( D3DRS_YUVENABLE, FALSE );
-
- DWORD alphaenabled;
- m_pD3DDevice->GetRenderState( D3DRS_ALPHABLENDENABLE, &alphaenabled );
- m_pD3DDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE );
- m_pD3DDevice->SetRenderState( D3DRS_ALPHATESTENABLE, FALSE );
-
- RECT rsf = { rs.left, rs.top>>1, rs.right, rs.bottom>>1 };
-
- if( !m_444GeneratedFull )
- {
- m_444GeneratedFull = true;
- InterleaveYUVto444P(
- m_YUVTexture[index][FIELD_FULL],
- NULL, // use motion from last frame as motion value
- p444PSourceFull,
- rs, rs, rs,
- 1, 1,
- 0.0f, 0.0f,
- CHROMAOFFSET_HORIZ, 0.0f);
- }
-#ifdef DBGBOB
- m_pD3DDevice->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA);
-#endif
-
- if( flags & RENDER_FLAG_TOP )
- {
- InterleaveYUVto444P(
- m_YUVTexture[index][FIELD_TOP],
- m_444PTextureFull, // use a downscaled motion value from the full frame,
- p444PSourceField,
- rsf, rs, rsf,
- 1, 1,
- 0.0f, 0.0f,
- CHROMAOFFSET_HORIZ, +CHROMAOFFSET_VERT);
- }
- else if( flags & RENDER_FLAG_BOT )
- {
- InterleaveYUVto444P(
- m_YUVTexture[index][FIELD_BOT],
- m_444PTextureFull, // use a downscaled motion value from the full frame,
- p444PSourceField,
- rsf, rs, rsf,
- 1, 1,
- 0.0f, 0.0f,
- CHROMAOFFSET_HORIZ, -CHROMAOFFSET_VERT);
- }
-
-#ifdef DBGBOB
- m_pD3DDevice->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALL);
-#endif
-
- //Okey, when the gpu is done with the textures here, they are free to be modified again
- if( !(flags & RENDER_FLAG_NOUNLOCK) )
- m_pD3DDevice->InsertCallback(D3DCALLBACK_WRITE,&TextureCallback, (DWORD)m_eventTexturesDone[index]);
-
- // Now perform the YUV->RGB conversion in a single pass, and render directly to the screen
- m_pD3DDevice->SetScreenSpaceOffset( -0.5f, -0.5f );
-
- if(true)
- {
- // NOTICE, field motion can have been replaced by downscaled frame motion
- // this method uses the difference between fields to estimate motion
- // it work sorta, but it can't for example handle horizontal
- // hairlines wich only exist in one field, they will flicker
- // as they get considered motion
-
-
- // render the full frame
- m_pD3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
- RenderYUVtoRGB(m_444PTextureFull, rs, rd, 0.0f, 0.0f);
-
- // render the field texture ontop
- if(m_444PTextureField && p444PSourceField)
- {
- m_pD3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE);
- m_pD3DDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL);
- m_pD3DDevice->SetRenderState(D3DRS_ALPHAREF, m_motionpass);
-
- if(flags & RENDER_FLAG_TOP)
- RenderYUVtoRGB(m_444PTextureField, rsf, rd, 0.0f, 0.25);
- else
- RenderYUVtoRGB(m_444PTextureField, rsf, rd, 0.0f, -0.25);
- }
- }
- else
- {
- // this method will use the difference between this and previous
- // frame as an estimate for motion. this will currently fail
- // on the first field that has motion. as then only that line
- // has motion. if the alpha channel where first downscaled
- // to the field texture lineary we should get away from that
-
- // render the field texture first
- if(m_444PTextureField && p444PSourceField)
- {
- m_pD3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
- if(flags & RENDER_FLAG_TOP)
- RenderYUVtoRGB(m_444PTextureField, rsf, rd, 0.0f, 0.25);
- else
- RenderYUVtoRGB(m_444PTextureField, rsf, rd, 0.0f, -0.25);
- }
-
- // fill in any place we have no motion with full texture
- m_pD3DDevice->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE);
- m_pD3DDevice->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_LESS);
- m_pD3DDevice->SetRenderState(D3DRS_ALPHAREF, m_motionpass);
- RenderYUVtoRGB(m_444PTextureFull, rs, rd, 0.0f, 0.0f);
- }
-
- m_pD3DDevice->SetScreenSpaceOffset(0.0f, 0.0f);
- m_pD3DDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, alphaenabled );
- m_pD3DDevice->SetRenderState( D3DRS_ALPHATESTENABLE, FALSE );
-
- m_pD3DDevice->SetTexture(0, NULL);
- m_pD3DDevice->SetTexture(1, NULL);
- m_pD3DDevice->SetTexture(2, NULL);
- m_pD3DDevice->SetTexture(3, NULL);
-
- m_pD3DDevice->SetPixelShader( NULL );
-
- SAFE_RELEASE(p444PSourceFull);
- SAFE_RELEASE(p444PSourceField);
- }
-
- CXBoxRenderer::Render(flags);
-}
-
-unsigned int CRGBRendererV2::PreInit()
-{
- CXBoxRenderer::PreInit();
- // Create the pixel shader
- if (!m_hInterleavingShader)
- {
- CSingleLock lock(g_graphicsContext);
- // shader to interleave separate Y U and V planes into a single YUV output
- const char* interleave =
- "xps.1.1\n"
- "def c0,1,0,0,0\n"
- "def c1,0,1,0,0\n"
- "def c2,0,0,1,0\n"
- "tex t0\n"
- "tex t1\n"
- "tex t2\n"
- "tex t3\n"
-
- // interleave our data
- "xmma discard,discard,r0, t0,c0, t1,c1\n"
- "mad r0, t2,c2,r0\n"
-
- "sub_x4 r1, r0,t3\n" // calculate the differens in this pixel values
- "dp3 r1.rgba, r1,r1\n" // take the absolute of the "yuv" difference vector
-// "add_d2 r1.a, r1, t3\n" // average with previouse value to avoid minor changes
- "mov r0.a, r1";
-
- const char* interleavealpha =
- "xps.1.1\n"
- "def c0,1,0,0,0\n"
- "def c1,0,1,0,0\n"
- "def c2,0,0,1,0\n"
- "tex t0\n"
- "tex t1\n"
- "tex t2\n"
- "tex t3\n"
-
- // interleave our data
- "xmma discard,discard,r0, t0,c0, t1,c1\n"
- "mad r0, t2,c2,r0\n"
-
- // use alpha from t3
- "mov r0.a, t3";
-
- // shader for 14bit accurate YUV to RGB (single pass :)
- const char* yuv2rgb =
- "xps.1.1\n"
- "def c0,0.0117647,0.0117647,0.0117647,0\n"
- "tex t0\n"
- "texreg2ar t1, t0\n"
- "texreg2gb t2, t0\n"
- "texreg2gb t3, t0\n"
- "add r0, t1, t2_bx2\n"
- "add r1, t1.a, t3\n"
- "mad r0, r1, c0, r0\n"
- "mov r0.a, t0";
-
- XGBuffer* pShader;
- XGAssembleShader("InterleaveShader", interleave, strlen(interleave), 0, NULL, &pShader, NULL, NULL, NULL, NULL, NULL);
- m_pD3DDevice->CreatePixelShader((D3DPIXELSHADERDEF*)pShader->GetBufferPointer(), &m_hInterleavingShader);
- pShader->Release();
-
- XGAssembleShader("InterleaveShaderAlpha", interleavealpha, strlen(interleavealpha), 0, NULL, &pShader, NULL, NULL, NULL, NULL, NULL);
- m_pD3DDevice->CreatePixelShader((D3DPIXELSHADERDEF*)pShader->GetBufferPointer(), &m_hInterleavingShaderAlpha);
- pShader->Release();
-
- XGAssembleShader("YUV2RGBShader", yuv2rgb, strlen(yuv2rgb), 0, NULL, &pShader, NULL, NULL, NULL, NULL, NULL);
- m_pD3DDevice->CreatePixelShader((D3DPIXELSHADERDEF*)pShader->GetBufferPointer(), &m_hYUVtoRGBLookup);
- pShader->Release();
-
- }
-
- return 0;
-}
-
-void CRGBRendererV2::UnInit()
-{
- CSingleLock lock(g_graphicsContext);
-
- Delete444PTexture();
- DeleteLookupTextures();
-
- if (m_hInterleavingShader)
- {
- m_pD3DDevice->DeletePixelShader(m_hInterleavingShader);
- m_hInterleavingShader = 0;
- }
-
- if (m_hInterleavingShaderAlpha)
- {
- m_pD3DDevice->DeletePixelShader(m_hInterleavingShaderAlpha);
- m_hInterleavingShaderAlpha = 0;
- }
-
- if (m_hYUVtoRGBLookup)
- {
- m_pD3DDevice->DeletePixelShader(m_hYUVtoRGBLookup);
- m_hYUVtoRGBLookup = 0;
- }
- CXBoxRenderer::UnInit();
-}
-
-void CRGBRendererV2::DeleteLookupTextures()
-{
- if (m_UVLookup)
- {
- m_UVLookup->Release();
- m_UVLookup = NULL;
- }
- if (m_UVErrorLookup)
- {
- m_UVErrorLookup->Release();
- m_UVErrorLookup = NULL;
- }
-}
-
-bool CRGBRendererV2::CreateLookupTextures(const YUVCOEF &coef, const YUVRANGE &range)
-{
- if(memcmp(&m_yuvcoef_last, &coef, sizeof(YUVCOEF)) == 0
- && memcmp(&m_yuvrange_last, &range, sizeof(YUVRANGE)) == 0)
- return true;
-
- DeleteLookupTextures();
- if (
- D3D_OK != m_pD3DDevice->CreateTexture(1 , 256, 1, 0, D3DFMT_A8L8 , 0, &m_YLookup) ||
- D3D_OK != m_pD3DDevice->CreateTexture(256, 256, 1, 0, D3DFMT_A8R8G8B8, 0, &m_UVLookup) ||
- D3D_OK != m_pD3DDevice->CreateTexture(256, 256, 1, 0, D3DFMT_A8R8G8B8, 0, &m_UVErrorLookup)
- )
- {
- DeleteLookupTextures();
- CLog::Log(LOGERROR, "Could not create RGB lookup textures");
- return false;
- }
-
- // fill in the lookup texture
- // create a temporary buffer as we need to swizzle the result
- D3DLOCKED_RECT lr;
- BYTE *pBuffY = new BYTE[1 * 256 * 2];
- BYTE *pBuff = new BYTE[256 * 256 * 4];
- BYTE *pErrorBuff = new BYTE[256 * 256 * 4];
-
- if(pBuffY)
- {
- // first column is our luminance data
- for (int y = 0; y < 256; y++)
- {
- float fY = (y - range.y_min) * 255.0f / (range.y_max - range.y_min);
-
- fY = CLAMP(fY, 0.0f, 255.0f);
-
- float fWhole = floor(fY);
- float fFrac = floor((fY - fWhole) * 85.0f + 0.5f); // 0 .. 1.0
-
- pBuffY[2*y] = (BYTE)fWhole;
- pBuffY[2*y+1] = (BYTE)fFrac;
- }
- }
-
- if (pBuff && pErrorBuff)
- {
- for (int u = 1; u < 256; u++)
- {
- for (int v = 0; v < 256; v++)
- {
- // convert to -0.5 .. 0.5 ( -127.5 .. 127.5 )
- float fV = (v - range.v_min) * 255.f / (range.v_max - range.v_min) - 127.5f;
- float fU = (u - range.u_min) * 255.f / (range.u_max - range.u_min) - 127.5f;
-
- fU = CLAMP(fU, -127.5f, 127.5f);
- fV = CLAMP(fV, -127.5f, 127.5f);
-
- // have U and V, calculate R, G and B contributions (lie between 0 and 255)
- // -1 is mapped to 0, 1 is mapped to 255
- float r = coef.r_up * fU + coef.r_vp * fV;
- float g = coef.g_up * fU + coef.g_vp * fV;
- float b = coef.b_up * fU + coef.b_vp * fV;
-
- float r_rnd = floor(r * 0.5f - 0.5f) * 2 + 1;
- float g_rnd = floor(g * 0.5f - 0.5f) * 2 + 1;
- float b_rnd = floor(b * 0.5f - 0.5f) * 2 + 1;
-
- float ps_r = (r_rnd - 1) * 0.5f + 128.0f;
- float ps_g = (g_rnd - 1) * 0.5f + 128.0f;
- float ps_b = (b_rnd - 1) * 0.5f + 128.0f;
-
- ps_r = CLAMP(ps_r, 0.0f, 255.0f);
- ps_g = CLAMP(ps_g, 0.0f, 255.0f);
- ps_b = CLAMP(ps_b, 0.0f, 255.0f);
-
- float r_frac = floor((r - r_rnd) * 85.0f + 0.5f);
- float b_frac = floor((b - b_rnd) * 85.0f + 0.5f);
- float g_frac = floor((g - g_rnd) * 85.0f + 0.5f);
-
- pBuff[4*u + 1024*v + 0] = (BYTE)ps_b;
- pBuff[4*u + 1024*v + 1] = (BYTE)ps_g;
- pBuff[4*u + 1024*v + 2] = (BYTE)ps_r;
- pBuff[4*u + 1024*v + 3] = 0;
- pErrorBuff[4*u + 1024*v + 0] = (BYTE)b_frac;
- pErrorBuff[4*u + 1024*v + 1] = (BYTE)g_frac;
- pErrorBuff[4*u + 1024*v + 2] = (BYTE)r_frac;
- pErrorBuff[4*u + 1024*v + 3] = 0;
- }
- }
- m_YLookup->LockRect(0, &lr, NULL, 0);
- XGSwizzleRect(pBuffY, 0, NULL, lr.pBits, 1, 256, NULL, 2);
- m_YLookup->UnlockRect(0);
- m_UVLookup->LockRect(0, &lr, NULL, 0);
- XGSwizzleRect(pBuff, 0, NULL, lr.pBits, 256, 256, NULL, 4);
- m_UVLookup->UnlockRect(0);
- m_UVErrorLookup->LockRect(0, &lr, NULL, 0);
- XGSwizzleRect(pErrorBuff, 0, NULL, lr.pBits, 256, 256, NULL, 4);
- m_UVErrorLookup->UnlockRect(0);
-
- m_yuvcoef_last = coef;
- m_yuvrange_last = range;
- }
- delete[] pBuff;
- delete[] pErrorBuff;
- delete[] pBuffY;
-
- return true;
-}
-void CRGBRendererV2::InterleaveYUVto444P(
- YUVPLANES pSources,
- LPDIRECT3DTEXTURE8 pAlpha,
- LPDIRECT3DSURFACE8 pTarget,
- RECT &source, RECT &sourcealpha, RECT &target,
- unsigned cshift_x, unsigned cshift_y,
- float offset_x, float offset_y,
- float coffset_x, float coffset_y)
-{
- coffset_x += offset_x / (1<<cshift_x);
- coffset_y += offset_y / (1<<cshift_y);
-
- for (int i = 0; i < 3; ++i)
- {
- m_pD3DDevice->SetTexture( i, pSources[i]);
- m_pD3DDevice->SetTextureStageState( i, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP );
- m_pD3DDevice->SetTextureStageState( i, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP );
- m_pD3DDevice->SetTextureStageState( i, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
- m_pD3DDevice->SetTextureStageState( i, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
- }
-
- m_pD3DDevice->SetVertexShader( FVF_YV12VERTEX );
-
- if(pAlpha)
- {
- m_pD3DDevice->SetTexture(3, pAlpha);
- m_pD3DDevice->SetPixelShader( m_hInterleavingShaderAlpha );
- }
- else
- {
- m_pD3DDevice->SetTexture(3, SURFTOTEX(pTarget));
- m_pD3DDevice->SetPixelShader( m_hInterleavingShader );
- }
-
- m_pD3DDevice->SetTextureStageState( 3, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP );
- m_pD3DDevice->SetTextureStageState( 3, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP );
- m_pD3DDevice->SetTextureStageState( 3, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
- m_pD3DDevice->SetTextureStageState( 3, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
-
-
- LPDIRECT3DSURFACE8 pOldRT = NULL;
- if( pTarget )
- {
- m_pD3DDevice->GetRenderTarget(&pOldRT);
- m_pD3DDevice->SetRenderTarget(pTarget, NULL);
- }
-
- m_pD3DDevice->SetScreenSpaceOffset(-0.5f, -0.5f);
- m_pD3DDevice->Begin(D3DPT_QUADLIST);
-
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD0, (float)source.left + offset_x, (float)source.top + offset_y);
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD1, (float)(source.left>>cshift_x) + coffset_x, (float)(source.top>>cshift_y) + coffset_y );
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD2, (float)(source.left>>cshift_x) + coffset_x, (float)(source.top>>cshift_y) + coffset_y );
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD3, (float)sourcealpha.left, (float)sourcealpha.top);
- m_pD3DDevice->SetVertexData4f( D3DVSDE_VERTEX, (float)target.left, (float)target.top, 0, 1.0f );
-
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD0, (float)source.right + offset_x, (float)source.top + offset_y);
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD1, (float)(source.right>>cshift_x) + coffset_x, (float)(source.top>>cshift_y) + coffset_y );
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD2, (float)(source.right>>cshift_x) + coffset_x, (float)(source.top>>cshift_y) + coffset_y );
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD3, (float)sourcealpha.right, (float)sourcealpha.top);
- m_pD3DDevice->SetVertexData4f( D3DVSDE_VERTEX, (float)target.right, (float)target.top, 0, 1.0f );
-
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD0, (float)source.right + offset_x, (float)source.bottom + offset_y);
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD1, (float)(source.right>>cshift_x) + coffset_x, (float)(source.bottom>>cshift_y) + coffset_y );
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD2, (float)(source.right>>cshift_x) + coffset_x, (float)(source.bottom>>cshift_y) + coffset_y );
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD3, (float)sourcealpha.right, (float)sourcealpha.bottom);
- m_pD3DDevice->SetVertexData4f( D3DVSDE_VERTEX, (float)target.right, (float)target.bottom, 0, 1.0f );
-
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD0, (float)source.left + offset_x, (float)source.bottom + offset_y);
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD1, (float)(source.left>>cshift_x) + coffset_x, (float)(source.bottom>>cshift_y) + coffset_y );
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD2, (float)(source.left>>cshift_x) + coffset_x, (float)(source.bottom>>cshift_y) + coffset_y );
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD3, (float)sourcealpha.left, (float)sourcealpha.bottom);
- m_pD3DDevice->SetVertexData4f( D3DVSDE_VERTEX, (float)target.left, (float)target.bottom, 0, 1.0f );
-
- m_pD3DDevice->End();
-
- m_pD3DDevice->SetScreenSpaceOffset(0.0f, 0.0f);
-
- m_pD3DDevice->SetTexture(0, NULL);
- m_pD3DDevice->SetTexture(1, NULL);
- m_pD3DDevice->SetTexture(2, NULL);
- m_pD3DDevice->SetTexture(3, NULL);
-
- if( pOldRT )
- {
- m_pD3DDevice->SetRenderTarget( pOldRT, NULL);
- pOldRT->Release();
- }
-}
-
-void CRGBRendererV2::RenderYUVtoRGB(
- D3DBaseTexture* pSource,
- RECT &source, RECT &target,
- float offset_x, float offset_y)
-{
- m_pD3DDevice->SetTexture( 0, pSource);
- m_pD3DDevice->SetTexture( 1, m_YLookup);
- m_pD3DDevice->SetTexture( 2, m_UVLookup);
- m_pD3DDevice->SetTexture( 3, m_UVErrorLookup);
-
- for (int i = 0; i < 4; ++i)
- {
- m_pD3DDevice->SetTextureStageState( i, D3DTSS_ADDRESSU, D3DTADDRESS_CLAMP );
- m_pD3DDevice->SetTextureStageState( i, D3DTSS_ADDRESSV, D3DTADDRESS_CLAMP );
- m_pD3DDevice->SetTextureStageState( i, D3DTSS_MAGFILTER, D3DTEXF_LINEAR );
- m_pD3DDevice->SetTextureStageState( i, D3DTSS_MINFILTER, D3DTEXF_LINEAR );
- }
-
- m_pD3DDevice->SetVertexShader( FVF_YUVRGBVERTEX );
- m_pD3DDevice->SetPixelShader( m_hYUVtoRGBLookup );
-
- // render the full frame
- m_pD3DDevice->Begin(D3DPT_QUADLIST);
-
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD1, 0.0f, 0.0f );
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD2, 0.0f, 0.0f );
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD3, 0.0f, 0.0f );
-
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD1, 1.0f, 0.0f );
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD2, 1.0f, 0.0f );
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD3, 1.0f, 0.0f );
-
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD1, 1.0f, 1.0f );
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD2, 1.0f, 1.0f );
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD3, 1.0f, 1.0f );
-
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD1, 0.0f, 1.0f );
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD2, 0.0f, 1.0f );
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD3, 0.0f, 1.0f );
-
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD0, (float)source.left + offset_x, (float)source.top + offset_y);
- m_pD3DDevice->SetVertexData4f( D3DVSDE_VERTEX, (float)target.left, (float)target.top, 0, 1.0f );
-
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD0, (float)source.right + offset_x, (float)source.top + offset_y);
- m_pD3DDevice->SetVertexData4f( D3DVSDE_VERTEX, (float)target.right, (float)target.top, 0, 1.0f );
-
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD0, (float)source.right + offset_x, (float)source.bottom + offset_y);
- m_pD3DDevice->SetVertexData4f( D3DVSDE_VERTEX, (float)target.right, (float)target.bottom, 0, 1.0f );
-
- m_pD3DDevice->SetVertexData2f( D3DVSDE_TEXCOORD0, (float)source.left + offset_x, (float)source.bottom + offset_y);
- m_pD3DDevice->SetVertexData4f( D3DVSDE_VERTEX, (float)target.left, (float)target.bottom, 0, 1.0f );
-
- m_pD3DDevice->End();
-
-}
+++ /dev/null
-#ifndef RGBV2_RENDERER
-#define RGBV2_RENDERER
-
-/*
- * Copyright (C) 2005-2013 Team XBMC
- * http://xbmc.org
- *
- * This Program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This Program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with XBMC; see the file COPYING. If not, see
- * <http://www.gnu.org/licenses/>.
- *
- */
-
-#include "XBoxRenderer.h"
-
-class CRGBRendererV2 : public CXBoxRenderer
-{
-public:
- CRGBRendererV2(LPDIRECT3DDEVICE8 pDevice);
- //~CRGBRendererV2();
-
- // Functions called from mplayer
- // virtual void WaitForFlip();
- virtual bool Configure(unsigned int width, unsigned int height, unsigned int d_width, unsigned int d_height, float fps, unsigned flags);
- virtual unsigned int PreInit();
- virtual void UnInit();
- virtual void FlipPage(int source);
-
-protected:
- virtual void Render(DWORD flags);
- virtual void ManageTextures();
-
- bool Create444PTexture(bool full, bool field);
- void Delete444PTexture();
- void Clear444PTexture(bool full, bool field);
-
- bool CreateLookupTextures(const YUVCOEF &coef, const YUVRANGE &range);
- void DeleteLookupTextures();
-
- void InterleaveYUVto444P(
- YUVPLANES pSources,
- LPDIRECT3DTEXTURE8 pAlpha,
- LPDIRECT3DSURFACE8 pTarget,
- RECT &source, RECT &sourcealpha, RECT &target,
- unsigned cshift_x, unsigned cshift_y,
- float offset_x, float offset_y,
- float coffset_x, float coffset_y);
-
- void RenderYUVtoRGB(
- D3DBaseTexture* pSource,
- RECT &source, RECT &target,
- float offset_x, float offset_y);
-
- // YUV interleaved texture
- LPDIRECT3DTEXTURE8 m_444PTextureFull;
- LPDIRECT3DTEXTURE8 m_444PTextureField;
-
- bool m_444GeneratedFull;
- int m_444RenderBuffer;
-
-
- // textures for YUV->RGB lookup
- LPDIRECT3DTEXTURE8 m_UVLookup;
- LPDIRECT3DTEXTURE8 m_YLookup;
- LPDIRECT3DTEXTURE8 m_UVErrorLookup;
- YUVRANGE m_yuvrange_last;
- YUVCOEF m_yuvcoef_last;
-
-
- // Pixel shaders
- DWORD m_hInterleavingShader;
- DWORD m_hInterleavingShaderAlpha;
- DWORD m_hYUVtoRGBLookup;
-
- BYTE m_motionpass;
-
- // Vertex types
- static const DWORD FVF_YUVRGBVERTEX = D3DFVF_XYZRHW | D3DFVF_TEX4;
- static const DWORD FVF_RGBVERTEX = D3DFVF_XYZRHW | D3DFVF_TEX1;
-};
-
-#endif
+++ /dev/null
-/*
- * Copyright (C) 2010-2013 Team XBMC
- * http://xbmc.org
- *
- * This Program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This Program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with XBMC; see the file COPYING. If not, see
- * <http://www.gnu.org/licenses/>.
- *
- */
-
-texture g_YTexture;
-texture g_UTexture;
-texture g_VTexture;
-texture g_KernelTexture;
-
-float2 g_YStep;
-float2 g_UVStep;
-
-float4x4 g_ColorMatrix;
-
-sampler YSampler =
- sampler_state {
- Texture = <g_YTexture>;
- AddressU = CLAMP;
- AddressV = CLAMP;
- MipFilter = LINEAR;
- MinFilter = POINT;
- MagFilter = POINT;
- };
-
-sampler USampler =
- sampler_state {
- Texture = <g_UTexture>;
- AddressU = CLAMP;
- AddressV = CLAMP;
- MipFilter = LINEAR;
- MinFilter = POINT;
- MagFilter = POINT;
- };
-
-sampler VSampler =
- sampler_state
- {
- Texture = <g_VTexture>;
- AddressU = CLAMP;
- AddressV = CLAMP;
- MipFilter = LINEAR;
- MinFilter = POINT;
- MagFilter = POINT;
- };
-
-sampler KernelSampler =
- sampler_state
- {
- Texture = <g_KernelTexture>;
- AddressU = CLAMP;
- AddressV = CLAMP;
- MipFilter = LINEAR;
- MinFilter = LINEAR;
- MagFilter = LINEAR;
- };
-
-struct VS_OUTPUT
-{
- float4 Position : POSITION;
- float2 TextureY : TEXCOORD0;
- float2 TextureU : TEXCOORD1;
- float2 TextureV : TEXCOORD2;
-};
-
-struct PS_OUTPUT
-{
- float4 RGBColor : COLOR0;
-};
-
-float4 weight(float pos)
-{
- return tex1D(KernelSampler, pos);
-}
-
-float pixel(sampler tex, float xpos, float ypos)
-{
- return tex2D(tex, float2(xpos, ypos)).r;
-}
-
-float getLine(sampler tex, float ypos, float4 xpos, float4 linetaps)
-{
- float pixels;
-
- pixels = pixel(tex, xpos.r, ypos) * linetaps.r;
- pixels += pixel(tex, xpos.g, ypos) * linetaps.g;
- pixels += pixel(tex, xpos.b, ypos) * linetaps.b;
- pixels += pixel(tex, xpos.a, ypos) * linetaps.a;
-
- return pixels;
-}
-
-float getPixel(sampler tex, float2 texCoord, float2 step)
-{
- float xf = frac(texCoord.x / step.x);
- float yf = frac(texCoord.y / step.y);
-
- float4 linetaps = weight(1.0 - xf);
- float4 columntaps = weight(1.0 - yf);
-
- float4 xpos = float4(
- (-0.5 - xf) * step.x + texCoord.x,
- ( 0.5 - xf) * step.x + texCoord.x,
- ( 1.5 - xf) * step.x + texCoord.x,
- ( 2.5 - xf) * step.x + texCoord.x);
-
- float fragColor;
- fragColor = getLine(tex, (-0.5 - yf) * step.y + texCoord.y, xpos, linetaps) * columntaps.r;
- fragColor += getLine(tex, ( 0.5 - yf) * step.y + texCoord.y, xpos, linetaps) * columntaps.g;
- fragColor += getLine(tex, ( 1.5 - yf) * step.y + texCoord.y, xpos, linetaps) * columntaps.b;
- fragColor += getLine(tex, ( 2.5 - yf) * step.y + texCoord.y, xpos, linetaps) * columntaps.a;
-
- return fragColor;
-}
-
-PS_OUTPUT YUV2RGB(VS_OUTPUT In)
-{
- PS_OUTPUT OUT;
- float4 YUV = float4(getPixel (YSampler, In.TextureY, g_YStep)
- , getPixel (USampler, In.TextureU, g_UVStep)
- , getPixel (VSampler, In.TextureV, g_UVStep)
- , 1.0);
- OUT.RGBColor = mul(YUV, g_ColorMatrix);
- OUT.RGBColor.a = 1.0;
- return OUT;
-}
-
-technique YUV2RGB_T
-{
- pass P0
- {
- PixelShader = compile ps_3_0 YUV2RGB();
- ZEnable = False;
- FillMode = Solid;
- FogEnable = False;
- }
-};
+++ /dev/null
-/*
- * Copyright (C) 2010-2013 Team XBMC
- * http://xbmc.org
- *
- * This Program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2, or (at your option)
- * any later version.
- *
- * This Program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with XBMC; see the file COPYING. If not, see
- * <http://www.gnu.org/licenses/>.
- *
- */
-
-texture g_YTexture;
-texture g_UTexture;
-texture g_VTexture;
-texture g_KernelTexture;
-
-float2 g_YStep;
-float2 g_UVStep;
-
-float4x4 g_ColorMatrix;
-
-sampler YSampler =
- sampler_state {
- Texture = <g_YTexture>;
- AddressU = CLAMP;
- AddressV = CLAMP;
- MipFilter = LINEAR;
- MinFilter = POINT;
- MagFilter = POINT;
- };
-
-sampler USampler =
- sampler_state {
- Texture = <g_UTexture>;
- AddressU = CLAMP;
- AddressV = CLAMP;
- MipFilter = LINEAR;
- MinFilter = POINT;
- MagFilter = POINT;
- };
-
-sampler VSampler =
- sampler_state
- {
- Texture = <g_VTexture>;
- AddressU = CLAMP;
- AddressV = CLAMP;
- MipFilter = LINEAR;
- MinFilter = POINT;
- MagFilter = POINT;
- };
-
-sampler KernelSampler =
- sampler_state
- {
- Texture = <g_KernelTexture>;
- AddressU = CLAMP;
- AddressV = CLAMP;
- MipFilter = LINEAR;
- MinFilter = LINEAR;
- MagFilter = LINEAR;
- };
-
-struct VS_OUTPUT
-{
- float4 Position : POSITION;
- float2 TextureY : TEXCOORD0;
- float2 TextureU : TEXCOORD1;
- float2 TextureV : TEXCOORD2;
-};
-
-struct PS_OUTPUT
-{
- float4 RGBColor : COLOR0;
-};
-
-float3 weight(float pos)
-{
- return tex1D(KernelSampler, pos).rgb;
-}
-
-float pixel(sampler tex, float xpos, float ypos)
-{
- return tex2D(tex, float2(xpos, ypos)).r;
-}
-
-float getLine(sampler tex, float ypos, float3 xpos1, float3 xpos2, float3 linetaps1, float3 linetaps2)
-{
- float pixels;
-
- pixels = pixel(tex, xpos1.r, ypos) * linetaps1.r;
- pixels += pixel(tex, xpos1.g, ypos) * linetaps2.r;
- pixels += pixel(tex, xpos1.b, ypos) * linetaps1.g;
- pixels += pixel(tex, xpos2.r, ypos) * linetaps2.g;
- pixels += pixel(tex, xpos2.g, ypos) * linetaps1.b;
- pixels += pixel(tex, xpos2.b, ypos) * linetaps2.b;
-
- return pixels;
-}
-
-float getPixel(sampler tex, float2 texCoord, float2 step)
-{
- float xf = frac(texCoord.x / step.x);
- float yf = frac(texCoord.y / step.y);
-
- float3 linetaps1 = weight((1.0 - xf) / 2.0);
- float3 linetaps2 = weight((1.0 - xf) / 2.0 + 0.5);
- float3 columntaps1 = weight((1.0 - yf) / 2.0);
- float3 columntaps2 = weight((1.0 - yf) / 2.0 + 0.5);
-
- float3 xpos1 = float3(
- (-1.5 - xf) * step.x + texCoord.x,
- (-0.5 - xf) * step.x + texCoord.x,
- ( 0.5 - xf) * step.x + texCoord.x);
- float3 xpos2 = float3(
- ( 1.5 - xf) * step.x + texCoord.x,
- ( 2.5 - xf) * step.x + texCoord.x,
- ( 3.5 - xf) * step.x + texCoord.x);
-
- float fragColor;
- fragColor = getLine(tex, (-1.5 - yf) * step.y + texCoord.y, xpos1, xpos2, linetaps1, linetaps2) * columntaps1.r;
- fragColor += getLine(tex, (-0.5 - yf) * step.y + texCoord.y, xpos1, xpos2, linetaps1, linetaps2) * columntaps2.r;
- fragColor += getLine(tex, ( 0.5 - yf) * step.y + texCoord.y, xpos1, xpos2, linetaps1, linetaps2) * columntaps1.g;
- fragColor += getLine(tex, ( 1.5 - yf) * step.y + texCoord.y, xpos1, xpos2, linetaps1, linetaps2) * columntaps2.g;
- fragColor += getLine(tex, ( 2.5 - yf) * step.y + texCoord.y, xpos1, xpos2, linetaps1, linetaps2) * columntaps1.b;
- fragColor += getLine(tex, ( 3.5 - yf) * step.y + texCoord.y, xpos1, xpos2, linetaps1, linetaps2) * columntaps2.b;
-
- return fragColor;
-}
-
-PS_OUTPUT YUV2RGB(VS_OUTPUT In)
-{
- PS_OUTPUT OUT;
- float4 YUV = float4(getPixel (YSampler, In.TextureY, g_YStep)
- , getPixel (USampler, In.TextureU, g_UVStep)
- , getPixel (VSampler, In.TextureV, g_UVStep)
- , 1.0);
- OUT.RGBColor = mul(YUV, g_ColorMatrix);
- OUT.RGBColor.a = 1.0;
- return OUT;
-}
-
-technique YUV2RGB_T
-{
- pass P0
- {
- PixelShader = compile ps_3_0 YUV2RGB();
- ZEnable = False;
- FillMode = Solid;
- FogEnable = False;
- }
-};