public DirectShowMovie()
     : base()
 {
     looping = false;
     allocator = null;
     streamer = null;
 }
        public bool Initialize(string n, string p, string t)
        {
            int hr = 0;

            path = p;
            name = n;
            textureName = t;
            if (textureName == null)
            {
                textureName = Manager.TextureName(this);
            }
            log.InfoFormat("DirectShowCodec[{0}] Initialize: {1} ({2}), texture '{3}'", ID(), name, path, textureName);

            // check for DirectX-ness
            if (!(Root.Instance.RenderSystem is Axiom.RenderSystems.DirectX9.D3D9RenderSystem))
            {
                throw new Exception("DirectShow movie codec is DirectX only");
            }
            if ((Root.Instance.RenderSystem as D3D9RenderSystem).PrimaryWindow == null)
            {
                throw new Exception("Initializing before primary window has been created");
            }
            D3DRenderWindow rw = (Root.Instance.RenderSystem as D3D9RenderSystem).PrimaryWindow;

            // Create a DirectShow FilterGraph
            graphBuilder = (IFilterGraph2)new FilterGraph();

            // Add it in ROT for debug purpose
            rot = new DsROTEntry(graphBuilder);

            // Create a VMR9 object
            vmr9 = (IBaseFilter)new VideoMixingRenderer9();

            IVMRFilterConfig9 filterConfig = (IVMRFilterConfig9)vmr9;

            // We want the Renderless mode!
            hr = filterConfig.SetRenderingMode(VMR9Mode.Renderless);
            DsError.ThrowExceptionForHR(hr);

            // One stream is enough for this sample
            hr = filterConfig.SetNumberOfStreams(1);
            DsError.ThrowExceptionForHR(hr);

            // Create the Allocator / Presenter object
            Device device = (Device)rw.GetCustomAttribute("D3DDEVICE");
            allocator = new DirectShowAllocator(device, ID(), TextureName());

            IVMRSurfaceAllocatorNotify9 vmrSurfAllocNotify = (IVMRSurfaceAllocatorNotify9)vmr9;

            // Notify the VMR9 filter about our allocator
            hr = vmrSurfAllocNotify.AdviseSurfaceAllocator(IntPtr.Zero, allocator);
            DsError.ThrowExceptionForHR(hr);

            // Notify our allocator about the VMR9 filter
            hr = allocator.AdviseNotify(vmrSurfAllocNotify);
            DsError.ThrowExceptionForHR(hr);

            IVMRMixerControl9 mixerControl = (IVMRMixerControl9)vmr9;

            // Select the mixer mode : YUV or RGB
            hr = mixerControl.SetMixingPrefs(VMR9MixerPrefs.RenderTargetYUV | VMR9MixerPrefs.NoDecimation | VMR9MixerPrefs.ARAdjustXorY | VMR9MixerPrefs.BiLinearFiltering);
            DsError.ThrowExceptionForHR(hr);

            // Add the VMR-9 filter to the graph
            hr = graphBuilder.AddFilter(vmr9, "Video Mixing Renderer 9");
            DsError.ThrowExceptionForHR(hr);

            bool shouldStream = false;
            string url = path;
            #if false
            int maxRedirects = DirectShowWebReader.MAX_REDIRECTS;
            DirectShowWebReader reader = null;
            while (maxRedirects != 0)
            {
                if (url.StartsWith("http://") || url.StartsWith("https://"))
                {
                    try
                    {
                        // Start reading the data
                        reader = new DirectShowWebReader();
                        hr = reader.Load(url);
                        DsError.ThrowExceptionForHR(hr);
                        shouldStream = true;
                        break;
                    }
                    catch (DirectShowWebReader.RedirectException e)
                    {
                        log.Info("Redirect to (" + e.url + ")");
                        url = e.url;
                        maxRedirects--;
                        reader = null;
                    }
                }
                else
                {
                    shouldStream = false;
                    reader = null;
                    break;
                }
            }
            if (maxRedirects == 0)
            {
                log.Warn("Stopped redirection after " + DirectShowWebReader.MAX_REDIRECTS + " attempts.");
            }
            #else
            shouldStream = DirectShowCodec.ShouldStream(url);
            #endif
            if(shouldStream)
            {
            #if false
                // Add our source filter to the graph
                DirectShowStreamer strm = new DirectShowStreamer(reader);
                hr = graphBuilder.AddFilter(strm, DirectShowStreamer.FILTER_NAME);
                DsError.ThrowExceptionForHR(hr);
                streamer = strm;
                streamer.SetType(reader.MajorType, reader.MinorType);

                // Render the file
                hr = graphBuilder.Render(strm.GetOutputPin());
                DsError.ThrowExceptionForHR(hr);
            #else
                WMAsfReader asf = new WMAsfReader();
                IBaseFilter ibf = (asf as IBaseFilter);
                IFileSourceFilter ifs = (asf as IFileSourceFilter);
                hr = ifs.Load(url, IntPtr.Zero);
                DsError.ThrowExceptionForHR(hr);

                // XXXMLM - how to set buffer time?
                // IWMStreamConfig2 on the output pins?

                hr = graphBuilder.AddFilter(ibf, "WM ASF Reader");
                DsError.ThrowExceptionForHR(hr);

                IEnumPins ie;
                IPin[] pins = new IPin[1];
                hr = ibf.EnumPins(out ie);
                int fetched = 0;
                while (hr == 0)
                {
                    hr = ie.Next(1, pins, out fetched);
                    if (fetched != 0)
                    {
                        hr = graphBuilder.Render(pins[0]);
                        DsError.ThrowExceptionForHR(hr);
                    }
                }
            #endif
            }
            else
            {
                // Render the file
                hr = graphBuilder.RenderFile(url, null);
                DsError.ThrowExceptionForHR(hr);
            }

            #if true
            // Run the graph
            hr = (graphBuilder as IMediaControl).Run();
            DsError.ThrowExceptionForHR(hr);

            // Wait for ready
            hr = (graphBuilder as IMediaControl).Pause();
            DsError.ThrowExceptionForHR(hr);

            ps = PLAY_STATE.BUFFERING;
            #endif
            return true;
        }
        public override void Unload()
        {
            lock (this)
            {
                int hr = 0;

                log.InfoFormat("DirectShowCodec[{0}]: unload", ID());

                // Remove the ROT entry
                if (rot != null)
                {
                    rot.Dispose();
                }

                if (graphBuilder != null)
                {
                    // Stop DirectShow notifications
                    hr = (graphBuilder as IMediaEventEx).SetNotifyWindow(IntPtr.Zero, 0, IntPtr.Zero);

                    // Stop the graph
                    hr = (graphBuilder as IMediaControl).StopWhenReady();
                    hr = (graphBuilder as IMediaControl).Stop();

                    // Dispose the allocator
                    allocator.Dispose();
                    allocator = null;

                    // Release DirectShow objects
                    Marshal.ReleaseComObject(vmr9);
                    Marshal.ReleaseComObject(graphBuilder);
                    graphBuilder = null;
                }

                if (streamer != null)
                {
                    streamer.Shutdown();
                    streamer = null;
                }
                base.Unload();
            }
        }