From 959133058bbe7711caa29ffac105efc3ccefac64 Mon Sep 17 00:00:00 2001 From: ened Date: Tue, 7 Oct 2025 21:35:00 +0900 Subject: [PATCH] Select dav1d decoder (WIP) --- .../vav2player/Vav2Player/App.xaml.cpp | 33 ++++++++++ .../Vav2Player/VideoPlayerControl2.xaml.cpp | 1 + .../src/Playback/FrameProcessor.cpp | 63 ++++++++++++++----- .../Vav2Player/src/Playback/FrameProcessor.h | 7 +++ .../src/Playback/PlaybackController.cpp | 55 +++++++++++++++- .../src/Playback/PlaybackController.h | 1 + .../src/Rendering/D3D12VideoRenderer.cpp | 19 +++++- .../Vav2Player/src/Rendering/IVideoBackend.h | 4 +- .../src/Rendering/RGBASurfaceBackend.cpp | 15 +++-- .../src/Rendering/RGBASurfaceBackend.h | 3 +- .../src/Rendering/YUV420PUploadBackend.cpp | 15 +++-- .../src/Rendering/YUV420PUploadBackend.h | 8 ++- .../Vav2Player/src/Utils/DecoderTypeUtils.h | 24 +++++++ .../platforms/windows/vavcore/src/VavCore.cpp | 3 + 14 files changed, 216 insertions(+), 35 deletions(-) create mode 100644 vav2/platforms/windows/applications/vav2player/Vav2Player/src/Utils/DecoderTypeUtils.h diff --git a/vav2/platforms/windows/applications/vav2player/Vav2Player/App.xaml.cpp b/vav2/platforms/windows/applications/vav2player/Vav2Player/App.xaml.cpp index 1f50d09..f87b693 100644 --- a/vav2/platforms/windows/applications/vav2player/Vav2Player/App.xaml.cpp +++ b/vav2/platforms/windows/applications/vav2player/Vav2Player/App.xaml.cpp @@ -4,6 +4,8 @@ #include "VavCore/VavCore.h" #include "src/Logger/SimpleLogger.h" #include "src/Logger/LogManager.h" +#include "src/Utils/DecoderTypeUtils.h" +#include using namespace winrt; using namespace winrt::Microsoft::UI::Xaml; @@ -50,6 +52,37 @@ namespace winrt::Vav2Player::implementation void App::OnLaunched(LaunchActivatedEventArgs const&) { + // Log current decoder settings on app launch + try { + auto localSettings = winrt::Windows::Storage::ApplicationData::Current().LocalSettings(); + auto values = localSettings.Values(); + + if (values.HasKey(L"DecoderType")) { + int32_t decoderTypeInt = winrt::unbox_value(values.Lookup(L"DecoderType")); + + const char* decoderName = ::Vav2Player::Utils::GetDecoderTypeName( + static_cast(decoderTypeInt)); + + // Log to UI (LogManager) + std::wstring decoderTypeName(decoderName, decoderName + strlen(decoderName)); + std::wostringstream logMsg; + logMsg << L"Current decoder setting: " << decoderTypeName + << L" (type=" << decoderTypeInt << L")"; + ::Vav2Player::LogManager::GetInstance().LogInfo(logMsg.str(), L"App"); + + ::Vav2Player::SimpleLogger::GetInstance().LogInfoF( + "[App] Current decoder setting: %s (type=%d)", decoderName, decoderTypeInt); + } else { + ::Vav2Player::LogManager::GetInstance().LogInfo(L"No decoder setting found, will use AUTO", L"App"); + ::Vav2Player::SimpleLogger::GetInstance().LogInfo( + "[App] No decoder setting found, will use AUTO"); + } + } catch (...) { + ::Vav2Player::LogManager::GetInstance().LogError(L"Failed to read decoder settings", L"App"); + ::Vav2Player::SimpleLogger::GetInstance().LogError( + "[App] Failed to read decoder settings"); + } + window = winrt::make(); window.Activate(); } diff --git a/vav2/platforms/windows/applications/vav2player/Vav2Player/VideoPlayerControl2.xaml.cpp b/vav2/platforms/windows/applications/vav2player/Vav2Player/VideoPlayerControl2.xaml.cpp index e2d44ab..7ef2e07 100644 --- a/vav2/platforms/windows/applications/vav2player/Vav2Player/VideoPlayerControl2.xaml.cpp +++ b/vav2/platforms/windows/applications/vav2player/Vav2Player/VideoPlayerControl2.xaml.cpp @@ -323,6 +323,7 @@ namespace winrt::Vav2Player::implementation // Link FrameProcessor to PlaybackController for timing synchronization if (m_frameProcessor) { m_playbackController->SetFrameProcessor(m_frameProcessor.get()); + m_frameProcessor->SetDecoderType(m_playbackController->GetDecoderType()); m_frameProcessor->PrepareVideoTexture(videoWidth, videoHeight); } diff --git a/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Playback/FrameProcessor.cpp b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Playback/FrameProcessor.cpp index 740a6f2..2330b04 100644 --- a/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Playback/FrameProcessor.cpp +++ b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Playback/FrameProcessor.cpp @@ -1,6 +1,8 @@ #include "pch.h" #include "FrameProcessor.h" +#include "../Utils/DecoderTypeUtils.h" #include "../Logger/SimpleLogger.h" +#include "../Logger/LogManager.h" #include #include @@ -28,6 +30,22 @@ void FrameProcessor::SetDispatcherQueue(winrt::Microsoft::UI::Dispatching::Dispa m_dispatcherQueue = queue; } +void FrameProcessor::SetDecoderType(VavCoreDecoderType type) +{ + m_decoderType = type; + + // Log to UI (LogManager) + std::wstring decoderTypeName(Utils::GetDecoderTypeName(type), + Utils::GetDecoderTypeName(type) + strlen(Utils::GetDecoderTypeName(type))); + std::wstring logMsg = L"Decoder type set to: " + decoderTypeName + + L" (type=" + std::to_wstring(static_cast(type)) + L")"; + LogManager::GetInstance().LogInfo(logMsg, L"FrameProcessor"); + + // Also log to console for debugging + LOGF_INFO("[FrameProcessor] Decoder type set to: %s (type=%d)", + Utils::GetDecoderTypeName(type), static_cast(type)); +} + void FrameProcessor::PrepareVideoTexture(uint32_t width, uint32_t height) { if (m_renderer) { @@ -54,24 +72,37 @@ bool FrameProcessor::ProcessFrame(VavCorePlayer* player, return false; } - // Get next RGBA texture from renderer (triple buffering) - ID3D12Resource* rgbaTexture = m_renderer->GetNextRGBATextureForCUDAInterop(); - if (!rgbaTexture) { - LOGF_ERROR("[FrameProcessor] Failed to get next RGBA texture"); - m_frameProcessing.store(false); - if (onComplete) onComplete(false); - return false; - } - - // Decode frame to D3D12 surface (blocking) + // Decode strategy based on decoder type auto decodeStart = std::chrono::high_resolution_clock::now(); VavCoreVideoFrame vavFrame = {}; - VavCoreResult result = vavcore_decode_to_surface( - player, - VAVCORE_SURFACE_D3D12_RESOURCE, - rgbaTexture, - &vavFrame - ); + VavCoreResult result; + + if (m_decoderType == VAVCORE_DECODER_DAV1D) { + // DAV1D: CPU decoding only + LOGF_DEBUG("[FrameProcessor] Using DAV1D CPU decode path"); + result = vavcore_decode_next_frame(player, &vavFrame); + if (result == VAVCORE_SUCCESS) { + vavFrame.surface_type = VAVCORE_SURFACE_CPU; + LOGF_DEBUG("[FrameProcessor] DAV1D decode success, surface_type=CPU"); + } + } else { + // NVDEC/Hardware: D3D12 surface decoding + ID3D12Resource* rgbaTexture = m_renderer->GetNextRGBATextureForCUDAInterop(); + if (!rgbaTexture) { + LOGF_ERROR("[FrameProcessor] Failed to get next RGBA texture"); + m_frameProcessing.store(false); + if (onComplete) onComplete(false); + return false; + } + + result = vavcore_decode_to_surface( + player, + VAVCORE_SURFACE_D3D12_RESOURCE, + rgbaTexture, + &vavFrame + ); + } + auto decodeEnd = std::chrono::high_resolution_clock::now(); double decodeTime = std::chrono::duration(decodeEnd - decodeStart).count(); diff --git a/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Playback/FrameProcessor.h b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Playback/FrameProcessor.h index 6e7be43..f23beef 100644 --- a/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Playback/FrameProcessor.h +++ b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Playback/FrameProcessor.h @@ -23,6 +23,10 @@ public: // Set renderer for frame output void SetRenderer(D3D12VideoRenderer* renderer); + // Set decoder type (to choose decode strategy) + void SetDecoderType(VavCoreDecoderType type); + VavCoreDecoderType GetDecoderType() const { return m_decoderType; } + // Set dispatcher queue for UI thread callbacks void SetDispatcherQueue(winrt::Microsoft::UI::Dispatching::DispatcherQueue const& queue); @@ -48,6 +52,9 @@ private: D3D12VideoRenderer* m_renderer = nullptr; // Non-owning pointer winrt::Microsoft::UI::Dispatching::DispatcherQueue m_dispatcherQueue{ nullptr }; + // Decoder configuration + VavCoreDecoderType m_decoderType = VAVCORE_DECODER_AUTO; + // Processing state (prevents NVDEC surface queue overflow) std::atomic m_frameProcessing{false}; diff --git a/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Playback/PlaybackController.cpp b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Playback/PlaybackController.cpp index ffc9361..b17a71e 100644 --- a/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Playback/PlaybackController.cpp +++ b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Playback/PlaybackController.cpp @@ -1,6 +1,7 @@ #include "pch.h" #include "PlaybackController.h" #include "FrameProcessor.h" +#include "../Utils/DecoderTypeUtils.h" #include "../Logger/SimpleLogger.h" #include #include @@ -12,6 +13,9 @@ PlaybackController::PlaybackController() // NOTE: VavCore is initialized globally in App.xaml.cpp // Do NOT call vavcore_initialize() here to avoid duplicate initialization LOGF_INFO("[PlaybackController] Constructor called (VavCore already initialized)"); + + // Load decoder settings from ApplicationData.LocalSettings + LoadDecoderSettings(); } PlaybackController::~PlaybackController() @@ -205,13 +209,62 @@ void PlaybackController::Seek(double timeSeconds) } } +void PlaybackController::LoadDecoderSettings() +{ + try { + // Load decoder settings from Windows.Storage.ApplicationData.Current.LocalSettings + auto localSettings = winrt::Windows::Storage::ApplicationData::Current().LocalSettings(); + auto values = localSettings.Values(); + + if (values.HasKey(L"DecoderType")) { + int32_t decoderTypeInt = winrt::unbox_value(values.Lookup(L"DecoderType")); + m_decoderType = static_cast(decoderTypeInt); + + // Log to UI (LogManager) + std::wstring decoderTypeName(Utils::GetDecoderTypeName(m_decoderType), + Utils::GetDecoderTypeName(m_decoderType) + strlen(Utils::GetDecoderTypeName(m_decoderType))); + std::wstring logMsg = L"Loaded decoder settings: " + decoderTypeName + + L" (type=" + std::to_wstring(static_cast(m_decoderType)) + L")"; + LogManager::GetInstance().LogInfo(logMsg, L"PlaybackController"); + + LOGF_INFO("[PlaybackController] Loaded decoder settings: %s (type=%d)", + Utils::GetDecoderTypeName(m_decoderType), static_cast(m_decoderType)); + } else { + // No saved settings, use default + m_decoderType = VAVCORE_DECODER_AUTO; + LogManager::GetInstance().LogInfo(L"No saved decoder settings, using default: AUTO", L"PlaybackController"); + LOGF_INFO("[PlaybackController] No saved decoder settings, using default: AUTO"); + } + } catch (const std::exception& e) { + // Fallback to AUTO if loading fails + m_decoderType = VAVCORE_DECODER_AUTO; + + std::string errorMsg = "Failed to load decoder settings: " + std::string(e.what()) + ", using AUTO"; + std::wstring wErrorMsg(errorMsg.begin(), errorMsg.end()); + LogManager::GetInstance().LogError(wErrorMsg, L"PlaybackController"); + + LOGF_ERROR("[PlaybackController] Failed to load decoder settings: %s, using AUTO", e.what()); + } +} + void PlaybackController::SetDecoderType(VavCoreDecoderType type) { m_decoderType = type; + // Log to UI (LogManager) + std::wstring decoderTypeName(Utils::GetDecoderTypeName(type), + Utils::GetDecoderTypeName(type) + strlen(Utils::GetDecoderTypeName(type))); + std::wstring logMsg = L"Decoder type changed to: " + decoderTypeName + + L" (type=" + std::to_wstring(static_cast(type)) + L")"; + LogManager::GetInstance().LogInfo(logMsg, L"PlaybackController"); + + LOGF_INFO("[PlaybackController] Decoder type changed to: %s (type=%d)", + Utils::GetDecoderTypeName(type), static_cast(type)); + if (m_vavCorePlayer) { vavcore_set_decoder_type(m_vavCorePlayer, type); - LOGF_INFO("[PlaybackController] Decoder type set to %d", static_cast(type)); + LogManager::GetInstance().LogInfo(L"Applied decoder type to active VavCore player", L"PlaybackController"); + LOGF_INFO("[PlaybackController] Applied decoder type to active VavCore player"); } } diff --git a/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Playback/PlaybackController.h b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Playback/PlaybackController.h index 84c72d3..51199df 100644 --- a/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Playback/PlaybackController.h +++ b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Playback/PlaybackController.h @@ -102,6 +102,7 @@ private: // Helper methods bool InitializeVavCore(); void CleanupVavCore(); + void LoadDecoderSettings(); // Load decoder settings from ApplicationData.LocalSettings void StartTimingThread(); void StopTimingThread(); void TimingThreadLoop(); diff --git a/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Rendering/D3D12VideoRenderer.cpp b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Rendering/D3D12VideoRenderer.cpp index aa74cc7..eed30b3 100644 --- a/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Rendering/D3D12VideoRenderer.cpp +++ b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Rendering/D3D12VideoRenderer.cpp @@ -155,8 +155,13 @@ HRESULT D3D12VideoRenderer::RenderVideoFrame(const VavCoreVideoFrame& frame, Vav // Get current back buffer ID3D12Resource* backBuffer = m_renderTargets[m_frameIndex].Get(); + // Get RTV handle for current back buffer + UINT rtvDescriptorSize = m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); + D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = m_rtvHeap->GetCPUDescriptorHandleForHeapStart(); + rtvHandle.ptr += m_frameIndex * rtvDescriptorSize; + // Delegate rendering to backend - hr = backend->RenderToBackBuffer(frame, backBuffer, m_commandList.Get()); + hr = backend->RenderToBackBuffer(frame, backBuffer, m_commandList.Get(), rtvHandle); if (FAILED(hr)) { return hr; } @@ -477,8 +482,16 @@ HRESULT D3D12VideoRenderer::InitializeBackends() { } IVideoBackend* D3D12VideoRenderer::SelectBackend(const VavCoreVideoFrame& frame) { - // For now, always use RGBA Surface backend for GPU-decoded frames - // Future: Check frame.surface_type to select appropriate backend + // Select backend based on frame surface type + if (frame.surface_type == VAVCORE_SURFACE_D3D12_RESOURCE) { + // Hardware decoder (NVDEC) - D3D12 RGBA texture + return m_rgbaSurfaceBackend.get(); + } else if (frame.surface_type == VAVCORE_SURFACE_CPU) { + // Software decoder (dav1d) - CPU YUV data + return m_yuv420pUploadBackend.get(); + } + + // Default to RGBA backend return m_rgbaSurfaceBackend.get(); } diff --git a/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Rendering/IVideoBackend.h b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Rendering/IVideoBackend.h index fb06150..8b928a3 100644 --- a/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Rendering/IVideoBackend.h +++ b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Rendering/IVideoBackend.h @@ -39,10 +39,12 @@ public: // Frame rendering // Renders the given frame to the specified back buffer + // rtvHandle: Render target view handle (used by backends that render directly) virtual HRESULT RenderToBackBuffer( const VavCoreVideoFrame& frame, ID3D12Resource* backBuffer, - ID3D12GraphicsCommandList* commandList) = 0; + ID3D12GraphicsCommandList* commandList, + D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle) = 0; // Format information // Returns an identifier for the format this backend supports diff --git a/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Rendering/RGBASurfaceBackend.cpp b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Rendering/RGBASurfaceBackend.cpp index 92c380e..93e4e57 100644 --- a/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Rendering/RGBASurfaceBackend.cpp +++ b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Rendering/RGBASurfaceBackend.cpp @@ -130,8 +130,11 @@ HRESULT RGBASurfaceBackend::CreateVideoTexture(uint32_t width, uint32_t height) HRESULT RGBASurfaceBackend::RenderToBackBuffer( const VavCoreVideoFrame& frame, ID3D12Resource* backBuffer, - ID3D12GraphicsCommandList* commandList) + ID3D12GraphicsCommandList* commandList, + D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle) { + // RGBASurfaceBackend doesn't need RTV (uses CopyResource) + (void)rtvHandle; if (!m_initialized) { return E_NOT_VALID_STATE; } @@ -183,8 +186,8 @@ HRESULT RGBASurfaceBackend::RenderToBackBuffer( barrierToRT.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES; commandList->ResourceBarrier(1, &barrierToRT); - // Create RTV for back buffer - D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle; + // Create RTV for back buffer (not needed anymore - use rtvHandle from parameter) + D3D12_CPU_DESCRIPTOR_HANDLE backBufferRtvHandle; D3D12_RENDER_TARGET_VIEW_DESC rtvDesc = {}; rtvDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM; rtvDesc.ViewDimension = D3D12_RTV_DIMENSION_TEXTURE2D; @@ -201,8 +204,8 @@ HRESULT RGBASurfaceBackend::RenderToBackBuffer( return hr; } - rtvHandle = rtvHeap->GetCPUDescriptorHandleForHeapStart(); - m_device->CreateRenderTargetView(backBuffer, &rtvDesc, rtvHandle); + backBufferRtvHandle = rtvHeap->GetCPUDescriptorHandleForHeapStart(); + m_device->CreateRenderTargetView(backBuffer, &rtvDesc, backBufferRtvHandle); // Set graphics pipeline commandList->SetPipelineState(m_pipelineState.Get()); @@ -219,7 +222,7 @@ HRESULT RGBASurfaceBackend::RenderToBackBuffer( commandList->SetGraphicsRootConstantBufferView(1, m_constantBuffer->GetGPUVirtualAddress()); // Set render target - commandList->OMSetRenderTargets(1, &rtvHandle, FALSE, nullptr); + commandList->OMSetRenderTargets(1, &backBufferRtvHandle, FALSE, nullptr); // Set viewport and scissor D3D12_VIEWPORT viewport = {}; diff --git a/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Rendering/RGBASurfaceBackend.h b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Rendering/RGBASurfaceBackend.h index b63b5d4..26099e3 100644 --- a/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Rendering/RGBASurfaceBackend.h +++ b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Rendering/RGBASurfaceBackend.h @@ -51,7 +51,8 @@ public: HRESULT RenderToBackBuffer( const VavCoreVideoFrame& frame, ID3D12Resource* backBuffer, - ID3D12GraphicsCommandList* commandList) override; + ID3D12GraphicsCommandList* commandList, + D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle) override; int GetSupportedFormatId() const override { return 1; diff --git a/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Rendering/YUV420PUploadBackend.cpp b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Rendering/YUV420PUploadBackend.cpp index 160e614..4c281ab 100644 --- a/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Rendering/YUV420PUploadBackend.cpp +++ b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Rendering/YUV420PUploadBackend.cpp @@ -429,7 +429,8 @@ HRESULT YUV420PUploadBackend::UpdateColorMatrix(const VavCoreVideoFrame& frame) HRESULT YUV420PUploadBackend::RenderToBackBuffer( const VavCoreVideoFrame& frame, ID3D12Resource* backBuffer, - ID3D12GraphicsCommandList* commandList) + ID3D12GraphicsCommandList* commandList, + D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle) { if (!m_initialized || !m_yTexture) return E_NOT_VALID_STATE; @@ -442,7 +443,7 @@ HRESULT YUV420PUploadBackend::RenderToBackBuffer( hr = ExecuteYUVToRGBConversion(commandList); if (FAILED(hr)) return hr; - hr = RenderRGBToBackBuffer(commandList, backBuffer); + hr = RenderRGBToBackBuffer(commandList, backBuffer, rtvHandle); if (FAILED(hr)) return hr; m_currentBufferIndex = (m_currentBufferIndex + 1) % BufferCount; @@ -499,14 +500,18 @@ HRESULT YUV420PUploadBackend::ExecuteYUVToRGBConversion(ID3D12GraphicsCommandLis return S_OK; } -HRESULT YUV420PUploadBackend::RenderRGBToBackBuffer(ID3D12GraphicsCommandList* commandList, ID3D12Resource* backBuffer) { +HRESULT YUV420PUploadBackend::RenderRGBToBackBuffer( + ID3D12GraphicsCommandList* commandList, + ID3D12Resource* backBuffer, + D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle) +{ UpdateConstantBuffer(); D3D12_RESOURCE_DESC backBufferDesc = backBuffer->GetDesc(); D3D12_RESOURCE_BARRIER barrier = ResourceBarrierTransition(backBuffer, D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET); commandList->ResourceBarrier(1, &barrier); - // Set render target - this part needs a proper RTV handle from the renderer orchestrator - // For now, assuming it's handled outside + // Set render target + commandList->OMSetRenderTargets(1, &rtvHandle, FALSE, nullptr); commandList->SetGraphicsRootSignature(m_graphicsRootSignature.Get()); commandList->SetPipelineState(m_graphicsPipelineState.Get()); diff --git a/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Rendering/YUV420PUploadBackend.h b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Rendering/YUV420PUploadBackend.h index c21a2f7..90e993a 100644 --- a/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Rendering/YUV420PUploadBackend.h +++ b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Rendering/YUV420PUploadBackend.h @@ -49,7 +49,8 @@ public: HRESULT RenderToBackBuffer( const VavCoreVideoFrame& frame, ID3D12Resource* backBuffer, - ID3D12GraphicsCommandList* commandList) override; + ID3D12GraphicsCommandList* commandList, + D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle) override; HRESULT UpdateFrame(const VavCoreVideoFrame& frame) override; @@ -138,7 +139,10 @@ private: HRESULT CopyUploadToGPU(ID3D12GraphicsCommandList* commandList, uint32_t bufferIndex); HRESULT ExecuteYUVToRGBConversion(ID3D12GraphicsCommandList* commandList); - HRESULT RenderRGBToBackBuffer(ID3D12GraphicsCommandList* commandList, ID3D12Resource* backBuffer); + HRESULT RenderRGBToBackBuffer( + ID3D12GraphicsCommandList* commandList, + ID3D12Resource* backBuffer, + D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle); // Shader compilation HRESULT CompileComputeShader(); diff --git a/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Utils/DecoderTypeUtils.h b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Utils/DecoderTypeUtils.h new file mode 100644 index 0000000..424225e --- /dev/null +++ b/vav2/platforms/windows/applications/vav2player/Vav2Player/src/Utils/DecoderTypeUtils.h @@ -0,0 +1,24 @@ +#pragma once + +#include "VavCore/VavCore.h" + +namespace Vav2Player { +namespace Utils { + +// Utility function to convert VavCoreDecoderType enum to human-readable string +// Used by: PlaybackController, FrameProcessor, App, SettingsPage +inline const char* GetDecoderTypeName(VavCoreDecoderType type) +{ + switch (type) { + case VAVCORE_DECODER_AUTO: return "AUTO"; + case VAVCORE_DECODER_DAV1D: return "dav1d (Software)"; + case VAVCORE_DECODER_NVDEC: return "NVDEC (NVIDIA)"; + case VAVCORE_DECODER_VPL: return "Intel VPL"; + case VAVCORE_DECODER_AMF: return "AMD AMF"; + case VAVCORE_DECODER_MEDIA_FOUNDATION: return "Media Foundation"; + default: return "UNKNOWN"; + } +} + +} // namespace Utils +} // namespace Vav2Player diff --git a/vav2/platforms/windows/vavcore/src/VavCore.cpp b/vav2/platforms/windows/vavcore/src/VavCore.cpp index b79168a..43b1644 100644 --- a/vav2/platforms/windows/vavcore/src/VavCore.cpp +++ b/vav2/platforms/windows/vavcore/src/VavCore.cpp @@ -780,6 +780,9 @@ VAVCORE_API VavCoreResult vavcore_decode_to_surface(VavCorePlayer* player, break; case VAVCORE_SURFACE_D3D12_RESOURCE: frame->surface_data.d3d12.d3d12_resource = target_surface; + // CRITICAL FIX: Copy CUDA fence value for D3D12-CUDA synchronization + // This fence value is set by NVDECAV1Decoder after CUDA kernel completion + frame->surface_data.d3d12.fence_value = videoFrame.sync_fence_value; break; case VAVCORE_SURFACE_CUDA_DEVICE: // CUDA device pointer will be set by decoder implementation