Beispiel #1
0
        internal static IRenderer AddRenderer(IDvdGraphBuilder pDVDGraphBuilder,
                                              IGraphBuilder pGraphBuilder,
                                              RendererBase renderer,
                                              IntPtr hMediaWindow)
        {
            // this methods will instruct DVDGraphBuilder to instantiate and use the specified renderer; it will return a wrapper if it was successful
            // it will return null if there were errors instantiating the preferred renderer;
            // in this case the program should fall back on the default renderer by calling GetExistingRenderer after the graph is built
            // it will throw an exception (originating from renderers' Initialize method) if initialization fails (similar behavior when adding renderers to non-DVD graphs)

            try
            {
                if (renderer.Instantiate(pDVDGraphBuilder, pGraphBuilder))
                {
                    if (!renderer.IsDelayedInitialize)
                    {
                        renderer.Initialize(pGraphBuilder, hMediaWindow);
                    }

                    renderer.GraphBuilder      = pGraphBuilder;
                    renderer.MediaWindowHandle = hMediaWindow;
                    renderer._ready            = true;
                    return(renderer);
                }

                return(null);
            }
            finally
            {
                if (renderer != null && !renderer._ready)
                {
                    renderer.Close();
                }
            }
        }
Beispiel #2
0
        internal static IRenderer AddRenderer(IDvdGraphBuilder pDVDGraphBuilder,
                                              IGraphBuilder pGraphBuilder,
                                              Renderer preferredVideoRenderer,
                                              IntPtr hMediaWindow)
        {
            // this methods will instruct DVDGraphBuilder to instantiate and use the preferred renderer; it will return a wrapper if it was successful
            // it will return null if:
            // a) preferredVideoRenderer is VR -> we can't instruct DVDGraphBuilder to create one so the program will have a possibility to fall back on the default one
            // b) there were errors instantiating the preferred renderer; in this case the program should fall back on the default renderer by calling GetExistingRenderer
            //    after the graph is built
            // it will throw an exception (originating from renderers' Initialize method) if initialization fails (similar behavior when adding renderers to non-DVD graphs)
            RendererBase renderer = null;

            try
            {
                if (preferredVideoRenderer != Renderer.VR)
                {
                    renderer = GetRenderer(preferredVideoRenderer);
                    return(AddRenderer(pDVDGraphBuilder, pGraphBuilder, renderer, hMediaWindow));
                }

                return(null);
            }
            finally
            {
                if (renderer != null && !renderer._ready)
                {
                    renderer.Close();
                }
            }
        }
Beispiel #3
0
        internal static IRenderer AddRenderer(IGraphBuilder pGraphBuilder,
                                              Renderer preferredVideoRenderer,
                                              ThrowExceptionForHRPointer errorFunc,
                                              IntPtr hMediaWindow,
                                              bool fallBackOnVR)
        {
            RendererBase renderer = GetRenderer(preferredVideoRenderer);

            return(AddRenderer(pGraphBuilder, renderer, errorFunc, hMediaWindow, fallBackOnVR));
        }
Beispiel #4
0
        internal static IRenderer AddRenderer(IGraphBuilder pGraphBuilder,
                                              RendererBase renderer,
                                              ThrowExceptionForHRPointer errorFunc,
                                              IntPtr hMediaWindow,
                                              bool fallBackOnVR)
        {
            try
            {
                bool bOk = renderer.InstantiateRenderer();
                if (!bOk)
                {
                    if (fallBackOnVR)
                    {
                        // try default renderer
                        renderer.Close();
                        renderer = GetRenderer(Renderer.VR);
                        renderer.InstantiateRenderer(); // it will throw FilterGraphBuilderException if it can't be instantiated
                    }
                    else
                    {
                        throw new FilterGraphBuilderException(GraphBuilderError.VideoRenderer);
                    }
                }

                renderer.AddToGraph(pGraphBuilder, errorFunc);

                // Windowed renderers should be initialized (parent window is set, etc) _after_ the renderer is connected because a video window is created then
                // On the contrary windowless renderes _must_ be initialized _before_ they are connected
                if (!renderer.IsDelayedInitialize)
                {
                    renderer.Initialize(pGraphBuilder, hMediaWindow);
                }

                renderer.GraphBuilder      = pGraphBuilder;
                renderer.MediaWindowHandle = hMediaWindow;
                renderer._ready            = true;
                return(renderer);
            }
            finally
            {
                if (!renderer._ready)
                {
                    renderer.Close();
                }
            }
        }
Beispiel #5
0
        public static RendererBase GetRenderer(Guid ClsId)
        {
            RendererBase renderer = null;

            if (ClsId == Clsid.VideoRenderer)
            {
                renderer = new VideoRenderer();
            }
            else if (ClsId == Clsid.VideoMixingRenderer)
            {
                renderer = new VMRWindowed(); // by default VMR operates in windowed mode with a single video stream, also called compatibility mode
            }
            else if (ClsId == Clsid.VideoMixingRenderer9)
            {
                renderer = new VMR9Windowed(); // VMR-9 defaults to windowed mode with four input pins
            }
            else if (ClsId == Clsid.EnhancedVideoRenderer)
            {
                renderer = new EVR(); // EVR is windowless with 1 input pin
            }
            return(renderer);
        }
Beispiel #6
0
        internal static IRenderer SubstituteRenderer(IGraphBuilder pGraphBuilder, IntPtr hMediaWindow, Renderer desiredRenderer)
        {
            RendererBase existingRenderer = (RendererBase)GetExistingRenderer(pGraphBuilder, hMediaWindow);
            // existingRenderer is either VR or VMR windowed (default mode for VMR); VMR9 and EVR are never default renderers
            // VR and VMRWindowed need delayed initialization or it's ok to reconnect them before we call GetNativeVideoSize

            // if desiredRenderer fails we will return the existing one
            IRenderer renderer = existingRenderer;

            if (existingRenderer.Renderer != desiredRenderer && desiredRenderer != Renderer.VR) // substitution with VR doesn't work well at least on Vista 64bit
            {
                RendererBase newRenderer = null;
                try
                {
                    newRenderer = (RendererBase)AddRenderer(pGraphBuilder,
                                                            desiredRenderer,
                                                            delegate(int hrCode, GraphBuilderError error) { },
                                                            hMediaWindow,
                                                            false);
                    IPin existingRendererInput, decoderOut;
                    if (existingRenderer.GetPins(out existingRendererInput, out decoderOut))
                    {
                        IPin newRendererInput = newRenderer.GetInputPin();
                        if (newRendererInput != null)
                        {
                            int hr = pGraphBuilder.Connect(decoderOut, newRendererInput);
                            if (DsHlp.SUCCEEDED(hr))
                            {
                                renderer    = newRenderer;
                                newRenderer = null; // so that we don't close it (see finally)

                                Marshal.ReleaseComObject(existingRendererInput);
                                existingRendererInput = null;
                                existingRenderer.RemoveFromGraph();
                            }
                            else
                            {
                                hr = pGraphBuilder.Connect(decoderOut, existingRendererInput);
                            }
                            Marshal.ReleaseComObject(newRendererInput);
                        }

                        if (existingRendererInput != null)
                        {
                            Marshal.ReleaseComObject(existingRendererInput);
                        }
                        Marshal.ReleaseComObject(decoderOut);
                    }
                }
                catch // VR throws it if it can't be instantiated; also renderers will throw an expection if they can't be added to the graph
                {     // we just ignore it here and return existingRenderer
                }
                finally
                {
                    if (newRenderer != null)
                    {
                        newRenderer.Close();
                    }
                }
            }
            return(renderer);
        }
Beispiel #7
0
        internal static IRenderer GetExistingRenderer(IGraphBuilder pGraphBuilder, IntPtr hMediaWindow)
        {
            // this method is to be called to create a wrapper for a renderer that is already in the graph (added by intelligent connect)
            // at the momemnt it is assumed that this is a Windowed Renderer (compatability assumption)
            RendererBase renderer = null;

            try
            {
                IEnumFilters pEnum = null;
                IBaseFilter  pFilter;
                int          cFetched;

                int hr = pGraphBuilder.EnumFilters(out pEnum);
                if (DsHlp.SUCCEEDED(hr))
                {
                    while (pEnum.Next(1, out pFilter, out cFetched) == DsHlp.S_OK)
                    {
                        Guid clsid;
                        if (pFilter.GetClassID(out clsid) == DsHlp.S_OK)
                        {
                            renderer = GetRenderer(clsid);
                            if (renderer != null)
                            {
                                renderer.BaseFilter = pFilter;
                                break;
                            }
                            else
                            {
                                Marshal.ReleaseComObject(pFilter);
                            }
                        }
                        else
                        {
                            Marshal.ReleaseComObject(pFilter);
                        }
                    }

                    Marshal.ReleaseComObject(pEnum);
                }

                if (renderer == null)
                {
                    renderer = TryGetUnknownRenderer(pGraphBuilder); // last resort
                }
                if (renderer == null)
                {
                    throw new FilterGraphBuilderException(GraphBuilderError.VideoRenderer); // we've tried hard enough, there is no point to continue
                }
                if (!renderer.IsDelayedInitialize)
                {
                    renderer.Initialize(pGraphBuilder, hMediaWindow);
                }

                renderer.GraphBuilder      = pGraphBuilder;
                renderer.MediaWindowHandle = hMediaWindow;
                renderer._ready            = true;
                return(renderer);
            }
            finally
            {
                if (renderer != null && !renderer._ready)
                {
                    renderer.Close();
                }
            }
        }
Beispiel #8
0
        private static RendererBase TryGetUnknownRenderer(IGraphBuilder pGraphBuilder)
        {
            // this is the last resort
            RendererBase renderer = null;

            IEnumFilters pEnum = null;
            IBaseFilter  pFilter;
            int          cFetched;

            int hr = pGraphBuilder.EnumFilters(out pEnum);

            if (DsHlp.SUCCEEDED(hr))
            {
                bool bFound = false;
                while (!bFound && pEnum.Next(1, out pFilter, out cFetched) == DsHlp.S_OK)
                {
                    IPin pPin = null;
                    // there should be no output pins
                    if ((pPin = DsUtils.GetPin(pFilter, PinDirection.Output, false)) != null)
                    {
                        // there is an unconnected output pin, this is not a renderer
                        Marshal.ReleaseComObject(pPin);
                    }
                    else if ((pPin = DsUtils.GetPin(pFilter, PinDirection.Output, true)) != null)
                    {
                        // there is a connected output pin, this is not a renderer
                        Marshal.ReleaseComObject(pPin);
                    }
                    else
                    {
                        // let's check the input pins: there must be at least one connected of type 'video'
                        int nSkip = 0;
                        while ((pPin = DsUtils.GetPin(pFilter, PinDirection.Input, true, nSkip)) != null)
                        {
                            if (DsUtils.IsMediaTypeSupported(pPin, MediaType.Video) == 0)
                            {
                                // there is connected input pin of type 'video'; this looks like a renderer
                                Marshal.ReleaseComObject(pPin);
                                renderer            = GetRenderer(Renderer.VR); // let's just default it VR
                                renderer.BaseFilter = pFilter;
                                bFound = true;
                                break;
                            }
                            else
                            {
                                nSkip++;
                                Marshal.ReleaseComObject(pPin);
                            }
                        }
                    }

                    if (!bFound)
                    {
                        Marshal.ReleaseComObject(pFilter);
                    }
                }

                Marshal.ReleaseComObject(pEnum);
            }

            return(renderer);
        }