diff --git a/vav2/Vav2Player/Vav2Player/VideoPlayerControl.xaml b/vav2/Vav2Player/Vav2Player/VideoPlayerControl.xaml index 773ee34..3d5e445 100644 --- a/vav2/Vav2Player/Vav2Player/VideoPlayerControl.xaml +++ b/vav2/Vav2Player/Vav2Player/VideoPlayerControl.xaml @@ -8,7 +8,8 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" Loaded="UserControl_Loaded" - Unloaded="UserControl_Unloaded"> + Unloaded="UserControl_Unloaded" + SizeChanged="UserControl_SizeChanged"> diff --git a/vav2/Vav2Player/Vav2Player/VideoPlayerControl.xaml.cpp b/vav2/Vav2Player/Vav2Player/VideoPlayerControl.xaml.cpp index c627520..0692efe 100644 --- a/vav2/Vav2Player/Vav2Player/VideoPlayerControl.xaml.cpp +++ b/vav2/Vav2Player/Vav2Player/VideoPlayerControl.xaml.cpp @@ -54,7 +54,6 @@ namespace winrt::Vav2Player::implementation ApplyAspectFitIfReady(); }); - OutputDebugStringA("VideoPlayerControl loaded successfully\n"); // Ready for user interaction } @@ -78,6 +77,7 @@ namespace winrt::Vav2Player::implementation if (m_playbackTimer) { m_playbackTimer.Stop(); + m_playbackTimer = nullptr; // Complete cleanup } if (m_gpuRenderer) @@ -92,7 +92,6 @@ namespace winrt::Vav2Player::implementation // Explicitly close file before destroying the reader if (m_fileReader->IsFileOpen()) { m_fileReader->CloseFile(); - OutputDebugStringA("[DEBUG] File explicitly closed\n"); } m_fileReader.reset(); } @@ -102,10 +101,8 @@ namespace winrt::Vav2Player::implementation m_isInitialized = false; m_isLoaded = false; - OutputDebugStringA("[DEBUG] UserControl_Unloaded: All resources cleaned up\n"); m_isInitialized = false; - OutputDebugStringA("VideoPlayerControl unloaded\n"); } catch (...) { @@ -113,6 +110,30 @@ namespace winrt::Vav2Player::implementation } } + void VideoPlayerControl::UserControl_SizeChanged(winrt::Windows::Foundation::IInspectable const&, winrt::Microsoft::UI::Xaml::SizeChangedEventArgs const& e) + { + // Recalculate AspectFit when container size changes + if (m_hasValidVideoSize && m_videoWidth > 0 && m_videoHeight > 0) { + UpdateVideoImageAspectFit(m_videoWidth, m_videoHeight); + } + + // Retry GPU rendering initialization if user prefers hardware rendering + // but we're currently using CPU rendering due to previous container size issues + if (m_useHardwareRendering && m_isLoaded) { + auto container = VideoDisplayArea(); + if (container) { + double containerWidth = container.ActualWidth(); + double containerHeight = container.ActualHeight(); + + // If container size is now valid and we're not showing GPU panel, retry GPU init + if (containerWidth > 0 && containerHeight > 0 && + VideoSwapChainPanel().Visibility() == winrt::Microsoft::UI::Xaml::Visibility::Collapsed) { + InitializeVideoRenderer(); + } + } + } + } + void VideoPlayerControl::HoverDetector_PointerEntered(winrt::Windows::Foundation::IInspectable const&, winrt::Microsoft::UI::Xaml::Input::PointerRoutedEventArgs const&) { // Controls are disabled for now @@ -260,224 +281,94 @@ namespace winrt::Vav2Player::implementation // Public Methods void VideoPlayerControl::LoadVideo(winrt::hstring const& filePath) { - OutputDebugStringA("[DEBUG] LoadVideo called\n"); - try - { - std::string filePathStr = winrt::to_string(filePath); - OutputDebugStringA(("[DEBUG] Loading file: " + filePathStr + "\n").c_str()); + std::string filePathStr = winrt::to_string(filePath); + UpdateStatus(L"Loading video..."); + LoadingRing().IsActive(true); - UpdateStatus(L"Loading video..."); - LoadingRing().IsActive(true); - - // Reset previous state - ResetVideoState(); - - // Create or reuse file reader - if (!m_fileReader) - { - OutputDebugStringA("[DEBUG] Creating WebMFileReader\n"); - m_fileReader = std::make_unique(); - } - else - { - // Explicitly close previous file if open - if (m_fileReader->IsFileOpen()) - { - OutputDebugStringA("[DEBUG] Closing previous file before loading new one\n"); - m_fileReader->CloseFile(); - } - } - - // Open file - OutputDebugStringA("[DEBUG] Opening file...\n"); - if (!m_fileReader->OpenFile(filePathStr)) - { - OutputDebugStringA("[DEBUG] Failed to open file\n"); - UpdateStatus(L"Failed to open video file"); - LoadingRing().IsActive(false); - return; - } - OutputDebugStringA("[DEBUG] File opened successfully\n"); - - // Get video tracks - OutputDebugStringA("[DEBUG] Getting video tracks...\n"); - auto tracks = m_fileReader->GetVideoTracks(); - if (tracks.empty()) - { - OutputDebugStringA("[DEBUG] No video tracks found\n"); - UpdateStatus(L"No video tracks found"); - LoadingRing().IsActive(false); - return; - } - OutputDebugStringA(("[DEBUG] Found " + std::to_string(tracks.size()) + " video tracks\n").c_str()); - - // Select first video track - OutputDebugStringA("[DEBUG] Selecting video track...\n"); - if (!m_fileReader->SelectVideoTrack(tracks[0].track_number)) - { - OutputDebugStringA("[DEBUG] Failed to select video track\n"); - UpdateStatus(L"Failed to select video track"); - LoadingRing().IsActive(false); - return; - } - OutputDebugStringA("[DEBUG] Video track selected successfully\n"); - - // Get metadata - OutputDebugStringA("[DEBUG] Getting video metadata...\n"); - auto metadata = m_fileReader->GetVideoMetadata(); - m_totalFrames = metadata.total_frames; - m_frameRate = metadata.frame_rate > 0 ? metadata.frame_rate : 30.0; - m_duration = m_totalFrames / m_frameRate; - - OutputDebugStringA(("[DEBUG] Video metadata: " + std::to_string(metadata.width) + "x" + std::to_string(metadata.height) + - ", " + std::to_string(m_totalFrames) + " frames, " + std::to_string(m_frameRate) + " fps\n").c_str()); - - // Try GPU rendering first, fallback to CPU if needed - UseHardwareRendering(true); - - // Create and initialize decoder - OutputDebugStringA("[DEBUG] Creating decoder...\n"); - if (!CreateDecoder()) - { - OutputDebugStringA("[DEBUG] Failed to create decoder\n"); - UpdateStatus(L"Failed to create decoder"); - LoadingRing().IsActive(false); - return; - } - - OutputDebugStringA("[DEBUG] Initializing decoder...\n"); - if (!InitializeDecoder()) - { - OutputDebugStringA("[DEBUG] Failed to initialize decoder\n"); - UpdateStatus(L"Failed to initialize decoder"); - LoadingRing().IsActive(false); - return; - } - OutputDebugStringA("[DEBUG] Decoder initialized successfully\n"); - - // Initialize video renderer - InitializeVideoRenderer(); - - // Set video dimensions from metadata for AspectFit - m_videoWidth = metadata.width; - m_videoHeight = metadata.height; - m_hasValidVideoSize = true; - m_isLoaded = true; // Set loaded state before AspectFit - OutputDebugStringA(("[DEBUG] Video dimensions set: " + std::to_string(m_videoWidth) + "x" + std::to_string(m_videoHeight) + "\n").c_str()); - - // Apply AspectFit now that we have video dimensions - ApplyAspectFitIfReady(); - LoadingRing().IsActive(false); - // Keep placeholder visible until first frame is rendered - - - UpdateStatus(L"Video loaded successfully"); - OutputDebugStringA(("[DEBUG] Video loaded successfully: " + filePathStr + "\n").c_str()); - - // Auto play if enabled - if (m_autoPlay) - { - OutputDebugStringA("[DEBUG] Auto play enabled - starting playback\n"); - Play(); - } + // Reset and create file reader + ResetVideoState(); + if (!m_fileReader) { + m_fileReader = std::make_unique(); + } else if (m_fileReader->IsFileOpen()) { + m_fileReader->CloseFile(); } - catch (...) - { - OutputDebugStringA("[DEBUG] Exception in LoadVideo\n"); - UpdateStatus(L"Error loading video"); + + // Open file and get tracks + if (!m_fileReader->OpenFile(filePathStr)) { + UpdateStatus(L"Failed to open video file"); LoadingRing().IsActive(false); + return; } + + auto tracks = m_fileReader->GetVideoTracks(); + if (tracks.empty() || !m_fileReader->SelectVideoTrack(tracks[0].track_number)) { + UpdateStatus(L"Failed to load video tracks"); + LoadingRing().IsActive(false); + return; + } + + // Set up video properties + auto metadata = m_fileReader->GetVideoMetadata(); + m_videoWidth = metadata.width; + m_videoHeight = metadata.height; + m_frameRate = metadata.frame_rate > 0 ? metadata.frame_rate : 30.0; + m_duration = metadata.total_frames / m_frameRate; + + // Create decoder and renderer + if (!CreateDecoder() || !InitializeDecoder()) { + UpdateStatus(L"Failed to initialize decoder"); + LoadingRing().IsActive(false); + return; + } + + InitializeVideoRenderer(); + m_hasValidVideoSize = true; + m_isLoaded = true; + + ApplyAspectFitIfReady(); + LoadingRing().IsActive(false); + UpdateStatus(L"Video loaded"); + + if (m_autoPlay) Play(); } void VideoPlayerControl::Play() { - OutputDebugStringA("[DEBUG] Play() called\n"); - if (!m_isLoaded || m_isPlaying) - { - OutputDebugStringA("[DEBUG] Play() - not ready or already playing\n"); + if (!m_isLoaded || m_isPlaying) { return; } m_isPlaying = true; UpdateStatus(L"Playing"); - - // Setup playback timer for continuous frame processing - if (!m_playbackTimer) + // Cleanup any existing timer before creating new one + if (m_playbackTimer) { - OutputDebugStringA("[DEBUG] Creating playback timer\n"); - m_playbackTimer = winrt::Microsoft::UI::Xaml::DispatcherTimer(); - - // Store weak reference to avoid circular dependency - auto weakThis = get_weak(); - m_playbackTimer.Tick([weakThis](auto&&, auto&&) { - if (auto strongThis = weakThis.get()) - { - OutputDebugStringA("[DEBUG] Timer tick - checking conditions\n"); - OutputDebugStringA(("[DEBUG] m_isPlaying: " + std::string(strongThis->m_isPlaying ? "true" : "false") + - ", m_isLoaded: " + std::string(strongThis->m_isLoaded ? "true" : "false") + "\n").c_str()); - - if (strongThis->m_isPlaying && strongThis->m_isLoaded) - { - try { - strongThis->ProcessSingleFrame(); - } - catch (...) { - OutputDebugStringA("[DEBUG] Exception in timer ProcessSingleFrame\n"); - strongThis->m_isPlaying = false; - strongThis->m_playbackTimer.Stop(); - } - } - else - { - OutputDebugStringA("[DEBUG] Timer tick - conditions not met, skipping frame processing\n"); - } - } - else - { - OutputDebugStringA("[DEBUG] Timer tick - object destroyed, stopping timer\n"); - } - }); + m_playbackTimer.Stop(); + m_playbackTimer = nullptr; } - // Set timer interval based on frame rate (default 30fps = 33.33ms) - auto interval = std::chrono::milliseconds(static_cast(1000.0 / m_frameRate)); - m_playbackTimer.Interval(interval); - - OutputDebugStringA(("[DEBUG] Timer interval set to: " + std::to_string(interval.count()) + "ms\n").c_str()); - OutputDebugStringA(("[DEBUG] Timer object valid: " + std::string(m_playbackTimer ? "true" : "false") + "\n").c_str()); - - m_playbackTimer.Start(); - OutputDebugStringA("[DEBUG] Timer.Start() called\n"); - - // Immediate test: try to process one frame manually to verify the pipeline works - OutputDebugStringA("[DEBUG] Testing immediate frame processing...\n"); - ProcessSingleFrame(); - - OutputDebugStringA(("[DEBUG] Started playback timer at " + std::to_string(m_frameRate) + " fps\n").c_str()); - - // Backup approach: Create a manual timer that restarts itself - OutputDebugStringA("[DEBUG] Setting up backup manual timer approach\n"); - auto manualTimer = winrt::Microsoft::UI::Xaml::DispatcherTimer(); - manualTimer.Interval(interval); - - // Manual timer approach with restart - manualTimer.Tick([this, manualTimer](auto&&, auto&&) mutable { - if (m_isPlaying && m_isLoaded) { - ProcessSingleFrame(); - // Schedule next frame - manualTimer.Start(); + // Create new playback timer + m_playbackTimer = winrt::Microsoft::UI::Xaml::DispatcherTimer(); + auto weakThis = get_weak(); + m_playbackTimer.Tick([weakThis](auto&&, auto&&) { + if (auto strongThis = weakThis.get()) { + if (strongThis->m_isPlaying && strongThis->m_isLoaded) { + strongThis->ProcessSingleFrame(); + } } }); - // Start both timers - manualTimer.Start(); - OutputDebugStringA("[DEBUG] Manual timer also started\n"); + auto interval = std::chrono::milliseconds(static_cast(1000.0 / m_frameRate)); + m_playbackTimer.Interval(interval); + m_playbackTimer.Start(); + + // Process first frame immediately + ProcessSingleFrame(); } void VideoPlayerControl::Pause() { - OutputDebugStringA("[DEBUG] Pause() called\n"); m_isPlaying = false; if (m_playbackTimer) { @@ -488,28 +379,27 @@ namespace winrt::Vav2Player::implementation void VideoPlayerControl::Stop() { - OutputDebugStringA("[DEBUG] Stop() called\n"); m_isPlaying = false; + + // Properly cleanup timer to prevent resource leaks if (m_playbackTimer) { m_playbackTimer.Stop(); + m_playbackTimer = nullptr; // Release timer completely } - // Reset position to beginning m_currentFrame = 0; m_currentTime = 0.0; // Reset file reader to beginning for next play if (m_fileReader && m_fileReader->IsFileOpen()) { - OutputDebugStringA("[DEBUG] Resetting file reader to beginning\n"); m_fileReader->Reset(); } // Reset decoder state if (m_decoder) { - OutputDebugStringA("[DEBUG] Resetting decoder state\n"); m_decoder->Reset(); } @@ -518,12 +408,22 @@ namespace winrt::Vav2Player::implementation void VideoPlayerControl::ProcessSingleFrame() { - // Simple validation - if (!m_isPlaying || !m_fileReader || !m_decoder) return; + OutputDebugStringA("[DEBUG] ProcessSingleFrame() called\n"); + // Simple validation + if (!m_isPlaying || !m_fileReader || !m_decoder) { + OutputDebugStringA(("[DEBUG] ProcessSingleFrame validation failed - playing:" + + std::string(m_isPlaying ? "true" : "false") + + " fileReader:" + std::string(m_fileReader ? "valid" : "null") + + " decoder:" + std::string(m_decoder ? "valid" : "null") + "\n").c_str()); + return; + } + + OutputDebugStringA("[DEBUG] Reading next packet...\n"); VideoPacket packet; if (!m_fileReader->ReadNextPacket(packet)) { + OutputDebugStringA("[DEBUG] End of video - stopping playback\n"); // End of video - stop playback m_isPlaying = false; if (m_playbackTimer) m_playbackTimer.Stop(); @@ -531,9 +431,14 @@ namespace winrt::Vav2Player::implementation return; } + OutputDebugStringA("[DEBUG] Decoding frame...\n"); VideoFrame frame; - if (!m_decoder->DecodeFrame(packet, frame)) return; // Skip failed frames + if (!m_decoder->DecodeFrame(packet, frame)) { + OutputDebugStringA("[DEBUG] Failed to decode frame - skipping\n"); + return; // Skip failed frames + } + OutputDebugStringA("[DEBUG] Rendering frame to screen...\n"); RenderFrameToScreen(frame); m_currentFrame++; @@ -563,14 +468,7 @@ namespace winrt::Vav2Player::implementation void VideoPlayerControl::RenderFrameSoftware(const VideoFrame& frame) { - OutputDebugStringA(("[DEBUG] RenderFrameSoftware() called - " + std::to_string(frame.width) + "x" + std::to_string(frame.height) + "\n").c_str()); - OutputDebugStringA(("[DEBUG] y_plane: " + std::string(frame.y_plane ? "valid" : "null") + "\n").c_str()); - - if (!frame.y_plane || frame.width == 0 || frame.height == 0) - { - OutputDebugStringA("[DEBUG] Invalid frame data - returning\n"); - return; - } + if (!frame.y_plane || frame.width == 0 || frame.height == 0) return; try { // Create or reuse WriteableBitmap for the frame @@ -578,7 +476,6 @@ namespace winrt::Vav2Player::implementation static_cast(m_renderBitmap.PixelWidth()) != frame.width || static_cast(m_renderBitmap.PixelHeight()) != frame.height) { - OutputDebugStringA("[DEBUG] Creating new WriteableBitmap\n"); m_renderBitmap = winrt::Microsoft::UI::Xaml::Media::Imaging::WriteableBitmap( frame.width, frame.height); VideoImage().Source(m_renderBitmap); @@ -594,21 +491,16 @@ namespace winrt::Vav2Player::implementation // Ensure video is visible VideoImage().Visibility(winrt::Microsoft::UI::Xaml::Visibility::Visible); - OutputDebugStringA(("Created WriteableBitmap: " + std::to_string(frame.width) + "x" + std::to_string(frame.height) + "\n").c_str()); } // Convert YUV to BGRA and render to bitmap auto buffer = m_renderBitmap.PixelBuffer(); uint32_t capacity = buffer.Capacity(); - OutputDebugStringA(("[DEBUG] Buffer capacity: " + std::to_string(capacity) + "\n").c_str()); - if (capacity >= frame.width * frame.height * 4) { - OutputDebugStringA("[DEBUG] Converting YUV to BGRA...\n"); // Simple approach: create BGRA data and copy to buffer std::vector bgra_data(frame.width * frame.height * 4); ConvertYUVToBGRA(frame, bgra_data.data(), frame.width, frame.height); - OutputDebugStringA("[DEBUG] Copying to bitmap buffer...\n"); // Copy BGRA data directly to bitmap buffer auto bufferByteAccess = buffer.as<::Windows::Storage::Streams::IBufferByteAccess>(); uint8_t* bufferData = nullptr; @@ -619,26 +511,21 @@ namespace winrt::Vav2Player::implementation // Trigger UI update m_renderBitmap.Invalidate(); - OutputDebugStringA(("[DEBUG] Frame rendered successfully: " + std::to_string(frame.width) + "x" + std::to_string(frame.height) + "\n").c_str()); } else { - OutputDebugStringA("[DEBUG] Buffer capacity too small\n"); } } catch (...) { - OutputDebugStringA("[DEBUG] Software rendering failed\n"); } } void VideoPlayerControl::ConvertYUVToBGRA(const VideoFrame& yuv_frame, uint8_t* bgra_buffer, uint32_t width, uint32_t height) { - OutputDebugStringA("[DEBUG] ConvertYUVToBGRA() called\n"); // YUV420P to BGRA conversion using BT.709 color space const uint8_t* y_plane = yuv_frame.y_plane.get(); const uint8_t* u_plane = yuv_frame.u_plane.get(); const uint8_t* v_plane = yuv_frame.v_plane.get(); if (!y_plane || !u_plane || !v_plane) { - OutputDebugStringA("[DEBUG] ConvertYUVToBGRA: Invalid plane data\n"); return; } @@ -646,7 +533,6 @@ namespace winrt::Vav2Player::implementation const uint32_t u_stride = yuv_frame.u_stride; const uint32_t v_stride = yuv_frame.v_stride; - OutputDebugStringA(("[DEBUG] YUV strides: Y=" + std::to_string(y_stride) + " U=" + std::to_string(u_stride) + " V=" + std::to_string(v_stride) + "\n").c_str()); for (uint32_t y = 0; y < height; y++) { const uint8_t* y_row = y_plane + y * y_stride; @@ -693,14 +579,12 @@ namespace winrt::Vav2Player::implementation void VideoPlayerControl::InitializeVideoRenderer() { - OutputDebugStringA("[DEBUG] InitializeVideoRenderer() called\n"); // Initialize rendering mode based on user selection if (!m_useHardwareRendering) { // Ensure software rendering UI is visible VideoSwapChainPanel().Visibility(winrt::Microsoft::UI::Xaml::Visibility::Collapsed); VideoImage().Visibility(winrt::Microsoft::UI::Xaml::Visibility::Visible); - OutputDebugStringA("[DEBUG] Initialized CPU rendering mode\n"); } else { @@ -720,28 +604,25 @@ namespace winrt::Vav2Player::implementation // Wait for container to be ready - don't use arbitrary fallback sizes if (containerWidth == 0 || containerHeight == 0) { - OutputDebugStringA("[DEBUG] GPU renderer: Container size not ready, deferring initialization\n"); - // Fallback to CPU rendering if container size unavailable + // Temporarily use CPU rendering until container size is available VideoSwapChainPanel().Visibility(winrt::Microsoft::UI::Xaml::Visibility::Collapsed); VideoImage().Visibility(winrt::Microsoft::UI::Xaml::Visibility::Visible); - m_useHardwareRendering = false; - OutputDebugStringA("[DEBUG] Switched to CPU rendering due to container size unavailable\n"); + // Don't change m_useHardwareRendering flag - keep user preference return; } - OutputDebugStringA(("[DEBUG] Initializing GPU renderer with size: " + std::to_string(containerWidth) + "x" + std::to_string(containerHeight) + "\n").c_str()); HRESULT hr = m_gpuRenderer->Initialize(VideoSwapChainPanel(), containerWidth, containerHeight); if (SUCCEEDED(hr)) { - OutputDebugStringA("[DEBUG] GPU rendering initialized successfully\n"); + // GPU rendering initialized successfully } else { - OutputDebugStringA("[DEBUG] GPU rendering initialization failed, falling back to CPU\n"); - m_useHardwareRendering = false; - m_gpuRenderer.reset(); + // GPU initialization failed - temporarily use CPU rendering + // Don't permanently change m_useHardwareRendering flag VideoSwapChainPanel().Visibility(winrt::Microsoft::UI::Xaml::Visibility::Collapsed); VideoImage().Visibility(winrt::Microsoft::UI::Xaml::Visibility::Visible); + // Keep GPU renderer for potential retry later } } } @@ -791,7 +672,6 @@ namespace winrt::Vav2Player::implementation void VideoPlayerControl::ApplyAspectFitIfReady() { if (!m_hasValidVideoSize || !m_isLoaded) { - OutputDebugStringA("[DEBUG] ApplyAspectFitIfReady: Not ready, skipping\n"); return; } @@ -800,10 +680,8 @@ namespace winrt::Vav2Player::implementation double containerWidth = container.ActualWidth(); double containerHeight = container.ActualHeight(); - OutputDebugStringA(("[DEBUG] ApplyAspectFitIfReady: Container size: " + std::to_string(containerWidth) + "x" + std::to_string(containerHeight) + "\n").c_str()); if (containerWidth <= 0 || containerHeight <= 0) { - OutputDebugStringA("[DEBUG] ApplyAspectFitIfReady: Container size invalid, skipping (will retry on SizeChanged)\n"); return; } @@ -812,8 +690,6 @@ namespace winrt::Vav2Player::implementation void VideoPlayerControl::UpdateVideoImageAspectFit(int videoWidth, int videoHeight) { - OutputDebugStringA(("[DEBUG] UpdateVideoImageAspectFit: " + std::to_string(videoWidth) + "x" + std::to_string(videoHeight) + "\n").c_str()); - // Store video dimensions for future use m_videoWidth = static_cast(videoWidth); m_videoHeight = static_cast(videoHeight); @@ -822,16 +698,13 @@ namespace winrt::Vav2Player::implementation // AspectFit calculation for proper video scaling auto container = VideoDisplayArea(); if (!container) { - OutputDebugStringA("[DEBUG] UpdateVideoImageAspectFit: No container\n"); return; } double containerWidth = container.ActualWidth(); double containerHeight = container.ActualHeight(); - OutputDebugStringA(("[DEBUG] UpdateVideoImageAspectFit: Container size: " + std::to_string(containerWidth) + "x" + std::to_string(containerHeight) + "\n").c_str()); if (containerWidth <= 0 || containerHeight <= 0) { - OutputDebugStringA("[DEBUG] UpdateVideoImageAspectFit: Invalid container size, skipping\n"); return; } @@ -849,20 +722,15 @@ namespace winrt::Vav2Player::implementation displayWidth = containerHeight * videoAspectRatio; } - OutputDebugStringA(("[DEBUG] UpdateVideoImageAspectFit: Calculated display size: " + std::to_string(displayWidth) + "x" + std::to_string(displayHeight) + "\n").c_str()); - // Apply AspectFit to both CPU and GPU rendering controls VideoImage().Width(displayWidth); VideoImage().Height(displayHeight); VideoImage().MaxWidth(displayWidth); VideoImage().MaxHeight(displayHeight); - // Also apply to GPU rendering SwapChainPanel VideoSwapChainPanel().Width(displayWidth); VideoSwapChainPanel().Height(displayHeight); - - OutputDebugStringA("[DEBUG] UpdateVideoImageAspectFit: AspectFit applied successfully\n"); } void VideoPlayerControl::Seek(double timeSeconds) diff --git a/vav2/Vav2Player/Vav2Player/VideoPlayerControl.xaml.h b/vav2/Vav2Player/Vav2Player/VideoPlayerControl.xaml.h index b60871a..6d8008f 100644 --- a/vav2/Vav2Player/Vav2Player/VideoPlayerControl.xaml.h +++ b/vav2/Vav2Player/Vav2Player/VideoPlayerControl.xaml.h @@ -19,6 +19,7 @@ namespace winrt::Vav2Player::implementation // Events void UserControl_Loaded(winrt::Windows::Foundation::IInspectable const& sender, winrt::Microsoft::UI::Xaml::RoutedEventArgs const& e); void UserControl_Unloaded(winrt::Windows::Foundation::IInspectable const& sender, winrt::Microsoft::UI::Xaml::RoutedEventArgs const& e); + void UserControl_SizeChanged(winrt::Windows::Foundation::IInspectable const& sender, winrt::Microsoft::UI::Xaml::SizeChangedEventArgs const& e); void HoverDetector_PointerEntered(winrt::Windows::Foundation::IInspectable const& sender, winrt::Microsoft::UI::Xaml::Input::PointerRoutedEventArgs const& e); void HoverDetector_PointerExited(winrt::Windows::Foundation::IInspectable const& sender, winrt::Microsoft::UI::Xaml::Input::PointerRoutedEventArgs const& e);