可以将xml阅读器功能放入D3drenderer.cs吗? [英] Can put xml reader function into D3drenderer.cs?

查看:58
本文介绍了可以将xml阅读器功能放入D3drenderer.cs吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是标准的d3drenderer.cs文件编码:

Below is the standard d3drenderer.cs file coding:

using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Threading;
using System.Xml.Linq;

namespace WPFMediaKit.DirectShow.Controls
{
    /// <summary>
    /// The D3DRenderer class provides basic functionality needed
    /// to render a D3D surface.  This class is abstract.
    /// </summary>
    public abstract class D3DRenderer : FrameworkElement
    {
        private string workingDirectory = AppDomain.CurrentDomain.BaseDirectory;
        /// <summary>
        /// The D3DImage used to render video
        /// </summary>
        private D3DImage m_d3dImage;

        /// <summary>
        /// The Image control that has the source
        /// to the D3DImage
        /// </summary>
        private Image m_videoImage;

        /// <summary>
        /// We keep reference to the D3D surface so
        /// we can delay loading it to avoid a black flicker
        /// when loading new media
        /// </summary>
        private IntPtr m_pBackBuffer = IntPtr.Zero;

        /// <summary>
        /// Flag to tell us if we have a new D3D
        /// Surface available
        /// </summary>
        private bool m_newSurfaceAvailable;

        /// <summary>
        /// A weak reference of D3DRenderers that have been cloned
        /// </summary>
        private readonly List<WeakReference> m_clonedD3Drenderers = new List<WeakReference>();

        /// <summary>
        /// Backing field for the RenderOnCompositionTargetRendering flag. 
        /// </summary>
        private bool m_renderOnCompositionTargetRendering;

        /// <summary>
        /// Temporary storage for the RenderOnCompositionTargetRendering flag.
        /// This is used to remember the value for when the control is loaded and unloaded.
        /// </summary>
        private bool m_renderOnCompositionTargetRenderingTemp;

        #region Stretch
        public static readonly DependencyProperty StretchProperty =
            DependencyProperty.Register("Stretch", typeof(Stretch), typeof(D3DRenderer),
                new FrameworkPropertyMetadata(Stretch.Uniform,
                    new PropertyChangedCallback(OnStretchChanged)));

        /// <summary>
        /// Defines what rules are applied to the stretching of the video
        /// </summary>
        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

        #region IsRenderingEnabled

        public static readonly DependencyProperty IsRenderingEnabledProperty =
            DependencyProperty.Register("IsRenderingEnabled", typeof(bool), typeof(D3DRenderer),
                new FrameworkPropertyMetadata(true));

        /// <summary>
        /// Enables or disables rendering of the video
        /// </summary>
        public bool IsRenderingEnabled
        {
            get { return (bool)GetValue(IsRenderingEnabledProperty); }
            set { SetValue(IsRenderingEnabledProperty, value); }
        }

        #endregion

        #region NaturalVideoHeight

        private static readonly DependencyPropertyKey NaturalVideoHeightPropertyKey
            = DependencyProperty.RegisterReadOnly("NaturalVideoHeight", typeof(int), typeof(MediaElementBase),
                new FrameworkPropertyMetadata(0));

        public static readonly DependencyProperty NaturalVideoHeightProperty
            = NaturalVideoHeightPropertyKey.DependencyProperty;

        /// <summary>
        /// Gets the natural pixel height of the current media.  
        /// The value will be 0 if there is no video in the media.
        /// </summary>
        public int NaturalVideoHeight
        {
            get { return (int)GetValue(NaturalVideoHeightProperty); }
        }

        /// <summary>
        /// Internal method to set the read-only NaturalVideoHeight DP
        /// </summary>
        protected void SetNaturalVideoHeight(int value)
        {
            SetValue(NaturalVideoHeightPropertyKey, value);
        }

        #endregion

        #region NaturalVideoWidth

        private static readonly DependencyPropertyKey NaturalVideoWidthPropertyKey
            = DependencyProperty.RegisterReadOnly("NaturalVideoWidth", typeof(int), typeof(MediaElementBase),
                new FrameworkPropertyMetadata(0));

        public static readonly DependencyProperty NaturalVideoWidthProperty
            = NaturalVideoWidthPropertyKey.DependencyProperty;

        /// <summary>
        /// Gets the natural pixel width of the current media.
        /// The value will be 0 if there is no video in the media.
        /// </summary>
        public int NaturalVideoWidth
        {
            get { return (int)GetValue(NaturalVideoWidthProperty); }
        }

        /// <summary>
        /// Internal method to set the read-only NaturalVideoWidth DP
        /// </summary>
        protected void SetNaturalVideoWidth(int value)
        {
            SetValue(NaturalVideoWidthPropertyKey, value);
        }

        #endregion

        #region HasVideo

        private static readonly DependencyPropertyKey HasVideoPropertyKey
            = DependencyProperty.RegisterReadOnly("HasVideo", typeof(bool), typeof(MediaElementBase),
                new FrameworkPropertyMetadata(false));

        public static readonly DependencyProperty HasVideoProperty
            = HasVideoPropertyKey.DependencyProperty;

        /// <summary>
        /// Is true if the media contains renderable video
        /// </summary>
        public bool HasVideo
        {
            get { return (bool)GetValue(HasVideoProperty); }
        }

        /// <summary>
        /// Internal method for setting the read-only HasVideo DP
        /// </summary>
        protected void SetHasVideo(bool value)
        {
            SetValue(HasVideoPropertyKey, value);
        }
        #endregion

        protected D3DRenderer()
        {
            InitializeD3DVideo();

            /* Hook into the framework events */
            Loaded += D3DRenderer_Loaded;
            Unloaded += D3DRenderer_Unloaded;
        }

        /// <summary>
        /// Handler for when the D3DRenderer is unloaded
        /// </summary>
        private void D3DRenderer_Unloaded(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;
        }

        /// <summary>
        /// Handler for when the D3DRenderer is loaded
        /// </summary>
        private void D3DRenderer_Loaded(object sender, RoutedEventArgs e)
        {
            /* Restore the property's value */
            RenderOnCompositionTargetRendering = m_renderOnCompositionTargetRenderingTemp;
        }

        /// <summary>
        /// Initializes the D3DRenderer control
        /// </summary>
        protected virtual void InitializeD3DVideo()
        {
            if (m_videoImage != null)
                return;

            /* Create our Image and it's D3DImage source */
            m_videoImage = new Image();
            m_d3dImage = new D3DImage();

            /* We hook into this event to handle when a D3D device is lost */
            D3DImage.IsFrontBufferAvailableChanged += D3DImage_IsFrontBufferAvailableChanged;

            /* Set our default stretch value of our video */
            m_videoImage.Stretch = (Stretch)StretchProperty.DefaultMetadata.DefaultValue;
            var activeProfiles = XElement.Load(workingDirectory + "ProfilesDisplay.xml");
            var a = activeProfiles.Element("_nABC").Value;
            

            /* Our source of the video image is the D3DImage */
            m_videoImage.Source = D3DImage;

            /* Register the Image as a visual child */
            AddVisualChild(m_videoImage);
        }

        /// <summary>
        /// This should only fire when a D3D device is lost
        /// </summary>
        private void D3DImage_IsFrontBufferAvailableChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            if (!D3DImage.IsFrontBufferAvailable)
                return;

            /* Flag that we have a new surface, even
             * though we really don't */
            m_newSurfaceAvailable = true;

            /* Force feed the D3DImage the Surface pointer */
            SetBackBufferInternal(m_pBackBuffer);
        }

        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;
            }
        }

        /// <summary>
        /// Renders the video with WPF's rendering using the CompositionTarget.Rendering event
        /// </summary>
        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 += CompositionTarget_Rendering;
                else if(!value)
                    CompositionTarget.Rendering -= CompositionTarget_Rendering;

                m_renderOnCompositionTargetRendering = value;
                m_renderOnCompositionTargetRenderingTemp = value;
            }
        }

        private void CompositionTarget_Rendering(object sender, EventArgs e)
        {
            InternalInvalidateVideoImage();
        }

        /// <summary>
        /// Used as a clone for a D3DRenderer
        /// </summary>
        private class ClonedD3DRenderer : D3DRenderer
        {}
        
        /// <summary>
        /// Creates a clone of the D3DRenderer.  This is a work for the visual
        /// brush not working cross-threaded
        /// </summary>
        /// <returns></returns>
        public D3DRenderer CloneD3DRenderer()
        {
            var renderer = new ClonedD3DRenderer();

            lock(m_clonedD3Drenderers)
            {
                m_clonedD3Drenderers.Add(new WeakReference(renderer));
            }

            renderer.SetBackBuffer(m_pBackBuffer);
            return renderer;
        }

        /// <summary>
        /// Cleans up any dead references we may have to any cloned renderers
        /// </summary>
        private void CleanZombieRenderers()
        {
            lock(m_clonedD3Drenderers)
            {
                var deadObjects = new List<WeakReference>();

                for (int i = 0; i < m_clonedD3Drenderers.Count; i++)
                {
                    if (!m_clonedD3Drenderers[i].IsAlive)
                        deadObjects.Add(m_clonedD3Drenderers[i]);
                }

                foreach(var deadGuy in deadObjects)
                {
                    m_clonedD3Drenderers.Remove(deadGuy);
                }
            }
        }

        /// <summary>
        /// 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
        /// </summary>
        /// <param name="backBuffer">The unmanaged pointer to the Direct3D Surface</param>
        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)
            {
                SetBackBufferInternal(m_pBackBuffer);
            }

            SetBackBufferForClones();
        }

        /// <summary>
        /// Sets the backbuffer for any cloned D3DRenderers
        /// </summary>
        private void SetBackBufferForClones()
        {
            lock (m_clonedD3Drenderers)
            {
                CleanZombieRenderers();

                foreach (var rendererRef in m_clonedD3Drenderers)
                {
                    var renderer = rendererRef.Target as D3DRenderer;
                    if (renderer != null)
                        renderer.SetBackBuffer(m_pBackBuffer);
                }
            }
        }

        /// <summary>
        /// Configures D3DImage with a new surface.  This happens immediately
        /// </summary>
        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();
                D3DImage.SetBackBuffer(D3DResourceType.IDirect3DSurface9, backBuffer);
                D3DImage.Unlock();
                SetNaturalWidthHeight();
            }
            catch (Exception)
            { }

            /* 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);
        }

        protected void InvalidateVideoImage()
        {
            if (!m_renderOnCompositionTargetRendering)
                InternalInvalidateVideoImage();
        }

        /// <summary>
        /// Invalidates the entire Direct3D image, notifying WPF to redraw
        /// </summary>
        protected void InternalInvalidateVideoImage()
        {
            /* Ensure we run on the correct Dispatcher */
            if(!D3DImage.Dispatcher.CheckAccess())
            {
                D3DImage.Dispatcher.BeginInvoke((Action)(() => InvalidateVideoImage()));
                return;
            }

            /* If there is a new Surface to set,
             * this method will do the trick */
            SetBackBufferInternal(m_pBackBuffer);

            /* Only render the video image if possible, or if IsRenderingEnabled is true */
            if (D3DImage.IsFrontBufferAvailable && IsRenderingEnabled && m_pBackBuffer != IntPtr.Zero)
            {
                try
                {
                    /* Invalidate the entire image */
                    D3DImage.Lock();
                    D3DImage.AddDirtyRect(new Int32Rect(0, /* Left */
                                                        0, /* Top */
                                                        D3DImage.PixelWidth, /* Width */
                                                        D3DImage.PixelHeight /* Height */));
                    D3DImage.Unlock();
                }
                catch
                { }
            }

            /* Invalidate all of our cloned D3DRenderers */
            InvalidateClonedVideoImages();
        }

        /// <summary>
        /// Invalidates any possible cloned renderer we may have
        /// </summary>
        private void InvalidateClonedVideoImages()
        {
            lock(m_clonedD3Drenderers)
            {
                CleanZombieRenderers();
 
                foreach(var rendererRef in m_clonedD3Drenderers)
                {
                    var renderer = rendererRef.Target as D3DRenderer;
                    if(renderer != null)
                        renderer.InvalidateVideoImage();
                }
            }
        }
    }
}

InitializeD3DVideo()函数中,我尝试从硬盘上的某个位置读取xml文件.但这无法完成.

In the InitializeD3DVideo() function, I try to read a xml file from a location from the harddisk. But it can't be done.

d3drenderer.cs是否无法从xml文件读取?我只想从xml文件的_nABC中读取一个值.

Is it that the d3drenderer.cs cannot read from a xml file? I just want to read a value from _nABC of the xml file.

推荐答案

朋友,

此论坛讨论的是Visual Studio WPF/SL设计器,Visual Studio指导自动化工具包,开发人员文档和帮助系统以及Visual Studio编辑器.

This forum is discussing Visual Studio WPF/SL Designer, Visual Studio Guidance Automation Toolkit, Developer Documentation and Help System, and Visual Studio Editor.

您的问题与C#有关,我将该线程移至相应的论坛寻求专业解答.感谢您的理解.

Your issue is related to C#, I will move this thread to corresponding forum for a professional answer. Thanks for your understanding. 

最诚挚的问候,

Fletcher


这篇关于可以将xml阅读器功能放入D3drenderer.cs吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆