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