Steve Lhomme pushed to branch master at VideoLAN / VLC
Commits:
2841b79d by Steve Lhomme at 2024-02-22T12:34:21+00:00
d3d11_scaler: only recreate the HQ Scaler texture
- - - - -
27391019 by Steve Lhomme at 2024-02-22T12:34:21+00:00
d3d11_scaler: allocate the HQ Scaler input texture with AMF API
No need to manage an extra variable, and that makes the code more generic.
- - - - -
e17246c5 by Steve Lhomme at 2024-02-22T12:34:21+00:00
d3d11_scaler: report AMF errors
- - - - -
43c44f30 by Steve Lhomme at 2024-02-22T12:34:21+00:00
d3d11_scaler: only (re)init the HQ Scaler when the output size changes
D3D11_UpscalerUpdate() is mostly called in those cases, but it's cleaner.
- - - - -
21f2fb90 by Steve Lhomme at 2024-02-22T12:34:21+00:00
d3d11_scaler: just reinit AMF when the scaler was already initialized
- - - - -
ef640c8b by Steve Lhomme at 2024-02-22T12:34:21+00:00
d3d11_scaler: ensure the AMF input/output textures matches the scaler sizes
- - - - -
1 changed file:
- modules/video_output/win32/d3d11_scaler.cpp
Changes:
=====================================
modules/video_output/win32/d3d11_scaler.cpp
=====================================
@@ -56,8 +56,8 @@ struct d3d11_scaler
#ifdef HAVE_AMF_SCALER
vlc_amf_context amf = {};
amf::AMFComponent *amf_scaler = nullptr;
+ bool amf_initialized{false};
amf::AMFSurface *amfInput = nullptr;
- ComPtr<ID3D11Texture2D> amfStaging;
d3d11_device_t *d3d_dev = nullptr;
#endif
};
@@ -315,27 +315,32 @@ int D3D11_UpscalerUpdate(vlc_object_t *vd, d3d11_scaler
*scaleProc, d3d11_device
{
AMF_RESULT res;
- if (scaleProc->amfInput != nullptr)
- {
- scaleProc->amfInput->Release();
- scaleProc->amfInput = nullptr;
- }
-
texDesc.Width = fmt->i_x_offset + fmt->i_visible_width;
texDesc.Height = fmt->i_y_offset + fmt->i_visible_height;
- hr = d3d_dev->d3ddevice->CreateTexture2D(&texDesc, nullptr,
scaleProc->amfStaging.ReleaseAndGetAddressOf());
- if (FAILED(hr))
+ if (scaleProc->amfInput != nullptr)
{
- msg_Err(vd, "Failed to create the staging texture.
(hr=0x%lX)", hr);
- goto done_super;
+ D3D11_TEXTURE2D_DESC stagingDesc;
+ auto packed =
scaleProc->amfInput->GetPlane(amf::AMF_PLANE_PACKED);
+ ID3D11Texture2D *amfStaging = reinterpret_cast<ID3D11Texture2D
*>(packed->GetNative());
+ amfStaging->GetDesc(&stagingDesc);
+ if (stagingDesc.Width != texDesc.Width || stagingDesc.Height
!= texDesc.Height)
+ {
+ scaleProc->amfInput->Release();
+ scaleProc->amfInput = nullptr;
+ }
}
- res =
scaleProc->amf.Context->CreateSurfaceFromDX11Native(scaleProc->amfStaging.Get(),
-
&scaleProc->amfInput,
- nullptr);
- if (unlikely(res != AMF_OK || scaleProc->amfInput == nullptr))
+
+ if (scaleProc->amfInput == nullptr)
{
- msg_Err(vd, "Failed to wrap D3D11 output texture. %d", res);
- goto done_super;
+ res =
scaleProc->amf.Context->AllocSurface(amf::AMF_MEMORY_DX11,
+
DXGIToAMF(scaleProc->d3d_fmt->formatTexture),
+ texDesc.Width,
texDesc.Height,
+
&scaleProc->amfInput);
+ if (unlikely(res != AMF_OK || scaleProc->amfInput == nullptr))
+ {
+ msg_Err(vd, "Failed to wrap D3D11 output texture. %d",
res);
+ goto done_super;
+ }
}
}
else
@@ -363,29 +368,41 @@ int D3D11_UpscalerUpdate(vlc_object_t *vd, d3d11_scaler
*scaleProc, d3d11_device
if (D3D11_AllocateResourceView(vlc_object_logger(vd),
d3d_dev->d3ddevice, scaleProc->d3d_fmt,
_upscaled, 0, scaleProc->SRVs) !=
VLC_SUCCESS)
goto done_super;
- }
#ifdef HAVE_AMF_SCALER
- if (scaleProc->amf_scaler)
- {
- AMF_RESULT res;
- res = scaleProc->amf_scaler->SetProperty(AMF_HQ_SCALER_OUTPUT_SIZE,
::AMFConstructSize(out_width, out_height));
- res = scaleProc->amf_scaler->SetProperty(AMF_HQ_SCALER_ENGINE_TYPE,
amf::AMF_MEMORY_DX11);
- res = scaleProc->amf_scaler->SetProperty(AMF_HQ_SCALER_ALGORITHM,
AMF_HQ_SCALER_ALGORITHM_VIDEOSR1_0);
- res = scaleProc->amf_scaler->SetProperty(AMF_HQ_SCALER_FROM_SRGB, 0);
- res = scaleProc->amf_scaler->SetProperty(AMF_HQ_SCALER_SHARPNESS, 0.5);
- res = scaleProc->amf_scaler->SetProperty(AMF_HQ_SCALER_FILL, 1);
- AMFColor black{0,0,0,255};
- res = scaleProc->amf_scaler->SetProperty(AMF_HQ_SCALER_FILL_COLOR,
black);
- // res = scaleProc->amf_scaler->SetProperty(AMF_HQ_SCALER_FRAME_RATE,
oFrameRate);
- auto amf_fmt = DXGIToAMF(scaleProc->d3d_fmt->formatTexture);
- res = scaleProc->amf_scaler->Init(amf_fmt,
- fmt->i_x_offset + fmt->i_visible_width,
- fmt->i_y_offset + fmt->i_visible_height);
- if (res != AMF_OK)
- return false;
+ if (scaleProc->amf_scaler)
+ {
+ AMF_RESULT res;
+ res =
scaleProc->amf_scaler->SetProperty(AMF_HQ_SCALER_OUTPUT_SIZE,
::AMFConstructSize(out_width, out_height));
+ res =
scaleProc->amf_scaler->SetProperty(AMF_HQ_SCALER_ENGINE_TYPE,
amf::AMF_MEMORY_DX11);
+ res = scaleProc->amf_scaler->SetProperty(AMF_HQ_SCALER_ALGORITHM,
AMF_HQ_SCALER_ALGORITHM_VIDEOSR1_0);
+ res = scaleProc->amf_scaler->SetProperty(AMF_HQ_SCALER_FROM_SRGB,
0);
+ res = scaleProc->amf_scaler->SetProperty(AMF_HQ_SCALER_SHARPNESS,
0.5);
+ res = scaleProc->amf_scaler->SetProperty(AMF_HQ_SCALER_FILL, 1);
+ AMFColor black{0,0,0,255};
+ res = scaleProc->amf_scaler->SetProperty(AMF_HQ_SCALER_FILL_COLOR,
black);
+ // res =
scaleProc->amf_scaler->SetProperty(AMF_HQ_SCALER_FRAME_RATE, oFrameRate);
+ auto amf_fmt = DXGIToAMF(scaleProc->d3d_fmt->formatTexture);
+ if (scaleProc->amf_initialized)
+ res = scaleProc->amf_scaler->ReInit(
+ fmt->i_x_offset + fmt->i_visible_width,
+ fmt->i_y_offset + fmt->i_visible_height);
+ else
+ res = scaleProc->amf_scaler->Init(amf_fmt,
+ fmt->i_x_offset + fmt->i_visible_width,
+ fmt->i_y_offset + fmt->i_visible_height);
+ if (res != AMF_OK)
+ {
+ msg_Err(vd, "Failed to (re)initialize scaler (err=%d)", res);
+ return false;
+ }
+ scaleProc->amf_initialized = true;
+ }
+#endif
}
- else
+
+#ifdef HAVE_AMF_SCALER
+ if (!scaleProc->amf_scaler)
{
#endif
RECT srcRect;
@@ -584,14 +601,24 @@ int D3D11_UpscalerScale(vlc_object_t *vd, d3d11_scaler
*scaleProc, picture_sys_d
AMF_RESULT res;
amf::AMFSurface *submitSurface;
- D3D11_TEXTURE2D_DESC texDesc;
- p_sys->texture[0]->GetDesc(&texDesc);
+ auto packedStaging =
scaleProc->amfInput->GetPlane(amf::AMF_PLANE_PACKED);
+ ID3D11Texture2D *amfStaging = reinterpret_cast<ID3D11Texture2D
*>(packedStaging->GetNative());
+
+#ifndef NDEBUG
+ D3D11_TEXTURE2D_DESC stagingDesc, inputDesc;
+ amfStaging->GetDesc(&stagingDesc);
+ p_sys->texture[KNOWN_DXGI_INDEX]->GetDesc(&inputDesc);
+ assert(stagingDesc.Width == inputDesc.Width);
+ assert(stagingDesc.Height == inputDesc.Height);
+ assert(stagingDesc.Format == inputDesc.Format);
+#endif
+
// copy source into staging as it may not be shared
d3d11_device_lock( scaleProc->d3d_dev );
-
scaleProc->d3d_dev->d3dcontext->CopySubresourceRegion(scaleProc->amfStaging.Get(),
+ scaleProc->d3d_dev->d3dcontext->CopySubresourceRegion(amfStaging,
0,
0, 0, 0,
-
p_sys->resource[KNOWN_DXGI_INDEX],
+
p_sys->texture[KNOWN_DXGI_INDEX],
p_sys->slice_index,
NULL);
d3d11_device_unlock( scaleProc->d3d_dev );
@@ -604,12 +631,18 @@ int D3D11_UpscalerScale(vlc_object_t *vd, d3d11_scaler
*scaleProc, picture_sys_d
return VLC_SUCCESS;
}
if (res != AMF_OK)
+ {
+ msg_Err(vd, "scaler input failed (err=%d)", res);
return VLC_EGENERIC;
+ }
amf::AMFData *amfOutput = nullptr;
res = scaleProc->amf_scaler->QueryOutput(&amfOutput);
if (res != AMF_OK)
+ {
+ msg_Err(vd, "scaler gave no output (err=%d)", res);
return VLC_EGENERIC;
+ }
assert(amfOutput->GetMemoryType() == amf::AMF_MEMORY_DX11);
amf::AMFSurface *amfOutputSurface =
reinterpret_cast<amf::AMFSurface*>(amfOutput);
@@ -617,6 +650,14 @@ int D3D11_UpscalerScale(vlc_object_t *vd, d3d11_scaler
*scaleProc, picture_sys_d
ID3D11Texture2D *out = reinterpret_cast<ID3D11Texture2D
*>(packed->GetNative());
+#ifndef NDEBUG
+ D3D11_TEXTURE2D_DESC outDesc;
+ out->GetDesc(&outDesc);
+ assert(outDesc.Width == scaleProc->Width);
+ assert(outDesc.Height == scaleProc->Height);
+ assert(outDesc.Format == inputDesc.Format);
+#endif
+
ReleaseSRVs(scaleProc);
ID3D11Texture2D *_upscaled[DXGI_MAX_SHADER_VIEW];
_upscaled[0] = out;
View it on GitLab:
https://code.videolan.org/videolan/vlc/-/compare/8aad07b588680adc5ed435ab5f48a12fd60c6dc4...ef640c8b63b4ffb224faf2161dd23e40bdc0fd3b
--
View it on GitLab:
https://code.videolan.org/videolan/vlc/-/compare/8aad07b588680adc5ed435ab5f48a12fd60c6dc4...ef640c8b63b4ffb224faf2161dd23e40bdc0fd3b
You're receiving this email because of your account on code.videolan.org.
VideoLAN code repository instance
_______________________________________________
vlc-commits mailing list
vlc-commits@videolan.org
https://mailman.videolan.org/listinfo/vlc-commits