Precompute the aspect ratio stretch to avoid having to change viewports twice each frame
This commit is contained in:
parent
4dc07bf63f
commit
918fea7d4b
1 changed files with 35 additions and 31 deletions
|
|
@ -563,8 +563,6 @@ void D3D11VARenderer::setHdrMode(bool enabled)
|
||||||
|
|
||||||
void D3D11VARenderer::renderFrame(AVFrame* frame)
|
void D3D11VARenderer::renderFrame(AVFrame* frame)
|
||||||
{
|
{
|
||||||
D3D11_VIEWPORT viewPort;
|
|
||||||
|
|
||||||
if (frame == nullptr) {
|
if (frame == nullptr) {
|
||||||
// End of stream - nothing to do for us
|
// End of stream - nothing to do for us
|
||||||
return;
|
return;
|
||||||
|
|
@ -582,33 +580,9 @@ void D3D11VARenderer::renderFrame(AVFrame* frame)
|
||||||
// because the render target view will be unbound by Present().
|
// because the render target view will be unbound by Present().
|
||||||
m_DeviceContext->OMSetRenderTargets(1, &m_RenderTargetView, nullptr);
|
m_DeviceContext->OMSetRenderTargets(1, &m_RenderTargetView, nullptr);
|
||||||
|
|
||||||
viewPort.MinDepth = 0;
|
|
||||||
viewPort.MaxDepth = 1;
|
|
||||||
|
|
||||||
// Set the viewport to render the video with aspect ratio scaling
|
|
||||||
SDL_Rect src, dst;
|
|
||||||
src.x = src.y = 0;
|
|
||||||
src.w = m_DecoderParams.width;
|
|
||||||
src.h = m_DecoderParams.height;
|
|
||||||
dst.x = dst.y = 0;
|
|
||||||
dst.w = m_DisplayWidth;
|
|
||||||
dst.h = m_DisplayHeight;
|
|
||||||
StreamUtils::scaleSourceToDestinationSurface(&src, &dst);
|
|
||||||
viewPort.TopLeftX = dst.x;
|
|
||||||
viewPort.TopLeftY = dst.y;
|
|
||||||
viewPort.Width = dst.w;
|
|
||||||
viewPort.Height = dst.h;
|
|
||||||
m_DeviceContext->RSSetViewports(1, &viewPort);
|
|
||||||
|
|
||||||
// Render our video frame with the aspect-ratio adjusted viewport
|
// Render our video frame with the aspect-ratio adjusted viewport
|
||||||
renderVideo(frame);
|
renderVideo(frame);
|
||||||
|
|
||||||
// Set the viewport to render overlays at the full window size
|
|
||||||
viewPort.TopLeftX = viewPort.TopLeftY = 0;
|
|
||||||
viewPort.Width = m_DisplayWidth;
|
|
||||||
viewPort.Height = m_DisplayHeight;
|
|
||||||
m_DeviceContext->RSSetViewports(1, &viewPort);
|
|
||||||
|
|
||||||
// Render overlays on top of the video stream
|
// Render overlays on top of the video stream
|
||||||
for (int i = 0; i < Overlay::OverlayMax; i++) {
|
for (int i = 0; i < Overlay::OverlayMax; i++) {
|
||||||
renderOverlay((Overlay::OverlayType)i);
|
renderOverlay((Overlay::OverlayType)i);
|
||||||
|
|
@ -1237,18 +1211,34 @@ bool D3D11VARenderer::setupRenderingResources()
|
||||||
|
|
||||||
// Create our fixed vertex buffer for video rendering
|
// Create our fixed vertex buffer for video rendering
|
||||||
{
|
{
|
||||||
SDL_assert(m_TextureAlignment != 0);
|
// Scale video to the window size while preserving aspect ratio
|
||||||
|
SDL_Rect src, dst;
|
||||||
|
src.x = src.y = 0;
|
||||||
|
src.w = m_DecoderParams.width;
|
||||||
|
src.h = m_DecoderParams.height;
|
||||||
|
dst.x = dst.y = 0;
|
||||||
|
dst.w = m_DisplayWidth;
|
||||||
|
dst.h = m_DisplayHeight;
|
||||||
|
StreamUtils::scaleSourceToDestinationSurface(&src, &dst);
|
||||||
|
|
||||||
|
// Convert screen space to normalized device coordinates
|
||||||
|
SDL_FRect renderRect;
|
||||||
|
renderRect.x = ((float)dst.x / (m_DisplayWidth / 2)) - 1.0f;
|
||||||
|
renderRect.y = ((float)dst.y / (m_DisplayHeight / 2)) - 1.0f;
|
||||||
|
renderRect.w = (float)dst.w / (m_DisplayWidth / 2);
|
||||||
|
renderRect.h = (float)dst.h / (m_DisplayHeight / 2);
|
||||||
|
|
||||||
// Don't sample from the alignment padding area since that's not part of the video
|
// Don't sample from the alignment padding area since that's not part of the video
|
||||||
|
SDL_assert(m_TextureAlignment != 0);
|
||||||
float uMax = (float)m_DecoderParams.width / FFALIGN(m_DecoderParams.width, m_TextureAlignment);
|
float uMax = (float)m_DecoderParams.width / FFALIGN(m_DecoderParams.width, m_TextureAlignment);
|
||||||
float vMax = (float)m_DecoderParams.height / FFALIGN(m_DecoderParams.height, m_TextureAlignment);
|
float vMax = (float)m_DecoderParams.height / FFALIGN(m_DecoderParams.height, m_TextureAlignment);
|
||||||
|
|
||||||
VERTEX verts[] =
|
VERTEX verts[] =
|
||||||
{
|
{
|
||||||
{-1, -1, 0, vMax},
|
{renderRect.x, renderRect.y, 0, vMax},
|
||||||
{-1, 1, 0, 0},
|
{renderRect.x, renderRect.y+renderRect.h, 0, 0},
|
||||||
{ 1, -1, uMax, vMax},
|
{renderRect.x+renderRect.w, renderRect.y, uMax, vMax},
|
||||||
{ 1, 1, uMax, 0},
|
{renderRect.x+renderRect.w, renderRect.y+renderRect.h, uMax, 0},
|
||||||
};
|
};
|
||||||
|
|
||||||
D3D11_BUFFER_DESC vbDesc = {};
|
D3D11_BUFFER_DESC vbDesc = {};
|
||||||
|
|
@ -1299,6 +1289,20 @@ bool D3D11VARenderer::setupRenderingResources()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set a viewport that fills the window
|
||||||
|
{
|
||||||
|
D3D11_VIEWPORT viewport;
|
||||||
|
|
||||||
|
viewport.TopLeftX = 0;
|
||||||
|
viewport.TopLeftY = 0;
|
||||||
|
viewport.Width = m_DisplayWidth;
|
||||||
|
viewport.Height = m_DisplayHeight;
|
||||||
|
viewport.MinDepth = 0;
|
||||||
|
viewport.MaxDepth = 1;
|
||||||
|
|
||||||
|
m_DeviceContext->RSSetViewports(1, &viewport);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue