mirror of
https://github.com/moonlight-stream/moonlight-qt
synced 2024-12-13 04:42:27 +00:00
Fix video scaling on DXVA2
This commit is contained in:
parent
a4ad58d9ec
commit
06501bd4b7
2 changed files with 43 additions and 13 deletions
|
@ -101,8 +101,8 @@ int DXVA2Renderer::ffGetBuffer2(AVCodecContext* context, AVFrame* frame, int)
|
|||
|
||||
frame->data[3] = frame->buf[0]->data;
|
||||
frame->format = AV_PIX_FMT_DXVA2_VLD;
|
||||
frame->width = me->m_Width;
|
||||
frame->height = me->m_Height;
|
||||
frame->width = me->m_VideoWidth;
|
||||
frame->height = me->m_VideoHeight;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -218,8 +218,8 @@ bool DXVA2Renderer::initializeDecoder()
|
|||
alignment = 16;
|
||||
}
|
||||
|
||||
hr = m_DecService->CreateSurface(FFALIGN(m_Width, alignment),
|
||||
FFALIGN(m_Height, alignment),
|
||||
hr = m_DecService->CreateSurface(FFALIGN(m_VideoWidth, alignment),
|
||||
FFALIGN(m_VideoHeight, alignment),
|
||||
ARRAYSIZE(m_DecSurfaces) - 1,
|
||||
m_Desc.Format,
|
||||
D3DPOOL_DEFAULT,
|
||||
|
@ -262,6 +262,9 @@ bool DXVA2Renderer::initializeRenderer()
|
|||
D3DSURFACE_DESC renderTargetDesc;
|
||||
m_RenderTarget->GetDesc(&renderTargetDesc);
|
||||
|
||||
m_DisplayWidth = renderTargetDesc.Width;
|
||||
m_DisplayHeight = renderTargetDesc.Height;
|
||||
|
||||
hr = DXVA2CreateVideoService(m_Device, IID_IDirectXVideoProcessorService,
|
||||
reinterpret_cast<void**>(&m_ProcService));
|
||||
|
||||
|
@ -302,6 +305,14 @@ bool DXVA2Renderer::initializeRenderer()
|
|||
caps.VideoProcessorOperations);
|
||||
continue;
|
||||
}
|
||||
else if (!(caps.VideoProcessorOperations & DXVA2_VideoProcess_StretchX) ||
|
||||
!(caps.VideoProcessorOperations & DXVA2_VideoProcess_StretchY)) {
|
||||
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
|
||||
"Device %d can't stretch video: %x",
|
||||
i,
|
||||
caps.VideoProcessorOperations);
|
||||
continue;
|
||||
}
|
||||
|
||||
m_ProcService->GetProcAmpRange(guids[i], &m_Desc, renderTargetDesc.Format, DXVA2_ProcAmp_Brightness, &m_BrightnessRange);
|
||||
m_ProcService->GetProcAmpRange(guids[i], &m_Desc, renderTargetDesc.Format, DXVA2_ProcAmp_Contrast, &m_ContrastRange);
|
||||
|
@ -341,8 +352,8 @@ bool DXVA2Renderer::initializeRenderer()
|
|||
bool DXVA2Renderer::initialize(SDL_Window* window, int videoFormat, int width, int height)
|
||||
{
|
||||
m_VideoFormat = videoFormat;
|
||||
m_Width = width;
|
||||
m_Height = height;
|
||||
m_VideoWidth = width;
|
||||
m_VideoHeight = height;
|
||||
|
||||
// FFmpeg will be decoding on different threads than the main thread that we're
|
||||
// currently running on right now. We must set this hint so SDL will pass
|
||||
|
@ -366,8 +377,8 @@ bool DXVA2Renderer::initialize(SDL_Window* window, int videoFormat, int width, i
|
|||
m_Device = SDL_RenderGetD3D9Device(m_SdlRenderer);
|
||||
|
||||
RtlZeroMemory(&m_Desc, sizeof(m_Desc));
|
||||
m_Desc.SampleWidth = m_Width;
|
||||
m_Desc.SampleHeight = m_Height;
|
||||
m_Desc.SampleWidth = m_VideoWidth;
|
||||
m_Desc.SampleHeight = m_VideoHeight;
|
||||
m_Desc.SampleFormat.VideoChromaSubsampling = DXVA2_VideoChromaSubsampling_ProgressiveChroma;
|
||||
m_Desc.SampleFormat.NominalRange = DXVA2_NominalRange_0_255;
|
||||
m_Desc.SampleFormat.VideoTransferMatrix = DXVA2_VideoTransferMatrix_BT709;
|
||||
|
@ -421,15 +432,31 @@ void DXVA2Renderer::renderFrame(AVFrame* frame)
|
|||
sample.SrcSurface = surface;
|
||||
sample.SrcRect.right = m_Desc.SampleWidth;
|
||||
sample.SrcRect.bottom = m_Desc.SampleHeight;
|
||||
sample.DstRect = sample.SrcRect;
|
||||
sample.SampleFormat = m_Desc.SampleFormat;
|
||||
sample.PlanarAlpha = DXVA2_Fixed32OpaqueAlpha();
|
||||
|
||||
// Center in frame and preserve aspect ratio
|
||||
double srcAspectRatio = (double)m_Desc.SampleWidth / (double)m_Desc.SampleHeight;
|
||||
double dstAspectRatio = (double)m_DisplayWidth / (double)m_DisplayHeight;
|
||||
if (dstAspectRatio < srcAspectRatio) {
|
||||
// Greater height per width
|
||||
int drawHeight = (int)(m_DisplayWidth / srcAspectRatio);
|
||||
sample.DstRect.top = (m_DisplayHeight - drawHeight) / 2;
|
||||
sample.DstRect.bottom = sample.DstRect.bottom + drawHeight;
|
||||
sample.DstRect.right = m_DisplayWidth;
|
||||
}
|
||||
else {
|
||||
// Greater width per height
|
||||
int drawWidth = (int)(m_DisplayHeight * srcAspectRatio);
|
||||
sample.DstRect.bottom = m_DisplayHeight;
|
||||
sample.DstRect.left = (m_DisplayWidth - drawWidth) / 2;
|
||||
sample.DstRect.right = drawWidth;
|
||||
}
|
||||
|
||||
DXVA2_VideoProcessBltParams bltParams = {};
|
||||
|
||||
bltParams.TargetFrame = m_FrameIndex++;
|
||||
bltParams.TargetRect.right = m_Desc.SampleWidth;
|
||||
bltParams.TargetRect.bottom = m_Desc.SampleHeight;
|
||||
bltParams.TargetRect = sample.DstRect;
|
||||
bltParams.BackgroundColor.Y = 0x1000;
|
||||
bltParams.BackgroundColor.Cb = 0x8000;
|
||||
bltParams.BackgroundColor.Cr = 0x8000;
|
||||
|
|
|
@ -39,8 +39,11 @@ private:
|
|||
const enum AVPixelFormat* pixFmts);
|
||||
|
||||
int m_VideoFormat;
|
||||
int m_Width;
|
||||
int m_Height;
|
||||
int m_VideoWidth;
|
||||
int m_VideoHeight;
|
||||
|
||||
int m_DisplayWidth;
|
||||
int m_DisplayHeight;
|
||||
|
||||
SDL_Renderer* m_SdlRenderer;
|
||||
|
||||
|
|
Loading…
Reference in a new issue