context: using System;
  using System.Runtime.InteropServices;
  using System.Windows.Forms;
  using System.Diagnostics;
  using System.Threading;
  using DirectShow;
  using System.Security.Permissions;
  using System.Collections.Generic;
  
  namespace Sonic
  {
      [SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
      [SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
      public class DSFilterGraphBase: COMHelper , IDisposable
      {
          #region Constants
  
          protected const int WM_GRAPHNOTIFY = 0x00008001;
  
          #endregion
  
          #region Helper Classes
  
          public class HelperForm : System.Windows.Forms.Form
          {
              protected override void WndProc(ref Message m)
              {
                  if (m.Msg == WM_GRAPHNOTIFY)
                  {
                      try
                      {
                          if (m.LParam != IntPtr.Zero)
                          {
                              DSFilterGraphBase _graph = (DSFilterGraphBase)Marshal.GetObjectForIUnknown(m.LParam);
                              if (_graph != null)
                              {
                                  if (_graph.ProcessGraphMessage())
                                  {
                                      _graph.Stop();
                                  }
                              }
                          }
                      }
                      catch
                      {
                      }
                  }
                  base.WndProc(ref m);
              }
          }
  
          #endregion
  
          #region Variables
  
          protected Control m_VideoControl = null;
          protected Control m_EventControl = new HelperForm();
          protected IGraphBuilder m_GraphBuilder = null;
          protected IMediaControl m_MediaControl = null;
          protected IMediaSeeking m_MediaSeeking = null;
          protected IMediaEventEx m_MediaEventEx = null;
          protected IVideoWindow m_VideoWindow = null;
          protected IBasicAudio m_BasicAudio = null;
          protected IBasicVideo m_BasicVideo = null;
          protected IVideoFrameStep m_FrameStep = null;
  
          protected bool m_bMute = false;
          protected int m_iVolume = 0;
          protected double m_dRate = 1.0;
          protected bool m_bShouldPreview = true;
  
          protected List<DSFilter> m_Filters = new List<DSFilter>();
  
          #endregion
  
          #region Constructor
  
          public DSFilterGraphBase()
          {
              
          }
  
          ~DSFilterGraphBase()
          {
              Dispose();
          }
  
          #endregion
  
          #region Properties
  
          public bool IsRunning
          {
              get
              {
                  if (m_MediaControl != null)
                  {
                      FilterState _state;
                      int hr = 0;
                      do
                      {
                          hr = m_MediaControl.GetState(200, out _state);
                      }
                      while (hr == 0x00040237 || hr == 0x00040268);
                      if (hr == 0)
                      {
                          return _state == FilterState.Running;
                      }
                  }
                  return false;
              }
          }
  
          public bool IsPaused
          {
              get
              {
                  if (m_MediaControl != null)
                  {
                      FilterState _state;
                      int hr = 0;
                      do
                      {
                          hr = m_MediaControl.GetState(200, out _state);
                      }
                      while (hr == 0x00040237 || hr == 0x00040268);
                      if (hr == 0)
                      {
                          return _state == FilterState.Paused;
                      }
                  }
                  return false;
              }
          }
  
          public bool IsStopped
          {
              get
              {
                  if (m_MediaControl != null)
                  {
                      FilterState _state;
                      int hr = 0;
                      do
                      {
                          hr = m_MediaControl.GetState(200, out _state);
                      }
                      while (hr == 0x00040237 || hr == 0x00040268);
                      if (hr == 0)
                      {
                          return _state == FilterState.Stopped;
                      }
                  }
                  return true;
              }
          }
  
          public long Position
          {
              get
              {
                  if (m_MediaSeeking != null)
                  {
                      long _time;
                      int hr = m_MediaSeeking.GetCurrentPosition(out _time);
                      Debug.Assert(hr == 0);
                      if (hr == 0) return _time;
                  }
                  return -1;
              }
              set
              {
                  if (m_MediaSeeking != null)
                  {
                      DsLong _stop = (long)0;
                      DsLong _current = value;
                      int hr = m_MediaSeeking.SetPositions(_current, AMSeekingSeekingFlags.AbsolutePositioning, _stop, AMSeekingSeekingFlags.NoPositioning);
                      Debug.Assert(hr >= 0);
                      if (OnPositionChange != null) OnPositionChange(this, EventArgs.Empty);
                  }
              }
          }
  
          public long Duration
          {
              get
              {
                  if (m_MediaSeeking != null)
                  {
                      long _time;
                      int hr = m_MediaSeeking.GetDuration(out _time);
                      Debug.Assert(hr == 0);
                      if (hr == 0) return _time;
                  }
                  return -1;
              }
          }
  
          public int Volume
          {
              get { return m_iVolume; }
              set
              {
                  m_iVolume = value;
                  if (!m_bMute)
                  {
                      SetVolume(value);
                  }
              }
          }
  
          public bool Mute
          {
              get { return m_bMute; }
              set
              {
                  if (m_bMute != value)
                  {
                      m_bMute = value;
                      SetVolume(m_bMute ? -10000 : m_iVolume);
                  }
              }
          }
  
          public double Rate
          {
              get
              {
                  return m_dRate;
              }
              set
              {
                  if (value > 0 && value <= 2.0)
                  {
                      if (m_MediaSeeking != null)
                      {
                          int hr = m_MediaSeeking.SetRate(value);
                          if (hr == 0)
                          {
                              m_dRate = value;
                          }
                      }
                      else
                      {
                          m_dRate = value;
                      }
                  }
              }
          }
  
          public Control VideoControl
          {
              get { return m_VideoControl; }
              set 
              {
                  if (m_VideoControl != value)
                  {
                      m_VideoControl = value;
                      m_VideoControl.Resize += new EventHandler(VideoControl_Resize);
                      m_VideoControl.VisibleChanged += new EventHandler(VideoControl_VisibleChanged);
                  }
              }
          }
  
          public bool Visible
          {
              get
              {
                  bool bVisible = ((m_VideoControl != null) ? m_VideoControl.Visible : false);
                  return m_bShouldPreview || bVisible;
              }
              set
              {
                  if (m_bShouldPreview != value)
                  {
                      m_bShouldPreview = value;
                      if (m_VideoWindow != null)
                      {
                          m_VideoWindow.put_AutoShow(m_bShouldPreview ? -1 : 0);
                          m_VideoWindow.put_Visible(m_bShouldPreview ? -1 : 0);
                      }
                  }
              }
          }
  
          public List<DSFilter> Filters
          {
              get 
              {
                  if (m_MediaControl == null)
                  {
                      while (m_Filters.Count > 0)
                      {
                          DSFilter _filter = m_Filters[0];
                          m_Filters.RemoveAt(0);
                          _filter.Dispose();
                      }
                      if (m_GraphBuilder != null)
                      {
                          IEnumFilters pEnum;
                          if (SUCCEEDED(m_GraphBuilder.EnumFilters(out pEnum)))
                          {
                              IBaseFilter[] aFilters = new IBaseFilter[1];
                              while (S_OK == pEnum.Next(1, aFilters, 0))
                              {
                                  m_Filters.Add(new DSFilter(aFilters[0]));
                              }
                              Marshal.ReleaseComObject(pEnum);
                          }
                      }
                  }
                  return m_Filters; 
              }
          }
  
          public int Count
          {
              get { return Filters.Count; }
          }
  
          public DSFilter AudioRenderer
          {
              get 
              {
                  List<DSFilter> _filters = Filters;
                  foreach (DSFilter _filter in _filters)
                  {
                      if (_filter.IsSupported(typeof(IBasicAudio).GUID))
                      {
                          return _filter;
                      }
                  }
                  return null; 
              }
          }
  
          public DSFilter VideoRenderer
          {
              get 
              {
                  List<DSFilter> _filters = Filters;
                  foreach (DSFilter _filter in _filters)
                  {
                      if (_filter.IsSupported(typeof(IVideoWindow)))
                      {
                          return _filter;
                      }
                  }
                  return null;
              }
          }
  
          public DSFilter this[int index]
          {
              get 
              {
                  try
                  {
                      return Filters[index];
                  }
                  catch
                  {
                      return null;
                  }
              }
          }
  
          public DSFilter this[string _name]
          {
              get 
              {
                  List<DSFilter> _filters = Filters;
                  foreach (DSFilter _filter in _filters)
                  {
                      if (_filter.Name == _name)
                      {
                          return _filter;
                      }
                  }
                  return null; 
              }
          }
  
          public bool IsAudioSupported
          {
              get 
              { 
                  return ((AudioRenderer != null) && AudioRenderer == true);
              }
          }
  
          #endregion
  
          #region Events
  
          public event EventHandler OnPlaybackPrepared;
          public event EventHandler OnPlaybackStart;
          public event EventHandler OnPlaybackStop;
          public event EventHandler OnPlaybackPause;
          public event EventHandler OnPositionChange;
          public event EventHandler OnPlaybackReady;
  
          #endregion
  
          #region Public Methods
  
          public virtual HRESULT Start()
          {
              int hr = 0;
  
gt:             if (m_MediaControl == null)