diff --git a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/DirectShowLib-2005.dll b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/DirectShowLib-2005.dll deleted file mode 100644 index ba30521..0000000 Binary files a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/DirectShowLib-2005.dll and /dev/null differ diff --git a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/EVRPresenter32.dll b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/EVRPresenter32.dll deleted file mode 100644 index 548ce8b..0000000 Binary files a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/EVRPresenter32.dll and /dev/null differ diff --git a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/EVRPresenter64.dll b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/EVRPresenter64.dll deleted file mode 100644 index 19c83b6..0000000 Binary files a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/EVRPresenter64.dll and /dev/null differ diff --git a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/Controls/D3DRenderer.cs b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/Controls/D3DRenderer.cs deleted file mode 100644 index b38fcfb..0000000 --- a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/Controls/D3DRenderer.cs +++ /dev/null @@ -1,682 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Threading; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Interop; -using System.Windows.Media; -using System.Windows.Threading; -using WPFMediaKit.Effects; - -namespace WPFMediaKit.DirectShow.Controls; - -/// -/// The D3DRenderer class provides basic functionality needed -/// to render a D3D surface. This class is abstract. -/// -public abstract class D3DRenderer : FrameworkElement -{ - #region Local Instances - - /// - /// The D3DImage used to render video - /// - private D3DImage m_d3dImage; - - /// - /// The Image control that has the source - /// to the D3DImage - /// - private Image m_videoImage; - - /// - /// We keep reference to the D3D surface so - /// we can delay loading it to avoid a black flicker - /// when loading new media - /// - private IntPtr m_pBackBuffer = IntPtr.Zero; - - /// - /// Flag to tell us if we have a new D3D - /// Surface available - /// - private bool m_newSurfaceAvailable; - - /// - /// A weak reference of D3DRenderers that have been cloned - /// - private readonly List m_clonedD3Drenderers = new List(); - - /// - /// Backing field for the RenderOnCompositionTargetRendering flag. - /// - private bool m_renderOnCompositionTargetRendering; - - /// - /// Temporary storage for the RenderOnCompositionTargetRendering flag. - /// This is used to remember the value for when the control is loaded and unloaded. - /// - private bool m_renderOnCompositionTargetRenderingTemp; - - /// - /// TryLock timeout for the invalidate video image. Low values means higher UI responsivity, but more video dropped frames. - /// - private Duration m_invalidateVideoImageLockDuration = new Duration(TimeSpan.FromMilliseconds(100)); - - /// - /// Flag to reduce redundant calls to the AddDirtyRect when the rendering thread is busy. - /// Int instead of bool for Interlocked support. - /// - private int m_videoImageInvalid = 1; - - #endregion Local Instances - - #region Dependency Properties - - #region Stretch - - public static readonly DependencyProperty StretchProperty = - DependencyProperty.Register("Stretch", typeof(Stretch), typeof(D3DRenderer), - new FrameworkPropertyMetadata(Stretch.Uniform, - new PropertyChangedCallback(OnStretchChanged))); - - /// - /// Defines what rules are applied to the stretching of the video - /// - public Stretch Stretch - { - get { return (Stretch)GetValue(StretchProperty); } - set { SetValue(StretchProperty, value); } - } - - private static void OnStretchChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((D3DRenderer)d).OnStretchChanged(e); - } - - private void OnStretchChanged(DependencyPropertyChangedEventArgs e) - { - m_videoImage.Stretch = (Stretch)e.NewValue; - } - - #endregion Stretch - - #region StretchDirection - - public static readonly DependencyProperty StretchDirectionProperty = - DependencyProperty.Register("StretchDirection", typeof(StretchDirection), typeof(D3DRenderer), - new FrameworkPropertyMetadata(StretchDirection.Both, - new PropertyChangedCallback(OnStretchDirectionChanged))); - - /// - /// Gets or Sets the value that indicates how the video is scaled. This is a dependency property. - /// - public StretchDirection StretchDirection - { - get { return (StretchDirection)GetValue(StretchDirectionProperty); } - set { SetValue(StretchDirectionProperty, value); } - } - - private static void OnStretchDirectionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((D3DRenderer)d).OnStretchDirectionChanged(e); - } - - protected virtual void OnStretchDirectionChanged(DependencyPropertyChangedEventArgs e) - { - m_videoImage.StretchDirection = (StretchDirection)e.NewValue; - } - - #endregion StretchDirection - - #region IsRenderingEnabled - - public static readonly DependencyProperty IsRenderingEnabledProperty = - DependencyProperty.Register("IsRenderingEnabled", typeof(bool), typeof(D3DRenderer), - new FrameworkPropertyMetadata(true)); - - /// - /// Enables or disables rendering of the video - /// - public bool IsRenderingEnabled - { - get { return (bool)GetValue(IsRenderingEnabledProperty); } - set { SetValue(IsRenderingEnabledProperty, value); } - } - - #endregion IsRenderingEnabled - - #region NaturalVideoHeight - - private static readonly DependencyPropertyKey NaturalVideoHeightPropertyKey - = DependencyProperty.RegisterReadOnly("NaturalVideoHeight", typeof(int), typeof(MediaElementBase), - new FrameworkPropertyMetadata(0)); - - public static readonly DependencyProperty NaturalVideoHeightProperty - = NaturalVideoHeightPropertyKey.DependencyProperty; - - /// - /// Gets the natural pixel height of the current media. - /// The value will be 0 if there is no video in the media. - /// - public int NaturalVideoHeight - { - get { return (int)GetValue(NaturalVideoHeightProperty); } - } - - /// - /// Internal method to set the read-only NaturalVideoHeight DP - /// - protected void SetNaturalVideoHeight(int value) - { - SetValue(NaturalVideoHeightPropertyKey, value); - } - - #endregion NaturalVideoHeight - - #region NaturalVideoWidth - - private static readonly DependencyPropertyKey NaturalVideoWidthPropertyKey - = DependencyProperty.RegisterReadOnly("NaturalVideoWidth", typeof(int), typeof(MediaElementBase), - new FrameworkPropertyMetadata(0)); - - public static readonly DependencyProperty NaturalVideoWidthProperty - = NaturalVideoWidthPropertyKey.DependencyProperty; - - /// - /// Gets the natural pixel width of the current media. - /// The value will be 0 if there is no video in the media. - /// - public int NaturalVideoWidth - { - get { return (int)GetValue(NaturalVideoWidthProperty); } - } - - /// - /// Internal method to set the read-only NaturalVideoWidth DP - /// - protected void SetNaturalVideoWidth(int value) - { - SetValue(NaturalVideoWidthPropertyKey, value); - } - - #endregion NaturalVideoWidth - - #region HasVideo - - private static readonly DependencyPropertyKey HasVideoPropertyKey - = DependencyProperty.RegisterReadOnly("HasVideo", typeof(bool), typeof(MediaElementBase), - new FrameworkPropertyMetadata(false)); - - public static readonly DependencyProperty HasVideoProperty - = HasVideoPropertyKey.DependencyProperty; - - /// - /// Is true if the media contains renderable video - /// - public bool HasVideo - { - get { return (bool)GetValue(HasVideoProperty); } - } - - /// - /// Internal method for setting the read-only HasVideo DP - /// - protected void SetHasVideo(bool value) - { - SetValue(HasVideoPropertyKey, value); - } - - #endregion HasVideo - - #region DeeperColor - - public static readonly DependencyProperty DeeperColorProperty = - DependencyProperty.Register("DeeperColor", typeof(bool), typeof(D3DRenderer), - new FrameworkPropertyMetadata(false, - new PropertyChangedCallback(OnDeeperColorChanged))); - - public bool DeeperColor - { - get { return (bool)GetValue(DeeperColorProperty); } - set { SetValue(DeeperColorProperty, value); } - } - - private static void OnDeeperColorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((D3DRenderer)d).OnDeeperColorChanged(e); - } - - protected virtual void OnDeeperColorChanged(DependencyPropertyChangedEventArgs e) - { - ToggleDeeperColorEffect((bool)e.NewValue); - } - - #endregion DeeperColor - - #endregion Dependency Properties - - #region Private Methods - - private void ToggleDeeperColorEffect(bool isEnabled) - { - m_videoImage.Effect = isEnabled ? new DeeperColorEffect() : null; - } - - /// - /// Handler for when the D3DRenderer is unloaded - /// - private void D3DRendererUnloaded(object sender, RoutedEventArgs e) - { - /* Remember what the property value was */ - m_renderOnCompositionTargetRenderingTemp = RenderOnCompositionTargetRendering; - - /* Make sure to unhook the static event hook because we are unloading */ - RenderOnCompositionTargetRendering = false; - } - - /// - /// Handler for when the D3DRenderer is loaded - /// - private void D3DRendererLoaded(object sender, RoutedEventArgs e) - { - /* Restore the property's value */ - RenderOnCompositionTargetRendering = m_renderOnCompositionTargetRenderingTemp; - } - - /// - /// Initializes the D3DRenderer control - /// - private void InitializeD3DVideo() - { - if (m_videoImage != null) - return; - - /* Create our Image and it's D3DImage source */ - m_videoImage = new Image(); - m_d3dImage = new D3DImage(); - - /* Set our default stretch value of our video */ - m_videoImage.Stretch = (Stretch)StretchProperty.DefaultMetadata.DefaultValue; - m_videoImage.StretchDirection = (StretchDirection)StretchProperty.DefaultMetadata.DefaultValue; - - /* Our source of the video image is the D3DImage */ - m_videoImage.Source = D3DImage; - - /* Register the Image as a visual child */ - AddVisualChild(m_videoImage); - - /* Bind the horizontal alignment dp of this control to that of the video image */ - var horizontalAlignmentBinding = new Binding("HorizontalAlignment") { Source = this }; - m_videoImage.SetBinding(HorizontalAlignmentProperty, horizontalAlignmentBinding); - - /* Bind the vertical alignment dp of this control to that of the video image */ - var verticalAlignmentBinding = new Binding("VerticalAlignment") { Source = this }; - m_videoImage.SetBinding(VerticalAlignmentProperty, verticalAlignmentBinding); - - ToggleDeeperColorEffect((bool)DeeperColorProperty.DefaultMetadata.DefaultValue); - } - - private void CompositionTargetRendering(object sender, EventArgs e) - { - InternalInvalidateVideoImage(); - } - - /// - /// Sets the backbuffer for any cloned D3DRenderers - /// - private void SetBackBufferForClones() - { - var backBuffer = m_pBackBuffer; - ForEachCloneD3DRenderer(r => r.SetBackBuffer(backBuffer)); - } - - /// - /// Configures D3DImage with a new surface. This happens immediately - /// - private void SetBackBufferInternal(IntPtr backBuffer) - { - /* Do nothing if we don't have a new surface available */ - if (!m_newSurfaceAvailable) - return; - - if (!D3DImage.Dispatcher.CheckAccess()) - { - D3DImage.Dispatcher.BeginInvoke((Action)(() => SetBackBufferInternal(backBuffer))); - return; - } - - /* We have this around a try/catch just in case we - * lose the device and our Surface is invalid. The - * try/catch may not be needed, but testing needs - * to take place before it's removed */ - try - { - D3DImage.Lock(); - //When front buffer is unavailable, use software render to keep rendering. - D3DImage.SetBackBuffer(D3DResourceType.IDirect3DSurface9, backBuffer, true); - } - catch - { } - finally - { - D3DImage.Unlock(); - } - - SetNaturalWidthHeight(); - - /* Clear our flag, so this won't be ran again - * until a new surface is sent */ - m_newSurfaceAvailable = false; - } - - private void SetNaturalWidthHeight() - { - SetNaturalVideoHeight(m_d3dImage.PixelHeight); - SetNaturalVideoWidth(m_d3dImage.PixelWidth); - } - - private bool GetSetVideoImageInvalid(bool value) - { - int oldValue = Interlocked.Exchange(ref m_videoImageInvalid, value ? 1 : 0); - return oldValue == 1; - } - - /// - /// Invalidates any possible cloned renderer we may have - /// - private void InvalidateClonedVideoImages() - { - ForEachCloneD3DRenderer(r => r.InvalidateVideoImage()); - } - - private void ForEachCloneD3DRenderer(Action action) - { - lock (m_clonedD3Drenderers) - { - bool needClean = false; - foreach (var rendererRef in m_clonedD3Drenderers) - { - var renderer = rendererRef.Target as D3DRenderer; - if (renderer != null) - action(renderer); - else - needClean = true; - } - - if (needClean) - CleanZombieRenderers(); - } - } - - /// - /// Cleans up any dead references we may have to any cloned renderers - /// - private void CleanZombieRenderers() - { - lock (m_clonedD3Drenderers) - { - m_clonedD3Drenderers.RemoveAll(c => !c.IsAlive); - } - } - - /// - /// Used as a clone for a D3DRenderer - /// - private class ClonedD3DRenderer : D3DRenderer - { } - - #endregion Private Methods - - #region Protected Methods - - protected override Size MeasureOverride(Size availableSize) - { - m_videoImage.Measure(availableSize); - return m_videoImage.DesiredSize; - } - - protected override Size ArrangeOverride(Size finalSize) - { - m_videoImage.Arrange(new Rect(finalSize)); - return finalSize; - } - - protected override int VisualChildrenCount - { - get - { - return 1; - } - } - - protected override Visual GetVisualChild(int index) - { - if (index > 0) - throw new IndexOutOfRangeException(); - - return m_videoImage; - } - - protected D3DImage D3DImage - { - get - { - return m_d3dImage; - } - } - - protected Image VideoImage - { - get - { - return m_videoImage; - } - } - - /// - /// Renders the video with WPF's rendering using the CompositionTarget.Rendering event - /// - protected bool RenderOnCompositionTargetRendering - { - get - { - return m_renderOnCompositionTargetRendering; - } - set - { - /* If it is being set to true and it was previously false - * then hook into the event */ - if (value && !m_renderOnCompositionTargetRendering) - CompositionTarget.Rendering += CompositionTargetRendering; - else if (!value) - CompositionTarget.Rendering -= CompositionTargetRendering; - - m_renderOnCompositionTargetRendering = value; - m_renderOnCompositionTargetRenderingTemp = value; - } - } - - /// - /// Configures D3DImage with a new surface. The back buffer is - /// not set until we actually receive a frame, this way we - /// can avoid a black flicker between media changes - /// - /// The unmanaged pointer to the Direct3D Surface - protected void SetBackBuffer(IntPtr backBuffer) - { - /* We only do this if target rendering is enabled because we must use an Invoke - * instead of a BeginInvoke to keep the Surfaces in sync and Invoke could be dangerous - * in other situations */ - if (RenderOnCompositionTargetRendering) - { - if (!D3DImage.Dispatcher.CheckAccess()) - { - D3DImage.Dispatcher.Invoke((Action)(() => SetBackBuffer(backBuffer)), DispatcherPriority.Render); - return; - } - } - - /* Flag a new surface */ - m_newSurfaceAvailable = true; - m_pBackBuffer = backBuffer; - - /* Make a special case for target rendering */ - if (RenderOnCompositionTargetRendering || m_pBackBuffer == IntPtr.Zero) - { - SetBackBufferInternal(m_pBackBuffer); - } - - SetBackBufferForClones(); - } - - protected void InvalidateVideoImage() - { - GetSetVideoImageInvalid(true); - - if (!m_renderOnCompositionTargetRendering) - InternalInvalidateVideoImage(); - } - - /// - /// Invalidates the entire Direct3D image, notifying WPF to redraw - /// - protected void InternalInvalidateVideoImage() - { - /* Ensure we run on the correct Dispatcher */ - if (!D3DImage.Dispatcher.CheckAccess()) - { - D3DImage.Dispatcher.BeginInvoke((Action)(() => InternalInvalidateVideoImage())); - return; - } - - /* If there is a new Surface to set, - * this method will do the trick */ - SetBackBufferInternal(m_pBackBuffer); - - // may save a few AddDirtyRect calls when the rendering thread is too busy - // or RenderOnCompositionTargetRendering is set but the video is not playing - bool invalid = GetSetVideoImageInvalid(false); - if (!invalid) - return; - - /* Only render the video image if possible, or if IsRenderingEnabled is true */ - if (IsRenderingEnabled && m_pBackBuffer != IntPtr.Zero) - { - try - { - if (!D3DImage.TryLock(InvalidateVideoImageLockDuration)) - return; - /* Invalidate the entire image */ - D3DImage.AddDirtyRect(new Int32Rect(0, /* Left */ - 0, /* Top */ - D3DImage.PixelWidth, /* Width */ - D3DImage.PixelHeight /* Height */)); - } - catch (Exception) - { } - finally - { - D3DImage.Unlock(); - } - } - - /* Invalidate all of our cloned D3DRenderers */ - InvalidateClonedVideoImages(); - } - - #endregion Protected Methods - - protected D3DRenderer() - { - InitializeD3DVideo(); - - /* Hook into the framework events */ - Loaded += D3DRendererLoaded; - Unloaded += D3DRendererUnloaded; - } - - /// - /// TryLock timeout for the invalidate video image. Low values means higher UI responsivity, but more video dropped frames. - /// - public Duration InvalidateVideoImageLockDuration - { - get { return m_invalidateVideoImageLockDuration; } - set - { - if (value == null) - throw new ArgumentNullException("InvalidateVideoImageLockDuration"); - m_invalidateVideoImageLockDuration = value; - } - } - - /// - /// Creates a clone of the D3DRenderer. This is a work for the visual - /// brush not working cross-threaded - /// - /// - public D3DRenderer CloneD3DRenderer() - { - var renderer = new ClonedD3DRenderer(); - - lock (m_clonedD3Drenderers) - { - m_clonedD3Drenderers.Add(new WeakReference(renderer)); - } - - renderer.SetBackBuffer(m_pBackBuffer); - return renderer; - } - - /// - /// Creates a cloned D3DImage image of the current video frame. - /// Return null in case of the frame is not valid. - /// The image can be used thread-safe. - /// - public D3DImage CloneSingleFrameD3DImage() - { - D3DImage d3d = new D3DImage(); - - /* We have this around a try/catch just in case we - * lose the device and our Surface is invalid. The - * try/catch may not be needed, but testing needs - * to take place before it's removed */ - try - { - D3DImageUtils.SetBackBufferWithLock(d3d, m_pBackBuffer); - } - catch (Exception) - { - return null; - } - return d3d; - } -} - -public static class D3DImageUtils -{ - public static void AddDirtyRectAll(D3DImage d3d) - { - d3d.AddDirtyRect(new Int32Rect(0, 0, d3d.PixelWidth, d3d.PixelHeight)); - } - - /// - /// Convenient method for making frame shots. - /// For the exceptions, see - /// - public static void SetBackBufferWithLock(D3DImage d3d, IntPtr backBuffer) - { - try - { - d3d.Lock(); - d3d.SetBackBuffer(D3DResourceType.IDirect3DSurface9, backBuffer); - // necessary when rendering on WPF screen only - AddDirtyRectAll(d3d); - } - finally - { - d3d.Unlock(); - } - } -} diff --git a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/Controls/DvdPlayerElement.cs b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/Controls/DvdPlayerElement.cs deleted file mode 100644 index 2465729..0000000 --- a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/Controls/DvdPlayerElement.cs +++ /dev/null @@ -1,498 +0,0 @@ -using System; -using System.ComponentModel; -using System.Windows; -using System.Windows.Input; -using WPFMediaKit.DirectShow.MediaPlayers; - -namespace WPFMediaKit.DirectShow.Controls; - -public class DvdPlayerElement : MediaSeekingElement -{ - #region Commands - - public static readonly RoutedCommand PlayTitleCommand = new RoutedCommand(); - public static readonly RoutedCommand GotoTitleMenuCommand = new RoutedCommand(); - public static readonly RoutedCommand GotoRootMenuCommand = new RoutedCommand(); - public static readonly RoutedCommand NextChapterCommand = new RoutedCommand(); - public static readonly RoutedCommand PreviousChapterCommand = new RoutedCommand(); - - private void OnPlayTitleCommandExecuted(object sender, ExecutedRoutedEventArgs e) - { - if (e.Parameter is int == false) - return; - - var title = (int)e.Parameter; - - PlayTitle(title); - } - - private void OnCanExecutePlayTitleCommand(object sender, CanExecuteRoutedEventArgs e) - { - e.CanExecute = IsPlaying; - } - - private void OnGotoTitleCommandExecuted(object sender, ExecutedRoutedEventArgs e) - { - GotoTitleMenu(); - } - - private void OnCanExecuteGotoTitleCommand(object sender, CanExecuteRoutedEventArgs e) - { - e.CanExecute = IsPlaying; - } - - private void OnGotoRootMenuExecuted(object sender, ExecutedRoutedEventArgs e) - { - GotoRootMenu(); - } - - private void OnCanExecuteGotoRootMenu(object sender, CanExecuteRoutedEventArgs e) - { - e.CanExecute = IsPlaying; - } - - private void OnNextChapterCommandExecuted(object sender, ExecutedRoutedEventArgs e) - { - PlayNextChapter(); - } - - private void OnCanNextChapterCommand(object sender, CanExecuteRoutedEventArgs e) - { - e.CanExecute = IsPlaying; - } - - private void OnPreviousChapterCommandExecuted(object sender, ExecutedRoutedEventArgs e) - { - PlayPreviousChapter(); - } - - private void OnCanPreviousChapterCommand(object sender, CanExecuteRoutedEventArgs e) - { - e.CanExecute = IsPlaying; - } - - #endregion Commands - - public DvdPlayerElement() - { - //RenderOnCompositionTargetRendering = true; - - CommandBindings.Add(new CommandBinding(GotoRootMenuCommand, - OnGotoRootMenuExecuted, - OnCanExecuteGotoRootMenu)); - - CommandBindings.Add(new CommandBinding(GotoTitleMenuCommand, - OnGotoTitleCommandExecuted, - OnCanExecuteGotoTitleCommand)); - - CommandBindings.Add(new CommandBinding(PlayTitleCommand, - OnPlayTitleCommandExecuted, - OnCanExecutePlayTitleCommand)); - - CommandBindings.Add(new CommandBinding(PreviousChapterCommand, - OnPreviousChapterCommandExecuted, - OnCanPreviousChapterCommand)); - - CommandBindings.Add(new CommandBinding(NextChapterCommand, - OnNextChapterCommandExecuted, - OnCanNextChapterCommand)); - } - - /// - /// Fires when a DVD specific error occurs - /// - public event EventHandler DvdError; - - private void InvokeDvdError(DvdError error) - { - var e = new DvdErrorArgs { Error = error }; - var dvdErrorHandler = DvdError; - if (dvdErrorHandler != null) dvdErrorHandler(this, e); - } - - #region Dependency Properties - - #region IsOverDvdButton - - private static readonly DependencyPropertyKey IsOverDvdButtonPropertyKey - = DependencyProperty.RegisterReadOnly("IsOverDvdButton", typeof(bool), typeof(DvdPlayerElement), - new FrameworkPropertyMetadata(false)); - - public static readonly DependencyProperty IsOverDvdButtonProperty - = IsOverDvdButtonPropertyKey.DependencyProperty; - - /// - /// Gets if the mouse is over a DVD button. This is a dependency property. - /// - public bool IsOverDvdButton - { - get { return (bool)GetValue(IsOverDvdButtonProperty); } - } - - protected void SetIsOverDvdButton(bool value) - { - SetValue(IsOverDvdButtonPropertyKey, value); - } - - #endregion IsOverDvdButton - - #region PlayOnInsert - - public static readonly DependencyProperty PlayOnInsertProperty = - DependencyProperty.Register("PlayOnInsert", typeof(bool), typeof(DvdPlayerElement), - new FrameworkPropertyMetadata(true, - new PropertyChangedCallback(OnPlayOnInsertChanged))); - - /// - /// Gets or sets if the DVD automatically plays when a DVD is inserted into the computer. - /// This is a dependency property. - /// - public bool PlayOnInsert - { - get { return (bool)GetValue(PlayOnInsertProperty); } - set { SetValue(PlayOnInsertProperty, value); } - } - - private static void OnPlayOnInsertChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((DvdPlayerElement)d).OnPlayOnInsertChanged(e); - } - - protected virtual void OnPlayOnInsertChanged(DependencyPropertyChangedEventArgs e) - { - } - - #endregion PlayOnInsert - - #region DvdEjected - - public static readonly RoutedEvent DvdEjectedEvent = EventManager.RegisterRoutedEvent("DvdEjected", - RoutingStrategy.Bubble, - typeof(RoutedEventHandler), - typeof(DvdPlayerElement)); - - /// - /// This event is fired when a DVD is ejected from the computer. This is a bubbled, routed event. - /// - public event RoutedEventHandler DvdEjected - { - add { AddHandler(DvdEjectedEvent, value); } - remove { RemoveHandler(DvdEjectedEvent, value); } - } - - #endregion DvdEjected - - #region DvdInserted - - public static readonly RoutedEvent DvdInsertedEvent = EventManager.RegisterRoutedEvent("DvdInserted", - RoutingStrategy.Bubble, - typeof(RoutedEventHandler), - typeof(DvdPlayerElement)); - - /// - /// Fires when a DVD is inserted into the computer. - /// This is a bubbled, routed event. - /// - public event RoutedEventHandler DvdInserted - { - add { AddHandler(DvdInsertedEvent, value); } - remove { RemoveHandler(DvdInsertedEvent, value); } - } - - #endregion DvdInserted - - #region CurrentDvdTime - - private static readonly DependencyPropertyKey CurrentDvdTimePropertyKey - = DependencyProperty.RegisterReadOnly("CurrentDvdTime", typeof(TimeSpan), typeof(DvdPlayerElement), - new FrameworkPropertyMetadata(TimeSpan.Zero)); - - public static readonly DependencyProperty CurrentDvdTimeProperty - = CurrentDvdTimePropertyKey.DependencyProperty; - - /// - /// Gets the current time the DVD playback is at. This is a read-only, - /// dependency property. - /// - public TimeSpan CurrentDvdTime - { - get { return (TimeSpan)GetValue(CurrentDvdTimeProperty); } - } - - protected void SetCurrentDvdTime(TimeSpan value) - { - SetValue(CurrentDvdTimePropertyKey, value); - } - - #endregion CurrentDvdTime - - #region DvdDirectory - - public static readonly DependencyProperty DvdDirectoryProperty = - DependencyProperty.Register("DvdDirectory", typeof(string), typeof(DvdPlayerElement), - new FrameworkPropertyMetadata("", - new PropertyChangedCallback(OnDvdDirectoryChanged))); - - /// - /// Gets or sets the directory the DVD is located at (ie D:\VIDEO_TS). If this is empty or null, - /// then DirectShow will try to play the first DVD found in the computer. - /// This is a dependency property. - /// - public string DvdDirectory - { - get { return (string)GetValue(DvdDirectoryProperty); } - set { SetValue(DvdDirectoryProperty, value); } - } - - private static void OnDvdDirectoryChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((DvdPlayerElement)d).OnDvdDirectoryChanged(e); - } - - protected virtual void OnDvdDirectoryChanged(DependencyPropertyChangedEventArgs e) - { - if (HasInitialized) - PlayerSetDvdDirectory(); - } - - private void PlayerSetDvdDirectory() - { - var dvdDirectory = DvdDirectory; - - DvdPlayer.Dispatcher.BeginInvoke((Action)delegate - { - /* Set the source type */ - DvdPlayer.DvdDirectory = dvdDirectory; - - Dispatcher.BeginInvoke((Action)delegate - { - if (IsLoaded) - ExecuteMediaState(LoadedBehavior); - //else - // ExecuteMediaState(UnloadedBehavior); - }); - }); - } - - #endregion DvdDirectory - - #endregion Dependency Properties - - public override void EndInit() - { - PlayerSetDvdDirectory(); - base.EndInit(); - } - - #region Public Methods - - /// - /// The SelectAngle method sets the new angle when the DVD Navigator is in an angle block - /// - /// Value of the new angle, which must be from 1 through 9 - public void SelectAngle(int angle) - { - DvdPlayer.Dispatcher.BeginInvoke((Action)(() => DvdPlayer.SelectAngle(angle))); - } - - /// - /// Returns the display from a submenu to its parent menu. - /// - public void ReturnFromSubmenu() - { - DvdPlayer.Dispatcher.BeginInvoke((Action)(() => DvdPlayer.ReturnFromSubmenu())); - } - - /// - /// Selects the specified relative button (upper, lower, right, left) - /// - /// Value indicating the button to select - public void SelectRelativeButton(DvdRelativeButtonEnum button) - { - DvdPlayer.Dispatcher.BeginInvoke((Action)(() => DvdPlayer.SelectRelativeButton(button))); - } - - /// - /// Leaves a menu and resumes playback. - /// - public void Resume() - { - DvdPlayer.Dispatcher.BeginInvoke((Action)(() => DvdPlayer.Resume())); - } - - /// - /// Plays the DVD forward at a specific speed - /// - /// The speed multiplier to play back. - public void PlayForwards(double speed) - { - DvdPlayer.Dispatcher.BeginInvoke((Action)(() => DvdPlayer.PlayForwards(speed))); - } - - /// - /// Plays the DVD backwards at a specific speed - /// - /// The speed multiplier to play back - public void PlayBackwards(double speed) - { - DvdPlayer.Dispatcher.BeginInvoke((Action)(() => DvdPlayer.PlayBackwards(speed))); - } - - /// - /// Play a title - /// - /// The index of the title to play back - public void PlayTitle(int titleIndex) - { - DvdPlayer.Dispatcher.BeginInvoke((Action)(() => DvdPlayer.PlayTitle(titleIndex))); - } - - /// - /// Plays the next chapter in the volume. - /// - public void PlayNextChapter() - { - DvdPlayer.Dispatcher.BeginInvoke((Action)(() => DvdPlayer.PlayNextChapter())); - } - - /// - /// Plays the previous chapter in the volume. - /// - public void PlayPreviousChapter() - { - DvdPlayer.Dispatcher.BeginInvoke((Action)(() => DvdPlayer.PlayPreviousChapter())); - } - - /// - /// Goes to the root menu of the DVD. - /// - public void GotoRootMenu() - { - DvdPlayer.Dispatcher.BeginInvoke((Action)(() => DvdPlayer.GotoRootMenu())); - } - - /// - /// Goes to the title menu of the DVD - /// - public void GotoTitleMenu() - { - DvdPlayer.Dispatcher.BeginInvoke((Action)(() => DvdPlayer.GotoTitleMenu())); - } - - /// - /// The Play method is overrided so we can - /// set the source to the media - /// - public override void Play() - { - var prop = DesignerProperties.IsInDesignModeProperty; - bool isInDesignMode = (bool)DependencyPropertyDescriptor - .FromProperty(prop, typeof(FrameworkElement)) - .Metadata.DefaultValue; - - if (isInDesignMode) - return; - - base.Play(); - } - - #endregion Public Methods - - #region Protected Methods - - protected DvdPlayer DvdPlayer - { - get { return MediaPlayerBase as DvdPlayer; } - } - - protected override void OnMouseMove(MouseEventArgs e) - { - /* Get the position of the mouse over the video image */ - Point position = e.GetPosition(VideoImage); - - /* Calculate the ratio of where the mouse is, to the actual width of the video. */ - double widthMultiplier = position.X / VideoImage.ActualWidth; - - /* Calculate the ratio of where the mouse is, to the actual height of the video */ - double heightMultiplier = position.Y / VideoImage.ActualHeight; - - DvdPlayer.Dispatcher.BeginInvoke((Action)(() => DvdPlayer.SelectAtPosition(widthMultiplier, heightMultiplier))); - base.OnMouseMove(e); - } - - protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) - { - Point position = e.GetPosition(VideoImage); - - /* Calculate the ratio of where the mouse is, to the actual width of the video. */ - double widthMultiplier = position.X / VideoImage.ActualWidth; - - /* Calculate the ratio of where the mouse is, to the actual height of the video */ - double heightMultiplier = position.Y / VideoImage.ActualHeight; - - DvdPlayer.Dispatcher.BeginInvoke((Action)(() => DvdPlayer.ActivateAtPosition(widthMultiplier, heightMultiplier))); - - base.OnMouseLeftButtonDown(e); - } - - protected override MediaPlayerBase OnRequestMediaPlayer() - { - /* Initialize the DVD player and hook into it's events */ - var player = new DvdPlayer(); - player.OnDvdEjected += DvdPlayerOnDvdEjected; - player.OnDvdInserted += DvdPlayerOnDvdInserted; - player.OnOverDvdButton += DvdPlayerOnOverDvdButton; - player.OnDvdTime += DvdPlayerOnDvdTime; - player.OnDvdError += DvdPlayerOnDvdError; - return player; - } - - #endregion Protected Methods - - #region Private Methods - - private void DvdPlayerOnDvdError(object sender, DvdErrorArgs e) - { - Dispatcher.BeginInvoke((Action)(() => InvokeDvdError(e.Error))); - } - - /// - /// The handler for when a new DVD is hit. The event is fired by the DVDPlayer class. - /// - private void DvdPlayerOnDvdTime(object sender, DvdTimeEventArgs e) - { - Dispatcher.BeginInvoke((Action)(() => SetCurrentDvdTime(e.DvdTime))); - } - - /// - /// The handler for when the mouse is over a DVD button. This event is fired by the DVD Player class. - /// - private void DvdPlayerOnOverDvdButton(object sender, OverDvdButtonEventArgs e) - { - Dispatcher.BeginInvoke((Action)(() => SetIsOverDvdButton(e.IsOverDvdButton))); - } - - /// - /// Fires when a new DVD is inserted into a DVD player on the computer. - /// - private void DvdPlayerOnDvdInserted(object sender, EventArgs e) - { - Dispatcher.BeginInvoke((Action)delegate - { - RaiseEvent(new RoutedEventArgs(DvdInsertedEvent)); - - if (PlayOnInsert) - Play(); - }); - } - - /// - /// Fires when the DVD is ejected from the computer. - /// - private void DvdPlayerOnDvdEjected(object sender, EventArgs e) - { - Dispatcher.BeginInvoke((Action)(() => RaiseEvent(new RoutedEventArgs(DvdEjectedEvent)))); - } - - #endregion Private Methods -} diff --git a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/Controls/MediaDetectorElement.cs b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/Controls/MediaDetectorElement.cs deleted file mode 100644 index 4278a9c..0000000 --- a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/Controls/MediaDetectorElement.cs +++ /dev/null @@ -1,331 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Threading; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Media.Imaging; -using System.Windows.Threading; -using WPFMediaKit.DirectShow.MediaPlayers; - -namespace WPFMediaKit.DirectShow.Controls; - -public class VideoFrame -{ - public VideoFrame(BitmapSource snapshot, TimeSpan mediaTime) - { - Snapshot = snapshot; - MediaTime = mediaTime; - snapshot.Freeze(); - } - - public BitmapSource Snapshot { get; private set; } - - public TimeSpan MediaTime { get; private set; } -} - -/// -/// This control is not finished. Do not use it ;) -/// -public class MediaDetectorElement : Control -{ - private readonly ObservableCollection m_frames; - private readonly MediaDetector m_mediaDetector; - - private bool m_cancelLoadFrames; - private double m_lastEndTime; - private int m_lastFrameCount; - private double m_lastStartTime; - private ItemsControl m_videoFrameItems; - - static MediaDetectorElement() - { - DefaultStyleKeyProperty.OverrideMetadata(typeof(MediaDetectorElement), - new FrameworkPropertyMetadata(typeof(MediaDetectorElement))); - } - - public MediaDetectorElement() - { - m_frames = new ObservableCollection(); - Frames = new ReadOnlyObservableCollection(m_frames); - - m_mediaDetector = CreateMediaDetector(); - Loaded += MediaDetectorElement_Loaded; - } - - public ReadOnlyObservableCollection Frames { get; private set; } - - #region MediaLength - - private static readonly DependencyPropertyKey MediaLengthPropertyKey - = DependencyProperty.RegisterReadOnly("MediaLength", typeof(double), typeof(MediaDetectorElement), - new FrameworkPropertyMetadata((double)0)); - - public static readonly DependencyProperty MediaLengthProperty - = MediaLengthPropertyKey.DependencyProperty; - - public double MediaLength - { - get { return (double)GetValue(MediaLengthProperty); } - } - - protected void SetMediaLength(double value) - { - SetValue(MediaLengthPropertyKey, value); - } - - #endregion MediaLength - - #region MediaSource - - public static readonly DependencyProperty MediaSourceProperty = - DependencyProperty.Register("MediaSource", typeof(Uri), typeof(MediaDetectorElement), - new FrameworkPropertyMetadata(null, - new PropertyChangedCallback(OnMediaSourceChanged))); - - public Uri MediaSource - { - get { return (Uri)GetValue(MediaSourceProperty); } - set { SetValue(MediaSourceProperty, value); } - } - - private static void OnMediaSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((MediaDetectorElement)d).OnMediaSourceChanged(e); - } - - protected virtual void OnMediaSourceChanged(DependencyPropertyChangedEventArgs e) - { - if (e.NewValue == null) - return; - - if (IsLoaded) - LoadMediaSource(); - } - - #endregion MediaSource - - #region VideoStartTime - - public static readonly DependencyProperty VideoStartTimeProperty = - DependencyProperty.Register("VideoStartTime", typeof(double), typeof(MediaDetectorElement), - new FrameworkPropertyMetadata((double)0, - new PropertyChangedCallback( - OnVideoStartTimeChanged))); - - public double VideoStartTime - { - get { return (double)GetValue(VideoStartTimeProperty); } - set { SetValue(VideoStartTimeProperty, value); } - } - - private static void OnVideoStartTimeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((MediaDetectorElement)d).OnVideoStartTimeChanged(e); - } - - protected virtual void OnVideoStartTimeChanged(DependencyPropertyChangedEventArgs e) - { - if (IsLoaded) - LoadVideoFrames(); - } - - #endregion VideoStartTime - - #region VideoEndTime - - public static readonly DependencyProperty VideoEndTimeProperty = - DependencyProperty.Register("VideoEndTime", typeof(double), typeof(MediaDetectorElement), - new FrameworkPropertyMetadata((double)0, - new PropertyChangedCallback(OnVideoEndTimeChanged))); - - public double VideoEndTime - { - get { return (double)GetValue(VideoEndTimeProperty); } - set { SetValue(VideoEndTimeProperty, value); } - } - - private static void OnVideoEndTimeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((MediaDetectorElement)d).OnVideoEndTimeChanged(e); - } - - protected virtual void OnVideoEndTimeChanged(DependencyPropertyChangedEventArgs e) - { - if (Parent != null) - LoadVideoFrames(); - } - - #endregion VideoEndTime - - #region VideoFrameCount - - public static readonly DependencyProperty VideoFrameCountProperty = - DependencyProperty.Register("VideoFrameCount", typeof(int), typeof(MediaDetectorElement), - new FrameworkPropertyMetadata(0, - new PropertyChangedCallback( - OnVideoFrameCountChanged))); - - public int VideoFrameCount - { - get { return (int)GetValue(VideoFrameCountProperty); } - set { SetValue(VideoFrameCountProperty, value); } - } - - private static void OnVideoFrameCountChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((MediaDetectorElement)d).OnVideoFrameCountChanged(e); - } - - protected virtual void OnVideoFrameCountChanged(DependencyPropertyChangedEventArgs e) - { - if (IsLoaded) - LoadVideoFrames(); - } - - #endregion VideoFrameCount - - private void LoadMediaSource() - { - if (MediaSource == null) - return; - - string filename = MediaSource.OriginalString; - - if (m_mediaDetector == null) - return; - - m_mediaDetector.Dispatcher.BeginInvoke((Action)delegate - { - m_mediaDetector.LoadMedia(filename); - SetMediaInfo(); - }); - } - - private void LoadVideoFrames() - { - double startTime = 0; - double endTime = 0; - int videoFrameCount = 0; - - startTime = VideoStartTime; - endTime = VideoEndTime; - videoFrameCount = VideoFrameCount; - - if (startTime == endTime) - videoFrameCount = 1; - - if (endTime < startTime) - { - m_frames.Clear(); - return; - } - - if (m_lastStartTime == startTime && m_lastEndTime == endTime && videoFrameCount == m_lastFrameCount) - return; - - m_lastStartTime = startTime; - m_lastEndTime = endTime; - m_lastFrameCount = videoFrameCount; - - m_cancelLoadFrames = true; - - double timeIncrement = (endTime - startTime) / videoFrameCount; - - var times = new List(); - double sec = startTime; - - for (int i = 0; i < videoFrameCount; i++) - { - times.Add(TimeSpan.FromSeconds(sec)); - sec += timeIncrement; - } - - m_mediaDetector.Dispatcher.BeginInvoke((Action)delegate - { - m_cancelLoadFrames = false; - Dispatcher.Invoke((Action)(() => m_frames.Clear())); - for (int i = 0; i < times.Count; i++) - { - if (m_cancelLoadFrames) - return; - - var frame = new VideoFrame(m_mediaDetector.GetImage(times[i]), - times[i]); - - Dispatcher.Invoke((Action)(() => m_frames.Add(frame))); - } - - var videoframe = new VideoFrame(m_mediaDetector.GetImage(TimeSpan.FromSeconds(endTime)), - TimeSpan.FromSeconds(endTime)); - - Dispatcher.Invoke((Action)(() => m_frames.Add(videoframe))); - - m_cancelLoadFrames = false; - }); - } - - private void SetMediaInfo() - { - Dispatcher.BeginInvoke( - (Action) - delegate - { - SetMediaLength(Math.Max(m_mediaDetector.AudioStreamLength.TotalSeconds, m_mediaDetector.VideoStreamLength.TotalSeconds)); - LoadVideoFrames(); - }); - } - - private void MediaDetectorElement_Loaded(object sender, RoutedEventArgs e) - { - LoadMediaSource(); - } - - public override void OnApplyTemplate() - { - m_videoFrameItems = GetTemplateChild("PART_VideoFrameItems") as ItemsControl; - - if (m_videoFrameItems != null) - m_videoFrameItems.ItemsSource = m_frames; - - base.OnApplyTemplate(); - } - - private static MediaDetector CreateMediaDetector() - { - MediaDetector detector = null; - - /* The reset event will block our thread while - * we create an intialize the player */ - var reset = new ManualResetEventSlim(false); - - /* We need to create a new thread for our Dispatcher */ - var t = new Thread((ThreadStart)delegate - { - detector = new MediaDetector(); - - /* We queue up a method to execute - * when the Dispatcher is ran. - * This will wake up the calling thread - * that has been blocked by the reset event */ - detector.Dispatcher.Invoke((Action)(() => reset.Set())); - - Dispatcher.Run(); - }) - { - Name = "MediaDetector", - IsBackground = true - }; - - t.SetApartmentState(ApartmentState.STA); - - /* Starts the thread and creates the object */ - t.Start(); - - /* We wait until our object is created and - * the new Dispatcher is running */ - reset.Wait(); - - return detector; - } -} diff --git a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/Controls/MediaElementBase.cs b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/Controls/MediaElementBase.cs deleted file mode 100644 index 64e9e9e..0000000 --- a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/Controls/MediaElementBase.cs +++ /dev/null @@ -1,651 +0,0 @@ -using System; -using System.Threading; -using System.Windows; -using System.Windows.Input; -using WPFMediaKit.DirectShow.MediaPlayers; - -namespace WPFMediaKit.DirectShow.Controls; - -/// -/// The MediaElementBase is the base WPF control for -/// making custom media players. The MediaElement uses the -/// D3DRenderer class for rendering video -/// -public abstract class MediaElementBase : D3DRenderer -{ - private Window m_currentWindow; - private bool m_windowHooked; - - ~MediaElementBase() - { - } - - #region Routed Events - - #region MediaOpened - - public static readonly RoutedEvent MediaOpenedEvent = EventManager.RegisterRoutedEvent("MediaOpened", - RoutingStrategy.Bubble, - typeof(RoutedEventHandler - ), - typeof(MediaElementBase)); - - /// - /// Fires when media has successfully been opened - /// - public event RoutedEventHandler MediaOpened - { - add { AddHandler(MediaOpenedEvent, value); } - remove { RemoveHandler(MediaOpenedEvent, value); } - } - - #endregion MediaOpened - - #region MediaClosed - - public static readonly RoutedEvent MediaClosedEvent = EventManager.RegisterRoutedEvent("MediaClosed", - RoutingStrategy.Bubble, - typeof(RoutedEventHandler), - typeof(MediaElementBase)); - - /// - /// Fires when media has been closed - /// - public event RoutedEventHandler MediaClosed - { - add { AddHandler(MediaClosedEvent, value); } - remove { RemoveHandler(MediaClosedEvent, value); } - } - - #endregion MediaClosed - - #region MediaEnded - - public static readonly RoutedEvent MediaEndedEvent = EventManager.RegisterRoutedEvent("MediaEnded", - RoutingStrategy.Bubble, - typeof(RoutedEventHandler), - typeof(MediaElementBase)); - - /// - /// Fires when media has completed playing - /// - public event RoutedEventHandler MediaEnded - { - add { AddHandler(MediaEndedEvent, value); } - remove { RemoveHandler(MediaEndedEvent, value); } - } - - #endregion MediaEnded - - #endregion Routed Events - - #region Dependency Properties - - #region PlayerState - - public static readonly DependencyProperty PlayerStateProperty = - DependencyProperty.Register("PlayerState", typeof(PlayerState), typeof(MediaElementBase), - new FrameworkPropertyMetadata(PlayerState.Closed)); - - /// - /// Get the current state of the media player - /// - public PlayerState PlayerState - { - get { return (PlayerState)GetValue(PlayerStateProperty); } - protected set { SetValue(PlayerStateProperty, value); } - } - - #endregion PlayerState - - #region UnloadedBehavior - - public static readonly DependencyProperty UnloadedBehaviorProperty = - DependencyProperty.Register("UnloadedBehavior", typeof(MediaState), typeof(MediaElementBase), - new FrameworkPropertyMetadata(MediaState.Close)); - - /// - /// Defines the behavior of the control when it is unloaded - /// - public MediaState UnloadedBehavior - { - get { return (MediaState)GetValue(UnloadedBehaviorProperty); } - set { SetValue(UnloadedBehaviorProperty, value); } - } - - #endregion UnloadedBehavior - - #region LoadedBehavior - - public static readonly DependencyProperty LoadedBehaviorProperty = - DependencyProperty.Register("LoadedBehavior", typeof(MediaState), typeof(MediaElementBase), - new FrameworkPropertyMetadata(MediaState.Play)); - - /// - /// Defines the behavior of the control when it is loaded - /// - public MediaState LoadedBehavior - { - get { return (MediaState)GetValue(LoadedBehaviorProperty); } - set { SetValue(LoadedBehaviorProperty, value); } - } - - #endregion LoadedBehavior - - #region Volume - - public static readonly DependencyProperty VolumeProperty = - DependencyProperty.Register("Volume", typeof(double), typeof(MediaElementBase), - new FrameworkPropertyMetadata(1.0d, - new PropertyChangedCallback(OnVolumeChanged))); - - /// - /// Gets or sets the audio volume. Specifies the volume, as a - /// number from 0 to 1. Full volume is 1, and 0 is silence. - /// - public double Volume - { - get { return (double)GetValue(VolumeProperty); } - set { SetValue(VolumeProperty, value); } - } - - private static void OnVolumeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((MediaElementBase)d).OnVolumeChanged(e); - } - - protected virtual void OnVolumeChanged(DependencyPropertyChangedEventArgs e) - { - if (HasInitialized) - MediaPlayerBase.Dispatcher.BeginInvoke((Action)delegate - { - MediaPlayerBase.Volume = (double)e.NewValue; - }); - } - - #endregion Volume - - #region Balance - - public static readonly DependencyProperty BalanceProperty = - DependencyProperty.Register("Balance", typeof(double), typeof(MediaElementBase), - new FrameworkPropertyMetadata(0d, - new PropertyChangedCallback(OnBalanceChanged))); - - /// - /// Gets or sets the balance on the audio. - /// The value can range from -1 to 1. The value -1 means the right channel is attenuated by 100 dB - /// and is effectively silent. The value 1 means the left channel is silent. The neutral value is 0, - /// which means that both channels are at full volume. When one channel is attenuated, the other - /// remains at full volume. - /// - public double Balance - { - get { return (double)GetValue(BalanceProperty); } - set { SetValue(BalanceProperty, value); } - } - - private static void OnBalanceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((MediaElementBase)d).OnBalanceChanged(e); - } - - protected virtual void OnBalanceChanged(DependencyPropertyChangedEventArgs e) - { - if (HasInitialized) - MediaPlayerBase.Dispatcher.BeginInvoke((Action)delegate - { - MediaPlayerBase.Balance = (double)e.NewValue; - }); - } - - #endregion Balance - - #region IsPlaying - - private static readonly DependencyPropertyKey IsPlayingPropertyKey - = DependencyProperty.RegisterReadOnly("IsPlaying", typeof(bool), typeof(MediaElementBase), - new FrameworkPropertyMetadata(false)); - - public static readonly DependencyProperty IsPlayingProperty - = IsPlayingPropertyKey.DependencyProperty; - - public bool IsPlaying - { - get { return (bool)GetValue(IsPlayingProperty); } - } - - protected void SetIsPlaying(bool value) - { - SetValue(IsPlayingPropertyKey, value); - } - - #endregion IsPlaying - - #endregion Dependency Properties - - #region Commands - - public static readonly RoutedCommand PlayerStateCommand = new RoutedCommand(); - public static readonly RoutedCommand TogglePlayPauseCommand = new RoutedCommand(); - - protected virtual void OnPlayerStateCommandExecuted(object sender, ExecutedRoutedEventArgs e) - { - if (e.Parameter is MediaState == false) - return; - - var state = (MediaState)e.Parameter; - - ExecuteMediaState(state); - } - - protected virtual void OnCanExecutePlayerStateCommand(object sender, CanExecuteRoutedEventArgs e) - { - e.CanExecute = true; - } - - protected virtual void OnTogglePlayPauseCommandExecuted(object sender, ExecutedRoutedEventArgs e) - { - if (IsPlaying) - Pause(); - else - Play(); - } - - protected virtual void OnCanExecuteTogglePlayPauseCommand(object sender, CanExecuteRoutedEventArgs e) - { - e.CanExecute = true; - } - - #endregion Commands - - /// - /// Notifies when the media has failed and produced an exception - /// - public event EventHandler MediaFailed; - - protected MediaElementBase() - { - DefaultApartmentState = ApartmentState.MTA; - - InitializeMediaPlayerPrivate(); - Loaded += MediaElementBaseLoaded; - Unloaded += MediaElementBaseUnloaded; - - CommandBindings.Add(new CommandBinding(PlayerStateCommand, - OnPlayerStateCommandExecuted, - OnCanExecutePlayerStateCommand)); - - CommandBindings.Add(new CommandBinding(TogglePlayPauseCommand, - OnTogglePlayPauseCommandExecuted, - OnCanExecuteTogglePlayPauseCommand)); - } - - private void InitializeMediaPlayerPrivate() - { - InitializeMediaPlayer(); - } - - protected MediaPlayerBase MediaPlayerBase { get; set; } - - protected ApartmentState DefaultApartmentState { get; set; } - - protected void EnsurePlayerThread() - { - MediaPlayerBase.EnsureThread(DefaultApartmentState); - } - - /// - /// Initializes the media player, hooking into events - /// and other general setup. - /// - protected virtual void InitializeMediaPlayer() - { - if (MediaPlayerBase != null) - return; - - MediaPlayerBase = OnRequestMediaPlayer(); - EnsurePlayerThread(); - - if (MediaPlayerBase == null) - { - throw new WPFMediaKitException("OnRequestMediaPlayer cannot return null"); - } - - /* Hook into the normal .NET events */ - MediaPlayerBase.MediaOpened += OnMediaPlayerOpenedPrivate; - MediaPlayerBase.MediaClosed += OnMediaPlayerClosedPrivate; - MediaPlayerBase.MediaFailed += OnMediaPlayerFailedPrivate; - MediaPlayerBase.MediaEnded += OnMediaPlayerEndedPrivate; - MediaPlayerBase.PlayerStateChanged += OnPlayerStateChanged; - - /* These events fire when we get new D3Dsurfaces or frames */ - MediaPlayerBase.NewAllocatorFrame += OnMediaPlayerNewAllocatorFramePrivate; - MediaPlayerBase.NewAllocatorSurface += OnMediaPlayerNewAllocatorSurfacePrivate; - } - - #region Private Event Handlers - - private void OnMediaPlayerFailedPrivate(object sender, MediaFailedEventArgs e) - { - OnMediaPlayerFailed(e); - } - - private void OnMediaPlayerNewAllocatorSurfacePrivate(object sender, IntPtr pSurface) - { - OnMediaPlayerNewAllocatorSurface(pSurface); - } - - private void OnMediaPlayerNewAllocatorFramePrivate() - { - OnMediaPlayerNewAllocatorFrame(); - } - - private void OnMediaPlayerClosedPrivate() - { - OnMediaPlayerClosed(); - } - - private void OnMediaPlayerEndedPrivate() - { - OnMediaPlayerEnded(); - } - - private void OnMediaPlayerOpenedPrivate() - { - OnMediaPlayerOpened(); - } - - #endregion Private Event Handlers - - /// - /// Fires the MediaFailed event - /// - /// The failed media arguments - protected void InvokeMediaFailed(MediaFailedEventArgs e) - { - EventHandler mediaFailedHandler = MediaFailed; - if (mediaFailedHandler != null) mediaFailedHandler(this, e); - } - - /// - /// Executes when a media operation failed - /// - /// The failed event arguments - protected virtual void OnMediaPlayerFailed(MediaFailedEventArgs e) - { - Dispatcher.BeginInvoke((Action)(() => SetIsPlaying(false))); - InvokeMediaFailed(e); - } - - /// - /// Is executes when a new D3D surfaces has been allocated - /// - /// The pointer to the D3D surface - protected virtual void OnMediaPlayerNewAllocatorSurface(IntPtr pSurface) - { - SetBackBuffer(pSurface); - } - - /// - /// Called for every frame in media that has video - /// - protected virtual void OnMediaPlayerNewAllocatorFrame() - { - InvalidateVideoImage(); - } - - /// - /// /// Called when the state of the player has changed - /// - /// Previous state - /// New State - protected virtual void OnPlayerStateChanged(PlayerState oldState, PlayerState newState) - { - Dispatcher.BeginInvoke((Action)((a, b) => b.PlayerState = a), newState, this); - } - - /// - /// Called when the media has been closed - /// - protected virtual void OnMediaPlayerClosed() - { - Dispatcher.BeginInvoke((Action)(() => SetIsPlaying(false))); - Dispatcher.BeginInvoke((Action)(() => RaiseEvent(new RoutedEventArgs(MediaClosedEvent)))); - } - - /// - /// Called when the media has ended - /// - protected virtual void OnMediaPlayerEnded() - { - Dispatcher.BeginInvoke((Action)(() => SetIsPlaying(false))); - Dispatcher.BeginInvoke((Action)(() => RaiseEvent(new RoutedEventArgs(MediaEndedEvent)))); - } - - /// - /// Executed when media has successfully been opened. - /// - protected virtual void OnMediaPlayerOpened() - { - /* Safely grab out our values */ - bool hasVideo = MediaPlayerBase.HasVideo; - int videoWidth = MediaPlayerBase.NaturalVideoWidth; - int videoHeight = MediaPlayerBase.NaturalVideoHeight; - double volume; - double balance; - - Dispatcher.BeginInvoke((Action)delegate - { - /* If we have no video just black out the video - * area by releasing the D3D surface */ - if (!hasVideo) - { - SetBackBuffer(IntPtr.Zero); - } - - SetNaturalVideoWidth(videoWidth); - SetNaturalVideoHeight(videoHeight); - - /* Set our dp values to match the media player */ - SetHasVideo(hasVideo); - - /* Get our DP values */ - volume = Volume; - balance = Balance; - - /* Make sure our volume and balances are set */ - MediaPlayerBase.Dispatcher.BeginInvoke((Action)delegate - { - MediaPlayerBase.Volume = volume; - MediaPlayerBase.Balance = balance; - }); - SetIsPlaying(true); - RaiseEvent(new RoutedEventArgs(MediaOpenedEvent)); - }); - } - - /// - /// Fires when the owner window is closed. Nothing will happen - /// if the visual does not belong to the visual tree with a root - /// of a WPF window - /// - private void WindowOwnerClosed(object sender, EventArgs e) - { - ExecuteMediaState(UnloadedBehavior); - } - - /// - /// Local handler for the Loaded event - /// - private void MediaElementBaseUnloaded(object sender, RoutedEventArgs e) - { - /* Make sure we call our virtual method every time! */ - OnUnloadedOverride(); - - if (Application.Current == null) - return; - - m_windowHooked = false; - - if (m_currentWindow == null) - return; - - m_currentWindow.Closed -= WindowOwnerClosed; - m_currentWindow = null; - } - - /// - /// Local handler for the Unloaded event - /// - private void MediaElementBaseLoaded(object sender, RoutedEventArgs e) - { - m_currentWindow = Window.GetWindow(this); - - if (m_currentWindow != null && !m_windowHooked) - { - m_currentWindow.Closed += WindowOwnerClosed; - m_windowHooked = true; - } - - OnLoadedOverride(); - } - - /// - /// Runs when the Loaded event is fired and executes - /// the LoadedBehavior - /// - protected virtual void OnLoadedOverride() - { - ExecuteMediaState(LoadedBehavior); - } - - /// - /// Runs when the Unloaded event is fired and executes - /// the UnloadedBehavior - /// - protected virtual void OnUnloadedOverride() - { - ExecuteMediaState(UnloadedBehavior); - } - - /// - /// Executes the actions associated to a MediaState - /// - /// The MediaState to execute - protected void ExecuteMediaState(MediaState state) - { - switch (state) - { - case MediaState.Manual: - break; - - case MediaState.Play: - Play(); - break; - - case MediaState.Stop: - Stop(); - break; - - case MediaState.Close: - Close(); - break; - - case MediaState.Pause: - Pause(); - break; - - default: - throw new ArgumentOutOfRangeException("state"); - } - } - - public override void BeginInit() - { - HasInitialized = false; - base.BeginInit(); - } - - public override void EndInit() - { - double balance = Balance; - double volume = Volume; - - MediaPlayerBase.Dispatcher.BeginInvoke((Action)delegate - { - MediaPlayerBase.Balance = balance; - MediaPlayerBase.Volume = volume; - }); - - HasInitialized = true; - base.EndInit(); - } - - public bool HasInitialized - { - get; - protected set; - } - - /// - /// Plays the media - /// - public virtual void Play() - { - MediaPlayerBase.EnsureThread(DefaultApartmentState); - MediaPlayerBase.Dispatcher.BeginInvoke((Action)(delegate - { - MediaPlayerBase.Play(); - Dispatcher.BeginInvoke(((Action)(() => SetIsPlaying(true)))); - })); - } - - /// - /// Pauses the media - /// - public virtual void Pause() - { - MediaPlayerBase.EnsureThread(DefaultApartmentState); - MediaPlayerBase.Dispatcher.BeginInvoke((Action)(() => MediaPlayerBase.Pause())); - SetIsPlaying(false); - } - - /// - /// Closes the media - /// - public virtual void Close() - { - SetBackBuffer(IntPtr.Zero); - InvalidateVideoImage(); - - if (!MediaPlayerBase.Dispatcher.ShuttingOrShutDown) - MediaPlayerBase.Dispatcher.BeginInvoke((Action)(delegate - { - MediaPlayerBase.Close(); - MediaPlayerBase.Dispose(); - })); - - SetIsPlaying(false); - } - - /// - /// Stops the media - /// - public virtual void Stop() - { - if (!MediaPlayerBase.Dispatcher.ShuttingOrShutDown) - MediaPlayerBase.Dispatcher.BeginInvoke((Action)(() => MediaPlayerBase.Stop())); - - SetIsPlaying(false); - } - - /// - /// Called when a MediaPlayerBase is required. - /// - /// This method must return a valid (not null) MediaPlayerBase - protected virtual MediaPlayerBase OnRequestMediaPlayer() - { - return null; - } -} diff --git a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/Controls/MediaSeekingElement.cs b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/Controls/MediaSeekingElement.cs deleted file mode 100644 index 99d503c..0000000 --- a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/Controls/MediaSeekingElement.cs +++ /dev/null @@ -1,341 +0,0 @@ -using System; -using System.Windows; -using WPFMediaKit.DirectShow.MediaPlayers; - -namespace WPFMediaKit.DirectShow.Controls; - -/// -/// The MediaSeekingElement adds media seeking functionality to -/// the MediaElementBase class. -/// -public abstract class MediaSeekingElement : MediaElementBase -{ - /// - /// This flag is used to ignore PropertyChangedCallbacks - /// for when a DependencyProperty is needs to be updated - /// from the media player thread - /// - private bool m_ignorePropertyChangedCallback; - - #region MediaPosition - - public static readonly DependencyProperty MediaPositionProperty = - DependencyProperty.Register("MediaPosition", typeof(long), typeof(MediaSeekingElement), - new FrameworkPropertyMetadata((long)0, - new PropertyChangedCallback(OnMediaPositionChanged))); - - public static readonly RoutedEvent MediaPositionChangedEvent = EventManager.RegisterRoutedEvent("MediaPositionChanged", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MediaSeekingElement)); - - /// - /// Is invoked whenever the current media position is changed. - /// - public event RoutedEventHandler MediaPositionChanged - { - add - { - this.AddHandler(MediaPositionChangedEvent, value); - } - remove - { - this.RemoveHandler(MediaPositionChangedEvent, value); - } - } - - /// - /// Gets or sets the media position in units of CurrentPositionFormat - /// - public long MediaPosition - { - get { return (long)GetValue(MediaPositionProperty); } - set { SetValue(MediaPositionProperty, value); } - } - - private static void OnMediaPositionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((MediaSeekingElement)d).OnMediaPositionChanged(e); - } - - protected virtual void OnMediaPositionChanged(DependencyPropertyChangedEventArgs e) - { - /* If the change came from within our class, - * ignore this callback */ - if ((m_ignorePropertyChangedCallback)) - { - m_ignorePropertyChangedCallback = false; - return; - } - - PlayerSetMediaPosition(); - } - - /// - /// Used to set the MediaPosition without firing the - /// PropertyChanged callback - /// - /// The value to set the MediaPosition to - protected void SetMediaPositionInternal(long value) - { - /* Flag that we want to ignore the next - *PropertyChangedCallback - * If the player is not currently paused!(otherwise it would only react every second seek) */ - m_ignorePropertyChangedCallback = this.PlayerState != PlayerState.Paused; - - MediaPosition = value; - RaiseEvent(new RoutedEventArgs(MediaPositionChangedEvent, this)); - } - - private void PlayerSetMediaPosition() - { - var position = MediaPosition; - if (MediaPlayerBase.Dispatcher.ShuttingOrShutDown) - return; - - MediaPlayerBase.Dispatcher.BeginInvoke((Action) - (() => MediaSeekingPlayer.MediaPosition = position)); - } - - #endregion MediaPosition - - #region MediaDuration - - private static readonly DependencyPropertyKey MediaDurationPropertyKey - = DependencyProperty.RegisterReadOnly("MediaDuration", typeof(long), typeof(MediaSeekingElement), - new FrameworkPropertyMetadata((long)0)); - - public static readonly DependencyProperty MediaDurationProperty - = MediaDurationPropertyKey.DependencyProperty; - - /// - /// Gets the duration of the media in the units of CurrentPositionFormat - /// - public long MediaDuration - { - get { return (long)GetValue(MediaDurationProperty); } - } - - /// - /// Internal method to set the read-only MediaDuration - /// - protected void SetMediaDuration(long value) - { - SetValue(MediaDurationPropertyKey, value); - } - - #endregion MediaDuration - - #region CurrentPositionFormat - - private static readonly DependencyPropertyKey CurrentPositionFormatPropertyKey - = DependencyProperty.RegisterReadOnly("CurrentPositionFormat", typeof(MediaPositionFormat), typeof(MediaSeekingElement), - new FrameworkPropertyMetadata(MediaPositionFormat.None)); - - public static readonly DependencyProperty CurrentPositionFormatProperty - = CurrentPositionFormatPropertyKey.DependencyProperty; - - /// - /// The current position format that the media is currently using - /// - public MediaPositionFormat CurrentPositionFormat - { - get { return (MediaPositionFormat)GetValue(CurrentPositionFormatProperty); } - } - - protected void SetCurrentPositionFormat(MediaPositionFormat value) - { - SetValue(CurrentPositionFormatPropertyKey, value); - } - - #endregion CurrentPositionFormat - - #region PreferedPositionFormat - - public static readonly DependencyProperty PreferedPositionFormatProperty = - DependencyProperty.Register("PreferedPositionFormat", typeof(MediaPositionFormat), typeof(MediaSeekingElement), - new FrameworkPropertyMetadata(MediaPositionFormat.MediaTime, - new PropertyChangedCallback(OnPreferedPositionFormatChanged))); - - /// - /// The MediaPositionFormat that is prefered to be used - /// - public MediaPositionFormat PreferedPositionFormat - { - get { return (MediaPositionFormat)GetValue(PreferedPositionFormatProperty); } - set { SetValue(PreferedPositionFormatProperty, value); } - } - - private static void OnPreferedPositionFormatChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((MediaSeekingElement)d).OnPreferedPositionFormatChanged(e); - } - - /// - /// Executes when a the prefered position format has changed - /// - protected virtual void OnPreferedPositionFormatChanged(DependencyPropertyChangedEventArgs e) - { - if (HasInitialized) - PlayerSetPreferedPositionFormat(); - } - - private void PlayerSetPreferedPositionFormat() - { - var format = PreferedPositionFormat; - MediaPositionFormat currentFormat; - long duration; - - /* We use BeginInvoke here to avoid what seems to be a deadlock */ - MediaSeekingPlayer.Dispatcher.BeginInvoke((Action)delegate - { - MediaSeekingPlayer.PreferedPositionFormat = format; - currentFormat = MediaSeekingPlayer.CurrentPositionFormat; - duration = MediaSeekingPlayer.Duration; - - Dispatcher.BeginInvoke((Action)delegate - { - SetCurrentPositionFormat(currentFormat); - SetMediaDuration(duration); - }); - }); - } - - #endregion PreferedPositionFormat - - #region SpeedRatio - - public static readonly DependencyProperty SpeedRatioProperty = - DependencyProperty.Register("SpeedRatio", typeof(double), typeof(MediaSeekingElement), - new FrameworkPropertyMetadata(1.0, - new PropertyChangedCallback(OnSpeedRatioChanged))); - - /// - /// Gets or sets the rate the media is played back - /// - public double SpeedRatio - { - get { return (double)GetValue(SpeedRatioProperty); } - set { SetValue(SpeedRatioProperty, value); } - } - - private static void OnSpeedRatioChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((MediaSeekingElement)d).OnSpeedRatioChanged(e); - } - - protected virtual void OnSpeedRatioChanged(DependencyPropertyChangedEventArgs e) - { - if (HasInitialized) - PlayerSetSpeedRatio(); - } - - private void PlayerSetSpeedRatio() - { - var speedRatio = SpeedRatio; - - MediaSeekingPlayer.Dispatcher.BeginInvoke((Action)delegate - { - MediaSeekingPlayer.SpeedRatio = speedRatio; - }); - } - - #endregion SpeedRatio - - public override void EndInit() - { - PlayerSetMediaPosition(); - PlayerSetPreferedPositionFormat(); - PlayerSetSpeedRatio(); - base.EndInit(); - } - - /// - /// Internal reference to the MediaSeekingPlayer - /// - protected MediaSeekingPlayer MediaSeekingPlayer - { - get { return MediaPlayerBase as MediaSeekingPlayer; } - } - - /// - /// Fires when a media operation has failed - /// - /// The failed arguments - protected override void OnMediaPlayerFailed(MediaFailedEventArgs e) - { - /* Reset some values on a failure of the media */ - Dispatcher.BeginInvoke((Action)delegate - { - SetMediaDuration(0); - MediaPosition = 0; - }); - - base.OnMediaPlayerFailed(e); - } - - /// - /// Occurs when the media player is being initialized. Here - /// the method is overridden as to attach to media seeking - /// related functionality - /// - protected override void InitializeMediaPlayer() - { - /* Let the base class have its way with it */ - base.InitializeMediaPlayer(); - - if (MediaSeekingPlayer == null) - throw new WPFMediaKitException("MediaSeekingPlayer is null or does not inherit MediaSeekingPlayer"); - - /* Let us know when the media position has changed */ - MediaSeekingPlayer.MediaPositionChanged += OnMediaPlayerPositionChangedPrivate; - } - - /// - /// A private handler for the MediaPositionChanged event of the media player - /// - private void OnMediaPlayerPositionChangedPrivate(object sender, EventArgs e) - { - OnMediaPlayerPositionChanged(); - } - - /// - /// Runs when the media player's position has changed - /// - protected virtual void OnMediaPlayerPositionChanged() - { - long position = MediaSeekingPlayer.MediaPosition; - long duration = MediaSeekingPlayer.Duration; - - Dispatcher.BeginInvoke((Action)delegate - { - if (MediaDuration != duration) - SetMediaDuration(duration); - - SetMediaPositionInternal(position); - }); - } - - /// - /// Runs when the MediaPlayer has successfully opened media - /// - protected override void OnMediaPlayerOpened() - { - MediaPositionFormat positionFormat = MediaSeekingPlayer.CurrentPositionFormat; - long duration = MediaSeekingPlayer.Duration; - - Dispatcher.BeginInvoke((Action)delegate - { - /* Set our DP values */ - SetCurrentPositionFormat(positionFormat); - SetMediaPositionInternal(0); - SetMediaDuration(duration); - double rate = SpeedRatio; - double volume = Volume; - MediaSeekingPlayer.Dispatcher.BeginInvoke((Action)delegate - { - MediaSeekingPlayer.SpeedRatio = rate; - MediaPlayerBase.Volume = volume; - }); - }); - - base.OnMediaPlayerOpened(); - } -} diff --git a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/Controls/MediaUriElement.cs b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/Controls/MediaUriElement.cs deleted file mode 100644 index e47df1f..0000000 --- a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/Controls/MediaUriElement.cs +++ /dev/null @@ -1,250 +0,0 @@ -using System; -using System.Windows; -using System.Windows.Threading; -using WPFMediaKit.DirectShow.MediaPlayers; - -namespace WPFMediaKit.DirectShow.Controls; - -/// -/// The MediaUriElement is a WPF control that plays media of a given -/// Uri. The Uri can be a file path or a Url to media. The MediaUriElement -/// inherits from the MediaSeekingElement, so where available, seeking is -/// also supported. -/// -public class MediaUriElement : MediaSeekingElement -{ - /// - /// The current MediaUriPlayer - /// - public MediaUriPlayer MediaUriPlayer - { - get - { - return MediaPlayerBase as MediaUriPlayer; - } - } - - #region VideoRenderer - - public static readonly DependencyProperty VideoRendererProperty = - DependencyProperty.Register("VideoRenderer", typeof(VideoRendererType), typeof(MediaUriElement), - new FrameworkPropertyMetadata(VideoRendererType.EnhancedVideoRenderer, - new PropertyChangedCallback(OnVideoRendererChanged))); - - public VideoRendererType VideoRenderer - { - get { return (VideoRendererType)GetValue(VideoRendererProperty); } - set { SetValue(VideoRendererProperty, value); } - } - - private static void OnVideoRendererChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((MediaUriElement)d).OnVideoRendererChanged(e); - } - - protected virtual void OnVideoRendererChanged(DependencyPropertyChangedEventArgs e) - { - if (HasInitialized) - PlayerSetVideoRenderer(); - } - - private void PlayerSetVideoRenderer() - { - var videoRendererType = VideoRenderer; - MediaUriPlayer.Dispatcher.BeginInvoke((Action)delegate - { - MediaUriPlayer.VideoRenderer = videoRendererType; - }); - } - - #endregion VideoRenderer - - /// - /// Step the count of frames. - /// - /// count of frames to step - public void FrameStep(int framecount) - { - MediaUriPlayer.Dispatcher.BeginInvoke((Action)delegate - { - MediaUriPlayer.StepFrame(framecount); - }); - } - - #region AudioRenderer - - public static readonly DependencyProperty AudioRendererProperty = - DependencyProperty.Register("AudioRenderer", typeof(string), typeof(MediaUriElement), - new FrameworkPropertyMetadata(MediaUriPlayer.DEFAULT_AUDIO_RENDERER_NAME, - new PropertyChangedCallback(OnAudioRendererChanged))); - - /// - /// The name of the audio renderer device to use. Null to disable audio. - /// - public string AudioRenderer - { - get { return (string)GetValue(AudioRendererProperty); } - set { SetValue(AudioRendererProperty, value); } - } - - private static void OnAudioRendererChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((MediaUriElement)d).OnAudioRendererChanged(e); - } - - protected virtual void OnAudioRendererChanged(DependencyPropertyChangedEventArgs e) - { - if (HasInitialized) - PlayerSetAudioRenderer(); - } - - private void PlayerSetAudioRenderer() - { - var audioDevice = AudioRenderer; - - MediaUriPlayer.Dispatcher.BeginInvoke((Action)delegate - { - /* Sets the audio device to use with the player */ - MediaUriPlayer.AudioRenderer = audioDevice; - }); - } - - #endregion AudioRenderer - - #region Source - - public static readonly DependencyProperty SourceProperty = - DependencyProperty.Register("Source", typeof(Uri), typeof(MediaUriElement), - new FrameworkPropertyMetadata(null, - new PropertyChangedCallback(OnSourceChanged))); - - /// - /// The Uri source to the media. This can be a file path or a - /// URL source - /// - public Uri Source - { - get { return (Uri)GetValue(SourceProperty); } - set { SetValue(SourceProperty, value); } - } - - private static void OnSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((MediaUriElement)d).OnSourceChanged(e); - } - - protected void OnSourceChanged(DependencyPropertyChangedEventArgs e) - { - if (HasInitialized) - PlayerSetSource(); - } - - private void PlayerSetSource() - { - var source = Source; - var rendererType = VideoRenderer; - - MediaPlayerBase.Dispatcher.BeginInvoke((Action)delegate - { - /* Set the renderer type */ - MediaUriPlayer.VideoRenderer = rendererType; - - /* Set the source type */ - MediaUriPlayer.Source = source; - - Dispatcher.BeginInvoke((Action)delegate - { - if (IsLoaded) - ExecuteMediaState(LoadedBehavior); - //else - // ExecuteMediaState(UnloadedBehavior); - }); - }); - } - - #endregion Source - - #region Loop - - public static readonly DependencyProperty LoopProperty = - DependencyProperty.Register("Loop", typeof(bool), typeof(MediaUriElement), - new FrameworkPropertyMetadata(false, - new PropertyChangedCallback(OnLoopChanged))); - - /// - /// Gets or sets whether the media should return to the begining - /// once the end has reached - /// - public bool Loop - { - get { return (bool)GetValue(LoopProperty); } - set { SetValue(LoopProperty, value); } - } - - private static void OnLoopChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((MediaUriElement)d).OnLoopChanged(e); - } - - protected virtual void OnLoopChanged(DependencyPropertyChangedEventArgs e) - { - if (HasInitialized) - PlayerSetLoop(); - } - - private void PlayerSetLoop() - { - var loop = Loop; - MediaPlayerBase.Dispatcher.BeginInvoke((Action)delegate - { - MediaUriPlayer.Loop = loop; - }); - } - - #endregion Loop - - public override void EndInit() - { - PlayerSetVideoRenderer(); - PlayerSetAudioRenderer(); - PlayerSetLoop(); - PlayerSetSource(); - base.EndInit(); - } - - public void DumpGraphInfo(string fileName) - { - MediaUriPlayer.DumpGraphInfo(fileName); - } - - /// - /// The Play method is overrided so we can - /// set the source to the media - /// - public override void Play() - { - EnsurePlayerThread(); - base.Play(); - } - - /// - /// The Pause method is overrided so we can - /// set the source to the media - /// - public override void Pause() - { - EnsurePlayerThread(); - - base.Pause(); - } - - /// - /// Gets the instance of the media player to initialize - /// our base classes with - /// - protected override MediaPlayerBase OnRequestMediaPlayer() - { - var player = new MediaUriPlayer(); - return player; - } -} diff --git a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/Controls/MultimediaUtil.cs b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/Controls/MultimediaUtil.cs deleted file mode 100644 index 964003b..0000000 --- a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/Controls/MultimediaUtil.cs +++ /dev/null @@ -1,95 +0,0 @@ -using DirectShowLib; -using System; -using System.Linq; - -namespace WPFMediaKit.DirectShow.Controls; - -public class MultimediaUtil -{ - #region Audio Renderer Methods - - /// - /// The private cache of the audio renderer names - /// - private static string[] m_audioRendererNames; - - /// - /// An array of audio renderer device names - /// on the current system - /// - public static string[] AudioRendererNames - { - get - { - if (m_audioRendererNames == null) - { - m_audioRendererNames = (from a in GetDevices(FilterCategory.AudioRendererCategory) - select a.Name).ToArray(); - } - return m_audioRendererNames; - } - } - - #endregion Audio Renderer Methods - - #region Video Input Devices - - /// - /// The private cache of the video input names - /// - private static string[] m_videoInputNames; - - /// - /// An array of video input device names - /// on the current system - /// - public static string[] VideoInputNames - { - get - { - if (m_videoInputNames == null) - { - m_videoInputNames = (from d in VideoInputDevices - select d.Name).ToArray(); - } - return m_videoInputNames; - } - } - - #endregion Video Input Devices - - private static DsDevice[] GetDevices(Guid filterCategory) - { - return (from d in DsDevice.GetDevicesOfCat(filterCategory) - select d).ToArray(); - } - - public static DsDevice[] VideoInputDevices - { - get - { - if (m_videoInputDevices == null) - { - m_videoInputDevices = GetDevices(FilterCategory.VideoInputDevice); - } - return m_videoInputDevices; - } - } - - private static DsDevice[] m_videoInputDevices; - - public static string[] VideoInputsDevicePaths - { - get - { - if (m_videoInputsDevicePaths == null) - { - m_videoInputsDevicePaths = (from d in VideoInputDevices - select d.DevicePath).ToArray(); - } - return m_videoInputsDevicePaths; - } - } - - private static string[] m_videoInputsDevicePaths; -} diff --git a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/Controls/ValueConverters.cs b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/Controls/ValueConverters.cs deleted file mode 100644 index f5ccd0c..0000000 --- a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/Controls/ValueConverters.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System; -using System.Globalization; -using System.Windows.Data; -using WPFMediaKit.DirectShow.MediaPlayers; - -namespace WPFMediaKit.DirectShow.Controls; - -/// -/// Converter used to convert MediaTime format to seconds -/// if the current MediaSeekingElement is using MediaTime -/// format. If the MediaSeekingElement is not using -/// MediaTime, then the converter will return the input -/// passed as the MediaTime. -/// -public class MediaTimeToSeconds : IMultiValueConverter -{ - #region IMultiValueConverter Members - - /// - /// Converts MediaTime to seconds - /// - /// There are two parameters to pass. The first is a MediaSeekingElement, - /// the second is a long of the MediaTime - /// - /// - /// - /// The time in seconds if MediaTime is being used, else the second input parameter is passed back - public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) - { - /* We only take two arguments */ - if (values.Length != 2) - return 0; - - /* We only support a MediaSeekingElement */ - var mediaPlayer = values[0] as MediaSeekingElement; - - /* If you didn't send us a MediaSeekingElement, then bugger off */ - if (mediaPlayer == null) - return 0; - - /* Our second param should be a long */ - long value; - - try - { - value = (long)values[1]; - } - catch (Exception) - { - /* Just return what was given to us */ - return values[1]; - } - - /* Only convert if we are dealing with MediaTime */ - if (mediaPlayer.CurrentPositionFormat == MediaPositionFormat.MediaTime) - { - double seconds = (double)value / MediaPlayerBase.DSHOW_ONE_SECOND_UNIT; - return seconds; - } - - return value; - } - - public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) - { - throw new NotImplementedException(); - } - - #endregion IMultiValueConverter Members -} diff --git a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/Controls/VideoCaptureElement.cs b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/Controls/VideoCaptureElement.cs deleted file mode 100644 index a5972fd..0000000 --- a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/Controls/VideoCaptureElement.cs +++ /dev/null @@ -1,302 +0,0 @@ -using DirectShowLib; -using System; -using System.Windows; -using System.Windows.Input; -using System.Windows.Interop; -using WPFMediaKit.DirectShow.MediaPlayers; - -namespace WPFMediaKit.DirectShow.Controls; - -/// -/// The VideoCaptureElement is a WPF control that -/// displays video from a capture device, such as -/// a web cam. -/// -public class VideoCaptureElement : MediaElementBase -{ - public VideoCaptureElement() - { - CommandBindings.Add(new CommandBinding(ShowPropertyPagesCommand, OnShowPropertyPagesCommand)); - } - - #region DesiredPixelWidth - - public static readonly DependencyProperty DesiredPixelWidthProperty = - DependencyProperty.Register("DesiredPixelWidth", typeof(int), typeof(VideoCaptureElement), - new FrameworkPropertyMetadata(0)); - - public int DesiredPixelWidth - { - get { return (int)GetValue(DesiredPixelWidthProperty); } - set { SetValue(DesiredPixelWidthProperty, value); } - } - - #endregion DesiredPixelWidth - - #region DesiredPixelHeight - - public static readonly DependencyProperty DesiredPixelHeightProperty = - DependencyProperty.Register("DesiredPixelHeight", typeof(int), typeof(VideoCaptureElement), - new FrameworkPropertyMetadata(0)); - - public int DesiredPixelHeight - { - get { return (int)GetValue(DesiredPixelHeightProperty); } - set { SetValue(DesiredPixelHeightProperty, value); } - } - - #endregion DesiredPixelHeight - - #region FPS - - public static readonly DependencyProperty FPSProperty = - DependencyProperty.Register("FPS", typeof(int), typeof(VideoCaptureElement), - new FrameworkPropertyMetadata(30)); - - public int FPS - { - get { return (int)GetValue(FPSProperty); } - set { SetValue(FPSProperty, value); } - } - - #endregion FPS - - #region Commands - - public static readonly RoutedCommand ShowPropertyPagesCommand = new RoutedCommand(); - - private void OnShowPropertyPagesCommand(object sender, ExecutedRoutedEventArgs e) - { - ShowPropertyPage(); - } - - #endregion Commands - - #region VideoCaptureSource - - public static readonly DependencyProperty VideoCaptureSourceProperty = - DependencyProperty.Register("VideoCaptureSource", typeof(string), typeof(VideoCaptureElement), - new FrameworkPropertyMetadata("", - new PropertyChangedCallback(OnVideoCaptureSourceChanged))); - - private bool m_sourceChanged; - - public string VideoCaptureSource - { - get { return (string)GetValue(VideoCaptureSourceProperty); } - set { SetValue(VideoCaptureSourceProperty, value); } - } - - public static readonly DependencyProperty VideoCaptureDeviceProperty = - DependencyProperty.Register("VideoCaptureDevice", typeof(DsDevice), typeof(VideoCaptureElement), - new FrameworkPropertyMetadata(null, new PropertyChangedCallback(OnVideoCaptureSourceChanged))); - - private bool m_DeviceChanged; - - public DsDevice VideoCaptureDevice - { - get { return (DsDevice)GetValue(VideoCaptureDeviceProperty); } - set { SetValue(VideoCaptureDeviceProperty, value); } - } - - private static void OnVideoCaptureSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((VideoCaptureElement)d).OnVideoCaptureSourceChanged(e); - } - - protected virtual void OnVideoCaptureSourceChanged(DependencyPropertyChangedEventArgs e) - { - if (e.Property == VideoCaptureSourceProperty) - m_sourceChanged = true; - else if (e.Property == VideoCaptureDeviceProperty) - m_DeviceChanged = true; - - if (HasInitialized) - PlayerVideoCaptureSource(); - } - - private void PlayerVideoCaptureSource() - { - if (m_sourceChanged) - { - string videoSource = VideoCaptureSource; - VideoCapturePlayer.Dispatcher.BeginInvoke((Action)delegate - { - VideoCapturePlayer.VideoCaptureSource = videoSource; - }); - m_sourceChanged = false; - } - else if (m_DeviceChanged) - { - DsDevice device = VideoCaptureDevice; - VideoCapturePlayer.Dispatcher.BeginInvoke((Action)delegate - { - VideoCapturePlayer.VideoCaptureDevice = device; - }); - m_DeviceChanged = false; - } - - //Dispatcher.BeginInvoke((Action)delegate - //{ - if (IsLoaded) - ExecuteMediaState(LoadedBehavior); - //else - // ExecuteMediaState(UnloadedBehavior); - //}); - } - - #endregion VideoCaptureSource - - #region EnableSampleGrabbing - - public static readonly DependencyProperty EnableSampleGrabbingProperty = - DependencyProperty.Register("EnableSampleGrabbing", typeof(bool), typeof(VideoCaptureElement), - new FrameworkPropertyMetadata((bool)false, - new PropertyChangedCallback(OnEnableSampleGrabbingChanged))); - - public bool EnableSampleGrabbing - { - get { return (bool)GetValue(EnableSampleGrabbingProperty); } - set { SetValue(EnableSampleGrabbingProperty, value); } - } - - private static void OnEnableSampleGrabbingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((VideoCaptureElement)d).OnEnableSampleGrabbingChanged(e); - } - - protected virtual void OnEnableSampleGrabbingChanged(DependencyPropertyChangedEventArgs e) - { - VideoCapturePlayer.EnableSampleGrabbing = (bool)e.NewValue; - } - - #endregion EnableSampleGrabbing - - #region UseYuv - - public static readonly DependencyProperty UseYuvProperty = - DependencyProperty.Register("UseYuv", typeof(bool), typeof(VideoCaptureElement), - new FrameworkPropertyMetadata((bool)false, - new PropertyChangedCallback(OnUseYuvChanged))); - - public bool UseYuv - { - get { return (bool)GetValue(UseYuvProperty); } - set { SetValue(UseYuvProperty, value); } - } - - /// - /// Handles changes to the UseYuv property. - /// - private static void OnUseYuvChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((VideoCaptureElement)d).OnUseYuvChanged(e); - } - - /// - /// Provides derived classes an opportunity to handle changes to the UseYuv property. - /// - protected virtual void OnUseYuvChanged(DependencyPropertyChangedEventArgs e) - { - } - - #endregion UseYuv - - public static readonly DependencyProperty OutputFileNameProperty = DependencyProperty.Register("OutputFileName", typeof(string), typeof(VideoCaptureElement), new FrameworkPropertyMetadata(string.Empty, new PropertyChangedCallback(OnOutputFileNameChanged))); - - protected static void OnOutputFileNameChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) - { - ((VideoCaptureElement)d).OnOutputFileNameChanged(e); - } - - protected virtual void OnOutputFileNameChanged(DependencyPropertyChangedEventArgs e) - { - this.VideoCapturePlayer.FileName = (string)e.NewValue; - } - - public string OutputFileName - { - get { return (string)GetValue(OutputFileNameProperty); } - set { SetValue(OutputFileNameProperty, value); } - } - - public override void EndInit() - { - SetParameters(); - PlayerVideoCaptureSource(); - base.EndInit(); - } - - public override void Play() - { - SetParameters(); - base.Play(); - } - - public event EventHandler NewVideoSample; - - private void InvokeNewVideoSample(VideoSampleArgs e) - { - EventHandler sample = NewVideoSample; - if (sample != null) sample(this, e); - } - - private void PlayerNewVideoSample(object sender, VideoSampleArgs e) - { - InvokeNewVideoSample(e); - } - - protected override void InitializeMediaPlayer() - { - base.InitializeMediaPlayer(); - - VideoCapturePlayer.NewVideoSample += PlayerNewVideoSample; - } - - protected VideoCapturePlayer VideoCapturePlayer - { - get - { - return MediaPlayerBase as VideoCapturePlayer; - } - } - - /// - /// Sets the parameters to the video capture player - /// - private void SetParameters() - { - int height = DesiredPixelHeight; - int width = DesiredPixelWidth; - int fps = FPS; - bool useYuv = UseYuv; - string filename = OutputFileName; - - VideoCapturePlayer.Dispatcher.BeginInvoke((Action)delegate - { - VideoCapturePlayer.UseYuv = useYuv; - VideoCapturePlayer.FPS = fps; - VideoCapturePlayer.DesiredWidth = width; - VideoCapturePlayer.DesiredHeight = height; - VideoCapturePlayer.FileName = filename; - }); - } - - public void ShowPropertyPage() - { - var window = Window.GetWindow(this); - var hwnd = IntPtr.Zero; - - if (window != null) - { - hwnd = new WindowInteropHelper(window).Handle; - } - - MediaPlayerBase.Dispatcher.BeginInvoke((Action)(() => VideoCapturePlayer.ShowCapturePropertyPages(hwnd))); - } - - protected override MediaPlayerBase OnRequestMediaPlayer() - { - return new VideoCapturePlayer(); - } -} diff --git a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/MediaPlayers/BaseClasses.cs b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/MediaPlayers/BaseClasses.cs deleted file mode 100644 index d62c781..0000000 --- a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/MediaPlayers/BaseClasses.cs +++ /dev/null @@ -1,1396 +0,0 @@ -using DirectShowLib; -using System; -using System.Collections.Generic; -using System.Drawing; -using System.Linq; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Threading; -using System.Windows.Forms; -using WPFMediaKit.MediaFoundation; -using WPFMediaKit.MediaFoundation.Interop; -using WPFMediaKit.Threading; -using Size = System.Windows.Size; - -namespace WPFMediaKit.DirectShow.MediaPlayers; - -public enum MediaState -{ - Manual, - Play, - Stop, - Close, - Pause -} - -public enum PlayerState -{ - Closed, - Playing, - Paused, - Stopped, - SteppingFrames -} - -/// -/// The types of position formats that -/// are available for seeking media -/// -public enum MediaPositionFormat -{ - MediaTime, - Frame, - Byte, - Field, - Sample, - None -} - -/// -/// Delegate signature to notify of a new surface -/// -/// The sender of the event -/// The pointer to the D3D surface -public delegate void NewAllocatorSurfaceDelegate(object sender, IntPtr pSurface); - -/// -/// The arguments that store information about a failed media attempt -/// -public class MediaFailedEventArgs : EventArgs -{ - public MediaFailedEventArgs(string message, Exception exception) - { - Message = message; - Exception = exception; - } - - public Exception Exception { get; protected set; } - public string Message { get; protected set; } -} - -/// -/// The custom allocator interface. All custom allocators need -/// to implement this interface. -/// -public interface ICustomAllocator : IDisposable -{ - /// - /// Invokes when a new frame has been allocated - /// to a surface - /// - event Action NewAllocatorFrame; - - /// - /// Invokes when a new surface has been allocated - /// - event NewAllocatorSurfaceDelegate NewAllocatorSurface; -} - -[ComImport, Guid("FA10746C-9B63-4b6c-BC49-FC300EA5F256")] -internal class EnhancedVideoRenderer -{ -} - -/// -/// A low level window class that is used to provide interop with libraries -/// that require an hWnd -/// -public class HiddenWindow : NativeWindow -{ - public delegate IntPtr WndProcHookDelegate(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled); - - private readonly List m_handlerlist = new List(); - - public void AddHook(WndProcHookDelegate method) - { - if (m_handlerlist.Contains(method)) - return; - - lock (((System.Collections.ICollection)m_handlerlist).SyncRoot) - m_handlerlist.Add(method); - } - - public void RemoveHook(WndProcHookDelegate method) - { - lock (((System.Collections.ICollection)m_handlerlist).SyncRoot) - m_handlerlist.Remove(method); - } - - /// - /// Invokes the windows procedure associated to this window - /// - /// The window message to send to window - protected override void WndProc(ref Message m) - { - bool isHandled = false; - - lock (((System.Collections.ICollection)m_handlerlist).SyncRoot) - { - foreach (WndProcHookDelegate method in m_handlerlist) - { - method.Invoke(m.HWnd, m.Msg, m.WParam, m.LParam, ref isHandled); - if (isHandled) - break; - } - } - - base.WndProc(ref m); - } -} - -/// -/// Specifies different types of DirectShow -/// Video Renderers -/// -public enum VideoRendererType -{ - VideoMixingRenderer9 = 0, - EnhancedVideoRenderer -} - -/// -/// The MediaPlayerBase is a base class to build raw, DirectShow based players. -/// It inherits from DispatcherObject to allow easy communication with COM objects -/// from different apartment thread models. -/// -public abstract class MediaPlayerBase : WorkDispatcherObject -{ - [DllImport("user32.dll", SetLastError = false)] - private static extern IntPtr GetDesktopWindow(); - - /// - /// A static value to hold a count for all graphs. Each graph - /// has it's own value that it uses and is updated by the - /// GraphInstanceCookie property in the get method - /// - private static int m_graphInstances; - - /// - /// The custom windows message constant for graph events - /// - private const int WM_GRAPH_NOTIFY = 0x0400 + 13; - - /// - /// One second in 100ns units - /// - public const long DSHOW_ONE_SECOND_UNIT = 10000000; - - /// - /// The IBasicAudio volume value for silence - /// - private const int DSHOW_VOLUME_SILENCE = -10000; - - /// - /// The IBasicAudio volume value for full volume - /// - private const int DSHOW_VOLUME_MAX = 0; - - /// - /// The IBasicAudio balance max absolute value - /// - private const int DSHOW_BALACE_MAX_ABS = 10000; - - /// - /// Rate which our DispatcherTimer polls the graph - /// - private const int DSHOW_TIMER_POLL_MS = 33; - - /// - /// UserId value for the VMR9 Allocator - Not entirely useful - /// for this application of the VMR - /// - private readonly IntPtr m_userId = new IntPtr(unchecked((int)0xDEADBEEF)); - - /// - /// Static lock. Seems multiple EVR controls instantiated at the same time crash - /// - private static readonly object m_videoRendererInitLock = new object(); - - /// - /// DirectShow interface for controlling audio - /// functions such as volume and balance - /// - private IBasicAudio m_basicAudio; - - /// - /// The custom DirectShow allocator - /// - private ICustomAllocator m_customAllocator; - - /// - /// The DirectShow filter graph reference - /// - private IFilterGraph m_graph; - - /// - /// The hWnd pointer we use for D3D stuffs - /// - private HiddenWindow m_window; - - /// - /// The DirectShow interface for controlling the - /// filter graph. This provides, Play, Pause, Stop, etc - /// functionality. - /// - private IMediaControl m_mediaControl; - - /// - /// The DirectShow interface for getting events - /// that occur in the FilterGraph. - /// - private IMediaEventEx m_mediaEvent; - - /// - /// Flag for if our media has video - /// - private bool m_hasVideo; - - /// - /// The natural video pixel height, if applicable - /// - private int m_naturalVideoHeight; - - /// - /// The natural video pixel width, if applicable - /// - private int m_naturalVideoWidth; - - /// - /// Our Win32 timer to poll the DirectShow graph - /// - private System.Timers.Timer m_timer; - - /// - /// The current state of the player - /// - private PlayerState m_playerState = PlayerState.Closed; - - /// - /// This objects last stand - /// - ~MediaPlayerBase() - { - Dispose(); - } - - /// - /// The global instance Id of the graph. We use this - /// for the WndProc callback method. - /// - private int? m_graphInstanceId; - - /// - /// The globally unqiue identifier of the graph - /// - protected int GraphInstanceId - { - get - { - if (m_graphInstanceId != null) - return m_graphInstanceId.Value; - - /* Increment our static value and store the current - * instance id of our player graph */ - m_graphInstanceId = Interlocked.Increment(ref m_graphInstances); - - return m_graphInstanceId.Value; - } - } - - /// - /// Helper function to get a valid hWnd to - /// use with DirectShow and Direct3D - /// - [MethodImpl(MethodImplOptions.Synchronized)] - private void GetMainWindowHwndHelper() - { - if (m_window == null) - m_window = new HiddenWindow(); - else - return; - - if (m_window.Handle == IntPtr.Zero) - { - lock (m_window) - { - m_window.CreateHandle(new CreateParams()); - } - } - } - - protected virtual HiddenWindow HwndHelper - { - get - { - if (m_window != null) - return m_window; - - GetMainWindowHwndHelper(); - - return m_window; - } - } - - /// - /// Is true if the media contains renderable video - /// - public virtual bool HasVideo - { - get - { - return m_hasVideo; - } - protected set - { - m_hasVideo = value; - } - } - - /// - /// Gets the natural pixel width of the current media. - /// The value will be 0 if there is no video in the media. - /// - public virtual int NaturalVideoWidth - { - get - { - VerifyAccess(); - return m_naturalVideoWidth; - } - protected set - { - VerifyAccess(); - m_naturalVideoWidth = value; - } - } - - /// - /// Gets the natural pixel height of the current media. - /// The value will be 0 if there is no video in the media. - /// - public virtual int NaturalVideoHeight - { - get - { - VerifyAccess(); - return m_naturalVideoHeight; - } - protected set - { - VerifyAccess(); - m_naturalVideoHeight = value; - } - } - - /// - /// Gets or sets the audio volume. Specifies the volume, as a - /// number from 0 to 1. Full volume is 1, and 0 is silence. - /// - public virtual double Volume - { - get - { - VerifyAccess(); - - /* Check if we even have an - * audio interface */ - if (m_basicAudio == null) - return 0; - - int dShowVolume; - - /* Get the current volume value from the interface */ - m_basicAudio.get_Volume(out dShowVolume); - - /* Do calulations to convert to a base of 0 for silence */ - dShowVolume -= DSHOW_VOLUME_SILENCE; - return (double)dShowVolume / -DSHOW_VOLUME_SILENCE; - } - set - { - VerifyAccess(); - - /* Check if we even have an - * audio interface */ - if (m_basicAudio == null) - return; - - if (value <= 0) /* Value should not be negative or else we treat as silence */ - m_basicAudio.put_Volume(DSHOW_VOLUME_SILENCE); - else if (value >= 1)/* Value should not be greater than one or else we treat as maximum volume */ - m_basicAudio.put_Volume(DSHOW_VOLUME_MAX); - else - { - /* With the IBasicAudio interface, sound is DSHOW_VOLUME_SILENCE - * for silence and DSHOW_VOLUME_MAX for full volume - * so we calculate that here based off an input of 0 of silence and 1.0 - * for full audio */ - int dShowVolume = (int)((1 - value) * DSHOW_VOLUME_SILENCE); - m_basicAudio.put_Volume(dShowVolume); - } - } - } - - /// - /// Gets or sets the balance on the audio. - /// The value can range from -1 to 1. The value -1 means the right channel is attenuated by 100 dB - /// and is effectively silent. The value 1 means the left channel is silent. The neutral value is 0, - /// which means that both channels are at full volume. When one channel is attenuated, the other - /// remains at full volume. - /// - public virtual double Balance - { - get - { - VerifyAccess(); - - /* Check if we even have an - * audio interface */ - if (m_basicAudio == null) - return 0; - - int balance; - - /* Get the interface supplied balance value */ - m_basicAudio.get_Balance(out balance); - - /* Calc and return the balance based on 0 == silence */ - return (double)balance / DSHOW_BALACE_MAX_ABS; - } - set - { - VerifyAccess(); - - /* Check if we even have an - * audio interface */ - if (m_basicAudio == null) - return; - - /* Calc the dshow balance value */ - int balance = (int)value * DSHOW_BALACE_MAX_ABS; - - m_basicAudio.put_Balance(balance); - } - } - - /// - /// Get the current state of the player - /// - public virtual PlayerState PlayerState - { - get { return this.m_playerState; } - protected set - { - PlayerState oldVal = m_playerState; - m_playerState = value; - - if (PlayerStateChanged != null && oldVal != value) - PlayerStateChanged(oldVal, value); - } - } - - /// - /// Event notifies when there is a new video frame - /// to be rendered - /// - public event Action NewAllocatorFrame; - - /// - /// Event notifies when there is a new surface allocated - /// - public event NewAllocatorSurfaceDelegate NewAllocatorSurface; - - /// - /// Event notifies when the player changes state - /// - public event Action PlayerStateChanged; - - /// - /// Frees any remaining memory - /// - public void Dispose() - { - Dispose(true); - //GC.SuppressFinalize(this); - } - - /// - /// Part of the dispose pattern - /// - protected virtual void Dispose(bool disposing) - { - //if (m_disposed) - // return; - - if (!disposing) - return; - - if (m_window != null) - { - m_window.RemoveHook(WndProcHook); - m_window.DestroyHandle(); - m_window = null; - } - - if (m_timer != null) - m_timer.Dispose(); - - m_timer = null; - - if (CheckAccess()) - { - FreeResources(); - Dispatcher.BeginInvokeShutdown(); - } - else - { - Dispatcher.BeginInvoke((Action)delegate - { - FreeResources(); - Dispatcher.BeginInvokeShutdown(); - }); - } - } - - /// - /// Polls the graph for various data about the media that is playing - /// - protected virtual void OnGraphTimerTick() - { - } - - /// - /// Is called when a new media event code occurs on the graph - /// - /// The event code that occured - /// The first parameter sent by the graph - /// The second parameter sent by the graph - protected virtual void OnMediaEvent(EventCode code, IntPtr param1, IntPtr param2) - { - switch (code) - { - case EventCode.Complete: - InvokeMediaEnded(null); - StopGraphPollTimer(); - break; - - case EventCode.Paused: - break; - - default: - break; - } - } - - /// - /// Starts the graph polling timer to update possibly needed - /// things like the media position - /// - protected void StartGraphPollTimer() - { - if (m_timer == null) - { - m_timer = new System.Timers.Timer(); - m_timer.Interval = DSHOW_TIMER_POLL_MS; - m_timer.Elapsed += TimerElapsed; - } - - m_timer.Enabled = true; - - /* Make sure we get windows messages */ - AddWndProcHook(); - } - - private void ProcessGraphEvents() - { - Dispatcher.BeginInvoke((Action)delegate - { - if (m_mediaEvent != null) - { - IntPtr param1; - IntPtr param2; - EventCode code; - - /* Get all the queued events from the interface */ - while (m_mediaEvent.GetEvent(out code, out param1, out param2, 0) == 0) - { - /* Handle anything for this event code */ - OnMediaEvent(code, param1, param2); - - /* Free everything..we only need the code */ - m_mediaEvent.FreeEventParams(code, param1, param2); - } - } - }); - } - - private void TimerElapsed(object sender, System.Timers.ElapsedEventArgs e) - { - Dispatcher.BeginInvoke((Action)delegate - { - ProcessGraphEvents(); - OnGraphTimerTick(); - }); - } - - /// - /// Stops the graph polling timer - /// - protected void StopGraphPollTimer() - { - if (m_timer != null) - { - m_timer.Stop(); - m_timer.Dispose(); - m_timer = null; - } - - /* Stop listening to windows messages */ - RemoveWndProcHook(); - } - - /// - /// Removes our hook that listens to windows messages - /// - private void RemoveWndProcHook() - { - /* Make sure to stop our IMediaEventEx also */ - UnsetMediaEventExNotifyWindow(); - //HwndHelper.RemoveHook(WndProcHook); - } - - /// - /// Adds a hook that listens to windows messages - /// - private void AddWndProcHook() - { - // HwndHelper.AddHook(WndProcHook); - } - - /// - /// Receives windows messages. This is primarily used to get - /// events that happen on our graph - /// - /// The window handle - /// The message Id - /// The message's wParam value - /// The message's lParam value - /// A value that indicates whether the message was handled. Set the value to true if the message was handled; otherwise, false. - private IntPtr WndProcHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) - { - ProcessGraphEvents(); - - return IntPtr.Zero; - } - - /// - /// Unhooks the IMediaEventEx from the notification hWnd - /// - private void UnsetMediaEventExNotifyWindow() - { - if (m_mediaEvent == null) - return; - - /* Setting the notify window to IntPtr.Zero unsubscribes the events */ - //int hr = m_mediaEvent.SetNotifyWindow(IntPtr.Zero, WM_GRAPH_NOTIFY, (IntPtr)GraphInstanceId); - } - - /// - /// Sets the MediaEventEx interface - /// - private void SetMediaEventExInterface(IMediaEventEx mediaEventEx) - { - m_mediaEvent = mediaEventEx; - - //int hr = m_mediaEvent.SetNotifyWindow(HwndHelper.Handle, WM_GRAPH_NOTIFY, (IntPtr)GraphInstanceId); - } - - /// - /// Configures all general DirectShow interfaces that the - /// FilterGraph supplies. - /// - /// The FilterGraph to setup - protected virtual void SetupFilterGraph(IFilterGraph graph) - { - m_graph = graph; - - /* Setup the interfaces and query basic information - * on the graph that is passed */ - SetBasicAudioInterface(m_graph as IBasicAudio); - SetMediaControlInterface(m_graph as IMediaControl); - SetMediaEventExInterface(m_graph as IMediaEventEx); - } - - /// - /// Sets the MediaControl interface - /// - private void SetMediaControlInterface(IMediaControl mediaControl) - { - m_mediaControl = mediaControl; - } - - /// - /// Sets the basic audio interface for controlling - /// volume and balance - /// - protected void SetBasicAudioInterface(IBasicAudio basicAudio) - { - m_basicAudio = basicAudio; - } - - /// - /// Notifies when the media has successfully been opened - /// - public event Action MediaOpened; - - /// - /// Notifies when the media has been closed - /// - public event Action MediaClosed; - - /// - /// Notifies when the media has failed and produced an exception - /// - public event EventHandler MediaFailed; - - /// - /// Notifies when the media has completed - /// - public event Action MediaEnded; - - /// - /// Registers the custom allocator and hooks into it's supplied events - /// - protected void RegisterCustomAllocator(ICustomAllocator allocator) - { - FreeCustomAllocator(); - - if (allocator == null) - return; - - m_customAllocator = allocator; - - m_customAllocator.NewAllocatorFrame += CustomAllocatorNewAllocatorFrame; - m_customAllocator.NewAllocatorSurface += CustomAllocatorNewAllocatorSurface; - } - - /// - /// Local event handler for the custom allocator's new surface event - /// - private void CustomAllocatorNewAllocatorSurface(object sender, IntPtr pSurface) - { - InvokeNewAllocatorSurface(pSurface); - } - - /// - /// Local event handler for the custom allocator's new frame event - /// - private void CustomAllocatorNewAllocatorFrame() - { - InvokeNewAllocatorFrame(); - } - - /// - /// Disposes of the current allocator - /// - protected void FreeCustomAllocator() - { - if (m_customAllocator == null) - return; - - m_customAllocator.NewAllocatorFrame -= CustomAllocatorNewAllocatorFrame; - m_customAllocator.NewAllocatorSurface -= CustomAllocatorNewAllocatorSurface; - - m_customAllocator.Dispose(); - - if (Marshal.IsComObject(m_customAllocator)) - Marshal.ReleaseComObject(m_customAllocator); - - m_customAllocator = null; - } - - /// - /// Resets the local graph resources to their - /// default settings - /// - private void ResetLocalGraphResources() - { - m_graph = null; - - if (m_basicAudio != null) - Marshal.ReleaseComObject(m_basicAudio); - m_basicAudio = null; - - if (m_mediaControl != null) - Marshal.ReleaseComObject(m_mediaControl); - m_mediaControl = null; - - if (m_mediaEvent != null) - Marshal.ReleaseComObject(m_mediaEvent); - m_mediaEvent = null; - } - - /// - /// Frees any allocated or unmanaged resources - /// - [MethodImpl(MethodImplOptions.Synchronized)] - protected virtual void FreeResources() - { - StopGraphPollTimer(); - ResetLocalGraphResources(); - FreeCustomAllocator(); - } - - /// - /// Creates a new renderer and configures it with a custom allocator - /// - /// The type of renderer we wish to choose - /// The DirectShow graph to add the renderer to - /// Number of input pins for the renderer - /// An initialized DirectShow renderer - protected IBaseFilter CreateVideoRenderer(VideoRendererType rendererType, IGraphBuilder graph, int streamCount) - { - IBaseFilter renderer; - - switch (rendererType) - { - case VideoRendererType.VideoMixingRenderer9: - renderer = CreateVideoMixingRenderer9(graph, streamCount); - break; - - case VideoRendererType.EnhancedVideoRenderer: - renderer = CreateEnhancedVideoRenderer(graph, streamCount); - break; - - default: - throw new ArgumentOutOfRangeException("rendererType"); - } - - return renderer; - } - - /// - /// Creates a new renderer and configures it with a custom allocator - /// - /// The type of renderer we wish to choose - /// The DirectShow graph to add the renderer to - /// An initialized DirectShow renderer - protected IBaseFilter CreateVideoRenderer(VideoRendererType rendererType, IGraphBuilder graph) - { - return CreateVideoRenderer(rendererType, graph, 1); - } - - /// - /// Creates an instance of the EVR - /// - private IBaseFilter CreateEnhancedVideoRenderer(IGraphBuilder graph, int streamCount) - { - EvrPresenter presenter; - IBaseFilter filter; - - lock (m_videoRendererInitLock) - { - var evr = new EnhancedVideoRenderer(); - filter = evr as IBaseFilter; - - int hr = graph.AddFilter(filter, string.Format("Renderer: {0}", VideoRendererType.EnhancedVideoRenderer)); - DsError.ThrowExceptionForHR(hr); - - /* QueryInterface for the IMFVideoRenderer */ - var videoRenderer = filter as IMFVideoRenderer; - - if (videoRenderer == null) - throw new WPFMediaKitException("Could not QueryInterface for the IMFVideoRenderer"); - - /* Create a new EVR presenter */ - presenter = EvrPresenter.CreateNew(); - - /* Initialize the EVR renderer with the custom video presenter */ - hr = videoRenderer.InitializeRenderer(null, presenter.VideoPresenter); - DsError.ThrowExceptionForHR(hr); - - var presenterSettings = presenter.VideoPresenter as IEVRPresenterSettings; - if (presenterSettings == null) - throw new WPFMediaKitException("Could not QueryInterface for the IEVRPresenterSettings"); - - presenterSettings.SetBufferCount(3); - - /* Use our interop hWnd */ - IntPtr handle = GetDesktopWindow();//HwndHelper.Handle; - - /* QueryInterface the IMFVideoDisplayControl */ - var displayControl = presenter.VideoPresenter as IMFVideoDisplayControl; - - if (displayControl == null) - throw new WPFMediaKitException("Could not QueryInterface the IMFVideoDisplayControl"); - - /* Configure the presenter with our hWnd */ - hr = displayControl.SetVideoWindow(handle); - DsError.ThrowExceptionForHR(hr); - - var filterConfig = filter as IEVRFilterConfig; - - if (filterConfig != null) - filterConfig.SetNumberOfStreams(streamCount); - } - - RegisterCustomAllocator(presenter); - - return filter; - } - - /// - /// Creates a new VMR9 renderer and configures it with an allocator. - /// - /// COMException is transalted to the WPFMediaKitException. - /// - /// - /// An initialized DirectShow VMR9 renderer. - /// When creating of VMR9 fails. - private IBaseFilter CreateVideoMixingRenderer9(IGraphBuilder graph, int streamCount) - { - try - { - return CreateVideoMixingRenderer9Inner(graph, streamCount); - } - catch (COMException ex) - { - throw new WPFMediaKitException("Could not create VMR9. " + Vmr9Allocator.VMR9_ERROR, ex); - } - } - - /// - /// Creates a new VMR9 renderer and configures it with an allocator. - /// - /// An initialized DirectShow VMR9 renderer. - /// When creating of VMR9 fails. - /// When creating of VMR9 fails. - private IBaseFilter CreateVideoMixingRenderer9Inner(IGraphBuilder graph, int streamCount) - { - IBaseFilter vmr9 = new VideoMixingRenderer9() as IBaseFilter; - var filterConfig = vmr9 as IVMRFilterConfig9; - if (filterConfig == null) - throw new WPFMediaKitException("Could not query VMR9 filter configuration. " + Vmr9Allocator.VMR9_ERROR); - - /* We will only have one video stream connected to the filter */ - int hr = filterConfig.SetNumberOfStreams(streamCount); - DsError.ThrowExceptionForHR(hr); - - /* Setting the renderer to "Renderless" mode - * sounds counter productive, but its what we - * need to do for setting up a custom allocator */ - hr = filterConfig.SetRenderingMode(VMR9Mode.Renderless); - DsError.ThrowExceptionForHR(hr); - - /* Query the allocator interface */ - var vmrSurfAllocNotify = vmr9 as IVMRSurfaceAllocatorNotify9; - if (vmrSurfAllocNotify == null) - throw new WPFMediaKitException("Could not query the VMR surface allocator. " + Vmr9Allocator.VMR9_ERROR); - - var allocator = new Vmr9Allocator(); - - /* We supply our custom allocator to the renderer */ - hr = vmrSurfAllocNotify.AdviseSurfaceAllocator(m_userId, allocator); - DsError.ThrowExceptionForHR(hr); - - hr = allocator.AdviseNotify(vmrSurfAllocNotify); - DsError.ThrowExceptionForHR(hr); - - RegisterCustomAllocator(allocator); - - hr = graph.AddFilter(vmr9, - string.Format("Renderer: {0}", VideoRendererType.VideoMixingRenderer9)); - DsError.ThrowExceptionForHR(hr); - - return vmr9; - } - - /// - /// Plays the media - /// - public virtual void Play() - { - VerifyAccess(); - - if (m_basicAudio != null) - { - //Balance = Balance; - //Volume = Volume; - } - - if (m_mediaControl != null) - { - m_mediaControl.Run(); - StartGraphPollTimer(); - PlayerState = PlayerState.Playing; - } - } - - /// - /// Stops the media - /// - public virtual void Stop() - { - VerifyAccess(); - - StopInternal(); - } - - /// - /// Stops the media, but does not VerifyAccess() on - /// the Dispatcher. This can be used by destructors - /// because it happens on another thread and our - /// DirectShow graph and COM run in MTA - /// - protected void StopInternal() - { - if (m_mediaControl != null) - { - m_mediaControl.Stop(); - FilterState filterState; - m_mediaControl.GetState(0, out filterState); - - while (filterState != FilterState.Stopped) - m_mediaControl.GetState(2, out filterState); - - PlayerState = PlayerState.Stopped; - } - } - - /// - /// Closes the media and frees its resources - /// - public virtual void Close() - { - VerifyAccess(); - StopInternal(); - FreeResources(); - PlayerState = PlayerState.Closed; - } - - /// - /// Pauses the media - /// - public virtual void Pause() - { - VerifyAccess(); - - if (m_mediaControl != null) - { - m_mediaControl.Pause(); - PlayerState = PlayerState.Paused; - } - } - - #region Event Invokes - - /// - /// Invokes the MediaEnded event, notifying any subscriber that - /// media has reached the end - /// - protected void InvokeMediaEnded(EventArgs e) - { - var mediaEndedHandler = MediaEnded; - if (mediaEndedHandler != null) - mediaEndedHandler(); - } - - /// - /// Invokes the MediaOpened event, notifying any subscriber that - /// media has successfully been opened - /// - protected void InvokeMediaOpened() - { - /* This is generally a good place to start - * our polling timer */ - StartGraphPollTimer(); - - var mediaOpenedHandler = MediaOpened; - if (mediaOpenedHandler != null) - mediaOpenedHandler(); - } - - /// - /// Invokes the MediaClosed event, notifying any subscriber that - /// the opened media has been closed - /// - protected void InvokeMediaClosed(EventArgs e) - { - StopGraphPollTimer(); - - var mediaClosedHandler = MediaClosed; - if (mediaClosedHandler != null) - mediaClosedHandler(); - } - - /// - /// Invokes the MediaFailed event, notifying any subscriber that there was - /// a media exception. - /// - /// The MediaFailedEventArgs contains the exception that caused this event to fire - protected void InvokeMediaFailed(MediaFailedEventArgs e) - { - var mediaFailedHandler = MediaFailed; - if (mediaFailedHandler != null) - mediaFailedHandler(this, e); - } - - /// - /// Invokes the NewAllocatorFrame event, notifying any subscriber that new frame - /// is ready to be presented. - /// - protected void InvokeNewAllocatorFrame() - { - var newAllocatorFrameHandler = NewAllocatorFrame; - if (newAllocatorFrameHandler != null) - newAllocatorFrameHandler(); - } - - /// - /// Invokes the NewAllocatorSurface event, notifying any subscriber of a new surface - /// - /// The COM pointer to the D3D surface - protected void InvokeNewAllocatorSurface(IntPtr pSurface) - { - var del = NewAllocatorSurface; - if (del != null) - del(this, pSurface); - } - - #endregion Event Invokes - - #region Helper Methods - - /// - /// Sets the natural pixel resolution the video in the graph - /// - /// The video renderer - protected void SetNativePixelSizes(IBaseFilter renderer) - { - Size size = GetVideoSize(renderer, PinDirection.Input, 0); - - NaturalVideoHeight = (int)size.Height; - NaturalVideoWidth = (int)size.Width; - - HasVideo = true; - } - - /// - /// Gets the video resolution of a pin on a renderer. - /// - /// The renderer to inspect - /// The direction the pin is - /// The zero based index of the pin to inspect - /// If successful a video resolution is returned. If not, a 0x0 size is returned - protected static Size GetVideoSize(IBaseFilter renderer, PinDirection direction, int pinIndex) - { - var size = new Size(); - - var mediaType = new AMMediaType(); - IPin pin = DsFindPin.ByDirection(renderer, direction, pinIndex); - - if (pin == null) - goto done; - - int hr = pin.ConnectionMediaType(mediaType); - - if (hr != 0) - goto done; - - /* Check to see if its a video media type */ - if (mediaType.formatType != FormatType.VideoInfo2 && - mediaType.formatType != FormatType.VideoInfo) - { - goto done; - } - - var videoInfo = new VideoInfoHeader(); - - /* Read the video info header struct from the native pointer */ - Marshal.PtrToStructure(mediaType.formatPtr, videoInfo); - - Rectangle rect = videoInfo.SrcRect.ToRectangle(); - size = new Size(rect.Width, rect.Height); - - done: - DsUtils.FreeAMMediaType(mediaType); - - if (pin != null) - Marshal.ReleaseComObject(pin); - return size; - } - - /// - /// Removes all filters from a DirectShow graph - /// - /// The DirectShow graph to remove all the filters from - protected static void RemoveAllFilters(IGraphBuilder graphBuilder) - { - if (graphBuilder == null) - return; - - IEnumFilters enumFilters; - - /* The list of filters from the DirectShow graph */ - var filtersArray = new List(); - - if (graphBuilder == null) - throw new ArgumentNullException("graphBuilder"); - - /* Gets the filter enumerator from the graph */ - int hr = graphBuilder.EnumFilters(out enumFilters); - DsError.ThrowExceptionForHR(hr); - - try - { - /* This array is filled with reference to a filter */ - var filters = new IBaseFilter[1]; - IntPtr fetched = IntPtr.Zero; - - /* Get reference to all the filters */ - while (enumFilters.Next(filters.Length, filters, fetched) == 0) - { - /* Add the filter to our array */ - filtersArray.Add(filters[0]); - } - } - finally - { - /* Enum filters is a COM, so release that */ - Marshal.ReleaseComObject(enumFilters); - } - - /* Loop over and release each COM */ - for (int i = 0; i < filtersArray.Count; i++) - { - graphBuilder.RemoveFilter(filtersArray[i]); - while (Marshal.ReleaseComObject(filtersArray[i]) > 0) - { } - } - } - - /// - /// Adds a filter to a DirectShow graph based on it's name and filter category - /// - /// The graph builder to add the filter to - /// The category the filter belongs to - /// The friendly name of the filter - /// Reference to the IBaseFilter that was added to the graph or returns null if unsuccessful - protected static IBaseFilter AddFilterByName(IGraphBuilder graphBuilder, Guid deviceCategory, string friendlyName) - { - var devices = DsDevice.GetDevicesOfCat(deviceCategory); - - var deviceList = (from d in devices - where d.Name == friendlyName - select d).ToList(); - DsDevice device = deviceList.FirstOrDefault(); - - foreach (var item in deviceList) - { - if (item != device) - item.Dispose(); - } - - return AddFilterByDevice(graphBuilder, device); - } - - protected static IBaseFilter AddFilterByDevicePath(IGraphBuilder graphBuilder, Guid deviceCategory, string devicePath) - { - var devices = DsDevice.GetDevicesOfCat(deviceCategory); - - var deviceList = (from d in devices - where d.DevicePath == devicePath - select d).ToList(); - DsDevice device = deviceList.FirstOrDefault(); - - foreach (var item in deviceList) - { - if (item != device) - item.Dispose(); - } - - return AddFilterByDevice(graphBuilder, device); - } - - private static IBaseFilter AddFilterByDevice(IGraphBuilder graphBuilder, DsDevice device) - { - if (graphBuilder == null) - throw new ArgumentNullException("graphBuilder"); - if (device == null) - return null; - - var filterGraph = graphBuilder as IFilterGraph2; - - if (filterGraph == null) - return null; - - IBaseFilter filter = null; - int hr = filterGraph.AddSourceFilterForMoniker(device.Mon, null, device.Name, out filter); - DsError.ThrowExceptionForHR(hr); - return filter; - } - - /// - /// Finds a pin that exists in a graph. - /// - /// The GUID of the major or minor type of the media - /// The direction of the pin - in/out - /// The graph to search in - /// Returns null if the pin was not found, or if a pin is found, returns the first instance of it - protected static IPin FindPinInGraphByMediaType(Guid majorOrMinorMediaType, PinDirection pinDirection, IGraphBuilder graph) - { - IEnumFilters enumFilters; - - /* Get the filter enum */ - graph.EnumFilters(out enumFilters); - - /* Init our vars */ - var filters = new IBaseFilter[1]; - var fetched = IntPtr.Zero; - IPin pin = null; - IEnumMediaTypes mediaTypesEnum = null; - - /* Loop over each filter in the graph */ - while (enumFilters.Next(1, filters, fetched) == 0) - { - var filter = filters[0]; - - int i = 0; - - /* Loop over each pin in the filter */ - while ((pin = DsFindPin.ByDirection(filter, pinDirection, i)) != null) - { - /* Get the pin enumerator */ - pin.EnumMediaTypes(out mediaTypesEnum); - var mediaTypesFetched = IntPtr.Zero; - var mediaTypes = new AMMediaType[1]; - - /* Enumerate the media types on the pin */ - while (mediaTypesEnum.Next(1, mediaTypes, mediaTypesFetched) == 0) - { - /* See if the major or subtype meets our requirements */ - if (mediaTypes[0].majorType.Equals(majorOrMinorMediaType) || mediaTypes[0].subType.Equals(majorOrMinorMediaType)) - { - /* We found a match */ - goto done; - } - } - i++; - } - } - - done: - if (mediaTypesEnum != null) - { - mediaTypesEnum.Reset(); - Marshal.ReleaseComObject(mediaTypesEnum); - } - - enumFilters.Reset(); - Marshal.ReleaseComObject(enumFilters); - - return pin; - } - - #endregion Helper Methods -} diff --git a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/MediaPlayers/ClassId.cs b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/MediaPlayers/ClassId.cs deleted file mode 100644 index 33f8262..0000000 --- a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/MediaPlayers/ClassId.cs +++ /dev/null @@ -1,72 +0,0 @@ -using System; - -// Code of MediaPortal (www.team-mediaportal.com) - -namespace WPFMediaKit.DirectShow.MediaPlayers; - -public class ClassId -{ - /// Prevent instantiation. - private ClassId() { } - - public static readonly Guid SystemDeviceEnum = new Guid(0x62BE5D10, 0x60EB, 0x11d0, 0xBD, 0x3B, 0x00, 0xA0, 0xC9, - 0x11, 0xCE, 0x86); - - /// The File Writer filter can be used to write files to disc regardless of format. - public static readonly Guid FileWriter = new Guid("8596E5F0-0DA5-11D0-BD21-00A0C911CE86"); - - /// The Filter Graph Manager builds and controls filter graphs. - public static readonly Guid FilterGraph = new Guid("E436EBB3-524F-11CE-9F53-0020AF0BA770"); - - /// The WM ASF Writer filter accepts a variable number of input streams and creates an ASF file. - public static readonly Guid WMAsfWriter = new Guid("7C23220E-55BB-11D3-8B16-00C04FB6BD3D"); - - /// The RecComp object creates new content recordings by concatenating existing recordings. - public static readonly Guid RecComp = new Guid("D682C4BA-A90A-42FE-B9E1-03109849C423"); - - /// The Recording object creates permanent recordings from streams that the Stream Buffer Sink filter captures. - public static readonly Guid RecordingAttributes = new Guid("CCAA63AC-1057-4778-AE92-1206AB9ACEE6"); - - /// The WavDes filter writes an audio stream to a WAV file. - public static readonly Guid WavDest = new Guid("3C78B8E2-6C4D-11d1-ADE2-0000F8754B99"); - - /// The Decrypter/Detagger filter conditionally decrypts samples that are encrypted by the Encrypter/Tagger filter. - public static readonly Guid DecryptTag = new Guid("C4C4C4F2-0049-4E2B-98FB-9537F6CE516D"); - - public static readonly Guid MPTSWriter = new Guid("8943BEB7-E0BC-453b-9EA5-EB93899FA51C"); - public static readonly Guid MPStreamAnalyzer = new Guid("BAAC8911-1BA2-4ec2-96BA-6FFE42B62F72"); - - public static readonly Guid PinCategoryVBI = new Guid(0xfb6c4284, 0x0353, 0x11d1, 0x90, 0x5f, 0x00, 0x00, 0xc0, 0xcc, - 0x16, 0xba); - - public static readonly Guid DirectVobSubAutoload = new Guid("9852A670-F845-491b-9BE6-EBD841B8A613"); - public static readonly Guid DirectVobSubNormal = new Guid("93A22E7A-5091-45ef-BA61-6DA26156A5D0"); - - public static readonly Guid InternalScriptRenderer = new Guid("48025243-2D39-11CE-875D-00608CB78066"); - - public static readonly Guid HaaliGuid = new Guid("55DA30FC-F16B-49FC-BAA5-AE59FC65F82D"); - public static readonly Guid MPCMatroska = new Guid("149D2E01-C32E-4939-80F6-C07B81015A7A"); - public static readonly Guid MPCMatroskaSource = new Guid("0A68C3B5-9164-4A54-AFAF-995B2FF0E0D4"); - - public static readonly Guid LAVFilterSource = new Guid("B98D13E7-55DB-4385-A33D-09FD1BA26338"); - public static readonly Guid LAVFilter = new Guid("171252A0-8820-4AFE-9DF8-5C92B2D66B04"); - public static readonly Guid LAVFilterVideo = new Guid("EE30215D-164F-4A92-A4EB-9D4C13390F9F"); - public static readonly Guid LAVFilterAudio = new Guid("E8E73B6B-4CB3-44A4-BE99-4F7BCB96E491"); - - public static readonly Guid FFDShowVideo = new Guid("04FE9017-F873-410e-871E-AB91661A4EF7"); - public static readonly Guid FFDShowVideoRaw = new Guid("0B390488-D80F-4a68-8408-48DC199F0E97"); - public static readonly Guid FFDShowVideoDXVA = new Guid("0B0EFF97-C750-462c-9488-B10E7D87F1A6"); - - public static readonly Guid Line21_1 = new Guid("6E8D4A20-310C-11D0-B79A-00AA003767A7"); - public static readonly Guid Line21_2 = new Guid("E4206432-01A1-4BEE-B3E1-3702C8EDC574"); - - public static readonly Guid FilesyncSource = new Guid("E436EBB5-524F-11CE-9F53-0020AF0BA770"); - - /// Creates an instance of a COM object by class ID. - /// The class ID of the component to instantiate. - /// A new instance of the class. - public static object CoCreateInstance(Guid id) - { - return Activator.CreateInstance(Type.GetTypeFromCLSID(id)); - } -} diff --git a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/MediaPlayers/DirectShowUtil.cs b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/MediaPlayers/DirectShowUtil.cs deleted file mode 100644 index 18cdbc7..0000000 --- a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/MediaPlayers/DirectShowUtil.cs +++ /dev/null @@ -1,225 +0,0 @@ -using DirectShowLib; -using System; -using System.Collections; -using System.IO; -using System.Runtime.InteropServices; - -// Code of MediaPortal (www.team-mediaportal.com) - -namespace WPFMediaKit.DirectShow.MediaPlayers; - -public static class DirectShowUtil -{ - private static readonly ILog log = LogManager.GetLogger(typeof(DirectShowUtil)); - - public static IBaseFilter AddFilterToGraph(IGraphBuilder graphBuilder, FilterName filterName, string baseDir, Guid clsid) - { - if (String.IsNullOrEmpty(filterName.Name)) - return null; - - try - { - IBaseFilter NewFilter = null; - - // use local lib - if (!String.IsNullOrEmpty(filterName.Filename) && filterName.CLSID != Guid.Empty) - { - if (filterName.Name == "System AsyncFileSource") - { - NewFilter = (IBaseFilter)(new AsyncReader()); - } - else - { - string dllPath = Path.Combine(baseDir, filterName.Filename); - NewFilter = FilterFromFile.LoadFilterFromDll(dllPath, filterName.CLSID, - !Path.IsPathRooted(dllPath)); - } - } - - // or try load from system - if (NewFilter == null) - { - foreach (Filter filter in Filters.LegacyFilters) - { - if (String.Compare(filter.Name, filterName.Name, true) == 0 && - (clsid == Guid.Empty || filter.CLSID == clsid)) - { - NewFilter = (IBaseFilter)Marshal.BindToMoniker(filter.MonikerString); - } - } - } - - int hr = graphBuilder.AddFilter(NewFilter, filterName.Name); - if (hr < 0) - { - log.Error("Unable to add filter: {0} to graph", filterName.Name); - NewFilter = null; - } - else - { - log.Debug("Added filter: {0} to graph", filterName.Name); - } - - if (NewFilter == null) - { - log.Error("Failed filter: {0} not found", filterName.Name); - } - - return NewFilter; - } - catch (Exception ex) - { - log.Error(ex, "Error adding filter: {0} to graph", filterName.Name); - return null; - } - } - - public static bool DisconnectAllPins(IGraphBuilder graphBuilder, IBaseFilter filter) - { - IEnumPins pinEnum; - int hr = filter.EnumPins(out pinEnum); - if (hr != 0 || pinEnum == null) - { - return false; - } - FilterInfo info; - filter.QueryFilterInfo(out info); - - Marshal.ReleaseComObject(info.pGraph); - bool allDisconnected = true; - for (; ; ) - { - IPin[] pins = new IPin[1]; - IntPtr fetched = IntPtr.Zero; - hr = pinEnum.Next(1, pins, fetched); - if (hr != 0 || fetched == IntPtr.Zero) - { - break; - } - PinInfo pinInfo; - pins[0].QueryPinInfo(out pinInfo); - DsUtils.FreePinInfo(pinInfo); - if (pinInfo.dir == PinDirection.Output) - { - if (!DisconnectPin(graphBuilder, pins[0])) - { - allDisconnected = false; - } - } - Marshal.ReleaseComObject(pins[0]); - } - Marshal.ReleaseComObject(pinEnum); - return allDisconnected; - } - - public static bool DisconnectPin(IGraphBuilder graphBuilder, IPin pin) - { - IPin other; - int hr = pin.ConnectedTo(out other); - bool allDisconnected = true; - PinInfo info; - pin.QueryPinInfo(out info); - DsUtils.FreePinInfo(info); - - if (hr == 0 && other != null) - { - other.QueryPinInfo(out info); - if (!DisconnectAllPins(graphBuilder, info.filter)) - { - allDisconnected = false; - } - hr = pin.Disconnect(); - if (hr != 0) - { - allDisconnected = false; - } - hr = other.Disconnect(); - if (hr != 0) - { - allDisconnected = false; - } - DsUtils.FreePinInfo(info); - Marshal.ReleaseComObject(other); - } - else - { - } - return allDisconnected; - } - - public static void RemoveFilters(IGraphBuilder graphBuilder) - { - RemoveFilters(graphBuilder, string.Empty); - } - - public static void RemoveFilters(IGraphBuilder graphBuilder, string filterName) - { - if (graphBuilder == null) - { - return; - } - - int hr = 0; - IEnumFilters enumFilters = null; - ArrayList filtersArray = new ArrayList(); - - try - { - hr = graphBuilder.EnumFilters(out enumFilters); - DsError.ThrowExceptionForHR(hr); - - IBaseFilter[] filters = new IBaseFilter[1]; - IntPtr fetched = IntPtr.Zero; - - while (enumFilters.Next(filters.Length, filters, fetched) == 0) - { - filtersArray.Add(filters[0]); - } - - foreach (IBaseFilter filter in filtersArray) - { - FilterInfo info; - filter.QueryFilterInfo(out info); - Marshal.ReleaseComObject(info.pGraph); - - try - { - if (!String.IsNullOrEmpty(filterName)) - { - if (String.Equals(info.achName, filterName)) - { - DisconnectAllPins(graphBuilder, filter); - hr = graphBuilder.RemoveFilter(filter); - DsError.ThrowExceptionForHR(hr); - Marshal.ReleaseComObject(filter); - log.Debug("Remove filter from graph: {0}", info.achName); - } - } - else - { - DisconnectAllPins(graphBuilder, filter); - hr = graphBuilder.RemoveFilter(filter); - DsError.ThrowExceptionForHR(hr); - int i = Marshal.ReleaseComObject(filter); - log.Debug(string.Format("Remove filter from graph: {0} {1}", info.achName, i)); - } - } - catch (Exception ex) - { - log.Error(ex, "Remove of filter failed with code (HR): {0}, explanation: {1}", info.achName, hr.ToString()); - } - } - } - catch (Exception) - { - return; - } - finally - { - if (enumFilters != null) - { - Marshal.ReleaseComObject(enumFilters); - } - } - } -} diff --git a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/MediaPlayers/DvdPlayer.cs b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/MediaPlayers/DvdPlayer.cs deleted file mode 100644 index 998339c..0000000 --- a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/MediaPlayers/DvdPlayer.cs +++ /dev/null @@ -1,1061 +0,0 @@ -using DirectShowLib; -using DirectShowLib.Dvd; -using System; -using System.Drawing; -using System.Runtime.InteropServices; - -namespace WPFMediaKit.DirectShow.MediaPlayers; - -/// -/// Arguments for an event reporting that the user's -/// mouse is over a Dvd button. -/// -public class OverDvdButtonEventArgs : EventArgs -{ - public OverDvdButtonEventArgs(bool isOverDvdButton) - { - IsOverDvdButton = isOverDvdButton; - } - - /// - /// Flag that defines if the cursor is over a Dvd button - /// - public bool IsOverDvdButton { get; private set; } -} - -/// -/// Value indicating the button to select -/// -public enum DvdRelativeButtonEnum -{ - /// - /// Left button - /// - Left = 1, - - /// - /// Lower button - /// - Lower = 2, - - /// - /// Right button - /// - Right = 3, - - /// - /// Upper button - /// - Upper = 4 -} - -/// -/// Defines Dvd error conditions -/// -public enum DvdError -{ - /// - /// Something unexpected happened; perhaps content is authored incorrectly. Playback is stopped. - /// - Unexpected, - - /// - /// Key exchange for DVD copy protection failed. Playback is stopped. - /// - CopyProtectFail, - - /// - /// DVD-Video disc is authored incorrectly for specification version 1. x. Playback is stopped. - /// - InvalidDvd10Disc, - - /// - /// The disc cannot be played because it is not authored to play in the system region. - /// You can try fixing the region mismatch by changing the system region with Dvdrgn.exe. - /// - InvalidDiscRegion, - - /// - /// Player parental level is lower than the lowest parental level available in the DVD content. Playback is stopped. - /// - LowParentalLevel, - - /// - /// Analog copy protection distribution failed. Playback stopped. - /// - MacrovisionFail, - - /// - /// No discs can be played because the system region does not match the decoder region. - /// - IncompatibleSystemAndDecoderRegions, - - /// - /// The disc cannot be played because the disc is not authored to be played in the decoder's region. - /// - IncompatibleDiscAndDecoderRegions -} - -public class DvdErrorArgs : EventArgs -{ - public DvdError Error { get; internal set; } -} - -/// -/// Arguments for an event reporting a new DVD time. -/// -public class DvdTimeEventArgs : EventArgs -{ - public DvdTimeEventArgs(TimeSpan dvdTime) - { - DvdTime = dvdTime; - } - - /// - /// The current Dvd time reported. - /// - public TimeSpan DvdTime { get; private set; } -} - -[ComImport, Guid("212690FB-83E5-4526-8FD7-74478B7939CD")] -internal class MicrosoftMpeg2VideoDecoder -{ -} - -[ComImport, Guid("E1F1A0B8-BEEE-490D-BA7C-066C40B5E2B9")] -internal class MicrosoftMpeg2AudioDecoder -{ -} - -/// -/// Plays a DVD disc or will play DVD video files from a path. -/// Normally, when a DVD is played with a custom allocator, IVideoWindow will -/// be queried from the graph. Since there will be no IVideoWindow in this graph -/// the IDvdControl2 will crash when we try to use the SelectAtPosition and -/// ActivateAtPosition. We get around this by sacrificing the Line21 pin and -/// connecting it to another video renderer that does have an IVideoWindow, but -/// we make sure to keep the actual hWnd hidden. -/// -public class DvdPlayer : MediaSeekingPlayer -{ - /// - /// Constant value for converting media time back and forth - /// to milliseconds; - /// - private const int MEDIA_TIME_TO_MILLISECONDS = 10000; - - /// - /// The current time the DVD playback is at - /// - private TimeSpan m_currentDvdTime; - - /// - /// Reference to the hidden render window - /// - private IVideoWindow m_dummyRenderWindow; - - /// - /// The total number of DVD buttons currently on screen - /// - private int m_dvdButtonCount; - - /// - /// The main interface for DVD control - /// - private IDvdControl2 m_dvdControl; - - /// - /// The main interface for DVD information - /// - private IDvdInfo2 m_dvdInfo; - - /// - /// The DirectShow filter graph - /// - private IGraphBuilder m_graph; - - /// - /// The renderer used to render video to WPF - /// - private IBaseFilter m_renderer; - -#if DEBUG - - /// - /// The 'Running Objects Table'. Used to remotely debug the graph - /// - private DsROTEntry m_rot; - -#endif - - /// - /// Used to store the dummy renderer target coords of the subpicture video - /// - private Rectangle m_renderTargetRect = Rectangle.Empty; - - /// - /// The GUID of the DVD subpicture media type - /// - private readonly Guid DVD_SUBPICTURE_TYPE = new Guid("{E06D802D-DB46-11CF-B4D1-00805F6CBBEA}"); - - /// - /// Flag to remember if we are over a DVD button. - /// - private bool m_isOverButton; - - /// - /// The input pin of the dummy renderer - /// - private IPin m_dummyRendererPin; - - /// - /// Fires when a DVD has been inserted - /// - public event EventHandler OnDvdInserted; - - /// - /// Fires when a DVD has been ejected - /// - public event EventHandler OnDvdEjected; - - /// - /// Fires when the DVD time changes - /// - public event EventHandler OnDvdTime; - - /// - /// Fires when the mouse is over a DVD button - /// - public event EventHandler OnOverDvdButton; - - /// - /// Fires when a DVD specific error occurs - /// - public event EventHandler OnDvdError; - - private bool m_dvdDirectoryDirty; - private string m_dvdDirectory; - - /// - /// The directory to try to play the DVD from. If this is null then - /// DirectShow will search for a DVD to play. - /// - public string DvdDirectory - { - get => m_dvdDirectory; - set - { - m_dvdDirectory = value; - m_dvdDirectoryDirty = true; - } - } - - #region Event Invokers - - private void InvokeDvdError(DvdError error) - { - var e = new DvdErrorArgs { Error = error }; - OnDvdError?.Invoke(this, e); - } - - private void InvokeOnDvdTime(DvdTimeEventArgs e) - { - OnDvdTime?.Invoke(this, e); - } - - private void InvokeOnOverDvdButton(bool isOverDvdButton) - { - var e = new OverDvdButtonEventArgs(isOverDvdButton); - OnOverDvdButton?.Invoke(this, e); - } - - private void InvokeOnDvdInserted() - { - OnDvdInserted?.Invoke(this, EventArgs.Empty); - } - - private void InvokeOnDvdEjected() - { - OnDvdEjected?.Invoke(this, EventArgs.Empty); - } - - #endregion Event Invokers - - /// - /// Navigates to the Root menu of the DVD title - /// - public void GotoRootMenu() - { - if (m_dvdControl == null) - return; - - m_dvdControl.ShowMenu(DvdMenuId.Root, - DvdCmdFlags.Block | DvdCmdFlags.Flush, - out IDvdCmd cmd); - - if (cmd != null) - Marshal.ReleaseComObject(cmd); - } - - /// - /// Gets the total number of titles on the DVD - /// - public int TitleCount - { - get - { - VerifyAccess(); - - if (m_dvdInfo == null) - return 0; - - m_dvdInfo.GetDVDVolumeInfo(out _, - out _, - out _, - out int titleCount); - - return titleCount; - } - } - - /// - /// Navigates to the Title menu of the DVD - /// - public void GotoTitleMenu() - { - VerifyAccess(); - - if (m_dvdControl == null) - return; - - m_dvdControl.ShowMenu(DvdMenuId.Title, - DvdCmdFlags.Block | DvdCmdFlags.Flush, - out IDvdCmd cmd); - - if (cmd != null) - Marshal.ReleaseComObject(cmd); - } - - /// - /// Returns the display from a submenu to its parent menu - /// - public void ReturnFromSubmenu() - { - VerifyAccess(); - - if (m_dvdControl == null) - return; - - m_dvdControl.ReturnFromSubmenu(DvdCmdFlags.None, out IDvdCmd cmd); - - if (cmd != null) - Marshal.ReleaseComObject(cmd); - } - - /// - /// The SelectAngle method sets the new angle when the DVD Navigator is in an angle block - /// - /// Value of the new angle, which must be from 1 through 9 - public void SelectAngle(int angle) - { - VerifyAccess(); - - if (m_dvdControl == null) - return; - - m_dvdControl.SelectAngle(angle, DvdCmdFlags.None, out IDvdCmd cmd); - - if (cmd != null) - Marshal.ReleaseComObject(cmd); - } - - /// - /// Leaves a menu and resumes playback. - /// - public void Resume() - { - VerifyAccess(); - - if (m_dvdControl == null) - return; - - m_dvdControl.Resume(DvdCmdFlags.None, out IDvdCmd cmd); - - if (cmd != null) - Marshal.ReleaseComObject(cmd); - } - - /// - /// Selects the specified relative button (upper, lower, right, left) - /// - public void SelectRelativeButton(DvdRelativeButtonEnum relativeButton) - { - VerifyAccess(); - - if (m_dvdControl == null) - return; - - m_dvdControl.SelectRelativeButton((DvdRelativeButton)relativeButton); - } - - /// - /// Selects a menu item at a certain position on the video - /// - /// The percentage to the right - /// The percentage to the bottom - public void SelectAtPosition(double widthRatio, double heightRatio) - { - VerifyAccess(); - - if (m_dvdControl == null || m_dvdButtonCount == 0) - return; - - /* We base our exact point based on the size of the subpicture target rect */ - var pixelPoint = new Point((int)(m_renderTargetRect.Width * widthRatio), - (int)(m_renderTargetRect.Height * heightRatio)); - - int hr = m_dvdControl.SelectAtPosition(pixelPoint); - - if (hr == 0) - { - if (m_isOverButton == false) - { - m_isOverButton = true; - InvokeOnOverDvdButton(m_isOverButton); - } - } - else - { - if (m_isOverButton) - { - m_isOverButton = false; - InvokeOnOverDvdButton(m_isOverButton); - } - } - } - - /// - /// Activates a menu item at a certain position on the video - /// - /// The ratio to the right - /// The ratio to the bottom - public void ActivateAtPosition(double widthRatio, double heightRatio) - { - VerifyAccess(); - - if (m_dvdControl == null || m_dvdButtonCount == 0) - return; - - /* We base our exact point based on the size of the subpicture target rect */ - var pixelPoint = new Point((int)(m_renderTargetRect.Width * widthRatio), - (int)(m_renderTargetRect.Height * heightRatio)); - - m_dvdControl.ActivateAtPosition(pixelPoint); - } - - /// - /// Sets the number of DVD buttons found in the current DVD video - /// - /// The total number of buttons - private void SetDvdButtonCount(int buttonCount) - { - m_dvdButtonCount = buttonCount; - - if (m_dvdButtonCount == 0) - { - m_isOverButton = false; - InvokeOnOverDvdButton(m_isOverButton); - } - - var mediaType = new AMMediaType(); - m_dummyRendererPin.ConnectionMediaType(mediaType); - - /* Check to see if its a video media type */ - if (mediaType.formatType != FormatType.VideoInfo2 && - mediaType.formatType != FormatType.VideoInfo) - { - DsUtils.FreeAMMediaType(mediaType); - return; - } - - var videoInfo = new VideoInfoHeader(); - - /* Read the video info header struct from the native pointer */ - Marshal.PtrToStructure(mediaType.formatPtr, videoInfo); - - /* Get the target rect */ - m_renderTargetRect = videoInfo.TargetRect.ToRectangle(); - - DsUtils.FreeAMMediaType(mediaType); - } - - /// - /// Plays a specific title by a given title index - /// - public void PlayTitle(int titleIndex) - { - VerifyAccess(); - - m_dvdControl.PlayTitle(titleIndex, DvdCmdFlags.Flush, out IDvdCmd cmd); - - if (cmd != null) - Marshal.ReleaseComObject(cmd); - } - - /// - /// Plays the next chapter of the DVD - /// - public void PlayNextChapter() - { - VerifyAccess(); - - if (m_dvdControl == null) - return; - - m_dvdControl.PlayNextChapter(DvdCmdFlags.Flush, out IDvdCmd cmd); - - if (cmd != null) - Marshal.ReleaseComObject(cmd); - } - - /// - /// Plays the DVD forward - /// - /// The speed at which the playback is done - public void PlayForwards(double speed) - { - VerifyAccess(); - - if (m_dvdControl == null) - return; - - m_dvdControl.PlayForwards(speed, DvdCmdFlags.None, out IDvdCmd cmd); - - if (cmd != null) - Marshal.ReleaseComObject(cmd); - } - - /// - /// Plays the DVD backwards - /// - /// The speed at the playback is done - public void PlayBackwards(double speed) - { - VerifyAccess(); - - if (m_dvdControl == null) - return; - - m_dvdControl.PlayBackwards(speed, DvdCmdFlags.None, out IDvdCmd cmd); - - if (cmd != null) - Marshal.ReleaseComObject(cmd); - } - - /// - /// Plays the previous chapter of the DVD - /// - public void PlayPreviousChapter() - { - VerifyAccess(); - - if (m_dvdControl == null) - return; - - m_dvdControl.PlayPrevChapter(DvdCmdFlags.Flush, out IDvdCmd cmd); - - if (cmd != null) - Marshal.ReleaseComObject(cmd); - } - - /// - /// Builds the DVD DirectShow graph - /// - private void BuildGraph() - { - try - { - FreeResources(); - - int hr; - - /* Create our new graph */ - m_graph = (IGraphBuilder)new FilterGraphNoThread(); - -#if DEBUG - m_rot = new DsROTEntry(m_graph); -#endif - /* We are going to use the VMR9 for now. The EVR does not - * seem to work with the interactive menus yet. It should - * play Dvds fine otherwise */ - var rendererType = VideoRendererType.VideoMixingRenderer9; - - /* Creates and initializes a new renderer ready to render to WPF */ - m_renderer = CreateVideoRenderer(rendererType, m_graph, 2); - - /* Do some VMR9 specific stuff */ - if (rendererType == VideoRendererType.VideoMixingRenderer9) - { - if (m_renderer is IVMRMixerControl9 mixer) - { - mixer.GetMixingPrefs(out VMR9MixerPrefs dwPrefs); - dwPrefs &= ~VMR9MixerPrefs.RenderTargetMask; - dwPrefs |= VMR9MixerPrefs.RenderTargetYUV; - - /* Enable this line to prefer YUV */ - //hr = mixer.SetMixingPrefs(dwPrefs); - } - } - - /* Create a new DVD Navigator. */ - var dvdNav = (IBaseFilter)new DVDNavigator(); - - /* The DVDControl2 interface lets us control DVD features */ - m_dvdControl = dvdNav as IDvdControl2; - - if (m_dvdControl == null) - throw new WPFMediaKitException("Could not QueryInterface the IDvdControl2 interface"); - - /* QueryInterface the DVDInfo2 */ - m_dvdInfo = dvdNav as IDvdInfo2; - - /* If a Dvd directory has been set then use it, if not, let DShow find the Dvd */ - if (!string.IsNullOrEmpty(DvdDirectory)) - { - hr = m_dvdControl.SetDVDDirectory(DvdDirectory); - DsError.ThrowExceptionForHR(hr); - } - - /* This gives us the DVD time in Hours-Minutes-Seconds-Frame time format, and other options */ - hr = m_dvdControl.SetOption(DvdOptionFlag.HMSFTimeCodeEvents, true); - DsError.ThrowExceptionForHR(hr); - - /* If the graph stops, resume at the same point */ - m_dvdControl.SetOption(DvdOptionFlag.ResetOnStop, false); - - hr = m_graph.AddFilter(dvdNav, "DVD Navigator"); - DsError.ThrowExceptionForHR(hr); - - IPin dvdVideoPin = null; - IPin dvdAudioPin = null; - IPin dvdSubPicturePin = null; - - IPin dvdNavPin; - int i = 0; - - /* Loop all the output pins on the DVD Navigator, trying to find which pins are which. - * We could more easily find the pins by name, but this is more fun...and more flexible - * if we ever want to use a 3rd party DVD navigator that used different pin names */ - while ((dvdNavPin = DsFindPin.ByDirection(dvdNav, PinDirection.Output, i)) != null) - { - var mediaTypes = new AMMediaType[1]; - IntPtr pFetched = IntPtr.Zero; - - IEnumMediaTypes mediaTypeEnum; - dvdNavPin.EnumMediaTypes(out mediaTypeEnum); - - /* Loop over each of the mediaTypes of each pin */ - while (mediaTypeEnum.Next(1, mediaTypes, pFetched) == 0) - { - AMMediaType mediaType = mediaTypes[0]; - - /* This will be the video stream pin */ - if (mediaType.subType == MediaSubType.Mpeg2Video) - { - /* Keep the ref and we'll work with it later */ - dvdVideoPin = dvdNavPin; - break; - } - - /* This will be the audio stream pin */ - if (mediaType.subType == MediaSubType.DolbyAC3 || - mediaType.subType == MediaSubType.Mpeg2Audio) - { - /* Keep the ref and we'll work with it later */ - dvdAudioPin = dvdNavPin; - break; - } - - /* This is the Dvd sub picture pin. This generally - * shows overlays for Dvd menus and sometimes closed captions */ - if (mediaType.subType == DVD_SUBPICTURE_TYPE) - { - /* Keep the ref and we'll work with it later */ - dvdSubPicturePin = dvdNavPin; - break; - } - } - - mediaTypeEnum.Reset(); - Marshal.ReleaseComObject(mediaTypeEnum); - i++; - } - - /* This is the windowed renderer. This is *NEEDED* in order - * for interactive menus to work with the other VMR9 in renderless mode */ - var dummyRenderer = (IBaseFilter)new VideoMixingRenderer9(); - var dummyRendererConfig = (IVMRFilterConfig9)dummyRenderer; - - /* In order for this interactive menu trick to work, the VMR9 - * must be set to Windowed. We will make sure the window is hidden later on */ - hr = dummyRendererConfig.SetRenderingMode(VMR9Mode.Windowed); - DsError.ThrowExceptionForHR(hr); - - hr = dummyRendererConfig.SetNumberOfStreams(1); - DsError.ThrowExceptionForHR(hr); - - hr = m_graph.AddFilter(dummyRenderer, "Dummy Windowed"); - DsError.ThrowExceptionForHR(hr); - - if (dvdAudioPin != null) - { - /* This should render out to the default audio device. We - * could modify this code here to go out any audio - * device, such as SPDIF or another sound card */ - hr = m_graph.Render(dvdAudioPin); - DsError.ThrowExceptionForHR(hr); - } - - /* Get the first input pin on our dummy renderer */ - m_dummyRendererPin = DsFindPin.ByConnectionStatus(dummyRenderer, /* Filter to search */ - PinConnectedStatus.Unconnected, - 0); - - /* Get an available pin on our real renderer */ - IPin rendererPin = DsFindPin.ByConnectionStatus(m_renderer, /* Filter to search */ - PinConnectedStatus.Unconnected, - 0); /* Pin index */ - - /* Connect the pin to the renderer */ - hr = m_graph.Connect(dvdVideoPin, rendererPin); - DsError.ThrowExceptionForHR(hr); - - /* Get the next available pin on our real renderer */ - rendererPin = DsFindPin.ByConnectionStatus(m_renderer, /* Filter to search */ - PinConnectedStatus.Unconnected, - 0); /* Pin index */ - - /* Render the sub picture, which will connect - * the DVD navigator to the codec, not the renderer */ - hr = m_graph.Render(dvdSubPicturePin); - DsError.ThrowExceptionForHR(hr); - - /* These are the subtypes most likely to be our dvd subpicture */ - var preferedSubpictureTypes = new[]{MediaSubType.ARGB4444, - MediaSubType.AI44, - MediaSubType.AYUV, - MediaSubType.ARGB32}; - IPin dvdSubPicturePinOut = null; - - /* Find what should be the subpicture pin out */ - foreach (var guidType in preferedSubpictureTypes) - { - dvdSubPicturePinOut = FindPinInGraphByMediaType(guidType, /* GUID of the media type being searched for */ - PinDirection.Output, - m_graph); /* Our current graph */ - if (dvdSubPicturePinOut != null) - break; - } - - if (dvdSubPicturePinOut == null) - throw new WPFMediaKitException("Could not find the sub picture pin out"); - - /* Here we connec thte Dvd sub picture pin to the video renderer. - * This enables the overlays on Dvd menus and some closed - * captions to be rendered. */ - hr = m_graph.Connect(dvdSubPicturePinOut, rendererPin); - DsError.ThrowExceptionForHR(hr); - - /* Search for the Line21 out in the graph */ - IPin line21Out = FindPinInGraphByMediaType(MediaType.AuxLine21Data, - PinDirection.Output, - m_graph); - if (line21Out == null) - throw new WPFMediaKitException("Could not find the Line21 pin out"); - - /* We connect our line21Out out in to the dummy renderer - * this is what ultimatly makes interactive DVDs work with - * VMR9 in renderless (for WPF) */ - hr = m_graph.Connect(line21Out, m_dummyRendererPin); - DsError.ThrowExceptionForHR(hr); - - /* This is the dummy renderers Win32 window. */ - m_dummyRenderWindow = dummyRenderer as IVideoWindow; - - if (m_dummyRenderWindow == null) - throw new WPFMediaKitException("Could not QueryInterface for IVideoWindow"); - - ConfigureDummyWindow(); - - /* Setup our base classes with this filter graph */ - SetupFilterGraph(m_graph); - - /* Sets the NaturalVideoWidth/Height */ - SetNativePixelSizes(m_renderer); - } - catch (Exception ex) - { - FreeResources(); - InvokeMediaFailed(new MediaFailedEventArgs(ex.Message, ex)); - return; - } - - InvokeMediaOpened(); - } - - /// - /// Configures our "dummy" IVideoWindow to work well - /// with our interactive menus and to make sure the - /// window remains hidden from view. - /// - private void ConfigureDummyWindow() - { - /* We want to hide our dummy renderer window */ - int hr = m_dummyRenderWindow.put_WindowState(WindowState.Hide); - DsError.ThrowExceptionForHR(hr); - - WindowStyle windowStyle; - - /* Get the current style of the window */ - m_dummyRenderWindow.get_WindowStyle(out windowStyle); - DsError.ThrowExceptionForHR(hr); - - /* Remove these styles using bitwise magic */ - windowStyle &= ~WindowStyle.SysMenu; - windowStyle &= ~WindowStyle.Caption; - windowStyle &= ~WindowStyle.Border; - - /* Change the window to our new style */ - hr = m_dummyRenderWindow.put_WindowStyle(windowStyle); - DsError.ThrowExceptionForHR(hr); - - /* This should hide the window from view */ - hr = m_dummyRenderWindow.put_Visible(OABool.False); - DsError.ThrowExceptionForHR(hr); - - /* Turn off auto show, so the renderer doesn't try to show itself */ - hr = m_dummyRenderWindow.put_AutoShow(OABool.False); - DsError.ThrowExceptionForHR(hr); - } - - /// - /// Gets or sets the position in miliseconds of the media - /// - public override long MediaPosition - { - get => (long)m_currentDvdTime.TotalMilliseconds * MEDIA_TIME_TO_MILLISECONDS; - set - { - var timeCode = new DvdHMSFTimeCode(); - var time = TimeSpan.FromMilliseconds(value / (double)MEDIA_TIME_TO_MILLISECONDS); - - timeCode.bHours = (byte)time.Hours; - timeCode.bMinutes = (byte)time.Minutes; - timeCode.bSeconds = (byte)time.Seconds; - - IDvdCmd cmd; - if (m_dvdControl == null) - return; - - m_dvdControl.PlayAtTime(timeCode, DvdCmdFlags.None, out cmd); - - if (cmd != null) - Marshal.ReleaseComObject(cmd); - } - } - - /// - /// Here we extract out the new Dvd duration of - /// the title currently being played - /// - private void SetTitleDuration() - { - var totalTime = new DvdHMSFTimeCode(); - int hr = m_dvdInfo.GetTotalTitleTime(totalTime, out DvdTimeCodeFlags flags); - - if (hr != 0) - return; - - /* Convert the total time of the title to milliseconds */ - Duration = (long)new TimeSpan(totalTime.bHours, - totalTime.bMinutes, - totalTime.bSeconds).TotalMilliseconds * MEDIA_TIME_TO_MILLISECONDS; - } - - /// - /// Is called when a new media event code occurs on the graph - /// - /// The event code that occured - /// The first parameter sent by the graph - /// The second parameter sent by the graph - protected override void OnMediaEvent(EventCode code, IntPtr lparam1, IntPtr lparam2) - { - switch (code) - { - case EventCode.DvdCurrentHmsfTime: - /* This is time in hours, minutes, seconds, frames format. - * The the time is one, 4 byte integer, each byte representing - * an hour, minute, second or frame */ - byte[] times = BitConverter.GetBytes(lparam1.ToInt32()); - m_currentDvdTime = new TimeSpan(times[0], times[1], times[2]); - - /* Report the time to anyone that cares to listen */ - InvokeOnDvdTime(new DvdTimeEventArgs(m_currentDvdTime)); - break; - - case EventCode.DvdDomainChange: - break; - - case EventCode.DvdTitleChange: - SetTitleDuration(); - break; - - case EventCode.DvdChapterStart: - SetTitleDuration(); - break; - - case EventCode.DvdAudioStreamChange: - break; - - case EventCode.DvdSubPicictureStreamChange: - break; - - case EventCode.DvdAngleChange: - /* For porn? */ - break; - - case EventCode.DvdButtonChange: - /* Keep track of button counts */ - SetDvdButtonCount(lparam1.ToInt32()); - break; - - case EventCode.DvdValidUopsChange: - break; - - case EventCode.DvdStillOn: - break; - - case EventCode.DvdStillOff: - break; - - case EventCode.DvdCurrentTime: - break; - - case EventCode.DvdError: - /* Notify any listener of any Dvd specific - * errors we may get when loading or playing Dvds */ - InvokeDvdError((DvdError)lparam1.ToInt32()); - break; - - case EventCode.DvdWarning: - break; - - case EventCode.DvdChapterAutoStop: - break; - - case EventCode.DvdNoFpPgc: - break; - - case EventCode.DvdPlaybackRateChange: - break; - - case EventCode.DvdParentalLevelChange: - break; - - case EventCode.DvdPlaybackStopped: - break; - - case EventCode.DvdAnglesAvailable: - break; - - case EventCode.DvdPlayPeriodAutoStop: - break; - - case EventCode.DvdButtonAutoActivated: - break; - - case EventCode.DvdCmdStart: - break; - - case EventCode.DvdCmdEnd: - break; - - case EventCode.DvdDiscEjected: - InvokeOnDvdEjected(); - break; - - case EventCode.DvdDiscInserted: - /* For some reason we only get this - * event when a Dvd graph has successfully - * been started. Otherwise it does not work */ - InvokeOnDvdInserted(); - break; - - case EventCode.DvdKaraokeMode: - /* For drunks */ - break; - - default: - break; - } - - base.OnMediaEvent(code, lparam1, lparam2); - } - - /// - /// Plays the Dvd - /// - public override void Play() - { - if (m_dvdControl == null || m_dvdDirectoryDirty) - { - m_dvdDirectoryDirty = false; - Stop(); - BuildGraph(); - } - - base.Play(); - } - - /// - /// Frees any allocated or unmanaged resources - /// - protected override void FreeResources() - { - base.FreeResources(); -#if DEBUG - if (m_rot != null) - m_rot.Dispose(); -#endif - if (m_dummyRendererPin != null) - { - Marshal.ReleaseComObject(m_dummyRendererPin); - m_dummyRendererPin = null; - } - if (m_dummyRenderWindow != null) - { - Marshal.ReleaseComObject(m_dummyRenderWindow); - m_dummyRenderWindow = null; - } - if (m_renderer != null) - { - Marshal.ReleaseComObject(m_renderer); - m_renderer = null; - } - if (m_dvdInfo != null) - { - Marshal.ReleaseComObject(m_dvdInfo); - m_dvdInfo = null; - } - if (m_dvdControl != null) - { - Marshal.ReleaseComObject(m_dvdControl); - m_dvdControl = null; - } - if (m_graph != null) - { - Marshal.ReleaseComObject(m_graph); - m_graph = null; - } - } -} diff --git a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/MediaPlayers/FilterFromFile.cs b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/MediaPlayers/FilterFromFile.cs deleted file mode 100644 index b1eaf8f..0000000 --- a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/MediaPlayers/FilterFromFile.cs +++ /dev/null @@ -1,169 +0,0 @@ -using DirectShowLib; -using System; -using System.Collections.Generic; -using System.IO; -using System.Reflection; -using System.Runtime.InteropServices; - -// Code of MediaPortal (www.team-mediaportal.com) - -namespace WPFMediaKit.DirectShow.MediaPlayers; - -[ComVisible(false)] -[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("00000001-0000-0000-C000-000000000046")] -internal interface IClassFactory -{ - void CreateInstance([MarshalAs(UnmanagedType.Interface)] object pUnkOuter, ref Guid refiid, [MarshalAs(UnmanagedType.Interface)] out object ppunk); - - void LockServer(bool fLock); -} - -/// -/// Helper class to load s from a file. It's not needed that the filter is registered. -/// -public static class FilterFromFile -{ - #region LoadLibraryEx Flags - - private const uint LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR = 0x00000100; - private const uint LOAD_LIBRARY_SEARCH_DEFAULT_DIRS = 0x00001000; - - #endregion LoadLibraryEx Flags - - #region Native API wrapper methods - - /// - /// The GetProcAddress function retrieves the address of an exported function or variable from the specified dynamic-link library (DLL). - /// - /// Handle to the DLL module that contains the function or variable. The LoadLibrary or GetModuleHandle function returns this handle. - /// Pointer to a null-terminated string containing the function or variable name, or the function's ordinal value. If this parameter is an ordinal value, it must be in the low-order word; the high-order word must be zero. - /// If the function succeeds, the return value is the address of the exported function or variable.


If the function fails, the return value is NULL. To get extended error information, call Marshal.GetLastWin32Error.
- [DllImport("kernel32.dll", EntryPoint = "GetProcAddress", CharSet = CharSet.Ansi)] - static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName); - - /// - /// Loads the specified module into the address space of the calling process. The specified module may cause other modules to be loaded. - /// - /// Pointer to a null-terminated string that names the executable module (either a .dll or .exe file). The name specified is the file name of the module and is not related to the name stored in the library module itself, as specified by the LIBRARY keyword in the module-definition (.def) file. - /// This parameter is reserved for future use. It must be IntPtr.Zero. - /// The action to be taken when loading the module. If no flags are specified, the behavior of this function is identical to that of the function. - /// If the function succeeds, the return value is a handle to the module.
If the function fails, the return value is NULL. To get extended error information, call Marshal.GetLastWin32Error.
- [DllImport("kernel32.dll")] - static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hFile, uint dwFlags); - - /// - /// The FreeLibrary function decrements the reference count of the loaded dynamic-link library (DLL). When the reference count reaches zero, the module is unmapped from the address space of the calling process and the handle is no longer valid. - /// - /// Handle to the loaded DLL module. The LoadLibrary or GetModuleHandle function returns this handle. - /// If the function succeeds, the return value is nonzero.


If the function fails, the return value is zero. To get extended error information, call Marshal.GetLastWin32Error.
- [DllImport("kernel32.dll", EntryPoint = "FreeLibrary", CharSet = CharSet.Ansi)] - static extern int FreeLibrary(IntPtr hLibModule); - - #endregion Native API wrapper methods - - #region Helper class DllList - - /// - /// Holds a list of dll handles and unloads the dlls in the destructor. - /// - private class DllList - { - private readonly List _handleList = new List(); - - public void AddDllHandle(IntPtr dllHandle) - { - lock (_handleList) - { - _handleList.Add(dllHandle); - } - } - - ~DllList() - { - foreach (IntPtr dllHandle in _handleList) - { - try - { - FreeLibrary(dllHandle); - } - catch { } - } - } - } - - #endregion Helper class DllList - - delegate int DllGetClassObject(ref Guid classId, ref Guid interfaceId, [Out, MarshalAs(UnmanagedType.Interface)] out object ppunk); - - private static readonly DllList DLL_LIST = new DllList(); - - /// - /// Gets a class factory for a specific COM Class ID. - /// - /// The dll where the COM class is implemented. - /// The requested Class ID. - /// IClassFactory instance used to create instances of that class. - internal static IClassFactory GetClassFactory(string dllName, Guid filterPersistClass) - { - // Load the class factory from the dll. - // By specifying the flags we allow to search for dependencies in the same folder as the file to be loaded - // as well as default dirs like System32 and the Application folder. - IntPtr dllHandle = LoadLibraryEx(dllName, IntPtr.Zero, - LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | LOAD_LIBRARY_SEARCH_DEFAULT_DIRS); - if (dllHandle == IntPtr.Zero) - return null; - - // Keep a reference to the dll until the process\AppDomain dies. - DLL_LIST.AddDllHandle(dllHandle); - - //Get a pointer to the DllGetClassObject function - IntPtr dllGetClassObjectPtr = GetProcAddress(dllHandle, "DllGetClassObject"); - if (dllGetClassObjectPtr == IntPtr.Zero) - return null; - - // Convert the function pointer to a .net delegate. - DllGetClassObject dllGetClassObject = (DllGetClassObject)Marshal.GetDelegateForFunctionPointer(dllGetClassObjectPtr, typeof(DllGetClassObject)); - - // Call the DllGetClassObject to retreive a class factory for out Filter class. - Guid baseFilterGuid = filterPersistClass; - Guid classFactoryGuid = typeof(IClassFactory).GUID; - Object unk; - if (dllGetClassObject(ref baseFilterGuid, ref classFactoryGuid, out unk) != 0) - return null; - - return (unk as IClassFactory); - } - - /// - /// Loads an COM .dll or .ax and creates an instance of the given Interface with IID . - /// - /// Filename of a .dll or .ax component - /// Interface to create an object instance for - /// Combine the given file name to a full path - /// Instance or null - public static IBaseFilter LoadFilterFromDll(string dllName, Guid interfaceId, bool useAssemblyRelativeLocation) - { - // Get a ClassFactory for our classID - string dllPath = useAssemblyRelativeLocation ? BuildAssemblyRelativePath(dllName) : dllName; - IClassFactory classFactory = GetClassFactory(dllPath, interfaceId); - if (classFactory == null) - return null; - - // And create an IFilter instance using that class factory - Guid baseFilterGuid = typeof(IBaseFilter).GUID; - object obj; - classFactory.CreateInstance(null, ref baseFilterGuid, out obj); - return (obj as IBaseFilter); - } - - /// - /// Builds a full path for a given that is located in the same folder as the . - /// - /// File name - /// Combined path - public static string BuildAssemblyRelativePath(string fileName) - { - string executingPath = Assembly.GetCallingAssembly().Location; - return Path.Combine(Path.GetDirectoryName(executingPath), fileName); - } -} diff --git a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/MediaPlayers/FilterName.cs b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/MediaPlayers/FilterName.cs deleted file mode 100644 index 41d1e93..0000000 --- a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/MediaPlayers/FilterName.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; - -namespace WPFMediaKit.DirectShow.MediaPlayers; - -public struct FilterName -{ - public FilterName(string name, Guid clsid, string filename) : this() - { - Name = name; - CLSID = clsid; - Filename = filename; - } - - public string Name { get; set; } - public Guid CLSID { get; set; } - public string Filename { get; set; } -} diff --git a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/MediaPlayers/Filters.cs b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/MediaPlayers/Filters.cs deleted file mode 100644 index 615e6a9..0000000 --- a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/MediaPlayers/Filters.cs +++ /dev/null @@ -1,451 +0,0 @@ -using DirectShowLib; -using System; -using System.Collections; -using System.Runtime.InteropServices; -using System.Runtime.InteropServices.ComTypes; - -// Code of MediaPortal (www.team-mediaportal.com) - -namespace WPFMediaKit.DirectShow.MediaPlayers; - -/// -/// Provides collections of devices and compression codecs -/// installed on the system. -/// -/// -/// Devices and compression codecs are implemented in DirectShow -/// as filters, see the class for more -/// information. To list the available video devices: -///
-/// Filters filters = new Filters(); -/// foreach ( Filter f in filters.VideoInputDevices ) -/// { -/// Debug.WriteLine( f.Name ); -/// } -///
-/// -///
-public class Filters -{ - // ------------------ Public Properties -------------------- - - /// Collection of available video capture devices. - public static FilterCollection VideoInputDevices; - - /// Collection of available audio capture devices. - public static FilterCollection AudioInputDevices; - - /// Collection of available video compressors. - public static FilterCollection VideoCompressors; - - /// Collection of available audio compressors. - public static FilterCollection AudioCompressors; - - public static FilterCollection LegacyFilters; - public static FilterCollection AudioRenderers; - public static FilterCollection WDMEncoders; - public static FilterCollection WDMcrossbars; - public static FilterCollection WDMTVTuners; - public static FilterCollection BDAReceivers; - public static FilterCollection AllFilters; - - static Filters() - { - VideoInputDevices = new FilterCollection(FilterCategory.VideoInputDevice, true); - AudioInputDevices = new FilterCollection(FilterCategory.AudioInputDevice, true); - VideoCompressors = new FilterCollection(FilterCategory.VideoCompressorCategory, true); - AudioCompressors = new FilterCollection(FilterCategory.AudioCompressorCategory, true); - LegacyFilters = new FilterCollection(FilterCategory.LegacyAmFilterCategory, true); - AudioRenderers = new FilterCollection(FilterCategory.AudioRendererDevice, true); - WDMEncoders = new FilterCollection(FilterCategory.AM_KSEncoder, true); - WDMcrossbars = new FilterCollection(FilterCategory.AM_KSCrossBar, true); - WDMTVTuners = new FilterCollection(FilterCategory.AM_KSTvTuner, true); - BDAReceivers = new FilterCollection(FilterCategory.AM_KS_BDA_RECEIVER_COMPONENT, true); - AllFilters = new FilterCollection(FilterCategory.ActiveMovieCategory, true); - } -} - -/// -/// A collection of Filter objects (DirectShow filters). -/// This is used by the class to provide -/// lists of capture devices and compression filters. This class -/// cannot be created directly. -/// -public class FilterCollection : CollectionBase -{ - /// Populate the collection with a list of filters from a particular category. - public FilterCollection(Guid category) - { - getFilters(category); - } - - /// Populate the collection with a list of filters from a particular category. - public FilterCollection(Guid category, bool resolveNames) - { - getFilters(category); - foreach (Filter f in InnerList) - { - f.ResolveName(); - } - } - - /// Populate the InnerList with a list of filters from a particular category - protected void getFilters(Guid category) - { - int hr; - object comObj = null; - ICreateDevEnum enumDev = null; - IEnumMoniker enumMon = null; - IMoniker[] mon = new IMoniker[1]; - - try - { - // Get the system device enumerator - Type srvType = Type.GetTypeFromCLSID(ClassId.SystemDeviceEnum); - if (srvType == null) - { - throw new NotImplementedException("System Device Enumerator"); - } - comObj = Activator.CreateInstance(srvType); - enumDev = (ICreateDevEnum)comObj; - - // Create an enumerator to find filters in category - hr = enumDev.CreateClassEnumerator(category, out enumMon, 0); - if (hr != 0) - { - return; //throw new NotSupportedException( "No devices of the category" ); - } - // Loop through the enumerator - IntPtr f = IntPtr.Zero; - do - { - // Next filter - hr = enumMon.Next(1, mon, f); - if ((hr != 0) || (mon[0] == null)) - { - break; - } - - // Add the filter - Filter filter = new Filter(mon[0]); - InnerList.Add(filter); - - // Release resources - Marshal.ReleaseComObject(mon[0]); - mon[0] = null; - } while (true); - - // Sort - //InnerList.Sort(); - } - finally - { - enumDev = null; - if (mon[0] != null) - { - Marshal.ReleaseComObject(mon[0]); - } - mon[0] = null; - if (enumMon != null) - { - Marshal.ReleaseComObject(enumMon); - } - enumMon = null; - if (comObj != null) - { - Marshal.ReleaseComObject(comObj); - } - comObj = null; - } - } - - /// Get the filter at the specified index. - public Filter this[int index] - { - get - { - if (index >= InnerList.Count) - { - return null; - } - return ((Filter)InnerList[index]); - } - } -} - -/// -/// Represents a DirectShow filter (e.g. video capture device, -/// compression codec). -/// -/// -/// To save a chosen filer for later recall -/// save the MonikerString property on the filter: -///
-/// string savedMonikerString = myFilter.MonikerString; -///
-/// -/// To recall the filter create a new Filter class and pass the -/// string to the constructor: -///
-/// Filter mySelectedFilter = new Filter( savedMonikerString ); -///
-///
-public class Filter : IComparable -{ - /// Human-readable name of the filter - private string _name = string.Empty; - - private bool _nameResolved = false; - - /// Unique string referencing this filter. This string can be used to recreate this filter. - public string MonikerString; - - /// getAnyMoniker take very long time, so use a cached value - private static IMoniker[] mon = null; - - /// Create a new filter from its moniker string. - public Filter(string monikerString) - { - MonikerString = monikerString; - } - - /// Create a new filter from its moniker - internal Filter(IMoniker moniker) - { - MonikerString = getMonikerString(moniker); - } - - public string Name - { - get - { - if (_nameResolved) - { - return _name; - } - _name = getName(MonikerString); - return _name; - } - } - - public Guid CLSID { get; protected set; } - - public void ResolveName() - { - if (_nameResolved) - { - return; - } - _name = getName(MonikerString); - } - - /// Retrieve the a moniker's display name (i.e. it's unique string) - protected string getMonikerString(IMoniker moniker) - { - string s; - moniker.GetDisplayName(null, null, out s); - return (s); - } - - /// Retrieve the human-readable name of the filter - protected string getName(IMoniker moniker) - { - object bagObj = null; - IPropertyBag bag = null; - try - { - Guid bagId = typeof(IPropertyBag).GUID; - moniker.BindToStorage(null, null, ref bagId, out bagObj); - bag = (IPropertyBag)bagObj; - object val = ""; - int hr = bag.Read("FriendlyName", out val, null); - if (hr != 0) - { - Marshal.ThrowExceptionForHR(hr); - } - string ret = val as string; - if ((ret == null) || (ret.Length < 1)) - { - throw new NotImplementedException("Device FriendlyName"); - } - - hr = bag.Read("CLSID", out val, null); - if (hr == 0) - { - CLSID = new Guid(val.ToString()); - } - - return (ret); - } - catch (Exception) - { - return (""); - } - finally - { - bag = null; - if (bagObj != null) - { - Marshal.ReleaseComObject(bagObj); - } - bagObj = null; - - _nameResolved = true; - } - } - - /// Get a moniker's human-readable name based on a moniker string. - protected string getName(string monikerString) - { - IMoniker parser = null; - IMoniker moniker = null; - try - { - parser = getAnyMoniker(); - int eaten; - parser.ParseDisplayName(null, null, monikerString, out eaten, out moniker); - return (getName(parser)); - } - finally - { - if (moniker != null) - { - Marshal.ReleaseComObject(moniker); - } - moniker = null; - _nameResolved = true; - } - } - - /// - /// This method gets a System.Runtime.InteropServices.ComTypes.IMoniker object. - /// - /// HACK: The only way to create a System.Runtime.InteropServices.ComTypes.IMoniker from a moniker - /// string is to use System.Runtime.InteropServices.ComTypes.IMoniker.ParseDisplayName(). So I - /// need ANY System.Runtime.InteropServices.ComTypes.IMoniker object so that I can call - /// ParseDisplayName(). Does anyone have a better solution? - /// - /// This assumes there is at least one video compressor filter - /// installed on the system. - /// - protected IMoniker getAnyMoniker() - { - Guid category = FilterCategory.VideoCompressorCategory; - int hr; - object comObj = null; - ICreateDevEnum enumDev = null; - IEnumMoniker enumMon = null; - - if (mon != null) - { - return mon[0]; - } - - mon = new IMoniker[1]; - - try - { - // Get the system device enumerator - Type srvType = Type.GetTypeFromCLSID(ClassId.SystemDeviceEnum); - if (srvType == null) - { - throw new NotImplementedException("System Device Enumerator"); - } - comObj = Activator.CreateInstance(srvType); - enumDev = (ICreateDevEnum)comObj; - - // Create an enumerator to find filters in category - hr = enumDev.CreateClassEnumerator(category, out enumMon, 0); - if (hr != 0) - { - throw new NotSupportedException("No devices of the category"); - } - - // Get first filter - IntPtr f = IntPtr.Zero; - hr = enumMon.Next(1, mon, f); - if ((hr != 0)) - { - mon[0] = null; - } - - return (mon[0]); - } - finally - { - enumDev = null; - if (enumMon != null) - { - Marshal.ReleaseComObject(enumMon); - } - enumMon = null; - if (comObj != null) - { - Marshal.ReleaseComObject(comObj); - } - comObj = null; - } - } - - /// - /// Compares the current instance with another object of - /// the same type. - /// - public int CompareTo(object obj) - { - if (obj == null) - { - return (1); - } - Filter f = (Filter)obj; - return (this.Name.CompareTo(f.Name)); - } -} - -public class FilterCategory // uuids.h : CLSID_* -{ - /// CLSID_AudioRendererCategory, audio render category - public static readonly Guid AudioRendererDevice = new Guid(0xe0f158e1, 0xcb04, 0x11d0, 0xbd, 0x4e, 0x0, 0xa0, 0xc9, - 0x11, 0xce, 0x86); - - /// CLSID_AudioInputDeviceCategory, audio capture category - public static readonly Guid AudioInputDevice = new Guid(0x33d9a762, 0x90c8, 0x11d0, 0xbd, 0x43, 0x00, 0xa0, 0xc9, - 0x11, 0xce, 0x86); - - /// CLSID_VideoInputDeviceCategory, video capture category - public static readonly Guid VideoInputDevice = new Guid(0x860BB310, 0x5D01, 0x11d0, 0xBD, 0x3B, 0x00, 0xA0, 0xC9, - 0x11, 0xCE, 0x86); - - /// CLSID_VideoCompressorCategory, Video compressor category - public static readonly Guid VideoCompressorCategory = new Guid(0x33d9a760, 0x90c8, 0x11d0, 0xbd, 0x43, 0x0, 0xa0, - 0xc9, 0x11, 0xce, 0x86); - - public static readonly Guid AM_KSTvTuner = new Guid(0xA799A800, 0xA46D, 0x11D0, 0xA1, 0x8C, 0x00, 0xA0, 0x24, 0x01, - 0xDC, 0xD4); - - public static readonly Guid AM_KS_BDA_RECEIVER_COMPONENT = new Guid(0xFD0A5AF4, 0xB41D, 0x11d2, 0x9c, 0x95, 0x00, - 0xc0, 0x4f, 0x79, 0x71, 0xe0); - - public static readonly Guid AM_KSCrossBar = new Guid(0xA799A801, 0xA46D, 0x11D0, 0xA1, 0x8C, 0x00, 0xA0, 0x24, 0x01, - 0xDC, 0xD4); - - public static readonly Guid AM_KSEncoder = new Guid(0x19689bf6, 0xc384, 0x48fd, 0xad, 0x51, 0x90, 0xe5, 0x8c, 0x79, - 0xf7, 0xb); - - /// CLSID_AudioCompressorCategory, audio compressor category - public static readonly Guid AudioCompressorCategory = new Guid(0x33d9a761, 0x90c8, 0x11d0, 0xbd, 0x43, 0x0, 0xa0, - 0xc9, 0x11, 0xce, 0x86); - - /// CLSID_LegacyAmFilterCategory, legacy filters - public static readonly Guid LegacyAmFilterCategory = new Guid(0x083863F1, 0x70DE, 0x11d0, 0xBD, 0x40, 0x00, 0xA0, - 0xC9, 0x11, 0xCE, 0x86); - - /// - /// #MW# CLSID_ActiveMovieCategory, a superset of all the available filters - /// - public static readonly Guid ActiveMovieCategory = new Guid(0xda4e3da0, 0xd07d, 0x11d0, 0xbd, 0x50, 0x0, 0xa0, 0xc9, - 0x11, 0xce, 0x86); - - public static readonly Guid IID_IKsPropertySet = new Guid(0x31efac30, 0x515c, 0x11d0, 0xa9, 0xaa, 0x00, 0xaa, 0x00, - 0x61, 0xbe, 0x93); -} diff --git a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/MediaPlayers/MediaDetector.cs b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/MediaPlayers/MediaDetector.cs deleted file mode 100644 index 2182c85..0000000 --- a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/MediaPlayers/MediaDetector.cs +++ /dev/null @@ -1,454 +0,0 @@ -using DirectShowLib; -using DirectShowLib.DES; -using System; -using System.Diagnostics; -using System.Drawing; -using System.Drawing.Imaging; -using System.Runtime.InteropServices; -using System.Text; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Threading; -using PixelFormat = System.Drawing.Imaging.PixelFormat; -using Size = System.Windows.Size; - -namespace WPFMediaKit.DirectShow.MediaPlayers; - -/// -/// The MediaDetector class allows to query meta data from audio/video media files. -/// This includes CODEC information and the ability to grab video snapshots. -/// -public class MediaDetector : DispatcherObject, IDisposable -{ - #region Locals - - private IMediaDet m_mediaDet; - private int m_audioBitsPerSample; - private int m_audioChannels; - private int m_audioSamplesPerSecond; - private double m_audioStreamLength; - private Guid m_audioSubType; - private Bitmap m_bitmap; - private string m_filename; - private string m_fourCC; - private int m_streamCount; - private int m_videoBitsPerPixel; - private Size m_videoResolution; - private double m_videoStreamLength; - private Guid m_videoSubType; - private double m_videoFrameRate; - - #endregion Locals - - /// - /// The video framerate - /// - public double VideoFrameRate - { - get { return m_videoFrameRate; } - } - - /// - /// The video CODEC tag - /// - public string FourCC - { - get { return m_fourCC; } - } - - /// - /// The bits per pixel of the video - /// - public int VideoBitsPerPixel - { - get { return m_videoBitsPerPixel; } - } - - /// - /// The length of the video stream - /// - public TimeSpan VideoStreamLength - { - get { return TimeSpan.FromSeconds(m_videoStreamLength); } - } - - /// - /// The length of the audio stream - /// - public TimeSpan AudioStreamLength - { - get { return TimeSpan.FromSeconds(m_audioStreamLength); } - } - - public Guid AudioSubType - { - get { return m_audioSubType; } - } - - public Guid VideoSubType - { - get { return m_videoSubType; } - } - - /// - /// The number of bits per sample in the audio stream - /// - public int AudioBitsPerSample - { - get { return m_audioBitsPerSample; } - } - - /// - /// The HZ of the audio samples - /// - public int AudioSamplesPerSecond - { - get { return m_audioSamplesPerSecond; } - } - - /// - /// The number of audio channels in audio stream - /// - public int AudioChannels - { - get { return m_audioChannels; } - } - - /// - /// The filename of the loaded media - /// - public string Filename - { - get { return m_filename; } - } - - /// - /// The native pixel size of the video, if a - /// video stream exists - /// - public Size VideoResolution - { - get { return m_videoResolution; } - } - - /// - /// The total amount of streams that exist in the media - /// - public int StreamCount - { - get { return m_streamCount; } - } - - /// - /// Is true if the loaded media has an audio stream - /// - public bool HasAudio { get; private set; } - - /// - /// Is true if the loaded media has a video stream - /// - public bool HasVideo { get; private set; } - - #region IDisposable Members - - public void Dispose() - { - FreeResources(); - - GC.SuppressFinalize(this); - } - - #endregion IDisposable Members - - [DllImport("kernel32.dll", EntryPoint = "RtlMoveMemory")] - private static extern void CopyMemory(IntPtr Destination, IntPtr Source, int Length); - - /// - /// Frees any memory and resets to a default state - /// - private void FreeResources() - { - m_audioBitsPerSample = 0; - m_audioChannels = 0; - m_audioSamplesPerSecond = 0; - m_audioStreamLength = 0; - m_audioSubType = Guid.Empty; - m_filename = ""; - m_fourCC = ""; - m_streamCount = 0; - m_videoBitsPerPixel = 0; - m_videoResolution = Size.Empty; - m_videoStreamLength = 0; - m_videoSubType = Guid.Empty; - m_videoFrameRate = 0; - HasAudio = false; - HasVideo = false; - - if (m_bitmap != null) - m_bitmap.Dispose(); - - m_bitmap = null; - - if (m_mediaDet != null) - { - Marshal.ReleaseComObject(m_mediaDet); - m_mediaDet = null; - } - } - - /// - /// Converts a FourCC code to a string - /// - private static string ConvertFourCC(int fourcc) - { - return Encoding.ASCII.GetString(BitConverter.GetBytes(fourcc)); - } - - /// - /// Loads a media file. - /// - /// The full path of the media file to load - public void LoadMedia(string filename) - { - VerifyAccess(); - - FreeResources(); - - m_filename = filename; - - try - { - if (string.IsNullOrEmpty(m_filename)) - return; - - LoadMedia(); - } - catch (Exception ex) - { - FreeResources(); - throw new WPFMediaKitException("Failed to load " + filename, ex); - } - } - - private void LoadMedia() - { - /*Create the COM object and query the IMediaDet interface */ - m_mediaDet = new MediaDet() as IMediaDet; - - if (m_mediaDet == null) - throw new NullReferenceException("Could not create an instance of MediaDet COM"); - - int hr = m_mediaDet.put_Filename(m_filename); - DsError.ThrowExceptionForHR(hr); - - /* We find out how many streams exist in the - * media file. These can be audio, video, etc */ - hr = m_mediaDet.get_OutputStreams(out m_streamCount); - DsError.ThrowExceptionForHR(hr); - - /* Loop over each of the streams and extract info from them */ - for (int i = 0; i < m_streamCount; i++) - { - /* Set the interface to look at a specific stream */ - hr = m_mediaDet.put_CurrentStream(i); - DsError.ThrowExceptionForHR(hr); - - Guid majorType; - - /* Get the major type of the media */ - hr = m_mediaDet.get_StreamType(out majorType); - DsError.ThrowExceptionForHR(hr); - - var mediaType = new AMMediaType(); - double framerate; - - /* Gets the AMMediaType so we can read some - * metadata on the stream */ - hr = m_mediaDet.get_StreamMediaType(mediaType); - DsError.ThrowExceptionForHR(hr); - - if (majorType == MediaType.Video) - { - ReadVideoFormat(mediaType); - hr = m_mediaDet.get_FrameRate(out framerate); - m_videoFrameRate = framerate; - } - else if (majorType == MediaType.Audio) - { - ReadAudioFormat(mediaType); - } - - /* We need to free this with the helper - * because it has an unmanaged pointer - * and we don't want any leaks */ - DsUtils.FreeAMMediaType(mediaType); - } - } - - /// - /// Reads the audio stream information from the media file - /// - private void ReadAudioFormat(AMMediaType mediaType) - { - m_audioSubType = mediaType.subType; - - int hr = m_mediaDet.get_StreamLength(out m_audioStreamLength); - DsError.ThrowExceptionForHR(hr); - - if (mediaType.formatType == FormatType.WaveEx) - { - HasAudio = true; - var waveFormatEx = (WaveFormatEx)Marshal.PtrToStructure(mediaType.formatPtr, typeof(WaveFormatEx)); - m_audioChannels = waveFormatEx.nChannels; - m_audioSamplesPerSecond = (waveFormatEx.nSamplesPerSec); - m_audioBitsPerSample = waveFormatEx.wBitsPerSample; - } - } - - /// - /// Reads the video stream information for the media file - /// - private void ReadVideoFormat(AMMediaType mediaType) - { - m_videoSubType = mediaType.subType; - - int hr = m_mediaDet.get_StreamLength(out m_videoStreamLength); - DsError.ThrowExceptionForHR(hr); - - if (mediaType.formatType == FormatType.VideoInfo) /* Most common video major type */ - { - HasVideo = true; - - /* 'Cast' the unmanaged pointer to our managed struct so we can read the meta data */ - var header = (VideoInfoHeader)Marshal.PtrToStructure(mediaType.formatPtr, typeof(VideoInfoHeader)); - m_fourCC = ConvertFourCC(header.BmiHeader.Compression); - m_videoBitsPerPixel = header.BmiHeader.BitCount; - m_videoResolution = new Size(header.BmiHeader.Width, header.BmiHeader.Height); - } - else if (mediaType.formatType == FormatType.VideoInfo2) /* Usually for interlaced video */ - { - HasVideo = true; - - /* 'Cast' the unmanaged pointer to our managed struct so we can read the meta data */ - var header = (VideoInfoHeader2)Marshal.PtrToStructure(mediaType.formatPtr, typeof(VideoInfoHeader2)); - m_fourCC = ConvertFourCC(header.BmiHeader.Compression); - m_videoResolution = new Size(header.BmiHeader.Width, header.BmiHeader.Height); - m_videoBitsPerPixel = header.BmiHeader.BitCount; - /* TODO: Pull out VideoInfoHeader2 specifics */ - } - } - - /// - /// Gets an image snapshot from the media file that was opened - /// - /// The media time position for the requested thumbnail - /// Returns a BitmapSource of the video position. - public unsafe BitmapSource GetImage(TimeSpan position) - { - VerifyAccess(); - - const int BITS_PER_PIXEL = 3; - - if (string.IsNullOrEmpty(m_filename)) - throw new WPFMediaKitException("A media file must be successfully loaded first."); - - if (!HasVideo) - throw new WPFMediaKitException("The media does not have a video stream"); - - double secondsPos = position.TotalSeconds; - - /* Our pointer to the bitmap's pixel buffer */ - IntPtr pBuffer = IntPtr.Zero; - - /* The WPF bitmap source we return */ - BitmapSource bmpSource = null; - - try - { - /* The size of our buffer */ - int bufferSize; - - /* Queries the size of the bitmap buffer first */ - int hr = m_mediaDet.GetBitmapBits(secondsPos, - out bufferSize, - IntPtr.Zero, - (int)VideoResolution.Width, - (int)VideoResolution.Height); - if (hr == 0) - { - /* Allocate some unmanaged memory, big enough for our bitmap bytes */ - pBuffer = Marshal.AllocCoTaskMem(bufferSize); - - /* Get the pixel buffer for the thumbnail */ - hr = m_mediaDet.GetBitmapBits(secondsPos, - out bufferSize, - pBuffer, - (int)VideoResolution.Width, - (int)VideoResolution.Height); - - DsError.ThrowExceptionForHR(hr); - - /* The bitmap header exists is the buffer. We 'cast' it out to read it */ - var bitmapHeader = (BitmapInfoHeader)Marshal.PtrToStructure(pBuffer, typeof(BitmapInfoHeader)); - - /* We use a pointer so we can do some pointer - * arithmetic. This method should be compatible - * with 32/64bit processes */ - var pBitmapData = (byte*)pBuffer.ToPointer(); - - pBitmapData += bitmapHeader.Size; - - /* This will be the pointer to the bitmap pixels */ - var bitmapData = new IntPtr(pBitmapData); - - /* We create a GDI bitmap, so we can flip it before we - * load it into a WPF BitmapSource */ - if (m_bitmap == null) - m_bitmap = new Bitmap(bitmapHeader.Width, - bitmapHeader.Height, - PixelFormat.Format24bppRgb); - - /* The GDI bitmap's pixels are locked so we can grab a pointer to the pixel buffer */ - BitmapData bmpData = m_bitmap.LockBits(new Rectangle(0, 0, bitmapHeader.Width, bitmapHeader.Height), - ImageLockMode.WriteOnly, - PixelFormat.Format24bppRgb); - - /* The we copy our pixel buffer to the GDI bitmap's pixel buffer */ - CopyMemory(bmpData.Scan0, bitmapData, (int)VideoResolution.Width * (int)VideoResolution.Height * BITS_PER_PIXEL); - - m_bitmap.UnlockBits(bmpData); - - /* The bitmap is bottom up, so it needs to be flipped */ - m_bitmap.RotateFlip(RotateFlipType.Rotate180FlipX); - - /* Lock the GDI pixel buffer so we can load them into a WPF BitmapSource */ - bmpData = m_bitmap.LockBits(new Rectangle(0, 0, bitmapHeader.Width, bitmapHeader.Height), - ImageLockMode.ReadOnly, - PixelFormat.Format24bppRgb); - - bmpSource = BitmapSource.Create((int)VideoResolution.Width, - (int)VideoResolution.Height, - 96, - 96, - PixelFormats.Bgr24, - null, - bmpData.Scan0, - bmpData.Stride * (int)VideoResolution.Height, - bmpData.Stride); - - m_bitmap.UnlockBits(bmpData); - } - } - catch (Exception ex) - { - Debug.WriteLine("GetImage error: " + ex.Message); - } - finally - { - if (pBuffer != IntPtr.Zero) - Marshal.FreeCoTaskMem(pBuffer); - } - - return bmpSource; - } -} diff --git a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/MediaPlayers/MediaSeekingPlayer.cs b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/MediaPlayers/MediaSeekingPlayer.cs deleted file mode 100644 index ec1c07b..0000000 --- a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/MediaPlayers/MediaSeekingPlayer.cs +++ /dev/null @@ -1,278 +0,0 @@ -using DirectShowLib; -using System; -using System.Runtime.InteropServices; - -namespace WPFMediaKit.DirectShow.MediaPlayers; - -/// -/// The MediaSeekingPlayer adds media seeking functionality to -/// to the MediaPlayerBase class -/// -public abstract class MediaSeekingPlayer : MediaPlayerBase -{ - /// - /// Local cache of the current position - /// - private long m_currentPosition; - - /// - /// The DirectShow media seeking interface - /// - private IMediaSeeking m_mediaSeeking; - - /// - /// Gets the duration in miliseconds, of the media that is opened - /// - public virtual long Duration { get; protected set; } - - /// - /// Sets the rate at which the media plays back - /// - public virtual double SpeedRatio - { - get - { - if (m_mediaSeeking == null) - return 1; - - double rate; - - m_mediaSeeking.GetRate(out rate); - return rate; - } - set - { - if (m_mediaSeeking == null) - return; - - double rate = value; - - int hr = m_mediaSeeking.SetRate(rate); - } - } - - /// - /// Gets or sets the position in miliseconds of the media - /// - public virtual long MediaPosition - { - get - { - VerifyAccess(); - return m_currentPosition; - } - set - { - VerifyAccess(); - m_currentPosition = value; - - if (m_mediaSeeking != null) - { - /* Try to set the media time */ - m_mediaSeeking.SetPositions(m_currentPosition, - AMSeekingSeekingFlags.AbsolutePositioning, - 0, - AMSeekingSeekingFlags.NoPositioning); - } - } - } - - /// - /// The current position format the media is using - /// - private MediaPositionFormat m_currentPositionFormat; - - /// - /// The prefered position format to use with the media - /// - private MediaPositionFormat m_preferedPositionFormat; - - /// - /// The current media positioning format - /// - public virtual MediaPositionFormat CurrentPositionFormat - { - get { return m_currentPositionFormat; } - protected set { m_currentPositionFormat = value; } - } - - /// - /// The prefered media positioning format - /// - public virtual MediaPositionFormat PreferedPositionFormat - { - get { return m_preferedPositionFormat; } - set - { - m_preferedPositionFormat = value; - SetMediaSeekingInterface(m_mediaSeeking); - } - } - - /// - /// Notifies when the position of the media has changed - /// - public event EventHandler MediaPositionChanged; - - protected void InvokeMediaPositionChanged(EventArgs e) - { - EventHandler mediaPositionChangedHandler = MediaPositionChanged; - if (mediaPositionChangedHandler != null) mediaPositionChangedHandler(this, e); - } - - /// - /// This method is overriden to get out the seeking - /// interfaces from the DirectShow graph - /// - protected override void SetupFilterGraph(IFilterGraph graph) - { - SetMediaSeekingInterface(graph as IMediaSeeking); - base.SetupFilterGraph(graph); - } - - /// - /// Frees any allocated or unmanaged resources - /// - protected override void FreeResources() - { - base.FreeResources(); - - if (m_mediaSeeking != null) - Marshal.ReleaseComObject(m_mediaSeeking); - - m_mediaSeeking = null; - m_currentPosition = 0; - } - - /// - /// Polls the graph for various data about the media that is playing - /// - protected override void OnGraphTimerTick() - { - /* Polls the current position */ - if (m_mediaSeeking != null) - { - long lCurrentPos; - - int hr = m_mediaSeeking.GetCurrentPosition(out lCurrentPos); - - if (hr == 0) - { - if (lCurrentPos != m_currentPosition) - { - m_currentPosition = lCurrentPos; - InvokeMediaPositionChanged(null); - } - } - } - - base.OnGraphTimerTick(); - } - - /// - /// Converts a MediaPositionFormat enum to a DShow TimeFormat GUID - /// - protected static Guid ConvertPositionFormat(MediaPositionFormat positionFormat) - { - Guid timeFormat; - - switch (positionFormat) - { - case MediaPositionFormat.MediaTime: - timeFormat = TimeFormat.MediaTime; - break; - - case MediaPositionFormat.Frame: - timeFormat = TimeFormat.Frame; - break; - - case MediaPositionFormat.Byte: - timeFormat = TimeFormat.Byte; - break; - - case MediaPositionFormat.Field: - timeFormat = TimeFormat.Field; - break; - - case MediaPositionFormat.Sample: - timeFormat = TimeFormat.Sample; - break; - - default: - timeFormat = TimeFormat.None; - break; - } - - return timeFormat; - } - - /// - /// Converts a DirectShow TimeFormat GUID to a MediaPositionFormat enum - /// - protected static MediaPositionFormat ConvertPositionFormat(Guid positionFormat) - { - MediaPositionFormat format; - - if (positionFormat == TimeFormat.Byte) - format = MediaPositionFormat.Byte; - else if (positionFormat == TimeFormat.Field) - format = MediaPositionFormat.Field; - else if (positionFormat == TimeFormat.Frame) - format = MediaPositionFormat.Frame; - else if (positionFormat == TimeFormat.MediaTime) - format = MediaPositionFormat.MediaTime; - else if (positionFormat == TimeFormat.Sample) - format = MediaPositionFormat.Sample; - else - format = MediaPositionFormat.None; - - return format; - } - - protected void SetDuration() - { - if (m_mediaSeeking == null) - return; - - long duration; - - /* Get the duration of the media. This value will - * be in whatever format that was set. ie Frame, MediaTime */ - m_mediaSeeking.GetDuration(out duration); - - Duration = duration; - } - - /// - /// Setup the IMediaSeeking interface - /// - protected void SetMediaSeekingInterface(IMediaSeeking mediaSeeking) - { - m_mediaSeeking = mediaSeeking; - - if (mediaSeeking == null) - { - CurrentPositionFormat = MediaPositionFormat.None; - Duration = 0; - return; - } - - /* Get our prefered DirectShow TimeFormat */ - Guid preferedFormat = ConvertPositionFormat(PreferedPositionFormat); - - /* Attempt to set the time format */ - mediaSeeking.SetTimeFormat(preferedFormat); - - Guid currentFormat; - - /* Gets the current time format - * we may not have been successful - * setting our prefered format */ - mediaSeeking.GetTimeFormat(out currentFormat); - - /* Set our property up with the right format */ - CurrentPositionFormat = ConvertPositionFormat(currentFormat); - - SetDuration(); - } -} diff --git a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/MediaPlayers/MediaUriPlayer.cs b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/MediaPlayers/MediaUriPlayer.cs deleted file mode 100644 index be108d9..0000000 --- a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/MediaPlayers/MediaUriPlayer.cs +++ /dev/null @@ -1,747 +0,0 @@ -using DirectShowLib; -using System; -using System.Runtime.ExceptionServices; -using System.Runtime.InteropServices; - -namespace WPFMediaKit.DirectShow.MediaPlayers; - -[ComImport, Guid("04FE9017-F873-410E-871E-AB91661A4EF7")] -internal class FFDShow -{ -} - -[ComImport, Guid("B98D13E7-55DB-4385-A33D-09FD1BA26338")] -public class LAVSplitterSource { } - -[ComImport, Guid("171252A0-8820-4AFE-9DF8-5C92B2D66B04")] -public class LAVSplitter { } - -[ComImport] -[Guid("e436ebb5-524f-11ce-9f53-0020af0ba770")] -public class AsyncReader { } - -/// -/// The MediaUriPlayer plays media files from a given Uri. -/// -public class MediaUriPlayer : MediaSeekingPlayer -{ - private static readonly ILog log = LogManager.GetLogger(typeof(MediaUriPlayer)); - - /// - /// The name of the default audio render. This is the - /// same on all versions of windows - /// - public const string DEFAULT_AUDIO_RENDERER_NAME = "Default DirectSound Device"; - - /// - /// Set the default audio renderer property backing - /// - private string m_audioRenderer = DEFAULT_AUDIO_RENDERER_NAME; - -#if DEBUG - - /// - /// Used to view the graph in graphedit - /// - private DsROTEntry m_dsRotEntry; - -#endif - - /// - /// The DirectShow graph interface. In this example - /// We keep reference to this so we can dispose - /// of it later. - /// - private IGraphBuilder m_graph; - - public IGraphBuilder Graph - { - get { return m_graph; } - } - - public MediaUriPlayer() - { - LAVFilterDirectory = "./"; - - //we are going to use this source for playback because it does not lock the file - AsyncFileSource = new FilterName("System AsyncFileSource", ClassId.FilesyncSource, "Not applicable"); - - //we are only using this source for determine if stream has video(bool HasVideo) NOT for playback - // because this source locks the file - SplitterSource = new FilterName("LAV Splitter Source", ClassId.LAVFilterSource, "LAVSplitter.ax"); - - Splitter = new FilterName("LAV Splitter", ClassId.LAVFilter, "LAVSplitter.ax"); - VideoDecoder = new FilterName("LAV Video Decoder", ClassId.LAVFilterVideo, "LAVVideo.ax"); - AudioDecoder = new FilterName("LAV Audio Decoder", ClassId.LAVFilterAudio, "LAVAudio.ax"); - } - - /// - /// The media Uri - /// - private Uri m_sourceUri; - - /// - /// Gets or sets the Uri source of the media - /// - public Uri Source - { - get - { - VerifyAccess(); - return m_sourceUri; - } - set - { - VerifyAccess(); - m_sourceUri = value; - - OpenSource(); - } - } - - /// - /// Return Source as a string path or uri. - /// - private string FileSource - { - get - { - if (m_sourceUri == null) - return null; - if (m_sourceUri.IsFile) - return m_sourceUri.LocalPath; - return m_sourceUri.ToString(); - } - } - - /// - /// The renderer type to use when - /// rendering video - /// - public VideoRendererType VideoRenderer - { - get; - set; - } - - /// - /// Implementation of framestepinterface to step video forward by minimum of one frame e.g. by mousewheel - /// - private IVideoFrameStep frameStep; - - /// - /// step the frames - /// - public void StepFrame(int framecount) - { - int i = frameStep.CanStep(0, null); - if (i == 0) - { - this.Play(); - frameStep.Step(framecount, null); - this.PlayerState = PlayerState.SteppingFrames; - } - } - - // - // Some video renderers support stepping media frame by frame with the - // IVideoFrameStep interface. See the interface documentation for more - // details on frame stepping. - // - private bool GetFrameStepInterface() - { - int hr = 0; - - IVideoFrameStep frameStepTest = null; - - // Get the frame step interface, if supported - frameStepTest = (IVideoFrameStep)this.m_graph; - - // Check if this decoder can step - hr = frameStepTest.CanStep(0, null); - if (hr == 0) - { - this.frameStep = frameStepTest; - return true; - } - else - { - this.frameStep = null; - return false; - } - } - - /// - /// The name of the audio renderer device - /// - public string AudioRenderer - { - get - { - VerifyAccess(); - return m_audioRenderer; - } - set - { - VerifyAccess(); - m_audioRenderer = value; - } - } - - /// - /// Gets or sets if the media should play in loop - /// or if it should just stop when the media is complete - /// - public bool Loop { get; set; } - - /// - /// Is ran everytime a new media event occurs on the graph - /// - /// The Event code that occured - /// The first event parameter sent by the graph - /// The second event parameter sent by the graph - protected override void OnMediaEvent(EventCode code, IntPtr lparam1, IntPtr lparam2) - { - if (Loop) - { - switch (code) - { - case EventCode.Complete: - MediaPosition = 0; - break; - } - } - else - /* Only run the base when we don't loop - * otherwise the default behavior is to - * fire a media ended event */ - base.OnMediaEvent(code, lparam1, lparam2); - } - - public void DumpGraphInfo(string fileName) - { - DumpGraphInfo(fileName, m_graph); - } - - public void DumpGraphInfo(string fileName, IGraphBuilder graph) - { - if (string.IsNullOrEmpty(fileName) || graph == null) return; - - string filterOutputString = string.Empty; - - IEnumFilters enumFilters; - int hr = graph.EnumFilters(out enumFilters); - DsError.ThrowExceptionForHR(hr); - - IntPtr fetched = IntPtr.Zero; - - IBaseFilter[] filters = { null }; - - int r = 0; - while (r == 0) - { - try - { - r = enumFilters.Next(filters.Length, filters, fetched); - DsError.ThrowExceptionForHR(r); - - if (filters == null || filters.Length == 0 || filters[0] == null) continue; - - FilterInfo filterInfo; - filters[0].QueryFilterInfo(out filterInfo); - - filterOutputString += string.Format("{0:X8}", Marshal.GetIUnknownForObjectInContext(filters[0]).ToInt32()) + " "; - - filterOutputString += filterInfo.achName + Environment.NewLine; - - /* We will want to enum all the pins on the source filter */ - IEnumPins pinEnum; - - hr = filters[0].EnumPins(out pinEnum); - DsError.ThrowExceptionForHR(hr); - - IntPtr fetched2 = IntPtr.Zero; - IPin[] pins = { null }; - - while (pinEnum.Next(pins.Length, pins, fetched2) == 0) - { - PinInfo pinInfo; - pins[0].QueryPinInfo(out pinInfo); - - var prefix = "[In ] "; - if (pinInfo.dir == PinDirection.Output) - prefix = "[Out] "; - - filterOutputString += string.Format("{0:X8}", Marshal.GetIUnknownForObjectInContext(pins[0]).ToInt32()) + " "; - filterOutputString += prefix + pinInfo.name + Environment.NewLine; - - Marshal.ReleaseComObject(pins[0]); - } - - Marshal.ReleaseComObject(pinEnum); - } - catch - { - r = 0; - continue; - } - } - - Marshal.ReleaseComObject(enumFilters); - - var file2 = System.IO.File.CreateText(fileName); - file2.AutoFlush = true; - file2.Write(filterOutputString); - file2.Close(); - } - - public string LAVFilterDirectory { get; set; } - public FilterName Splitter { get; set; } - public FilterName SplitterSource { get; set; } - public FilterName VideoDecoder { get; set; } - public FilterName AudioDecoder { get; set; } - public FilterName AsyncFileSource { get; set; } - - /// - /// Opens the media by initializing the DirectShow graph - /// - [HandleProcessCorruptedStateExceptions] - protected virtual void OpenSource() - { - /* Make sure we clean up any remaining mess */ - FreeResources(); - - string fileSource = FileSource; - - if (string.IsNullOrEmpty(fileSource)) - return; - - try - { - //lets get over with it right here - HasVideo = DoesItHaveVideo(FileSource); - GC.Collect(); - GC.WaitForPendingFinalizers(); - - /* Creates the GraphBuilder COM object */ - m_graph = new FilterGraphNoThread() as IGraphBuilder; - - if (m_graph == null) - throw new WPFMediaKitException("Could not create a graph"); - - var filterGraph = m_graph as IFilterGraph2; - - if (filterGraph == null) - throw new WPFMediaKitException("Could not QueryInterface for the IFilterGraph2"); - - IBaseFilter sourceFilter; - int hr; - - // Set LAV Splitter - /* LAVSplitterSource reader = new LAVSplitterSource(); - sourceFilter = reader as IBaseFilter; - var objectWithSite = reader as IObjectWithSite; - if (objectWithSite != null) - { - objectWithSite.SetSite(this); - } - - hr = m_graph.AddFilter(sourceFilter, SplitterSource); - DsError.ThrowExceptionForHR(hr);*/ - - //we are using AsyncFileSource here, so that file will not be locked during preview - sourceFilter = DirectShowUtil.AddFilterToGraph(m_graph, AsyncFileSource, LAVFilterDirectory, Guid.Empty); - if (sourceFilter == null) - throw new WPFMediaKitException("Could not add SplitterSource to graph."); - - IFileSourceFilter interfaceFile = (IFileSourceFilter)sourceFilter; - hr = interfaceFile.Load(fileSource, null); - DsError.ThrowExceptionForHR(hr); - - // we are going to need LavSpltter here, to connect AsyncFileSource with VideoDecoder - DirectShowUtil.AddFilterToGraph(m_graph, Splitter, LAVFilterDirectory, Guid.Empty); - - DirectShowUtil.AddFilterToGraph(m_graph, VideoDecoder, LAVFilterDirectory, Guid.Empty); - - try - { - // use preffered audio filter - InsertAudioFilter(sourceFilter, AudioDecoder); - } - catch (Exception ex) - { - // codecs misconfigured - log.Error(ex, "Cannot add audio decoder: {0}", AudioDecoder); - } - - // use prefered audio renderer - try - { - InsertAudioRenderer(AudioRenderer); - } - catch (Exception ex) - { - log.Error(ex, "Cannot add audio render: {0}", AudioRenderer); - } - - IBaseFilter renderer = CreateVideoRenderer(VideoRenderer, m_graph, 2); - - /* We will want to enum all the pins on the source filter */ - IEnumPins pinEnum; - - hr = sourceFilter.EnumPins(out pinEnum); - DsError.ThrowExceptionForHR(hr); - - IntPtr fetched = IntPtr.Zero; - IPin[] pins = { null }; - - /* Counter for how many pins successfully rendered */ - int pinsRendered = 0; - - if (VideoRenderer == VideoRendererType.VideoMixingRenderer9) - { - var mixer = renderer as IVMRMixerControl9; - - if (mixer != null) - { - VMR9MixerPrefs dwPrefs; - mixer.GetMixingPrefs(out dwPrefs); - dwPrefs &= ~VMR9MixerPrefs.RenderTargetMask; - dwPrefs |= VMR9MixerPrefs.RenderTargetRGB; - //mixer.SetMixingPrefs(dwPrefs); - } - } - - /* Loop over each pin of the source filter */ - while (pinEnum.Next(pins.Length, pins, fetched) == 0) - { - if (filterGraph.RenderEx(pins[0], - AMRenderExFlags.RenderToExistingRenderers, - IntPtr.Zero) >= 0) - pinsRendered++; - - Marshal.ReleaseComObject(pins[0]); - } - - Marshal.ReleaseComObject(pinEnum); - Marshal.ReleaseComObject(sourceFilter); - - if (pinsRendered == 0) - throw new WPFMediaKitException("Could not render any streams from the source Uri"); - -#if DEBUG - /* Adds the GB to the ROT so we can view - * it in graphedit */ - m_dsRotEntry = new DsROTEntry(m_graph); -#endif - /* Configure the graph in the base class */ - SetupFilterGraph(m_graph); - - GetFrameStepInterface(); - } - catch (Exception ex) - { - /* This exection will happen usually if the media does - * not exist or could not open due to not having the - * proper filters installed */ - - // Fallback try auto graph: - var result = oldOpenSource(); - - if (!result) - { - FreeResources(); - - HasVideo = false; - - /* Fire our failed event */ - InvokeMediaFailed(new MediaFailedEventArgs(ex.Message, ex)); - - return; - } - } - - InvokeMediaOpened(); - } - - private bool DoesItHaveVideo(string filename) - { - if (string.IsNullOrEmpty(filename)) - return false; - bool result; - IGraphBuilder temp_graph = new FilterGraphNoThread() as IGraphBuilder; - try - { - if (temp_graph == null) - throw new WPFMediaKitException("Could not create a graph"); - - var filterGraph = temp_graph as IFilterGraph2; - - if (filterGraph == null) - throw new WPFMediaKitException("Could not QueryInterface for the IFilterGraph2"); - - IBaseFilter sourceFilter; - int hr; - - sourceFilter = DirectShowUtil.AddFilterToGraph(temp_graph, SplitterSource, LAVFilterDirectory, Guid.Empty); - if (sourceFilter == null) - throw new WPFMediaKitException("Could not add SplitterSource to graph."); - - IFileSourceFilter interfaceFile = (IFileSourceFilter)sourceFilter; - hr = interfaceFile.Load(filename, null); - DsError.ThrowExceptionForHR(hr); - - // Set Video Codec - // Remove Pin - var videoPinFrom = DirectShowLib.DsFindPin.ByName(sourceFilter, "Video"); - IPin videoPinTo; - if (videoPinFrom != null) - { - hr = videoPinFrom.ConnectedTo(out videoPinTo); - if (hr >= 0 && videoPinTo != null) - { - PinInfo pInfo; - videoPinTo.QueryPinInfo(out pInfo); - FilterInfo fInfo; - pInfo.filter.QueryFilterInfo(out fInfo); - - DirectShowUtil.DisconnectAllPins(temp_graph, pInfo.filter); - temp_graph.RemoveFilter(pInfo.filter); - - DsUtils.FreePinInfo(pInfo); - Marshal.ReleaseComObject(fInfo.pGraph); - Marshal.ReleaseComObject(videoPinTo); - videoPinTo = null; - } - Marshal.ReleaseComObject(videoPinFrom); - videoPinFrom = null; - - result = true; - } - else - { - result = false; - } - - DirectShowUtil.RemoveFilters(temp_graph, SplitterSource.Name); - Marshal.FinalReleaseComObject(sourceFilter); - } - catch - { result = false; } - finally - { - Marshal.ReleaseComObject(temp_graph); - } - return result; - } - - [HandleProcessCorruptedStateExceptions] - private bool oldOpenSource() - { - /* Make sure we clean up any remaining mess */ - FreeResources(); - - string fileSource = FileSource; - - if (string.IsNullOrEmpty(fileSource)) - return false; - - try - { - /* Creates the GraphBuilder COM object */ - m_graph = new FilterGraphNoThread() as IGraphBuilder; - - if (m_graph == null) - throw new WPFMediaKitException("Could not create a graph"); - - // use prefered audio renderer - try - { - InsertAudioRenderer(AudioRenderer); - } - catch (Exception ex) - { - log.Error(ex, "Cannot add audio render: {0}", AudioRenderer); - } - - IBaseFilter renderer = CreateVideoRenderer(VideoRenderer, m_graph, 2); - - var filterGraph = m_graph as IFilterGraph2; - - if (filterGraph == null) - throw new WPFMediaKitException("Could not QueryInterface for the IFilterGraph2"); - - IBaseFilter sourceFilter; - - /* Have DirectShow find the correct source filter for the Uri */ - int hr = filterGraph.AddSourceFilter(fileSource, fileSource, out sourceFilter); - DsError.ThrowExceptionForHR(hr); - - /* Check for video stream*/ - var videoPinFrom = DsFindPin.ByName(sourceFilter, "Video"); - if (videoPinFrom != null) - { - Marshal.ReleaseComObject(videoPinFrom); - HasVideo = true; - } - else - { - HasVideo = false; - } - - /* We will want to enum all the pins on the source filter */ - IEnumPins pinEnum; - - hr = sourceFilter.EnumPins(out pinEnum); - DsError.ThrowExceptionForHR(hr); - - IntPtr fetched = IntPtr.Zero; - IPin[] pins = { null }; - - /* Counter for how many pins successfully rendered */ - int pinsRendered = 0; - - if (VideoRenderer == VideoRendererType.VideoMixingRenderer9) - { - var mixer = renderer as IVMRMixerControl9; - - if (mixer != null) - { - VMR9MixerPrefs dwPrefs; - mixer.GetMixingPrefs(out dwPrefs); - dwPrefs &= ~VMR9MixerPrefs.RenderTargetMask; - dwPrefs |= VMR9MixerPrefs.RenderTargetRGB; - //mixer.SetMixingPrefs(dwPrefs); - } - } - - /* Loop over each pin of the source filter */ - while (pinEnum.Next(pins.Length, pins, fetched) == 0) - { - if (filterGraph.RenderEx(pins[0], - AMRenderExFlags.RenderToExistingRenderers, - IntPtr.Zero) >= 0) - pinsRendered++; - - Marshal.ReleaseComObject(pins[0]); - } - - Marshal.ReleaseComObject(pinEnum); - Marshal.ReleaseComObject(sourceFilter); - - if (pinsRendered == 0) - throw new WPFMediaKitException("Could not render any streams from the source Uri"); - -#if DEBUG - /* Adds the GB to the ROT so we can view - * it in graphedit */ - m_dsRotEntry = new DsROTEntry(m_graph); -#endif - /* Configure the graph in the base class */ - SetupFilterGraph(m_graph); - - /* Sets the NaturalVideoWidth/Height */ - //SetNativePixelSizes(renderer); - } - catch (Exception ex) - { - /* This exection will happen usually if the media does - * not exist or could not open due to not having the - * proper filters installed */ - FreeResources(); - - /* Fire our failed event */ - InvokeMediaFailed(new MediaFailedEventArgs(ex.Message, ex)); - - return false; - } - - InvokeMediaOpened(); - - return true; - } - - /// - /// Inserts the audio renderer by the name. - /// - protected virtual void InsertAudioRenderer(string audioRenderer) - { - if (string.IsNullOrEmpty(audioRenderer)) - return; - - /* Add our prefered audio renderer */ - AddFilterByName(m_graph, DirectShowLib.FilterCategory.AudioRendererCategory, audioRenderer); - } - - protected virtual void InsertAudioFilter(IBaseFilter sourceFilter, FilterName audioDecoder) - { - if (audioDecoder.CLSID == Guid.Empty) - return; - - // Set Audio Codec - // Remove Pin - var audioPinFrom = DirectShowLib.DsFindPin.ByName(sourceFilter, "Audio"); - IPin audioPinTo; - if (audioPinFrom != null) - { - int hr = audioPinFrom.ConnectedTo(out audioPinTo); - if (hr >= 0 && audioPinTo != null) - { - PinInfo pInfo; - audioPinTo.QueryPinInfo(out pInfo); - FilterInfo fInfo; - pInfo.filter.QueryFilterInfo(out fInfo); - - DirectShowUtil.DisconnectAllPins(m_graph, pInfo.filter); - m_graph.RemoveFilter(pInfo.filter); - - DsUtils.FreePinInfo(pInfo); - Marshal.ReleaseComObject(fInfo.pGraph); - Marshal.ReleaseComObject(audioPinTo); - audioPinTo = null; - } - Marshal.ReleaseComObject(audioPinFrom); - audioPinFrom = null; - } - - DirectShowUtil.AddFilterToGraph(m_graph, audioDecoder, LAVFilterDirectory, Guid.Empty); - } - - /// - /// Frees all unmanaged memory and resets the object back - /// to its initial state - /// - protected override void FreeResources() - { -#if DEBUG - /* Remove us from the ROT */ - if (m_dsRotEntry != null) - { - m_dsRotEntry.Dispose(); - m_dsRotEntry = null; - } -#endif - - /* We run the StopInternal() to avoid any - * Dispatcher VeryifyAccess() issues because - * this may be called from the GC */ - StopInternal(); - - if (m_graph != null) - { - DirectShowUtil.RemoveFilters(m_graph); - Marshal.ReleaseComObject(m_graph); - m_graph = null; - - base.FreeResources(); - - /* Only run the media closed if we have an - * initialized filter graph */ - InvokeMediaClosed(EventArgs.Empty); - } - else - { - base.FreeResources(); - } - } -} diff --git a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/MediaPlayers/PropertyPageHelper.cs b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/MediaPlayers/PropertyPageHelper.cs deleted file mode 100644 index 70a2ce0..0000000 --- a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/MediaPlayers/PropertyPageHelper.cs +++ /dev/null @@ -1,103 +0,0 @@ -using DirectShowLib; -using System; -using System.Runtime.InteropServices; -using System.Windows.Forms; - -namespace WPFMediaKit.DirectShow.MediaPlayers; - -public class PropertyPageHelper : IDisposable -{ - private const string NO_PROPERTY_PAGE_FOUND = "No property page found."; - - [DllImport("olepro32.dll", CharSet = CharSet.Unicode, ExactSpelling = true)] - private static extern int OleCreatePropertyFrame(IntPtr hwndOwner, - int x, - int y, - string lpszCaption, - int cObjects, - [In, MarshalAs(UnmanagedType.Interface)] ref object ppUnk, - int cPages, - IntPtr pPageClsId, - int lcid, - int dwReserved, - IntPtr pvReserved); - - private ISpecifyPropertyPages m_specifyPropertyPages; - - public PropertyPageHelper(IBaseFilter filter) - { - m_specifyPropertyPages = filter as ISpecifyPropertyPages; - } - - public PropertyPageHelper(DsDevice dev) - { - try - { - object source; - var id = typeof(IBaseFilter).GUID; - dev.Mon.BindToObject(null, null, ref id, out source); - if (source != null) - { - var filter = (IBaseFilter)source; - m_specifyPropertyPages = filter as ISpecifyPropertyPages; - } - } - catch - { - MessageBox.Show(NO_PROPERTY_PAGE_FOUND); - } - } - - #region IDisposable Members - - public void Dispose() - { - m_specifyPropertyPages = null; - } - - #endregion IDisposable Members - - public void Show(IntPtr hWnd) - { - var cauuid = new DsCAUUID(); - try - { - int hr = m_specifyPropertyPages.GetPages(out cauuid); - if (hr != 0) - { - Marshal.ThrowExceptionForHR(hr); - } - - object objRef = m_specifyPropertyPages; - hr = OleCreatePropertyFrame(hWnd, - 30, - 30, - null, - 1, - ref objRef, - cauuid.cElems, - cauuid.pElems, - 0, - 0, - IntPtr.Zero); - - DsError.ThrowExceptionForHR(hr); - } - catch (Exception) - { - MessageBox.Show(NO_PROPERTY_PAGE_FOUND); - } - finally - { - if (cauuid.pElems != IntPtr.Zero) - { - Marshal.FreeCoTaskMem(cauuid.pElems); - } - } - } - - public void Show(Control owner) - { - Show(owner.Handle); - } -} diff --git a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/MediaPlayers/VideoCapturePlayer.cs b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/MediaPlayers/VideoCapturePlayer.cs deleted file mode 100644 index 54cda0a..0000000 --- a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/MediaPlayers/VideoCapturePlayer.cs +++ /dev/null @@ -1,614 +0,0 @@ -using DirectShowLib; -using System; -using System.Drawing; -using System.Drawing.Imaging; -using System.Runtime.InteropServices; - -namespace WPFMediaKit.DirectShow.MediaPlayers; - -public class VideoSampleArgs : EventArgs -{ - public Bitmap VideoFrame { get; internal set; } -} - -/// -/// A Player that plays video from a video capture device. -/// -public class VideoCapturePlayer : MediaPlayerBase, ISampleGrabberCB -{ - [DllImport("Kernel32.dll", EntryPoint = "RtlMoveMemory")] - private static extern void CopyMemory(IntPtr destination, IntPtr source, [MarshalAs(UnmanagedType.U4)] int length); - - #region Locals - - /// - /// The video capture pixel height - /// - private int m_desiredHeight = 240; - - /// - /// The video capture pixel width - /// - private int m_desiredWidth = 320; - - /// - /// The video capture's frames per second - /// - private int m_fps = 30; - - /// - /// Our DirectShow filter graph - /// - private IGraphBuilder m_graph; - - /// - /// The DirectShow video renderer - /// - private IBaseFilter m_renderer; - - /// - /// The capture device filter - /// - private IBaseFilter m_captureDevice; - - /// - /// The name of the video capture source device - /// - private string m_videoCaptureSource; - - /// - /// Flag to detect if the capture source has changed - /// - private bool m_videoCaptureSourceChanged; - - /// - /// The video capture device - /// - private DsDevice m_videoCaptureDevice; - - /// - /// Flag to detect if the capture source device has changed - /// - private bool m_videoCaptureDeviceChanged; - - /// - /// The sample grabber interface used for getting samples in a callback - /// - private ISampleGrabber m_sampleGrabber; - - private string m_fileName; - -#if DEBUG - private DsROTEntry m_rotEntry; -#endif - - #endregion Locals - - /// - /// Gets or sets if the instance fires an event for each of the samples - /// - public bool EnableSampleGrabbing { get; set; } - - /// - /// Fires when a new video sample is ready - /// - public event EventHandler NewVideoSample; - - private void InvokeNewVideoSample(VideoSampleArgs e) - { - EventHandler sample = NewVideoSample; - if (sample != null) sample(this, e); - } - - /// - /// The name of the video capture source to use - /// - public string VideoCaptureSource - { - get - { - VerifyAccess(); - return m_videoCaptureSource; - } - set - { - VerifyAccess(); - m_videoCaptureSource = value; - m_videoCaptureSourceChanged = true; - - /* Free our unmanaged resources when - * the source changes */ - FreeResources(); - } - } - - public DsDevice VideoCaptureDevice - { - get - { - VerifyAccess(); - return m_videoCaptureDevice; - } - set - { - VerifyAccess(); - m_videoCaptureDevice = value; - m_videoCaptureDeviceChanged = true; - - /* Free our unmanaged resources when - * the source changes */ - FreeResources(); - } - } - - /// - /// The frames per-second to play - /// the capture device back at - /// - public int FPS - { - get - { - VerifyAccess(); - return m_fps; - } - set - { - VerifyAccess(); - - /* We support only a minimum of - * one frame per second */ - if (value < 1) - value = 1; - - m_fps = value; - } - } - - /// - /// Gets or sets if Yuv is the prefered color space - /// - public bool UseYuv { get; set; } - - /// - /// The desired pixel width of the video - /// - public int DesiredWidth - { - get - { - VerifyAccess(); - return m_desiredWidth; - } - set - { - VerifyAccess(); - m_desiredWidth = value; - } - } - - /// - /// The desired pixel height of the video - /// - public int DesiredHeight - { - get - { - VerifyAccess(); - return m_desiredHeight; - } - set - { - VerifyAccess(); - m_desiredHeight = value; - } - } - - public string FileName - { - get - { - //VerifyAccess(); - return m_fileName; - } - set - { - //VerifyAccess(); - m_fileName = value; - } - } - - /// - /// Plays the video capture device - /// - public override void Play() - { - VerifyAccess(); - - if (m_graph == null) - SetupGraph(); - - base.Play(); - } - - /// - /// Pauses the video capture device - /// - public override void Pause() - { - VerifyAccess(); - - if (m_graph == null) - SetupGraph(); - - base.Pause(); - } - - public void ShowCapturePropertyPages(IntPtr hwndOwner) - { - VerifyAccess(); - - if (m_captureDevice == null) - return; - - using (var dialog = new PropertyPageHelper(m_captureDevice)) - { - dialog.Show(hwndOwner); - } - } - - /// - /// Configures the DirectShow graph to play the selected video capture - /// device with the selected parameters - /// - private void SetupGraph() - { - /* Clean up any messes left behind */ - FreeResources(); - - try - { - /* Create a new graph */ - m_graph = (IGraphBuilder)new FilterGraphNoThread(); - -#if DEBUG - m_rotEntry = new DsROTEntry(m_graph); -#endif - - /* Create a capture graph builder to help - * with rendering a capture graph */ - var graphBuilder = (ICaptureGraphBuilder2)new CaptureGraphBuilder2(); - - /* Set our filter graph to the capture graph */ - int hr = graphBuilder.SetFiltergraph(m_graph); - DsError.ThrowExceptionForHR(hr); - - /* Add our capture device source to the graph */ - if (m_videoCaptureSourceChanged) - { - m_captureDevice = AddFilterByName(m_graph, - FilterCategory.VideoInputDevice, - VideoCaptureSource); - - m_videoCaptureSourceChanged = false; - } - else if (m_videoCaptureDeviceChanged) - { - m_captureDevice = AddFilterByDevicePath(m_graph, - FilterCategory.VideoInputDevice, - VideoCaptureDevice.DevicePath); - - m_videoCaptureDeviceChanged = false; - } - - /* If we have a null capture device, we have an issue */ - if (m_captureDevice == null) - throw new WPFMediaKitException(string.Format("Capture device {0} not found or could not be created", VideoCaptureSource)); - - if (UseYuv && !EnableSampleGrabbing) - { - /* Configure the video output pin with our parameters and if it fails - * then just use the default media subtype*/ - if (!SetVideoCaptureParameters(graphBuilder, m_captureDevice, MediaSubType.YUY2)) - SetVideoCaptureParameters(graphBuilder, m_captureDevice, Guid.Empty); - } - else - /* Configure the video output pin with our parameters */ - SetVideoCaptureParameters(graphBuilder, m_captureDevice, Guid.Empty); - - var rendererType = VideoRendererType.VideoMixingRenderer9; - - /* Creates a video renderer and register the allocator with the base class */ - m_renderer = CreateVideoRenderer(rendererType, m_graph, 1); - - if (rendererType == VideoRendererType.VideoMixingRenderer9) - { - var mixer = m_renderer as IVMRMixerControl9; - - if (mixer != null && !EnableSampleGrabbing && UseYuv) - { - VMR9MixerPrefs dwPrefs; - mixer.GetMixingPrefs(out dwPrefs); - dwPrefs &= ~VMR9MixerPrefs.RenderTargetMask; - dwPrefs |= VMR9MixerPrefs.RenderTargetYUV; - /* Prefer YUV */ - mixer.SetMixingPrefs(dwPrefs); - } - } - - if (EnableSampleGrabbing) - { - m_sampleGrabber = (ISampleGrabber)new SampleGrabber(); - SetupSampleGrabber(m_sampleGrabber); - hr = m_graph.AddFilter(m_sampleGrabber as IBaseFilter, "SampleGrabber"); - DsError.ThrowExceptionForHR(hr); - } - - IBaseFilter mux = null; - IFileSinkFilter sink = null; - if (!string.IsNullOrEmpty(this.m_fileName)) - { - hr = graphBuilder.SetOutputFileName(MediaSubType.Asf, this.m_fileName, out mux, out sink); - DsError.ThrowExceptionForHR(hr); - - hr = graphBuilder.RenderStream(PinCategory.Capture, MediaType.Video, m_captureDevice, null, mux); - DsError.ThrowExceptionForHR(hr); - - // use the first audio device - var audioDevices = DsDevice.GetDevicesOfCat(FilterCategory.AudioInputDevice); - - if (audioDevices.Length > 0) - { - var audioDevice = AddFilterByDevicePath(m_graph, - FilterCategory.AudioInputDevice, - audioDevices[0].DevicePath); - - hr = graphBuilder.RenderStream(PinCategory.Capture, MediaType.Audio, audioDevice, null, mux); - DsError.ThrowExceptionForHR(hr); - } - } - - hr = graphBuilder.RenderStream(PinCategory.Preview, - MediaType.Video, - m_captureDevice, - null, - m_renderer); - - DsError.ThrowExceptionForHR(hr); - - /* Register the filter graph - * with the base classes */ - SetupFilterGraph(m_graph); - - /* Sets the NaturalVideoWidth/Height */ - SetNativePixelSizes(m_renderer); - - HasVideo = true; - - /* Make sure we Release() this COM reference */ - if (mux != null) - { - Marshal.ReleaseComObject(mux); - } - if (sink != null) - { - Marshal.ReleaseComObject(sink); - } - - Marshal.ReleaseComObject(graphBuilder); - } - catch (Exception ex) - { - /* Something got fuct up */ - FreeResources(); - InvokeMediaFailed(new MediaFailedEventArgs(ex.Message, ex)); - } - - /* Success */ - InvokeMediaOpened(); - } - - /// - /// Sets the capture parameters for the video capture device - /// - private bool SetVideoCaptureParameters(ICaptureGraphBuilder2 capGraph, IBaseFilter captureFilter, Guid mediaSubType) - { - /* The stream config interface */ - object streamConfig; - - /* Get the stream's configuration interface */ - int hr = capGraph.FindInterface(PinCategory.Capture, - MediaType.Video, - captureFilter, - typeof(IAMStreamConfig).GUID, - out streamConfig); - - DsError.ThrowExceptionForHR(hr); - - var videoStreamConfig = streamConfig as IAMStreamConfig; - - /* If QueryInterface fails... */ - if (videoStreamConfig == null) - { - throw new WPFMediaKitException("Failed to get IAMStreamConfig"); - } - - /* The media type of the video */ - AMMediaType media; - - /* Get the AMMediaType for the video out pin */ - hr = videoStreamConfig.GetFormat(out media); - DsError.ThrowExceptionForHR(hr); - - /* Make the VIDEOINFOHEADER 'readable' */ - var videoInfo = new VideoInfoHeader(); - Marshal.PtrToStructure(media.formatPtr, videoInfo); - - /* Setup the VIDEOINFOHEADER with the parameters we want */ - videoInfo.AvgTimePerFrame = DSHOW_ONE_SECOND_UNIT / FPS; - videoInfo.BmiHeader.Width = DesiredWidth; - videoInfo.BmiHeader.Height = DesiredHeight; - - if (mediaSubType != Guid.Empty) - { - int fourCC = 0; - byte[] b = mediaSubType.ToByteArray(); - fourCC = b[0]; - fourCC |= b[1] << 8; - fourCC |= b[2] << 16; - fourCC |= b[3] << 24; - - videoInfo.BmiHeader.Compression = fourCC; - media.subType = mediaSubType; - } - - /* Copy the data back to unmanaged memory */ - Marshal.StructureToPtr(videoInfo, media.formatPtr, false); - - /* Set the format */ - hr = videoStreamConfig.SetFormat(media); - - /* We don't want any memory leaks, do we? */ - DsUtils.FreeAMMediaType(media); - - if (hr < 0) - return false; - - return true; - } - - private Bitmap m_videoFrame; - - private void InitializeBitmapFrame(int width, int height) - { - if (m_videoFrame != null) - { - m_videoFrame.Dispose(); - } - - m_videoFrame = new Bitmap(width, height, PixelFormat.Format24bppRgb); - } - - #region ISampleGrabberCB Members - - int ISampleGrabberCB.SampleCB(double sampleTime, IMediaSample pSample) - { - var mediaType = new AMMediaType(); - - /* We query for the media type the sample grabber is using */ - int hr = m_sampleGrabber.GetConnectedMediaType(mediaType); - - var videoInfo = new VideoInfoHeader(); - - /* 'Cast' the pointer to our managed struct */ - Marshal.PtrToStructure(mediaType.formatPtr, videoInfo); - - /* The stride is "How many bytes across for each pixel line (0 to width)" */ - int stride = Math.Abs(videoInfo.BmiHeader.Width * (videoInfo.BmiHeader.BitCount / 8 /* eight bits per byte */)); - int width = videoInfo.BmiHeader.Width; - int height = videoInfo.BmiHeader.Height; - - if (m_videoFrame == null) - InitializeBitmapFrame(width, height); - - if (m_videoFrame == null) - return 0; - - BitmapData bmpData = m_videoFrame.LockBits(new Rectangle(0, 0, width, height), - ImageLockMode.ReadWrite, - PixelFormat.Format24bppRgb); - - /* Get the pointer to the pixels */ - IntPtr pBmp = bmpData.Scan0; - - IntPtr samplePtr; - - /* Get the native pointer to the sample */ - pSample.GetPointer(out samplePtr); - - int pSize = stride * height; - - /* Copy the memory from the sample pointer to our bitmap pixel pointer */ - CopyMemory(pBmp, samplePtr, pSize); - - m_videoFrame.UnlockBits(bmpData); - - InvokeNewVideoSample(new VideoSampleArgs { VideoFrame = m_videoFrame }); - - DsUtils.FreeAMMediaType(mediaType); - - /* Dereference the sample COM object */ - Marshal.ReleaseComObject(pSample); - return 0; - } - - int ISampleGrabberCB.BufferCB(double sampleTime, IntPtr pBuffer, int bufferLen) - { - throw new NotImplementedException(); - } - - #endregion ISampleGrabberCB Members - - private void SetupSampleGrabber(ISampleGrabber sampleGrabber) - { - var mediaType = new DirectShowLib.AMMediaType - { - majorType = MediaType.Video, - subType = MediaSubType.RGB24, - formatType = FormatType.VideoInfo - }; - - int hr = sampleGrabber.SetMediaType(mediaType); - - DsUtils.FreeAMMediaType(mediaType); - DsError.ThrowExceptionForHR(hr); - - hr = sampleGrabber.SetCallback(this, 0); - DsError.ThrowExceptionForHR(hr); - } - - protected override void FreeResources() - { - /* We run the StopInternal() to avoid any - * Dispatcher VeryifyAccess() issues */ - StopInternal(); - - /* Let's clean up the base - * class's stuff first */ - base.FreeResources(); - -#if DEBUG - if (m_rotEntry != null) - m_rotEntry.Dispose(); - - m_rotEntry = null; -#endif - if (m_videoFrame != null) - { - m_videoFrame.Dispose(); - m_videoFrame = null; - } - if (m_renderer != null) - { - Marshal.FinalReleaseComObject(m_renderer); - m_renderer = null; - } - if (m_captureDevice != null) - { - Marshal.FinalReleaseComObject(m_captureDevice); - m_captureDevice = null; - } - if (m_sampleGrabber != null) - { - Marshal.FinalReleaseComObject(m_sampleGrabber); - m_sampleGrabber = null; - } - if (m_graph != null) - { - Marshal.FinalReleaseComObject(m_graph); - m_graph = null; - - InvokeMediaClosed(EventArgs.Empty); - } - } -} diff --git a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/MediaPlayers/Vmr9Allocator.cs b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/MediaPlayers/Vmr9Allocator.cs deleted file mode 100644 index 4f6ca8f..0000000 --- a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectShow/MediaPlayers/Vmr9Allocator.cs +++ /dev/null @@ -1,613 +0,0 @@ -using DirectShowLib; -using System; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Threading; -using WPFMediaKit.DirectX; - -namespace WPFMediaKit.DirectShow.MediaPlayers; - -/// -/// The Vmr9Allocator is a custom allocator for the VideoMixingRenderer9 -/// -[ComVisible(true)] -public class Vmr9Allocator : IVMRSurfaceAllocator9, IVMRImagePresenter9, ICustomAllocator -{ - internal const string VMR9_ERROR = "Do you have the graphics driver and DirectX properly installed?"; - - /// - /// Base constant for FAIL error codes - /// - private const int E_FAIL = unchecked((int)0x80004005); - - /// - /// The SDK version of D3D we are using - /// - private const ushort D3D_SDK_VERSION = 32; - - /// - /// Lock for shared resources - /// - private static object m_staticLock = new object(); - - /// - /// Direct3D functions - /// - private IDirect3D9 m_d3d; - - /// - /// Direct3D functions of Vista - /// - private IDirect3D9Ex m_d3dEx; - - /// - /// The window handle, needed for D3D intialization - /// - private static readonly IntPtr m_hWnd; - - /// - /// The Direct3D device - /// - private IDirect3DDevice9 m_device; - - /// - /// Lock for instance's resources - /// - private readonly object m_instanceLock = new object(); - - /// - /// Part of the "Dispose" pattern - /// - private bool m_disposed; - - public bool IsDisposed - { get { return m_disposed; } } - - /// - /// Applications use this interface to set a custom allocator-presenter - /// and the allocator-presenter uses this interface to inform the VMR of - /// changes to the system environment that affect the Direct3D surfaces. - /// - private IVMRSurfaceAllocatorNotify9 m_allocatorNotify; - - /// - /// Fires each time a frame needs to be presented - /// - public event Action NewAllocatorFrame; - - /// - /// Fires when new D3D surfaces are allocated - /// - public event NewAllocatorSurfaceDelegate NewAllocatorSurface; - - /// - /// Private surface for YUV stuffs - /// - private IDirect3DSurface9 m_privateSurface; - - /// - /// Private texture for YUV stuffs - /// - private IDirect3DTexture9 m_privateTexture; - - [DllImport("user32.dll", SetLastError = false)] - private static extern IntPtr GetDesktopWindow(); - - static Vmr9Allocator() - { - m_hWnd = GetDesktopWindow(); - } - - /// - /// Creates a new VMR9 custom allocator to use with Direct3D - /// - public Vmr9Allocator() - { - /* Use the 9Ex for Vista */ - int hr = 0; - if (IsVistaOrBetter) - hr = Direct3D.Direct3DCreate9Ex(D3D_SDK_VERSION, out m_d3dEx); - else /* For XP */ - m_d3d = Direct3D.Direct3DCreate9(D3D_SDK_VERSION); - - if (m_d3dEx == null && m_d3d == null) - { - string hrStr = hr == 0 ? "" : $"({hr:X})"; - throw new WPFMediaKitException($"Could not create IDirect3D9 {hrStr}. " + VMR9_ERROR); - } - - CreateDevice(); - } - - /// - /// Fires the OnNewAllocatorSurface event, notifying the - /// subscriber that new surfaces are available - /// - private void InvokeNewSurfaceEvent(IntPtr pSurface) - { - if (NewAllocatorSurface != null) - NewAllocatorSurface(this, pSurface); - } - - /// - /// Fires the NewAllocatorFrame event notifying the - /// subscriber that a new frame is ready to be presented - /// - private void InvokeNewAllocatorFrame() - { - Action newAllocatorFrameHandler = NewAllocatorFrame; - if (newAllocatorFrameHandler != null) newAllocatorFrameHandler(); - } - - /// - /// Frees any remaining unmanaged memory - /// - public void Dispose() - { - Dispose(true); - //GC.SuppressFinalize(this); - } - - /// - /// Part of the dispose pattern - /// - protected virtual void Dispose(bool disposing) - { - //if (m_disposed) return; - - if (disposing) - { - InvokeNewSurfaceEvent(IntPtr.Zero); - /* Pass a dummy cookie to TerminateDevice */ - TerminateDevice(IntPtr.Zero); - - if (m_allocatorNotify != null) - { - Marshal.FinalReleaseComObject(m_allocatorNotify); - m_allocatorNotify = null; - } - - if (m_d3d != null) - { - Marshal.FinalReleaseComObject(m_d3d); - m_d3d = null; - } - - if (m_d3dEx != null) - { - Marshal.FinalReleaseComObject(m_d3dEx); - m_d3dEx = null; - } - - if (m_device != null) - { - Marshal.FinalReleaseComObject(m_device); - m_device = null; - } - } - - m_disposed = true; - } - - /// - /// Current Direct3D surfaces our allocator has ready and allocated - /// - private IntPtr[] DxSurfaces { get; set; } - - /// - /// The StartPresenting method is called just before the video starts playing. - /// The allocator-presenter should perform any necessary configuration in this method. - /// - /// - /// An application-defined DWORD_PTR cookie that uniquely identifies this instance of the - /// VMR for use in scenarios when one instance of the allocator-presenter is used with multiple VMR instances. - /// - /// Returns an HRESULT - public int StartPresenting(IntPtr userId) - { - return m_device == null ? E_FAIL : 0; - } - - /// - /// The StopPresenting method is called just after the video stops playing. - /// The allocator-presenter should perform any necessary cleanup in this method. - /// - /// - /// An application-defined DWORD_PTR cookie that uniquely identifies this instance of the - /// VMR for use in scenarios when one instance of the allocator-presenter is used with multiple VMR instances. - /// - /// - public int StopPresenting(IntPtr dwUserID) - { - return 0; - } - - /// - /// The PresentImage method is called at precisely the moment this video frame should be presented. - /// - /// - /// An application-defined DWORD_PTR that uniquely identifies this instance of the VMR in scenarios when - /// multiple instances of the VMR are being used with a single instance of an allocator-presenter. - /// - /// - /// Specifies a VMR9PresentationInfo structure that contains information about the video frame. - /// - /// Returns an HRESULT - public int PresentImage(IntPtr dwUserID, ref VMR9PresentationInfo lpPresInfo) - { - VMR9PresentationInfo presInfo = lpPresInfo; - - int hr = 0; - - try - { - lock (m_staticLock) - { - /* Test to see if our device was lost, is so fix it */ - TestRestoreLostDevice(); - - if (m_privateSurface != null) - hr = m_device.StretchRect(presInfo.lpSurf, - presInfo.rcSrc, - m_privateSurface, - presInfo.rcDst, - 0); - if (hr < 0) - return hr; - } - - /* Notify to our listeners we just got a new frame */ - InvokeNewAllocatorFrame(); - - hr = 0; - } - catch (Exception) - { - hr = E_FAIL; - } - - return hr; - } - - /// - /// Tests if the D3D device has been lost and if it has - /// it is retored. This happens on XP with things like - /// resolution changes or pressing ctrl + alt + del. With - /// Vista, this will most likely never be called unless the - /// video driver hangs or is changed. - /// - private void TestRestoreLostDevice() - { - if (m_device == null) - return; - - /* This will throw an exception - * if the device is lost */ - int hr = m_device.TestCooperativeLevel(); - - /* Do nothing if S_OK */ - if (hr == 0) - return; - - FreeSurfaces(); - CreateDevice(); - - /* TODO: This is bad. FIX IT! - * Figure out how to tell when the new - * device is ready to use */ - Thread.Sleep(1500); - - IntPtr pDev = GetComPointer(m_device); - - /* Update with our new device */ - m_allocatorNotify.ChangeD3DDevice(pDev, GetAdapterMonitor(0)); - } - - /// - /// Gets the pointer to the adapter monitor - /// - /// The ordinal of the adapter - /// A pointer to the adaptor monitor - private IntPtr GetAdapterMonitor(uint adapterOrdinal) - { - IntPtr pMonitor = m_d3dEx != null ? m_d3dEx.GetAdapterMonitor(adapterOrdinal) : m_d3d.GetAdapterMonitor(adapterOrdinal); - - return pMonitor; - } - - /// - /// The InitializeDevice method is called by the Video Mixing Renderer 9 (VMR-9) - /// when it needs the allocator-presenter to allocate surfaces. - /// - /// - /// Application-defined identifier. This value is the same value that the application - /// passed to the IVMRSurfaceAllocatorNotify9.AdviseSurfaceAllocator method in the - /// dwUserID parameter. - /// - /// - /// Pointer to a VMR9AllocationInfo structure that contains a description of the surfaces to create. - /// - /// - /// On input, specifies the number of surfaces to create. When the method returns, - /// this parameter contains the number of buffers that were actually allocated. - /// - /// Returns an HRESULT code - public int InitializeDevice(IntPtr userId, ref VMR9AllocationInfo lpAllocInfo, ref int lpNumBuffers) - { - if (m_allocatorNotify == null) - { - return E_FAIL; - } - - try - { - int hr; - - lock (m_staticLock) - { - /* These two pointers are passed to the the helper - * to create our D3D surfaces */ - var pDevice = GetComPointer(m_device); - var pMonitor = GetAdapterMonitor(0); - - /* Setup our D3D Device with our renderer */ - hr = m_allocatorNotify.SetD3DDevice(pDevice, pMonitor); - DsError.ThrowExceptionForHR(hr); - - /* This is only used if the AllocateSurfaceHelper is used */ - lpAllocInfo.dwFlags |= VMR9SurfaceAllocationFlags.TextureSurface; - - /* Make sure our old surfaces are free'd */ - FreeSurfaces(); - - /* This is an IntPtr array of pointers to D3D surfaces */ - DxSurfaces = new IntPtr[lpNumBuffers]; - - /* This is where the magic happens, surfaces are allocated */ - hr = m_allocatorNotify.AllocateSurfaceHelper(ref lpAllocInfo, ref lpNumBuffers, DxSurfaces); - - if (hr < 0) - { - FreeSurfaces(); - - if (lpAllocInfo.Format > 0) - { - hr = m_device.CreateTexture(lpAllocInfo.dwWidth, - lpAllocInfo.dwHeight, - 1, - 1, - D3DFORMAT.D3DFMT_X8R8G8B8, - 0, - out m_privateTexture, - IntPtr.Zero); - - DsError.ThrowExceptionForHR(hr); - - hr = m_privateTexture.GetSurfaceLevel(0, out m_privateSurface); - DsError.ThrowExceptionForHR(hr); - } - - lpAllocInfo.dwFlags &= ~VMR9SurfaceAllocationFlags.TextureSurface; - lpAllocInfo.dwFlags |= VMR9SurfaceAllocationFlags.OffscreenSurface; - - DxSurfaces = new IntPtr[lpNumBuffers]; - - hr = m_allocatorNotify.AllocateSurfaceHelper(ref lpAllocInfo, - ref lpNumBuffers, - DxSurfaces); - if (hr < 0) - { - FreeSurfaces(); - return hr; - } - } - } - - /* Nofity to our listeners we have new surfaces */ - InvokeNewSurfaceEvent(m_privateSurface != null ? GetComPointer(m_privateSurface) : DxSurfaces[0]); - - return hr; - } - catch - { - return E_FAIL; - } - } - - /// - /// The TerminateDevice method releases the Direct3D device. - /// - /// - /// Application-defined identifier. This value is the same value that the application - /// passed to the IVMRSurfaceAllocatorNotify9.AdviseSurfaceAllocator method - /// in the dwUserID parameter. - /// - /// - public int TerminateDevice(IntPtr id) - { - FreeSurfaces(); - return 0; - } - - /// - /// The GetSurface method retrieves a Direct3D surface - /// - /// - /// Application-defined identifier. This value is - /// the same value that the application passed to the - /// IVMRSurfaceAllocatorNotify9.AdviseSurfaceAllocator - /// method in the dwUserID parameter. - /// - /// - /// Specifies the index of the surface to retrieve. - /// - /// - /// - /// Address of a variable that receives an IDirect3DSurface9 - /// interface pointer. The caller must release the interface. - /// - public int GetSurface(IntPtr userId, int surfaceIndex, int surfaceFlags, out IntPtr lplpSurface) - { - lplpSurface = IntPtr.Zero; - - if (DxSurfaces == null) - return E_FAIL; - - if (surfaceIndex > DxSurfaces.Length) - return E_FAIL; - - lock (m_instanceLock) - { - if (DxSurfaces == null) - return E_FAIL; - - lplpSurface = DxSurfaces[surfaceIndex]; - - /* Increment the reference count to our surface, - * which is a pointer to a COM object */ - Marshal.AddRef(lplpSurface); - return 0; - } - } - - /// - /// The AdviseNotify method provides the allocator-presenter with the VMR-9 filter's - /// interface for notification callbacks. If you are using a custom allocator-presenter, - /// the application must call this method on the allocator-presenter, with a pointer to - /// the VMR's IVMRSurfaceAllocatorNotify9 interface. The allocator-presenter uses this - /// interface to communicate with the VMR. - /// - /// - /// Specifies the IVMRSurfaceAllocatorNotify9 interface that the allocator-presenter will - /// use to pass notifications back to the VMR. - /// Returns an HRESULT value - public int AdviseNotify(IVMRSurfaceAllocatorNotify9 lpIVMRSurfAllocNotify) - { - lock (m_staticLock) - { - m_allocatorNotify = lpIVMRSurfAllocNotify; - - var pMonitor = GetAdapterMonitor(0); - var pDevice = GetComPointer(m_device); - return m_allocatorNotify.SetD3DDevice(pDevice, pMonitor); - } - } - - /// - /// Gets a native pointer to a COM object. This method does not - /// add a reference count. - /// - /// The RCW to the COM object - /// Pointer to the COM object - private static IntPtr GetComPointer(object comObj) - { - if (!Marshal.IsComObject(comObj)) - throw new ArgumentException("comObj"); - - IntPtr pComObj = Marshal.GetIUnknownForObject(comObj); - - /* Get IUnknownForObject adds a reference count - * to the COM object so we remove a reference count - * before we return the pointer to avoid any possible - * memory leaks with COM */ - Marshal.Release(pComObj); - - return pComObj; - } - - ~Vmr9Allocator() - { - Dispose(); - } - - /// - /// Gets if the current operating system is - /// Windows Vista or higher. - /// - private static bool IsVistaOrBetter - { - get - { - return Environment.OSVersion.Version.Major >= 6; - } - } - - /// - /// Creates a Direct3D device - /// - [MethodImpl(MethodImplOptions.Synchronized)] - private void CreateDevice() - { - if (m_device != null) - return; - - var param = new D3DPRESENT_PARAMETERS - { - Windowed = 1, - Flags = ((short)D3DPRESENTFLAG.D3DPRESENTFLAG_VIDEO), - BackBufferFormat = D3DFORMAT.D3DFMT_X8R8G8B8, - SwapEffect = D3DSWAPEFFECT.D3DSWAPEFFECT_COPY - }; - - /* The COM pointer to our D3D Device */ - IntPtr dev; - - /* Windows Vista runs much more performant with the IDirect3DDevice9Ex */ - int hr = 0; - if (m_d3dEx != null) - { - hr = m_d3dEx.CreateDeviceEx(0, D3DDEVTYPE.D3DDEVTYPE_HAL, m_hWnd, - CreateFlags.D3DCREATE_SOFTWARE_VERTEXPROCESSING | CreateFlags.D3DCREATE_MULTITHREADED, - ref param, IntPtr.Zero, out dev); - } - else/* Windows XP */ - { - hr = m_d3d.CreateDevice(0, D3DDEVTYPE.D3DDEVTYPE_HAL, m_hWnd, - CreateFlags.D3DCREATE_SOFTWARE_VERTEXPROCESSING | CreateFlags.D3DCREATE_MULTITHREADED, - ref param, out dev); - } - - if (dev == IntPtr.Zero) - throw new WPFMediaKitException($"Cannot create D3D device ({hr:X}). Do you have D3D acceleration enabled for your graphics card?"); - - m_device = (IDirect3DDevice9)Marshal.GetObjectForIUnknown(dev); - Marshal.Release(dev); - } - - /// - /// Releases reference to all allocated D3D surfaces - /// - private void FreeSurfaces() - { - lock (m_instanceLock) - { - if (m_privateSurface != null) - { - Marshal.ReleaseComObject(m_privateSurface); - m_privateSurface = null; - } - - if (m_privateTexture != null) - { - Marshal.ReleaseComObject(m_privateTexture); - m_privateTexture = null; - } - - if (DxSurfaces != null) - { - foreach (var ptr in DxSurfaces) - { - if (ptr != IntPtr.Zero) - { - /* Release COM reference */ - Marshal.Release(ptr); - } - } - } - - /* Make sure we uninitialize the pointer array - * so the rest of our code knows it is invalid */ - DxSurfaces = null; - } - } -} diff --git a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectX/Direct3D.cs b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectX/Direct3D.cs deleted file mode 100644 index 793bb79..0000000 --- a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/DirectX/Direct3D.cs +++ /dev/null @@ -1,1142 +0,0 @@ -using DirectShowLib; -using System; -using System.Drawing; -using System.Runtime.InteropServices; -using System.Security; - -namespace WPFMediaKit.DirectX; - -[StructLayout(LayoutKind.Sequential)] -public class RECT -{ - public int left; - public int top; - public int right; - public int bottom; -} - -/// -/// CLSID_IDirect3DDevice9 -/// -[ComImport, Guid("D0223B96-BF7A-43fd-92BD-A43B0D82B9EB"), - InterfaceType(ComInterfaceType.InterfaceIsIUnknown), SuppressUnmanagedCodeSecurity] -public interface IDirect3DDevice9 -{ - [PreserveSig, SuppressUnmanagedCodeSecurity] - int TestCooperativeLevel(); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - uint GetAvailableTextureMem(); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - int EvictManagedResources(); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - int GetDirect3D([Out] out IDirect3D9 ppD3D9); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - int GetDeviceCaps([In, Out] ref D3DCAPS9 pCaps); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - int GetDisplayMode(uint iSwapChain, D3DDISPLAYMODE pMode); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - int GetCreationParameters([In, Out] ref D3DDEVICE_CREATION_PARAMETERS pParameters); - - int SetCursorProperties(); - - int SetCursorPosition(); - - int ShowCursor(bool bShow); - - int CreateAdditionalSwapChain(); - - int GetSwapChain(); - - uint GetNumberOfSwapChains(); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - int Reset([In, Out] ref D3DPRESENT_PARAMETERS pPresentationParameters); - - int Present(); - - int GetBackBuffer(); - - int GetRasterStatus(); - - int SetDialogBoxMode(); - - int SetGammaRamp(); - - int GetGammaRamp(); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - int CreateTexture(int Width, int Height, int Levels, int Usage, D3DFORMAT Format, int Pool, - out IDirect3DTexture9 ppTexture, IntPtr pSharedHandle); - - int CreateVolumeTexture(); - - int CreateCubeTexture(); - - int CreateVertexBuffer(); - - int CreateIndexBuffer(); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - int CreateRenderTarget(int width, int height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, - uint MultisampleQuality, [MarshalAs(UnmanagedType.Bool)] bool Lockable, [Out] out IntPtr pSurface, - IntPtr pSharedSurface); - - int CreateDepthStencilSurface(); - - int UpdateSurface(); - - int UpdateTexture(); - - int GetRenderTargetData(); - - int GetFrontBufferData(); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - int StretchRect(IntPtr pSourceSurface, DsRect pSourceRect, IDirect3DSurface9 pDestSurface, DsRect pDestRect, int Filter); - - int ColorFill(); - - int CreateOffscreenPlainSurface(); - - int SetRenderTarget(); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - int GetRenderTarget([Out] out IntPtr pSurface); - - int SetDepthStencilSurface(); - - int GetDepthStencilSurface(); - - int BeginScene(); - - int EndScene(); - - int Clear(); - - int SetTransform(); - - int GetTransform(); - - int MultiplyTransform(); - - int SetViewport(); - - int GetViewport(); - - int SetMaterial(); - - int GetMaterial(); - - int SetLight(); - - int GetLight(); - - int LightEnable(); - - int GetLightEnable(); - - int SetClipPlane(); - - int GetClipPlane(); - - int SetRenderState(); - - int GetRenderState(); - - int CreateStateBlock(); - - int BeginStateBlock(); - - int EndStateBlock(); - - int SetClipStatus(); - - int GetClipStatus(); - - int GetTexture(); - - int SetTexture(); - - int GetTextureStageState(); - - int SetTextureStageState(); - - int GetSamplerState(); - - int SetSamplerState(); - - int ValidateDevice(); - - int SetPaletteEntries(); - - int GetPaletteEntries(); - - int SetCurrentTexturePalette(); - - int GetCurrentTexturePalette(); - - int SetScissorRect(); - - int GetScissorRect(); - - int SetSoftwareVertexProcessing(bool bSoftware); - - bool GetSoftwareVertexProcessing(); - - int SetNPatchMode(float nSegments); - - float GetNPatchMode(); - - int DrawPrimitive(); - - int DrawIndexedPrimitive(); - - int DrawPrimitiveUP(); - - int DrawIndexedPrimitiveUP(); - - int ProcessVertices(); - - int CreateVertexDeclaration(); - - int SetVertexDeclaration(); - - int GetVertexDeclaration(); - - int SetFVF(); - - int GetFVF(); - - int CreateVertexShader(); - - int SetVertexShader(); - - int GetVertexShader(); - - int SetVertexShaderConstantF(); - - int GetVertexShaderConstantF(); - - int SetVertexShaderConstantI(); - - int GetVertexShaderConstantI(); - - int SetVertexShaderConstantB(); - - int GetVertexShaderConstantB(); - - int SetStreamSource(); - - int GetStreamSource(); - - int SetStreamSourceFreq(); - - int GetStreamSourceFreq(); - - int SetIndices(); - - int GetIndices(); - - int CreatePixelShader(); - - int SetPixelShader(); - - int GetPixelShader(); - - int SetPixelShaderConstantF(); - - int GetPixelShaderConstantF(); - - int SetPixelShaderConstantI(); - - int GetPixelShaderConstantI(); - - int SetPixelShaderConstantB(); - - int GetPixelShaderConstantB(); - - int DrawRectPatch(); - - int DrawTriPatch(); - - int DeletePatch(uint Handle); - - int CreateQuery(); -} - -[ComImport, Guid("B18B10CE-2649-405a-870F-95F777D4313A"), - InterfaceType(ComInterfaceType.InterfaceIsIUnknown), SuppressUnmanagedCodeSecurity] -public interface IDirect3DDevice9Ex : IDirect3DDevice9 -{ - [PreserveSig, SuppressUnmanagedCodeSecurity] - new int TestCooperativeLevel(); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - new int GetAvailableTextureMem(); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - new int EvictManagedResources(); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - new int GetDirect3D([Out] out IDirect3D9 ppD3D9); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - new int GetDeviceCaps([In, Out] ref D3DCAPS9 pCaps); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - new int GetDisplayMode(uint iSwapChain, D3DDISPLAYMODE pMode); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - new int GetCreationParameters([In, Out] ref D3DDEVICE_CREATION_PARAMETERS pParameters); - - new int SetCursorProperties(); - - new int SetCursorPosition(); - - new int ShowCursor(bool bShow); - - new int CreateAdditionalSwapChain(); - - new int GetSwapChain(); - - new int GetNumberOfSwapChains(); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - new int Reset([In, Out] ref D3DPRESENT_PARAMETERS pPresentationParameters); - - new int Present(); - - new int GetBackBuffer(); - - new int GetRasterStatus(); - - new int SetDialogBoxMode(); - - new int SetGammaRamp(); - - new int GetGammaRamp(); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - new int CreateTexture(int Width, int Height, int Levels, int Usage, D3DFORMAT Format, int Pool, - out IDirect3DTexture9 ppTexture, IntPtr pSharedHandle); - - new int CreateVolumeTexture(); - - new int CreateCubeTexture(); - - new int CreateVertexBuffer(); - - new int CreateIndexBuffer(); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - new int CreateRenderTarget(int width, int height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, - uint MultisampleQuality, [MarshalAs(UnmanagedType.Bool)] bool Lockable, [Out] out IntPtr pSurface, - IntPtr pSharedSurface); - - new int CreateDepthStencilSurface(); - - new int UpdateSurface(); - - new int UpdateTexture(); - - new int GetRenderTargetData(); - - new int GetFrontBufferData(); - - new int StretchRect(IntPtr pSourceSurface, DsRect pSourceRect, IDirect3DSurface9 pDestSurface, DsRect pDestRect, int Filter); - - new int ColorFill(); - - new int CreateOffscreenPlainSurface(); - - new int SetRenderTarget(); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - new int GetRenderTarget([Out] out IntPtr pSurface); - - new int SetDepthStencilSurface(); - - new int GetDepthStencilSurface(); - - new int BeginScene(); - - new int EndScene(); - - new int Clear(); - - new int SetTransform(); - - new int GetTransform(); - - new int MultiplyTransform(); - - new int SetViewport(); - - new int GetViewport(); - - new int SetMaterial(); - - new int GetMaterial(); - - new int SetLight(); - - new int GetLight(); - - new int LightEnable(); - - new int GetLightEnable(); - - new int SetClipPlane(); - - new int GetClipPlane(); - - new int SetRenderState(); - - new int GetRenderState(); - - new int CreateStateBlock(); - - new int BeginStateBlock(); - - new int EndStateBlock(); - - new int SetClipStatus(); - - new int GetClipStatus(); - - new int GetTexture(); - - new int SetTexture(); - - new int GetTextureStageState(); - - new int SetTextureStageState(); - - new int GetSamplerState(); - - new int SetSamplerState(); - - new int ValidateDevice(); - - new int SetPaletteEntries(); - - new int GetPaletteEntries(); - - new int SetCurrentTexturePalette(); - - new int GetCurrentTexturePalette(); - - new int SetScissorRect(); - - new int GetScissorRect(); - - new int SetSoftwareVertexProcessing(bool bSoftware); - - new bool GetSoftwareVertexProcessing(); - - new int SetNPatchMode(float nSegments); - - new float GetNPatchMode(); - - new int DrawPrimitive(); - - new int DrawIndexedPrimitive(); - - new int DrawPrimitiveUP(); - - new int DrawIndexedPrimitiveUP(); - - new int ProcessVertices(); - - new int CreateVertexDeclaration(); - - new int SetVertexDeclaration(); - - new int GetVertexDeclaration(); - - new int SetFVF(); - - new int GetFVF(); - - new int CreateVertexShader(); - - new int SetVertexShader(); - - new int GetVertexShader(); - - new int SetVertexShaderConstantF(); - - new int GetVertexShaderConstantF(); - - new int SetVertexShaderConstantI(); - - new int GetVertexShaderConstantI(); - - new int SetVertexShaderConstantB(); - - new int GetVertexShaderConstantB(); - - new int SetStreamSource(); - - new int GetStreamSource(); - - new int SetStreamSourceFreq(); - - new int GetStreamSourceFreq(); - - new int SetIndices(); - - new int GetIndices(); - - new int CreatePixelShader(); - - new int SetPixelShader(); - - new int GetPixelShader(); - - new int SetPixelShaderConstantF(); - - new int GetPixelShaderConstantF(); - - new int SetPixelShaderConstantI(); - - new int GetPixelShaderConstantI(); - - new int SetPixelShaderConstantB(); - - new int GetPixelShaderConstantB(); - - new int DrawRectPatch(); - - new int DrawTriPatch(); - - new int DeletePatch(uint Handle); - - new int CreateQuery(); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - int SetConvolutionMonoKernel(int width, int height, IntPtr rows, IntPtr columns); - - int ComposeRects(); - - int PresentEx(); - - int GetGPUThreadPriority(); - - int SetGPUThreadPriority(); - - int WaitForVBlank(); - - int CheckResourceResidency(); - - int SetMaximumFrameLatency(); - - int GetMaximumFrameLatency(); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - int CheckDeviceState(IntPtr hWnd); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - int CreateRenderTargetEx(int width, int height, D3DFORMAT Format, D3DMULTISAMPLE_TYPE MultiSample, - uint MultisampleQuality, [MarshalAs(UnmanagedType.Bool)] bool Lockable, [Out] out IntPtr pSurface, - [In, Out] ref IntPtr pSharedSurface, uint Usage); - - /* - STDMETHOD(SetConvolutionMonoKernel)(THIS_ UINT width,UINT height,float* rows,float* columns) PURE; -STDMETHOD(ComposeRects)(THIS_ IDirect3DSurface9* pSrc,IDirect3DSurface9* pDst,IDirect3DVertexBuffer9* pSrcRectDescs,UINT NumRects,IDirect3DVertexBuffer9* pDstRectDescs,D3DCOMPOSERECTSOP Operation,int Xoffset,int Yoffset) PURE; -STDMETHOD(PresentEx)(THIS_ CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion,DWORD dwFlags) PURE; -STDMETHOD(GetGPUThreadPriority)(THIS_ INT* pPriority) PURE; -STDMETHOD(SetGPUThreadPriority)(THIS_ INT Priority) PURE; -STDMETHOD(WaitForVBlank)(THIS_ UINT iSwapChain) PURE; -STDMETHOD(CheckResourceResidency)(THIS_ IDirect3DResource9** pResourceArray,UINT32 NumResources) PURE; -STDMETHOD(SetMaximumFrameLatency)(THIS_ UINT MaxLatency) PURE; -STDMETHOD(GetMaximumFrameLatency)(THIS_ UINT* pMaxLatency) PURE; -STDMETHOD(CheckDeviceState)(THIS_ HWND hDestinationWindow) PURE; -STDMETHOD(CreateRenderTargetEx)(THIS_ UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,DWORD MultisampleQuality,BOOL Lockable,IDirect3DSurface9** ppSurface,HANDLE* pSharedHandle,DWORD Usage) PURE; -STDMETHOD(CreateOffscreenPlainSurfaceEx)(THIS_ UINT Width,UINT Height,D3DFORMAT Format,D3DPOOL Pool,IDirect3DSurface9** ppSurface,HANDLE* pSharedHandle,DWORD Usage) PURE; -STDMETHOD(CreateDepthStencilSurfaceEx)(THIS_ UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,DWORD MultisampleQuality,BOOL Discard,IDirect3DSurface9** ppSurface,HANDLE* pSharedHandle,DWORD Usage) PURE; -STDMETHOD(ResetEx)(THIS_ D3DPRESENT_PARAMETERS* pPresentationParameters,D3DDISPLAYMODEEX *pFullscreenDisplayMode) PURE; -STDMETHOD(GetDisplayModeEx)(THIS_ UINT iSwapChain,D3DDISPLAYMODEEX* pMode,D3DDISPLAYROTATION* pRotation) PURE; - */ -} - -[ComImport, SuppressUnmanagedCodeSecurity, -Guid("0CFBAF3A-9FF6-429a-99B3-A2796AF8B89B"), -InterfaceType(ComInterfaceType.InterfaceIsIUnknown), SuppressUnmanagedCodeSecurity] -public interface IDirect3DSurface9 -{ - [PreserveSig, SuppressUnmanagedCodeSecurity] - void GetDevice(out IDirect3DDevice9 ppDevice); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - void SetPrivateData(Guid refguid, IntPtr pData, int SizeOfData, int Flags); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - void GetPrivateData(Guid refguid, IntPtr pData, out int pSizeOfData); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - void FreePrivateData(Guid refguid); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - int SetPriority(int PriorityNew); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - int GetPriority(); - - void PreLoad(); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - D3DRESOURCETYPE GetType(); - - void GetContainer(Guid riid, out object ppContainer); - - void GetDesc(out D3DSURFACE_DESC pDesc); - - void LockRect(D3DLOCKED_RECT pLockedRect, Rectangle pRect, int Flags); - - void UnlockRect(); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - int GetDC(out IntPtr phdc); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - int ReleaseDC(IntPtr hdc); -} - -public enum D3DRESOURCETYPE -{ - D3DRTYPE_SURFACE = 1, - D3DRTYPE_VOLUME = 2, - D3DRTYPE_TEXTURE = 3, - D3DRTYPE_VOLUMETEXTURE = 4, - D3DRTYPE_CUBETEXTURE = 5, - D3DRTYPE_VERTEXBUFFER = 6, - D3DRTYPE_INDEXBUFFER = 7, //if this changes, change _D3DDEVINFO_RESOURCEMANAGER definition - - D3DRTYPE_FORCE_DWORD = 0x7fffffff -} - -[StructLayout(LayoutKind.Sequential)] -public struct D3DLOCKED_RECT -{ -} - -[StructLayout(LayoutKind.Sequential)] -public struct D3DSURFACE_DESC -{ -} - -[StructLayout(LayoutKind.Sequential)] -public struct D3DDEVICE_CREATION_PARAMETERS -{ - private uint AdapterOrdinal; - private D3DDEVTYPE DeviceType; - private IntPtr hFocusWindow; - private int BehaviorFlags; -} - -[StructLayout(LayoutKind.Sequential)] -public struct D3DCAPS9 -{ - /* Device Info */ - public D3DDEVTYPE DeviceType; - public uint AdapterOrdinal; - - /* Caps from DX7 Draw */ - public int Caps; - public int Caps2; - public int Caps3; - public int PresentationIntervals; - - /* Cursor Caps */ - public int CursorCaps; - - /* 3D Device Caps */ - public int DevCaps; - - public int PrimitiveMiscCaps; - public int RasterCaps; - public int ZCmpCaps; - public int SrcBlendCaps; - public int DestBlendCaps; - public int AlphaCmpCaps; - public int ShadeCaps; - public int TextureCaps; - public int TextureFilterCaps; // D3DPTFILTERCAPS for IDirect3DTexture9's - public int CubeTextureFilterCaps; // D3DPTFILTERCAPS for IDirect3DCubeTexture9's - public int VolumeTextureFilterCaps; // D3DPTFILTERCAPS for IDirect3DVolumeTexture9's - public int TextureAddressCaps; // D3DPTADDRESSCAPS for IDirect3DTexture9's - public int VolumeTextureAddressCaps; // D3DPTADDRESSCAPS for IDirect3DVolumeTexture9's - - public int LineCaps; // D3DLINECAPS - - public int MaxTextureWidth, MaxTextureHeight; - public int MaxVolumeExtent; - - public int MaxTextureRepeat; - public int MaxTextureAspectRatio; - public int MaxAnisotropy; - private float MaxVertexW; - - private float GuardBandLeft; - private float GuardBandTop; - private float GuardBandRight; - private float GuardBandBottom; - - private float ExtentsAdjust; - public int StencilCaps; - - public int FVFCaps; - public int TextureOpCaps; - public int MaxTextureBlendStages; - public int MaxSimultaneousTextures; - - public int VertexProcessingCaps; - public int MaxActiveLights; - public int MaxUserClipPlanes; - public int MaxVertexBlendMatrices; - public int MaxVertexBlendMatrixIndex; - - private float MaxPointSize; - - public int MaxPrimitiveCount; // max number of primitives per DrawPrimitive call - public int MaxVertexIndex; - public int MaxStreams; - public int MaxStreamStride; // max stride for SetStreamSource - - public int VertexShaderVersion; - public int MaxVertexShaderConst; // number of vertex shader constant registers - - public int PixelShaderVersion; - private float PixelShader1xMaxValue; // max value storable in registers of ps.1.x shaders - - // Here are the DX9 specific ones - public int DevCaps2; - - private float MaxNpatchTessellationLevel; - public int Reserved5; - - public uint MasterAdapterOrdinal; // ordinal of master adaptor for adapter group - public uint AdapterOrdinalInGroup; // ordinal inside the adapter group - public uint NumberOfAdaptersInGroup; // number of adapters in this adapter group (only if master) - public int DeclTypes; // Data types, supported in vertex declarations - public int NumSimultaneousRTs; // Will be at least 1 - public int StretchRectFilterCaps; // Filter caps supported by StretchRect - private D3DVSHADERCAPS2_0 VS20Caps; - private D3DPSHADERCAPS2_0 PS20Caps; - public int VertexTextureFilterCaps; // D3DPTFILTERCAPS for IDirect3DTexture9's for texture, used in vertex shaders - public int MaxVShaderInstructionsExecuted; // maximum number of vertex shader instructions that can be executed - public int MaxPShaderInstructionsExecuted; // maximum number of pixel shader instructions that can be executed - public int MaxVertexShader30InstructionSlots; - public int MaxPixelShader30InstructionSlots; -} - -[StructLayout(LayoutKind.Sequential)] -public struct D3DVSHADERCAPS2_0 -{ - private int Caps; - private int DynamicFlowControlDepth; - private int NumTemps; - private int StaticFlowControlDepth; -} - -[StructLayout(LayoutKind.Sequential)] -public struct D3DPSHADERCAPS2_0 -{ - private int Caps; - private int DynamicFlowControlDepth; - private int NumTemps; - private int StaticFlowControlDepth; - private int NumInstructionSlots; -} - -public enum D3DSCANLINEORDERING -{ - D3DSCANLINEORDERING_UNKNOWN = 0, - D3DSCANLINEORDERING_PROGRESSIVE = 1, - D3DSCANLINEORDERING_INTERLACED = 2, -} - -[StructLayout(LayoutKind.Sequential)] -public struct D3DDISPLAYMODEEX -{ - public uint Size; - public uint Width; - public uint Height; - public uint RefreshRate; - public D3DFORMAT Format; - public D3DSCANLINEORDERING ScanLineOrdering; -} - -[ComImport, SuppressUnmanagedCodeSecurity, -Guid("85C31227-3DE5-4f00-9B3A-F11AC38C18B5"), -InterfaceType(ComInterfaceType.InterfaceIsIUnknown), SuppressUnmanagedCodeSecurity] -public interface IDirect3DTexture9 -{ - [PreserveSig, SuppressUnmanagedCodeSecurity] - void GetDevice(); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - void SetPrivateData(Guid refguid, IntPtr pData, int SizeOfData, int Flags); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - void GetPrivateData(Guid refguid, IntPtr pData, IntPtr pSizeOfData); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - void FreePrivateData(Guid refguid); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - void SetPriority(int PriorityNew); - - void GetPriority(); - - void PreLoad(); - - void GetType(); - - void SetLOD(int LODNew); - - void GetLOD(); - - void GetLevelCount(); - - void SetAutoGenFilterType(int FilterType); - - int GetAutoGenFilterType(); - - void GenerateMipSubLevels(); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - void GetLevelDesc(int Level, IntPtr pDesc); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - int GetSurfaceLevel(int Level, out IDirect3DSurface9 ppSurfaceLevel); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - void LockRect(int Level, ref D3DLOCKED_RECT pLockedRect, RECT pRect, int Flags); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - void UnlockRect(int Level); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - void AddDirtyRect(RECT pDirtyRect); -} - -[ComImport, SuppressUnmanagedCodeSecurity, -Guid("02177241-69FC-400C-8FF1-93A44DF6861D"), -InterfaceType(ComInterfaceType.InterfaceIsIUnknown), SuppressUnmanagedCodeSecurity] -public interface IDirect3D9Ex : IDirect3D9 -{ - [PreserveSig, SuppressUnmanagedCodeSecurity] - new int RegisterSoftwareDevice([In, Out] IntPtr pInitializeFunction); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - new int GetAdapterCount(); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - new int GetAdapterIdentifier(uint Adapter, uint Flags, uint pIdentifier); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - new uint GetAdapterModeCount(uint Adapter, D3DFORMAT Format); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - new int EnumAdapterModes(uint Adapter, D3DFORMAT Format, uint Mode, [Out] out D3DDISPLAYMODE pMode); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - new int GetAdapterDisplayMode(ushort Adapter, [Out] out D3DFORMAT Format); - - #region Method Placeholders - - [PreserveSig] - new int CheckDeviceType(); - - [PreserveSig] - new int CheckDeviceFormat(); - - [PreserveSig] - new int CheckDeviceMultiSampleType(); - - [PreserveSig] - new int CheckDepthStencilMatch(); - - [PreserveSig] - new int CheckDeviceFormatConversion(); - - [PreserveSig] - new int GetDeviceCaps(); - - #endregion Method Placeholders - - [PreserveSig, SuppressUnmanagedCodeSecurity] - new IntPtr GetAdapterMonitor(uint Adapter); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - new int CreateDevice(int Adapter, - D3DDEVTYPE DeviceType, - IntPtr hFocusWindow, - CreateFlags BehaviorFlags, - [In, Out] - ref D3DPRESENT_PARAMETERS pPresentationParameters, - [Out] out IntPtr ppReturnedDeviceInterface); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - uint GetAdapterModeCountEx(); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - int EnumAdapterModesEx(); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - int GetAdapterDisplayModeEx(); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - int CreateDeviceEx(int Adapter, - D3DDEVTYPE DeviceType, - IntPtr hFocusWindow, - CreateFlags BehaviorFlags, - [In, Out] - ref D3DPRESENT_PARAMETERS pPresentationParameters, - [In, Out] - IntPtr pFullscreenDisplayMode, - [Out] out IntPtr ppReturnedDeviceInterface); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - int GetAdapterLUID(); -} - -[ComImport, SuppressUnmanagedCodeSecurity, -Guid("81BDCBCA-64D4-426d-AE8D-AD0147F4275C"), -InterfaceType(ComInterfaceType.InterfaceIsIUnknown), SuppressUnmanagedCodeSecurity] -public interface IDirect3D9 -{ - [PreserveSig, SuppressUnmanagedCodeSecurity] - int RegisterSoftwareDevice([In, Out] IntPtr pInitializeFunction); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - int GetAdapterCount(); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - int GetAdapterIdentifier(uint Adapter, uint Flags, uint pIdentifier); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - uint GetAdapterModeCount(uint Adapter, D3DFORMAT Format); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - int EnumAdapterModes(uint Adapter, D3DFORMAT Format, uint Mode, [Out] out D3DDISPLAYMODE pMode); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - int GetAdapterDisplayMode(ushort Adapter, [Out] out D3DFORMAT Format); - - #region Method Placeholders - - [PreserveSig] - int CheckDeviceType(); - - [PreserveSig] - int CheckDeviceFormat(); - - [PreserveSig] - int CheckDeviceMultiSampleType(); - - [PreserveSig] - int CheckDepthStencilMatch(); - - [PreserveSig] - int CheckDeviceFormatConversion(); - - [PreserveSig] - int GetDeviceCaps(); - - #endregion Method Placeholders - - [PreserveSig, SuppressUnmanagedCodeSecurity] - IntPtr GetAdapterMonitor(uint Adapter); - - [PreserveSig, SuppressUnmanagedCodeSecurity] - int CreateDevice(int Adapter, - D3DDEVTYPE DeviceType, - IntPtr hFocusWindow, - CreateFlags BehaviorFlags, - [In, Out] - ref D3DPRESENT_PARAMETERS pPresentationParameters, - [Out] out IntPtr ppReturnedDeviceInterface); -} - -[StructLayout(LayoutKind.Sequential)] -public struct D3DDISPLAYMODE -{ - public uint Width; - public uint Height; - public uint RefreshRate; - public D3DFORMAT Format; -} - -[Flags] -public enum CreateFlags -{ - D3DCREATE_FPU_PRESERVE = 0x00000002, - D3DCREATE_MULTITHREADED = 0x00000004, - D3DCREATE_PUREDEVICE = 0x00000010, - D3DCREATE_SOFTWARE_VERTEXPROCESSING = 0x00000020, - D3DCREATE_HARDWARE_VERTEXPROCESSING = 0x00000040, - D3DCREATE_MIXED_VERTEXPROCESSING = 0x00000080, - D3DCREATE_DISABLE_DRIVER_MANAGEMENT = 0x00000100, - D3DCREATE_ADAPTERGROUP_DEVICE = 0x00000200, - D3DCREATE_DISABLE_DRIVER_MANAGEMENT_EX = 0x00000400 -} - -[Flags] -public enum D3DDEVTYPE -{ - D3DDEVTYPE_HAL = 1, - D3DDEVTYPE_REF = 2, - D3DDEVTYPE_SW = 3, - D3DDEVTYPE_NULLREF = 4, -} - -[Flags] -public enum D3DFORMAT -{ - D3DFMT_UNKNOWN = 0, - D3DFMT_R8G8B8 = 20, - D3DFMT_A8R8G8B8 = 21, - D3DFMT_X8R8G8B8 = 22, - D3DFMT_R5G6B5 = 23, - D3DFMT_X1R5G5B5 = 24, - D3DFMT_A1R5G5B5 = 25, - D3DFMT_A4R4G4B4 = 26, - D3DFMT_R3G3B2 = 27, - D3DFMT_A8 = 28, - D3DFMT_A8R3G3B2 = 29, - D3DFMT_X4R4G4B4 = 30, - D3DFMT_A2B10G10R10 = 31, - D3DFMT_A8B8G8R8 = 32, - D3DFMT_X8B8G8R8 = 33, - D3DFMT_G16R16 = 34, - D3DFMT_A2R10G10B10 = 35, - D3DFMT_A16B16G16R16 = 36, - D3DFMT_A8P8 = 40, - D3DFMT_P8 = 41, - D3DFMT_L8 = 50, - D3DFMT_A8L8 = 51, - D3DFMT_A4L4 = 52, - D3DFMT_V8U8 = 60, - D3DFMT_L6V5U5 = 61, - D3DFMT_X8L8V8U8 = 62, - D3DFMT_Q8W8V8U8 = 63, - D3DFMT_V16U16 = 64, - D3DFMT_A2W10V10U10 = 67, - D3DFMT_D16_LOCKABLE = 70, - D3DFMT_D32 = 71, - D3DFMT_D15S1 = 73, - D3DFMT_D24S8 = 75, - D3DFMT_D24X8 = 77, - D3DFMT_D24X4S4 = 79, - D3DFMT_D16 = 80, - D3DFMT_D32F_LOCKABLE = 82, - D3DFMT_D24FS8 = 83, - /* Z-Stencil formats valid for CPU access */ - D3DFMT_D32_LOCKABLE = 84, - D3DFMT_S8_LOCKABLE = 85, - D3DFMT_L16 = 81, - D3DFMT_VERTEXDATA = 100, - D3DFMT_INDEX16 = 101, - D3DFMT_INDEX32 = 102, - D3DFMT_Q16W16V16U16 = 110, - - // Floating point surface formats - // s10e5 formats (16-bits per channel) - D3DFMT_R16F = 111, - - D3DFMT_G16R16F = 112, - D3DFMT_A16B16G16R16F = 113, - - // IEEE s23e8 formats (32-bits per channel) - D3DFMT_R32F = 114, - - D3DFMT_G32R32F = 115, - D3DFMT_A32B32G32R32F = 116, - D3DFMT_CxV8U8 = 117, - - // Monochrome 1 bit per pixel format - D3DFMT_A1 = 118, - - // Binary format indicating that the data has no inherent type - D3DFMT_BINARYBUFFER = 199, -} - -[Flags] -public enum D3DSWAPEFFECT -{ - D3DSWAPEFFECT_DISCARD = 1, - D3DSWAPEFFECT_FLIP = 2, - D3DSWAPEFFECT_COPY = 3, -} - -[Flags] -public enum D3DMULTISAMPLE_TYPE -{ - D3DMULTISAMPLE_NONE = 0, - D3DMULTISAMPLE_NONMASKABLE = 1, - D3DMULTISAMPLE_2_SAMPLES = 2, - D3DMULTISAMPLE_3_SAMPLES = 3, - D3DMULTISAMPLE_4_SAMPLES = 4, - D3DMULTISAMPLE_5_SAMPLES = 5, - D3DMULTISAMPLE_6_SAMPLES = 6, - D3DMULTISAMPLE_7_SAMPLES = 7, - D3DMULTISAMPLE_8_SAMPLES = 8, - D3DMULTISAMPLE_9_SAMPLES = 9, - D3DMULTISAMPLE_10_SAMPLES = 10, - D3DMULTISAMPLE_11_SAMPLES = 11, - D3DMULTISAMPLE_12_SAMPLES = 12, - D3DMULTISAMPLE_13_SAMPLES = 13, - D3DMULTISAMPLE_14_SAMPLES = 14, - D3DMULTISAMPLE_15_SAMPLES = 15, - D3DMULTISAMPLE_16_SAMPLES = 16, -} - -[Flags] -public enum D3DPRESENTFLAG -{ - D3DPRESENTFLAG_LOCKABLE_BACKBUFFER = 0x00000001, - D3DPRESENTFLAG_DISCARD_DEPTHSTENCIL = 0x00000002, - D3DPRESENTFLAG_DEVICECLIP = 0x00000004, - D3DPRESENTFLAG_VIDEO = 0x00000010 -} - -[StructLayout(LayoutKind.Sequential)] -public struct D3DPRESENT_PARAMETERS -{ - public uint BackBufferWidth; - public uint BackBufferHeight; - public D3DFORMAT BackBufferFormat; - public uint BackBufferCount; - public D3DMULTISAMPLE_TYPE MultiSampleType; - public int MultiSampleQuality; - public D3DSWAPEFFECT SwapEffect; - public IntPtr hDeviceWindow; - public int Windowed; - public int EnableAutoDepthStencil; - public D3DFORMAT AutoDepthStencilFormat; - public int Flags; - /* FullScreen_RefreshRateInHz must be zero for Windowed mode */ - public uint FullScreen_RefreshRateInHz; - public uint PresentationInterval; -} - -public class Direct3D -{ - [DllImport("d3d9.dll", EntryPoint = "Direct3DCreate9", CallingConvention = CallingConvention.StdCall), - SuppressUnmanagedCodeSecurity] - [return: MarshalAs(UnmanagedType.Interface)] - public static extern IDirect3D9 Direct3DCreate9(ushort SDKVersion); - - [DllImport("d3d9.dll", EntryPoint = "Direct3DCreate9Ex", CallingConvention = CallingConvention.StdCall), - SuppressUnmanagedCodeSecurity] - public static extern int Direct3DCreate9Ex(ushort SDKVersion, [Out] out IDirect3D9Ex ex); -} diff --git a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/Effects/DeeperColor.cs b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/Effects/DeeperColor.cs deleted file mode 100644 index 2257d25..0000000 --- a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/Effects/DeeperColor.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System; -using System.Reflection; -using System.Windows; -using System.Windows.Media; -using System.Windows.Media.Effects; - -namespace WPFMediaKit.Effects; - -/// -/// This is a WPF pixel shader effect that will scale 16-235 HD-TV pixel output to -/// 0-255 pixel values for deeper color on video. -/// -public class DeeperColorEffect : ShaderEffect -{ - private static string m_assemblyShortName; - - public static DependencyProperty InputProperty = RegisterPixelShaderSamplerProperty("Input", typeof(DeeperColorEffect), 0); - - public DeeperColorEffect() - { - var u = new Uri(@"pack://application:,,,/" + AssemblyShortName + ";component/Effects/DeeperColor.ps"); - PixelShader = new PixelShader { UriSource = u }; - UpdateShaderValue(InputProperty); - } - - private static string AssemblyShortName - { - get - { - if (m_assemblyShortName == null) - { - Assembly a = typeof(DeeperColorEffect).Assembly; - m_assemblyShortName = a.ToString().Split(',')[0]; - } - - return m_assemblyShortName; - } - } - - public Brush Input - { - get - { - return ((Brush)(GetValue(InputProperty))); - } - set - { - SetValue(InputProperty, value); - } - } -} diff --git a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/Effects/DeeperColor.fx b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/Effects/DeeperColor.fx deleted file mode 100644 index 0abde77..0000000 --- a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/Effects/DeeperColor.fx +++ /dev/null @@ -1,9 +0,0 @@ -sampler2D implicitInputSampler : register(s0); - -#define const1 (16.0/255.0) -#define const2 (255.0/219.0) - -float4 main(float2 tex : TEXCOORD0) : COLOR -{ - return((tex2D( implicitInputSampler, tex ) - const1 ) * const2); -} \ No newline at end of file diff --git a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/Effects/DeeperColor.ps b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/Effects/DeeperColor.ps deleted file mode 100644 index 35dc511..0000000 Binary files a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/Effects/DeeperColor.ps and /dev/null differ diff --git a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/ILog.cs b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/ILog.cs deleted file mode 100644 index 65ffde7..0000000 --- a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/ILog.cs +++ /dev/null @@ -1,135 +0,0 @@ -using System; -using System.Diagnostics; - -namespace WPFMediaKit; - -/// -/// A logger. -/// -public interface ILog -{ - /// - /// If the info level is enabled. - /// - bool IsInfoEnabled { get; } - - /// - /// If the debug level is enabled. - /// - bool IsDebugEnabled { get; } - - /// - /// Logs the error message with a possible exception. - /// - /// The exception. May be null. - /// A (formatted) message. - /// Arguments to the formatted message. May be missing. - void Error(Exception exception, string message, params object[] args); - - /// - /// Logs the warning message. - /// - /// A (formatted) message. - /// Arguments to the formatted message. May be missing. - void Warn(string message, params object[] args); - - /// - /// Logs the info message. - /// - /// A (formatted) message. - /// Arguments to the formatted message. May be missing. - void Info(string message, params object[] args); - - /// - /// Logs the debug message. - /// - /// A (formatted) message. - /// Arguments to the formatted message. May be missing. - void Debug(string message, params object[] args); -} - -public static class ILogExtensions -{ - /// - /// Log the error without an exception. - /// - public static void Error(this ILog thiz, string message, params object[] args) - => thiz.Error(null, message, args); -} - -/// -/// Logging to . -/// -public class DebugTraceLog : ILog -{ - private string _name; - - public DebugTraceLog(string name) - { - _name = name; - } - - public virtual bool IsInfoEnabled => true; - - public virtual bool IsDebugEnabled => true; - - public virtual void Error(Exception exception, string message, params object[] args) - { - Trace.TraceError(AddName(message), args); - if (exception != null) - Trace.TraceError(exception.ToString()); - } - - public virtual void Warn(string message, params object[] args) - { - Trace.TraceWarning(AddName(message), args); - } - - public virtual void Info(string message, params object[] args) - { - if (!IsInfoEnabled) - return; - Trace.TraceInformation(AddName(message), args); - } - - public virtual void Debug(string message, params object[] args) - { - if (!IsDebugEnabled) - return; - Trace.WriteLine(string.Format(AddName(message), args)); - } - - protected virtual string AddName(string message) - { - if (string.IsNullOrEmpty(_name)) - return message; - return _name + " - " + message; - } -} - -/// -/// No-op implementation of ILog. -/// -public class NullLog : ILog -{ - private static NullLog _instance; - - public static NullLog Instance - => _instance != null ? _instance : (_instance = new NullLog()); - - public bool IsInfoEnabled => false; - - public virtual bool IsDebugEnabled => false; - - public void Error(Exception exception, string message, params object[] args) - { } - - public void Info(string message, params object[] args) - { } - - public void Debug(string message, params object[] args) - { } - - public void Warn(string message, params object[] args) - { } -} diff --git a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/LogManager.cs b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/LogManager.cs deleted file mode 100644 index 8862846..0000000 --- a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/LogManager.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; - -namespace WPFMediaKit; - -/// -/// Log manager for the WPF-MediaKit. Set to change the logging. -/// -public static class LogManager -{ - /// - /// Main func to get an for the provided logger name. Default is set to . - /// - /// May be changed by the user code. Set to to switch off the logging. - /// - /// - public static Func LoggerFunc = name => new DebugTraceLog(name); - - /// - /// Returns an for the provided logger name. - /// - public static ILog GetLogger(string name) - => LoggerFunc(name); - - /// - /// Retuns an for the provided logger name. - /// - public static ILog GetLogger(Type type) - => LoggerFunc(type.FullName); -} diff --git a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/MediaFoundation/COMUtils.cs b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/MediaFoundation/COMUtils.cs deleted file mode 100644 index 3eae39c..0000000 --- a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/MediaFoundation/COMUtils.cs +++ /dev/null @@ -1,279 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.IO; -using System.Reflection; -using System.Runtime.InteropServices; -using System.Security; -using System.Security.Permissions; - -namespace WPFMediaKit.MediaFoundation; - -public class COMUtil -{ - /// - /// Check if a COM Object is available - /// - /// The CLSID of this object - /// true if the object is available, false if not - [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)] - public static bool IsObjectInstalled(Guid clsid) - { - object comobj = null; - try - { - Type type = Type.GetTypeFromCLSID(clsid); - comobj = Activator.CreateInstance(type); - return comobj != null; - } - catch (Exception) - { - return false; - } - finally { SafeRelease(comobj); } - } - - /// - /// Release a ComObject - /// - /// - /// ref counter of the object - public static int SafeRelease(object obj) - { - return (obj != null && Marshal.IsComObject(obj)) ? Marshal.ReleaseComObject(obj) : 0; - } - - /// - /// Try (final) release a Com-Object and set the obj to null - /// - /// - /// - /// true if object is released (not null and a com object) - public static bool TryFinalRelease(ref I comobj) - { - if (comobj != null) - { - if (Marshal.IsComObject(comobj)) - while (Marshal.ReleaseComObject(comobj) > 0) ; - - comobj = default(I); - return true; - } - return false; - } - - //********* - //Beispiel - //********* - // Guid vom filter - // Guid mpaguid = new Guid("3D446B6F-71DE-4437-BE15-8CE47174340F"); - // falls nötig, den pfad zur *.ax bzw. dll datei - // IBaseFilter baseFilter = CreateFromDll("MpaDecFilter.ax", mpaguid); - // graphBuilder.AddFilter(baseFilter, "MPEG1 Audio Decoder"); - - #region Create COM-Object from file - - /// Function to get a COM object from file (dll) - /// a (unmanaged) dll-file where the COM object is implemented - /// objects Guid - /// a interface or null if not loaded - /// Thrown if the method can't creat COM-object - /// Thrown if the dll not found - /// - [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)] - public static T CreateFromDll(string dllName, Guid mpaguid) - { - if (String.IsNullOrEmpty(dllName)) - throw new ArgumentNullException("dllName"); - - //Get a classFactory for our classID - IClassFactory classFactory = ComHelper.GetClassFactory(dllName, mpaguid); - if (classFactory == null) - throw new COMException(String.Format("Can't create ClassFactory from '{0}", dllName)); - - //And create an object-instance using that class factory - Guid iGUID = typeof(T).GUID; - Object obj; - - try - { - Marshal.ThrowExceptionForHR(classFactory.CreateInstance(null, ref iGUID, out obj)); - return (T)obj; - } - finally { Marshal.ReleaseComObject(classFactory); } - } - - #endregion Create COM-Object from file - - #region IClassFactory Interface - - [ComVisible(true), ComImport, SuppressUnmanagedCodeSecurity, - Guid("00000001-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] - public interface IClassFactory - { - [PreserveSig] - int CreateInstance([In, MarshalAs(UnmanagedType.IUnknown)] object pUnkOuter, - [In] ref Guid riid, - [Out, MarshalAs(UnmanagedType.Interface)] out object obj); - - [PreserveSig] - int LockServer([In] bool fLock); - } - - #endregion IClassFactory Interface - - #region ComHelper class Load Com-Objects from file - - /// - /// Utility class to get a Class Factory for a certain Class ID - /// by loading the dll that implements that class - /// - public static class ComHelper - { - private static DLLLoader loader = new DLLLoader(); - - /// - /// Gets a class factory for a specific COM Class ID. - /// - /// The dll where the COM class is implemented - /// The requested Class ID - /// IClassFactory instance used to create instances of that class - /// Thrown if the method can't creat COM-object - /// Thrown if the dll not found - public static IClassFactory GetClassFactory(string dllName, Guid filtersGuiid) - { - IntPtr dllHandle = loader.GetDLLHandle(dllName); - Object unk; - - //Get a pointer to the DllGetClassObject function - IntPtr dllGetClassObjectPtr = GetProcAddress(dllHandle, "DllGetClassObject"); - if (dllGetClassObjectPtr == IntPtr.Zero) - return null; - - //Call the DllGetClassObject to retreive a class factory for out Filter class - Guid IClassFactory_GUID = typeof(IClassFactory).GUID; //IClassFactory class id - - //Convert the function pointer to a .net delegate - DllGetClassObject dllGetClassObject = (DllGetClassObject)Marshal.GetDelegateForFunctionPointer(dllGetClassObjectPtr, typeof(DllGetClassObject)); - - return (dllGetClassObject(ref filtersGuiid, ref IClassFactory_GUID, out unk) != 0) ? null : (unk as IClassFactory); - } - - /// - /// Builds a full path for a given that is located in the same folder as the . - /// - /// File name - /// Combined path - public static string BuildAssemblyRelativePath(string fileName) - { - string executingPath = Assembly.GetCallingAssembly().Location; - return Path.Combine(Path.GetDirectoryName(executingPath), fileName); - } - - //DllGetClassObject fuction pointer signature - private delegate int DllGetClassObject(ref Guid ClassId, ref Guid InterfaceId, [Out, MarshalAs(UnmanagedType.Interface)] out object ppunk); - - /// - /// The GetProcAddress function retrieves the address of an exported function or variable from the specified dynamic-link library (DLL). - /// - /// Handle to the DLL module that contains the function or variable. - /// The LoadLibrary or GetModuleHandle function returns this handle. - /// Pointer to a null-terminated string containing the function or variable name, - /// or the function's ordinal value. If this parameter is an ordinal value, - /// it must be in the low-order word; the high-order word must be zero. - /// If the function succeeds, the return value is the address of the exported function or variable.

- ///
If the function fails, the return value is NULL. To get extended error information, call Marshal.GetLastWin32Error.
- [DllImport("kernel32.dll", EntryPoint = "GetProcAddress", CharSet = CharSet.Ansi), SuppressUnmanagedCodeSecurity] - internal static extern IntPtr GetProcAddress(IntPtr hModule, string lpProcName); - - /// - /// LoadLibrary function maps the specified executable module into the address space of the calling process. - /// - /// Pointer to a null-terminated string that names the executable module. - /// The name specified is the file name of the module and is not related to the name stored in the library module itself, - /// as specified by the LIBRARY keyword in the module-definition (.def) file. - /// If the function succeeds, the return value is a handle to the module.

- ///
If the function fails, the return value is NULL. To get extended error information, call Marshal.GetLastWin32Error.
- [DllImport("kernel32.dll", EntryPoint = "LoadLibraryA", SetLastError = true, CharSet = CharSet.Ansi), SuppressUnmanagedCodeSecurity] - internal static extern IntPtr LoadLibrary(string lpLibFileName); - - /// - /// The FreeLibrary function decrements the reference count of the loaded dynamic-link library (DLL). - /// When the reference count reaches zero, the module is unmapped from the address space of the calling process and the handle is no longer valid. - /// - /// Handle to the loaded DLL module. The LoadLibrary or GetModuleHandle function returns this handle. - /// If the function succeeds, the return value is nonzero.


- /// If the function fails, the return value is zero. To get extended error information, call Marshal.GetLastWin32Error.
- [DllImport("kernel32.dll", EntryPoint = "FreeLibrary", SetLastError = true, CharSet = CharSet.Ansi), SuppressUnmanagedCodeSecurity] - internal static extern int FreeLibrary(IntPtr hLibModule); - - #region private DLLLoader class - - private class DLLLoader - { - private Dictionary loadedDlls = new Dictionary(); - - private delegate int PointerToMethodInvoker(); - - ~DLLLoader() - { - lock (loadedDlls) - { - foreach (var dllHandle in loadedDlls.Values) - { - try { FreeLibrary(dllHandle); } - catch { } - } - } - } - - /// - /// GetDLLHandle - /// - /// - /// the handle from registered dll - public IntPtr GetDLLHandle(string dllName) - { - IntPtr handle; - - lock (loadedDlls) - { - if (!loadedDlls.TryGetValue(dllName, out handle)) - { - handle = LoadLibrary(dllName); - if (handle == IntPtr.Zero) - throw new Win32Exception(string.Format("Can't load library '{0}'.", dllName)); - - // Keep a reference to the dll until the process\AppDomain dies. - loadedDlls.Add(dllName, handle); - } - return handle; - } - } - - public void RegisterComDLL(IntPtr dllHandle) - { - CallPointerMethod(dllHandle, "DllRegisterServer"); - } - - public void UnRegisterComDLL(IntPtr dllHandle) - { - CallPointerMethod(dllHandle, "DllUnregisterServer"); - } - - private void CallPointerMethod(IntPtr dllHandle, string methodName) - { - IntPtr dllEntryPoint = GetProcAddress(dllHandle, methodName); - if (IntPtr.Zero == dllEntryPoint) - throw new Win32Exception(Marshal.GetLastWin32Error()); - - var method = (PointerToMethodInvoker)Marshal.GetDelegateForFunctionPointer(dllEntryPoint, typeof(PointerToMethodInvoker)); - method(); - } - } - - #endregion private DLLLoader class - } - - #endregion ComHelper class Load Com-Objects from file -} diff --git a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/MediaFoundation/EvrPresenter.cs b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/MediaFoundation/EvrPresenter.cs deleted file mode 100644 index 5890e78..0000000 --- a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/MediaFoundation/EvrPresenter.cs +++ /dev/null @@ -1,328 +0,0 @@ -using DirectShowLib; -using System; -using System.Runtime.InteropServices; -using System.Security; -using WPFMediaKit.DirectShow.MediaPlayers; -using WPFMediaKit.MediaFoundation.Interop; - -namespace WPFMediaKit.MediaFoundation; - -#region Custom COM Types - -/* -[ComVisible(true), ComImport, SuppressUnmanagedCodeSecurity, - Guid("00000001-0000-0000-C000-000000000046"), - InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] -internal interface IClassFactory -{ - [PreserveSig] - int CreateInstance([In, MarshalAs(UnmanagedType.Interface)] object pUnkOuter, - ref Guid riid, - [Out, MarshalAs(UnmanagedType.Interface)] out object obj); - - [PreserveSig] - int LockServer([In] bool fLock); -} -*/ - -[ComVisible(true), ComImport, SuppressUnmanagedCodeSecurity, - Guid("B92D8991-6C42-4e51-B942-E61CB8696FCB"), - InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] -internal interface IEVRPresenterCallback -{ - [PreserveSig] - int PresentSurfaceCB(IntPtr pSurface); -} - -[ComVisible(true), ComImport, SuppressUnmanagedCodeSecurity, - Guid("9019EA9C-F1B4-44b5-ADD5-D25704313E48"), - InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] -internal interface IEVRPresenterRegisterCallback -{ - [PreserveSig] - int RegisterCallback(IEVRPresenterCallback pCallback); -} - -[ComVisible(true), ComImport, SuppressUnmanagedCodeSecurity, - Guid("4527B2E7-49BE-4b61-A19D-429066D93A99"), - InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] -internal interface IEVRPresenterSettings -{ - [PreserveSig] - int SetBufferCount(int count); - - [PreserveSig] - int GetBufferCount(out int count); // Added - - [PreserveSig] - int RegisterCallback(IEVRPresenterCallback pCallback); // Added -} - -#endregion Custom COM Types - -[ComVisible(true)] -public class EvrPresenter : ICustomAllocator, IEVRPresenterCallback -{ - private const int PRESENTER_BUFFER_COUNT = 5; - private IntPtr m_lastSurface; - private IMFVideoPresenter m_VideoPresenter; - - private EvrPresenter() - { - } - - ~EvrPresenter() - { - Dispose(false); - } - - #region Interop - - /// - /// The GUID of our EVR custom presenter COM object - /// - private static readonly Guid EVR_PRESENTER_CLSID = new Guid(0x9807fc9c, 0x807b, 0x41e3, 0x98, 0xa8, 0x75, 0x17, - 0x6f, 0x95, 0xa0, 0x63); - - /* - /// - /// The GUID of IUnknown - /// - private static readonly Guid IUNKNOWN_GUID = new Guid("{00000000-0000-0000-C000-000000000046}"); - - /// - /// Static method in the 32 bit dll to create our IClassFactory - /// - [PreserveSig] - [DllImport("EvrPresenter32.dll", EntryPoint = "DllGetClassObject")] - private static extern int DllGetClassObject32([MarshalAs(UnmanagedType.LPStruct)] Guid clsid, - [MarshalAs(UnmanagedType.LPStruct)] Guid riid, - [MarshalAs(UnmanagedType.IUnknown)] out object ppv); - - /// - /// Static method in the 62 bit dll to create our IClassFactory - /// - [PreserveSig] - [DllImport("EvrPresenter64.dll", EntryPoint = "DllGetClassObject")] - private static extern int DllGetClassObject64([MarshalAs(UnmanagedType.LPStruct)] Guid clsid, - [MarshalAs(UnmanagedType.LPStruct)] Guid riid, - [MarshalAs(UnmanagedType.IUnknown)] out object ppv); - */ - - #endregion Interop - - /* - /// - /// Returns the bittage of this process, ie 32 or 64 bit - /// - private static int ProcessBits - { - get { return IntPtr.Size * 8; } - } -*/ - - /// - /// The custom EVR video presenter COM object - /// - public IMFVideoPresenter VideoPresenter - { - get { return m_VideoPresenter; } - private set { m_VideoPresenter = value; } - } - - #region ICustomAllocator Members - - /// - /// Invokes when a new frame has been allocated - /// to a surface - /// - public event Action NewAllocatorFrame; - - /// - /// Invokes when a new surface has been allocated - /// - public event NewAllocatorSurfaceDelegate NewAllocatorSurface; - - #region IDisposable - - public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - protected void Dispose(bool dispose) - { - if (dispose) - { - var settings = m_VideoPresenter as IEVRPresenterSettings; - - if (settings != null) - settings.RegisterCallback(null); - } - COMUtil.TryFinalRelease(ref m_VideoPresenter); - } - - public void Stop() - { - var settings = m_VideoPresenter as IEVRPresenterSettings; - - if (settings != null) - settings.RegisterCallback(null); - } - - #endregion IDisposable - - #endregion ICustomAllocator Members - - #region IEVRPresenterCallback Members - - /// - /// Called by the custom EVR Presenter, notifying that - /// there is a new D3D surface and/or there needs to be - /// a frame rendered - /// - /// The Direct3D surface - /// A HRESULT - public int PresentSurfaceCB(IntPtr pSurface) - { - /* Check if the surface is the same as the last*/ - if (m_lastSurface != pSurface) - InvokeNewAllocatorSurface(pSurface); - - /* Store ref to the pointer so we can compare - * it next time this method is called */ - m_lastSurface = pSurface; - - InvokeNewAllocatorFrame(); - return 0; - } - - #endregion IEVRPresenterCallback Members - - /// - /// Create a new EVR video presenter - /// - /// - public static EvrPresenter CreateNew() - { - // object comObject; - // int hr; - - /* Our exception var we use to hold the exception - * until we need to throw it (after clean up) */ - // Exception exception = null; - - /* A COM object we query form our native library */ - // IClassFactory factory = null; - - /* Create our 'helper' class */ - var evrPresenter = new EvrPresenter(); - IMFVideoPresenter presenter = null; - try - { - var path = System.IO.Path.GetDirectoryName(new Uri(typeof(EvrPresenter).Assembly.CodeBase).LocalPath); - var dlltoload = System.IO.Path.Combine(path, IntPtr.Size == 8 ? @"EvrPresenter64.dll" : @"EvrPresenter32.dll"); - presenter = COMUtil.CreateFromDll(dlltoload, EVR_PRESENTER_CLSID); - - int count; - var settings = presenter as IEVRPresenterSettings; - DsError.ThrowExceptionForHR(settings.RegisterCallback(evrPresenter)); - DsError.ThrowExceptionForHR(settings.GetBufferCount(out count)); - DsError.ThrowExceptionForHR(settings.SetBufferCount(PRESENTER_BUFFER_COUNT)); - - /* Populate the IMFVideoPresenter */ - evrPresenter.VideoPresenter = presenter; - } - catch (Exception ex) - { - COMUtil.TryFinalRelease(ref presenter); - throw new WPFMediaKitException("Could not create EnhancedVideoRenderer", ex); - } - - return evrPresenter; - - // /* Call the DLL export to create the class factory */ - /* if(ProcessBits == 32) - hr = DllGetClassObject32(EVR_PRESENTER_CLSID, IUNKNOWN_GUID, out comObject); - else if(ProcessBits == 64) - hr = DllGetClassObject64(EVR_PRESENTER_CLSID, IUNKNOWN_GUID, out comObject); - else - { - exception = new Exception(string.Format("{0} bit processes are unsupported", ProcessBits)); - goto bottom; - } - */ - /* Check if our call to our DLL failed */ - /* if(hr != 0 || comObject == null) - { - exception = new COMException("Could not create a new class factory.", hr); - goto bottom; - } - */ - /* Cast the COM object that was returned to a COM interface type */ - /* factory = comObject as IClassFactory; - - if(factory == null) - { - exception = new Exception("Could not QueryInterface for the IClassFactory interface"); - goto bottom; - } - - /* Get the GUID of the IMFVideoPresenter */ - // Guid guidVideoPresenter = typeof(IMFVideoPresenter).GUID; - - /* Creates a new instance of the IMFVideoPresenter */ - // factory.CreateInstance(null, ref guidVideoPresenter, out comObject); - - /* QueryInterface for the IMFVideoPresenter */ - // var presenter = comObject as IMFVideoPresenter; - - /* QueryInterface for our callback registration interface */ - /* var registerCb = comObject as IEVRPresenterRegisterCallback; - if(registerCb == null) - { - exception = new Exception("Could not QueryInterface for IEVRPresenterRegisterCallback"); - goto bottom; - } - */ - /* Register the callback to the 'helper' class we created */ - // registerCb.RegisterCallback(evrPresenter); - - /* Populate the IMFVideoPresenter */ - // evrPresenter.VideoPresenter = presenter; - - // bottom: - - // if(factory != null) - // Marshal.FinalReleaseComObject(factory); - - /* if(exception != null) - throw exception; - - return evrPresenter;*/ - } - - #region Event Invokers - - /// - /// Fires the NewAllocatorFrame event - /// - private void InvokeNewAllocatorFrame() - { - var newAllocatorFrameAction = NewAllocatorFrame; - if (newAllocatorFrameAction != null) newAllocatorFrameAction(); - } - - /// - /// Fires the NewAlloctorSurface event - /// - /// D3D surface pointer - private void InvokeNewAllocatorSurface(IntPtr pSurface) - { - var del = NewAllocatorSurface; - if (del != null) del(this, pSurface); - } - - #endregion Event Invokers -} diff --git a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/MediaFoundation/Interop.cs b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/MediaFoundation/Interop.cs deleted file mode 100644 index 5251ee3..0000000 --- a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/MediaFoundation/Interop.cs +++ /dev/null @@ -1,132 +0,0 @@ -using System; -using System.Runtime.InteropServices; -using System.Security; - -namespace WPFMediaKit.MediaFoundation.Interop; - -[ComImport, SuppressUnmanagedCodeSecurity, -InterfaceType(ComInterfaceType.InterfaceIsIUnknown), -Guid("83E91E85-82C1-4ea7-801D-85DC50B75086")] -public interface IEVRFilterConfig -{ - [PreserveSig] - int SetNumberOfStreams(int dwMaxStreams); - - [PreserveSig] - void GetNumberOfStreams(out int pdwMaxStreams); -} - -[ComImport, SuppressUnmanagedCodeSecurity, -Guid("DFDFD197-A9CA-43D8-B341-6AF3503792CD"), -InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] -public interface IMFVideoRenderer -{ - [PreserveSig] - int InitializeRenderer([In, MarshalAs(UnmanagedType.Interface)] object pVideoMixer, [In, MarshalAs(UnmanagedType.Interface)] IMFVideoPresenter pVideoPresenter); -} - -[ComImport, SuppressUnmanagedCodeSecurity, -InterfaceType(ComInterfaceType.InterfaceIsIUnknown), -Guid("F6696E82-74F7-4F3D-A178-8A5E09C3659F")] -public interface IMFClockStateSink -{ - [PreserveSig] - int OnClockStart([In] long hnsSystemTime, [In] long llClockStartOffset); - - [PreserveSig] - int OnClockStop([In] long hnsSystemTime); - - [PreserveSig] - int OnClockPause([In] long hnsSystemTime); - - [PreserveSig] - int OnClockRestart([In] long hnsSystemTime); - - [PreserveSig] - int OnClockSetRate([In] long hnsSystemTime, [In] float flRate); -} - -[ComImport, SuppressUnmanagedCodeSecurity, -InterfaceType(ComInterfaceType.InterfaceIsIUnknown), -Guid("29AFF080-182A-4A5D-AF3B-448F3A6346CB")] -public interface IMFVideoPresenter : IMFClockStateSink -{ - #region IMFClockStateSink - - [PreserveSig] - new void OnClockStart([In] long hnsSystemTime, [In] long llClockStartOffset); - - [PreserveSig] - new void OnClockStop([In] long hnsSystemTime); - - [PreserveSig] - new void OnClockPause([In] long hnsSystemTime); - - [PreserveSig] - new void OnClockRestart([In] long hnsSystemTime); - - [PreserveSig] - new void OnClockSetRate([In] long hnsSystemTime, [In] float flRate); - - #endregion IMFClockStateSink - - [PreserveSig] - int ProcessMessage(); - - [PreserveSig] - int GetCurrentMediaType(); -} - -[ComImport, SuppressUnmanagedCodeSecurity, -Guid("A490B1E4-AB84-4D31-A1B2-181E03B1077A"), -InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] -public interface IMFVideoDisplayControl -{ - [PreserveSig] - int GetNativeVideoSize(/* not impl */); - - [PreserveSig] - int GetIdealVideoSize(/* not impl */); - - [PreserveSig] - int SetVideoPosition(/* not impl */); - - [PreserveSig] - int GetVideoPosition(/* not impl */); - - [PreserveSig] - int SetAspectRatioMode(/* not impl */); - - [PreserveSig] - int GetAspectRatioMode(/* not impl */); - - [PreserveSig] - int SetVideoWindow([In] IntPtr hwndVideo); - - [PreserveSig] - int GetVideoWindow(out IntPtr phwndVideo); - - [PreserveSig] - int RepaintVideo(); - - [PreserveSig] - int GetCurrentImage(/* not impl */); - - [PreserveSig] - int SetBorderColor([In] int Clr); - - [PreserveSig] - int GetBorderColor(out int pClr); - - [PreserveSig] - int SetRenderingPrefs(/* not impl */); - - [PreserveSig] - int GetRenderingPrefs(/* not impl */); - - [PreserveSig] - int SetFullscreen(/* not impl */); - - [PreserveSig] - int GetFullscreen(/* not impl */); -} diff --git a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/Properties/Resources.Designer.cs b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/Properties/Resources.Designer.cs deleted file mode 100644 index 4cedfd1..0000000 --- a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/Properties/Resources.Designer.cs +++ /dev/null @@ -1,63 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace WPFMediaKit.Properties { - using System; - - - /// - /// A strongly-typed resource class, for looking up localized strings, etc. - /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - internal class Resources { - - private static global::System.Resources.ResourceManager resourceMan; - - private static global::System.Globalization.CultureInfo resourceCulture; - - [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - internal Resources() { - } - - /// - /// Returns the cached ResourceManager instance used by this class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Resources.ResourceManager ResourceManager { - get { - if (object.ReferenceEquals(resourceMan, null)) { - global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("WPFMediaKit.Properties.Resources", typeof(Resources).Assembly); - resourceMan = temp; - } - return resourceMan; - } - } - - /// - /// Overrides the current thread's CurrentUICulture property for all - /// resource lookups using this strongly typed resource class. - /// - [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] - internal static global::System.Globalization.CultureInfo Culture { - get { - return resourceCulture; - } - set { - resourceCulture = value; - } - } - } -} diff --git a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/Properties/Resources.resx b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/Properties/Resources.resx deleted file mode 100644 index af7dbeb..0000000 --- a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/Properties/Resources.resx +++ /dev/null @@ -1,117 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - text/microsoft-resx - - - 2.0 - - - System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - \ No newline at end of file diff --git a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/Properties/Settings.Designer.cs b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/Properties/Settings.Designer.cs deleted file mode 100644 index 2a08b0e..0000000 --- a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/Properties/Settings.Designer.cs +++ /dev/null @@ -1,26 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// Runtime Version:4.0.30319.42000 -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace WPFMediaKit.Properties { - - - [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.9.0.0")] - internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { - - private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); - - public static Settings Default { - get { - return defaultInstance; - } - } - } -} diff --git a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/Properties/Settings.settings b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/Properties/Settings.settings deleted file mode 100644 index 033d7a5..0000000 --- a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/Properties/Settings.settings +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/Themes/Generic.xaml b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/Themes/Generic.xaml deleted file mode 100644 index f572aff..0000000 --- a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/Themes/Generic.xaml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/Themes/MediaDetectorGeneric.xaml b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/Themes/MediaDetectorGeneric.xaml deleted file mode 100644 index 1880d2e..0000000 --- a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/Themes/MediaDetectorGeneric.xaml +++ /dev/null @@ -1,65 +0,0 @@ - - - \ No newline at end of file diff --git a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/Threading/WorkDispatcher.cs b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/Threading/WorkDispatcher.cs deleted file mode 100644 index a4f4fee..0000000 --- a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/Threading/WorkDispatcher.cs +++ /dev/null @@ -1,333 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Security; -using System.Threading; - -namespace WPFMediaKit.Threading; - -public class ShutdownFinishedEventArgs : EventArgs -{ - public bool CancelShutdown { get; set; } -} - -/// -/// Custom dispatcher to deal with MTA and DShow, -/// see https://groups.google.com/forum/#!topic/wpf-disciples/kLdMgVzeWig -/// -public class WorkDispatcher -{ - /// - /// Flag to set if the dispatcher needs to shutdown - /// - private bool m_shutdown; - - private bool m_shuttingDown; - - private object m_queueLock = new object(); - - /// - /// Queue of delegates to execute - /// - private readonly Queue m_queue = new Queue(); - - /// - /// The thread this dispatcher is running on - /// - private Thread m_dispatcherThread; - - /// - /// The message to post to our message pump to wake it up - /// for processing the managed delegate queue - /// - private const int WM_DISPATCHER_NOTIFY_DELEGATE = 0x0400 + 69; - - /// - /// Windows message notifiying listener's of the pump we outta there - /// and the pump is about to end - /// - private const int WM_QUIT = 0x12; - - /// - /// The OS's thread identifier - /// - private int m_threadId; - - public event EventHandler ShutdownFinished; - - public event EventHandler ShutdownStarted; - - private void InvokeShutdownStarted() - { - ShutdownStarted?.Invoke(this, EventArgs.Empty); - } - - ~WorkDispatcher() - { - BeginInvokeShutdown(); - } - - private ShutdownFinishedEventArgs InvokeShutdownFinished() - { - var e = new ShutdownFinishedEventArgs(); - ShutdownFinished?.Invoke(this, e); - - return e; - } - - /// - /// The thread that the dispatcher is running under - /// - public Thread DispatcherThread - { - get => m_dispatcherThread; - private set - { - m_dispatcherThread = value; - } - } - - /// - /// Flag, that the dispatcher is in the shutting down process. - /// - public bool ShuttingDown - { - get => m_shuttingDown; - private set => m_shuttingDown = value; - } - - /// - /// Flag that the dispather has shut down. - /// - public bool Shutdown - { - get => m_shutdown; - private set => m_shutdown = value; - } - - public bool ShuttingOrShutDown - => ShuttingDown || Shutdown; - - /// - /// Async executes a method on our Dispatcher's thread - /// - /// The delegate to execute - [MethodImpl(MethodImplOptions.Synchronized)] - public void BeginInvoke(Delegate method) - { - //if (Shutdown) - // return; - - lock (m_queueLock) - { - /* Add the delegate to our queue */ - m_queue.Enqueue(method); - } - - /* Wake up our thread to notify that - * it has something to execute */ - InvokeNotifyMessageDelegate(); - } - - /// - /// Wakes up the pump to notify there are delegates to execute - /// - private void InvokeNotifyMessageDelegate() - { - /* Post the thread to our message pump */ - PostThreadMessage(m_threadId, WM_DISPATCHER_NOTIFY_DELEGATE, 0, 0); - } - - /// - /// Shuts down the dispatcher and completes any - /// delegates or messages that are in the queue - /// - [MethodImpl(MethodImplOptions.Synchronized)] - public void BeginInvokeShutdown() - { - if (Shutdown) - return; - - ShuttingDown = true; - - InvokeShutdownStarted(); - /* Process the pump */ - InvokeNotifyMessageDelegate(); - - PostQuit(); - } - - /// - /// Forces execution of any messages in the queue - /// - public void DoEvents() - { - InvokeNotifyMessageDelegate(); - } - - /// - /// Runs the message pump in the Dispatcher - /// - public void Run(ManualResetEventSlim resetEvent) - { - if (m_threadId != 0) - throw new InvalidOperationException("Only one thread can execute in the dispatcher at a time"); - - DispatcherThread = Thread.CurrentThread; - - /* Reset our flag */ - Shutdown = false; - - /* We need to store the thread id for some p/invoke later */ - m_threadId = GetCurrentThreadId(); - - // Call PeekMessage to create the message queue before the event is set - PeekMessage(out Msg msg, IntPtr.Zero, 0, 0, 0); - resetEvent.Set(); - - /* Begins the pump */ - DoMessagePump(); - } - - /// - /// Executes all the queued delegates - /// - private void DoManagedMessageQueue() - { - Queue methods; - - lock (m_queueLock) - { - if (m_queue.Count <= 0) - return; - - /* Copy our delegates over to safe queue - * so we can run the delegates outside - * this thread lock we got going on */ - methods = new Queue(m_queue); - m_queue.Clear(); - } - - /* Execute all the delegates in the queue */ - while (methods.Count > 0) - { - var method = methods.Dequeue(); - - try - { - if (method != null) - method.DynamicInvoke(null); - } - catch - { - throw; - } - } - } - - /// - /// Posts a quit message to the message queue. - /// This lets all pump listeners know that - /// the end is near and abandon all resources - /// - private void PostQuit() - { - PostThreadMessage(m_threadId, WM_QUIT, 0, 0); - } - - /// - /// The heart of the message pump. This method - /// will not return until the message pump has - /// been terminated. - /// - private void DoMessagePump() - { - top: - - Msg msg; - - DoManagedMessageQueue(); - - /* Blocking call to GetMessage */ - while (GetMessage(out msg, IntPtr.Zero, 0, 0)) - { - switch (msg.message) - { - case WM_DISPATCHER_NOTIFY_DELEGATE: - DoManagedMessageQueue(); - continue; - default: - break; - } - - /* Trys to translate the message. - * Only here for completeness */ - TranslateMessage(ref msg); - - /* Dispatches the win32 message to a wnd proc. - * The real magic is here */ - DispatchMessage(ref msg); - } - - OleUninitialize(); - CoUninitialize(); - - OleUninitialize(); - CoUninitialize(); - if (InvokeShutdownFinished().CancelShutdown) - { - Shutdown = false; - ShuttingDown = false; - goto top; - } - - Shutdown = true; - ShuttingDown = false; - m_threadId = 0; - DispatcherThread = null; - } - - #region PInvoke - - [DllImport("ole32.dll")] - static extern void CoUninitialize(); - - [DllImport("user32"), SuppressUnmanagedCodeSecurity] - public static extern bool PostThreadMessage(int threadId, uint msg, - ushort wParam, uint lParam); - - [DllImport("user32.dll")] - [return: MarshalAs(UnmanagedType.Bool)] - private static extern bool GetMessage(out Msg lpMsg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax); - - [DllImport("user32.dll")] - [return: MarshalAs(UnmanagedType.Bool)] - private static extern bool PeekMessage(out Msg lpMsg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax, uint wRemoveMsg); - - [DllImport("user32.dll")] - private static extern IntPtr DispatchMessage([In] ref Msg lpmsg); - - [DllImport("user32.dll")] - static extern bool TranslateMessage([In] ref Msg lpMsg); - - [StructLayout(LayoutKind.Sequential)] - private struct Msg - { - public IntPtr hwnd; - public int message; - public IntPtr wParam; - public IntPtr lParam; - public int time; - public int pt_x; - public int pt_y; - } - - [DllImport("kernel32"), SuppressUnmanagedCodeSecurity] - static extern int GetCurrentThreadId(); - - [DllImport("ole32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)] - public static extern int OleUninitialize(); - - #endregion PInvoke -} diff --git a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/Threading/WorkDispatcherObject.cs b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/Threading/WorkDispatcherObject.cs deleted file mode 100644 index 595f3ee..0000000 --- a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/Threading/WorkDispatcherObject.cs +++ /dev/null @@ -1,97 +0,0 @@ -using System; -using System.Threading; - -namespace WPFMediaKit.Threading; - -public abstract class WorkDispatcherObject -{ - private bool m_restartThread; - - public bool CheckAccess() - { - lock (Dispatcher) - { - if (Dispatcher.DispatcherThread == Thread.CurrentThread) - return true; - - return false; - } - } - - public void VerifyAccess() - { - lock (Dispatcher) - { - if (Dispatcher.DispatcherThread != Thread.CurrentThread) - throw new InvalidOperationException("Not the same thread"); - } - } - - public void EnsureThread(ApartmentState apartmentState) - { - lock (Dispatcher) - { - if (Dispatcher.ShuttingDown) - { - m_restartThread = true; - return; - } - - if (Dispatcher.DispatcherThread == null) - { - StartNewDispatcherThread(apartmentState); - } - } - } - - private void StartNewDispatcherThread(ApartmentState apartmentState) - { - var reset = new ManualResetEventSlim(); - - var t = new Thread((ThreadStart)delegate - { - Thread.CurrentThread.Name = string.Format("WorkDispatcherThread"); - - Dispatcher.Run(reset); - }) - { - IsBackground = true - }; - - t.SetApartmentState(apartmentState); - - t.Priority = ThreadPriority.Normal; - - /* Starts the thread and creates the object */ - t.Start(); - - /* We wait until our dispatcher is initialized and - * the new Dispatcher is running */ - reset.Wait(); - } - - protected WorkDispatcherObject() - { - Dispatcher = new WorkDispatcher(); - Dispatcher.ShutdownFinished += Dispatcher_ShutdownFinished; - } - - private void Dispatcher_ShutdownFinished(object sender, ShutdownFinishedEventArgs e) - { - lock (Dispatcher) - { - /* If our restart thread flag is set, - * then we want to cancel our dispatcher's - * shutdown and have it continue it's - * processing of messages and delegates */ - e.CancelShutdown = m_restartThread; - m_restartThread = false; - } - } - - public WorkDispatcher Dispatcher - { - get; - private set; - } -} diff --git a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/WPFMediaKitException.cs b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/WPFMediaKitException.cs deleted file mode 100644 index a902798..0000000 --- a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/Mediakit/WPFMediaKitException.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using System.Runtime.Serialization; - -namespace WPFMediaKit; - -public class WPFMediaKitException : Exception -{ - public WPFMediaKitException() - : base() - { - } - - public WPFMediaKitException(string message) - : base(message) - { - } - - public WPFMediaKitException(string message, Exception innerException) - : base(message, innerException) - { - } - - protected WPFMediaKitException(SerializationInfo info, StreamingContext context) - : base(info, context) - { - } -} diff --git a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/QuickLook.Plugin.VideoViewer.csproj b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/QuickLook.Plugin.VideoViewer.csproj index e09fbdf..a2f4348 100644 --- a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/QuickLook.Plugin.VideoViewer.csproj +++ b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/QuickLook.Plugin.VideoViewer.csproj @@ -36,22 +36,16 @@ - - + False - Mediakit\Assemblies\DirectShowLib-2005.dll - - - - {85FDD6BA-871D-46C8-BD64-F6BB0CB5EA95} @@ -66,15 +60,6 @@ - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - PreserveNewest @@ -93,6 +78,10 @@ + + + + Properties\GitVersion.cs diff --git a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/ViewerPanel.xaml b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/ViewerPanel.xaml index 3f076b6..e2d815e 100644 --- a/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/ViewerPanel.xaml +++ b/QuickLook.Plugin/QuickLook.Plugin.VideoViewer/ViewerPanel.xaml @@ -5,7 +5,7 @@ xmlns:glassLayer="clr-namespace:QuickLook.Controls.GlassLayer;assembly=QuickLook" xmlns:local="clr-namespace:QuickLook.Plugin.VideoViewer" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:mediakit="clr-namespace:WPFMediaKit.DirectShow.Controls" + xmlns:mediakit="clr-namespace:WPFMediaKit.DirectShow.Controls;assembly=QuickLook.WPFMediaKit" x:Name="viewerPanel" d:DesignHeight="300" d:DesignWidth="500"