private HRESULT RenameOutputPin(SplitterOutputPin pPin, uint oldStreamId, uint newStreamId) { // Output Pin was found // Stop the Graph, remove the old filter, render the graph again, start it up again // This only works on pins that were connected before, or the filter graph could .. well, break if (pPin != null && pPin.IsConnected) { Logger.Info("RenameOutputPin() - Switching {0} Stream {1} to {2}", pPin.Name, oldStreamId, newStreamId); IMediaControl pControl = (IMediaControl)FilterGraph; FilterState oldState; // Get the graph state // If the graph is in transition, we'll get the next state, not the previous var hr = (HRESULT)pControl.GetState(10, out oldState); // Stop the filter graph hr = (HRESULT)pControl.Stop(); // Audio Filters get their connected filter removed // This way we make sure we reconnect to the proper filter // Other filters just disconnect and try to reconnect later on PinInfo pInfo; IPinImpl connectedPin = pPin.Connected; hr = (HRESULT)connectedPin.QueryPinInfo(out pInfo); // Update Output Pin AMMediaType pmt; if (MediaTypeBuilder.TryGetType(_streamParser.InputStream.AudioStream, out pmt)) { pPin.SetMediaType(pmt); } int mtIdx = connectedPin.QueryAccept(pmt); bool bMediaTypeFound = (mtIdx >= 0); if (pInfo.filter != null) { bool bRemoveFilter = !bMediaTypeFound; if (bRemoveFilter) { hr = (HRESULT)FilterGraph.RemoveFilter(pInfo.filter); // Use IGraphBuilder to rebuild the graph IGraphBuilder pGraphBuilder = (IGraphBuilder)FilterGraph; // Instruct the GraphBuilder to connect us again hr = (HRESULT)pGraphBuilder.Render(pPin); } else { hr = (HRESULT)ReconnectPin(pPin, pmt); } pPin.SetMediaType(pmt); } // Re-start the graph if (oldState == FilterState.Paused) { hr = (HRESULT)pControl.Pause(); } else if (oldState == FilterState.Running) { hr = (HRESULT)pControl.Run(); } return(hr); } return(E_FAIL); }