using System.Linq; using System.Windows.Media.Imaging; using ytLive.Models; using ytLive.Services; namespace ytLive.ViewModels; // Media source (TASK 21): decode sessions are owned app-wide by // MediaVideoSourceManager, refcounted by MediaPath. Modeled on the Webcam/Background // partials: the readonly manager field is assigned in the core constructor, the // shared WriteableBitmap published per file is adopted by every media Source whose // MediaPath matches, and ResolveOutputFrame feeds the live compositor. public partial class MainViewModel { // Decode resolution: the 1920x1080 master. Media frames are scaled to the // element rect by the compositor (UniformToFill), so this is the capture size. private const int MediaDecodeWidth = 1920; private const int MediaDecodeHeight = 1080; private readonly MediaVideoSourceManager _mediaManager; // MediaVideoSourceManager publishes one shared WriteableBitmap per file; every // media Source pointing at that path picks it up for the preview/canvas. private void OnMediaPreviewBitmapChanged(string path, WriteableBitmap bitmap) { foreach (var source in Scenes.SelectMany(s => s.Elements.OfType()) .Where(s => s.IsMediaSource && s.MediaPath == path)) source.VideoImageSource = bitmap; } // Called from the encoder error path is out of scope (TASK 21 sees the decoder // fail at startup); log to the debug console for now, surfaced via the UI later. private static void OnMediaFailed(string path, string message) => System.Diagnostics.Debug.WriteLine($"MediaSource: '{path}' failed: {message}"); }