/// <summary> /// Adds the subtitle filter to the graph. /// </summary> /// <param name="_graphBuilder"></param> /// <returns></returns> public IBaseFilter AddSubtitleFilter(IGraphBuilder _graphBuilder) { try { _filter = DirectShowUtil.AddFilterToGraph(_graphBuilder, "MediaPortal DVBSub3"); _subFilter = _filter as IDVBSubtitleSource; Log.Debug("SubtitleRenderer: CreateFilter success: " + (_filter != null) + " & " + (_subFilter != null)); } catch (Exception e) { Log.Error(e); } _subFilter.StatusTest(111); IntPtr pCallback = Marshal.GetFunctionPointerForDelegate(_callBack); _subFilter.SetBitmapCallback(pCallback); _subFilter.StatusTest(222); IntPtr pResetCallBack = Marshal.GetFunctionPointerForDelegate(_resetCallBack); _subFilter.SetResetCallback(pResetCallBack); IntPtr pUpdateTimeoutCallBack = Marshal.GetFunctionPointerForDelegate(_updateTimeoutCallBack); _subFilter.SetUpdateTimeoutCallback(pUpdateTimeoutCallBack); return(_filter); }
public void AddPreferedCodecs(IGraphBuilder _graphBuilder) { // add preferred video & audio codecs string strVideoCodec = ""; string strAudioCodec = ""; string strAudiorenderer = ""; int intFilters = 0; // FlipGer: count custom filters string strFilters = ""; // FlipGer: collect custom filters using (MediaPortal.Profile.Settings xmlreader = new MPSettings()) { // FlipGer: load infos for custom filters int intCount = 0; while (xmlreader.GetValueAsString("dvdplayer", "filter" + intCount.ToString(), "undefined") != "undefined") { if (xmlreader.GetValueAsBool("dvdplayer", "usefilter" + intCount.ToString(), false)) { strFilters += xmlreader.GetValueAsString("dvdplayer", "filter" + intCount.ToString(), "undefined") + ";"; intFilters++; } intCount++; } strVideoCodec = xmlreader.GetValueAsString("dvdplayer", "videocodec", ""); strAudioCodec = xmlreader.GetValueAsString("dvdplayer", "audiocodec", ""); strAudiorenderer = xmlreader.GetValueAsString("dvdplayer", "audiorenderer", "Default DirectSound Device"); } if (strVideoCodec.Length > 0) { DirectShowUtil.AddFilterToGraph(_graphBuilder, strVideoCodec); } if (strAudioCodec.Length > 0) { DirectShowUtil.AddFilterToGraph(_graphBuilder, strAudioCodec); } if (strAudiorenderer.Length > 0) { DirectShowUtil.AddAudioRendererToGraph(_graphBuilder, strAudiorenderer, false); } // FlipGer: add custom filters to graph string[] arrFilters = strFilters.Split(';'); for (int i = 0; i < intFilters; i++) { DirectShowUtil.AddFilterToGraph(_graphBuilder, arrFilters[i]); } }
bool?tryAddSourceFilter() { bool? result = null; IBaseFilter sourceFilter = null; try { sourceFilter = DirectShowUtil.AddFilterToGraph(graphBuilder, sourceFilterName); if (sourceFilter != null) { //openProgress = sourceFilter as IAMOpenProgress; result = true; Logger.Instance.Debug("AirPlayerVideo: Using source filter '{0}'", sourceFilterName); } } catch (Exception ex) { Logger.Instance.Warn("Error adding '{0}' filter to graph: {1}", sourceFilterName, ex.Message); } finally { if (sourceFilter != null) { DirectShowUtil.ReleaseComObject(sourceFilter); } } if (result == null && sourceFilterName != DEFAULT_SOURCE_FILTER) { Logger.Instance.Warn("Failed to add source filter '{0}', falling back to default source filter '{1}'", sourceFilterName, DEFAULT_SOURCE_FILTER); sourceFilterName = DEFAULT_SOURCE_FILTER; return(tryAddSourceFilter()); } return(result); }
public static IBaseFilter AddToGraph(IGraphBuilder graphBuilder) { IBaseFilter vob = null; using (Settings xmlreader = new MPSettings()) { string engineType = xmlreader.GetValueAsString("subtitles", "engine", "DirectVobSub"); XySubFilter = engineType.Equals("XySubFilter"); } if (!XySubFilter) { DirectShowUtil.FindFilterByClassID(graphBuilder, ClassId.DirectVobSubAutoload, out vob); if (vob == null) { //Try the "normal" filter then. DirectShowUtil.FindFilterByClassID(graphBuilder, ClassId.DirectVobSubNormal, out vob); } } else { //Try the XySubFilter "autoload" filter. DirectShowUtil.FindFilterByClassID(graphBuilder, ClassId.XySubFilterAutoload, out vob); if (vob != null) { return(vob); } //Try the XySubFilter "normal" filter then. DirectShowUtil.FindFilterByClassID(graphBuilder, ClassId.XySubFilterNormal, out vob); if (vob != null) { return(vob); } vob = DirectShowUtil.AddFilterToGraph(graphBuilder, "XySubFilter"); if (vob == null) { Log.Warn("VideoPlayerVMR9: DirectVobSub or XySubFilter filter not found! You need to install XySubFilter"); return(null); } Log.Debug("VideoPlayerVMR9: VobSub filter added to graph"); return(vob); } //if the directvobsub filter has not been added to the graph. (i.e. with evr) //we add a bit more intelligence to determine if subtitles are enabled. //and if subtitles are present for the video / movie then we add it if necessary to the graph. if (vob == null) { Log.Info("VideoPlayerVMR9: No VobSub filter in the current graph"); //the filter has not been added lets check if it should be added or not. //add the filter to the graph vob = DirectShowUtil.AddFilterToGraph(graphBuilder, "DirectVobSub"); if (vob == null) { Log.Warn("VideoPlayerVMR9: DirectVobSub or XySubFilter filter not found! You need to install VSFilter"); return(null); } Log.Debug("VideoPlayerVMR9: VobSub filter added to graph"); } else // VobSub already loaded { return(vob); } // Check if Haali Media Splitter is in the graph. IBaseFilter hms = null; DirectShowUtil.FindFilterByClassID(graphBuilder, ClassId.HaaliGuid, out hms); if (hms == null) { DirectShowUtil.FindFilterByClassID(graphBuilder, ClassId.MPCMatroska, out hms); } if (hms == null) { DirectShowUtil.FindFilterByClassID(graphBuilder, ClassId.MPCMatroskaSource, out hms); } if (hms == null) { DirectShowUtil.FindFilterByClassID(graphBuilder, ClassId.LAVFilter, out hms); } if (hms == null) { DirectShowUtil.FindFilterByClassID(graphBuilder, ClassId.LAVFilterSource, out hms); } if (hms != null) { IPin pinSubTo = null; // It is. Connect it' subtitle output pin (if any) to Vobsub's subtitle input. pinSubTo = DirectShowUtil.FindPin(hms, PinDirection.Output, "Subtitle"); if (pinSubTo == null) { while (true) { IPin freeSubtitle = DirectShowUtil.FindFirstFreePinSub(hms, PinDirection.Output, ""); IPin freeVobSub = DirectShowUtil.FindFirstFreePin(vob, PinDirection.Input, "Input"); if (freeSubtitle != null && freeVobSub != null) { Log.Debug("VideoPlayerVMR9: Connecting Matroska's subtitle output to VobSub's input."); graphBuilder.Connect(freeSubtitle, freeVobSub); DirectShowUtil.ReleaseComObject(freeSubtitle); freeSubtitle = null; DirectShowUtil.ReleaseComObject(freeVobSub); freeVobSub = null; } else { break; } } } DirectShowUtil.ReleaseComObject(hms); hms = null; if (pinSubTo != null) { Log.Debug("VideoPlayerVMR9: Connecting Haali's subtitle output to VobSub's input."); // Try to render pins IPin pinVobSubSub = DirectShowUtil.FindPin(vob, PinDirection.Input, "Input"); // If pinSubTo is already connected (disconnect it) graphBuilder.Disconnect(pinSubTo); graphBuilder.Connect(pinSubTo, pinVobSubSub); DirectShowUtil.ReleaseComObject(pinSubTo); pinSubTo = null; DirectShowUtil.ReleaseComObject(pinVobSubSub); pinVobSubSub = null; } } // Now check if vobsub's video input is not connected. // Check only if vmr9 is connected (render was successful). VMR9Util Vmr9 = VMR9Util.g_vmr9; if (Vmr9.IsVMR9Connected) { Log.Debug("VideoPlayerVMR9: Connect VobSub's video pins"); IPin pinVobSubVideoIn = DsFindPin.ByDirection(vob, PinDirection.Input, 0); IPin pinVobSubVideoOut = DsFindPin.ByDirection(vob, PinDirection.Output, 0); // This is the pin that we will connect to vobsub's input. IPin pinVideoTo = Vmr9.PinConnectedTo; IPin pinVideoFrom = null; pinVideoTo.ConnectedTo(out pinVideoFrom); pinVideoTo.Disconnect(); pinVideoFrom.Disconnect(); //Now make connection to VobSub int hr = graphBuilder.Connect(pinVideoTo, pinVobSubVideoIn); //hr = graphBuilder.Render(pinVideoFrom); if (hr != 0) { Log.Error("VideoPlayerVMR9: could not connect Vobsub's input video pin"); return(null); } hr = graphBuilder.Connect(pinVobSubVideoOut, pinVideoFrom); //hr = graphBuilder.Render(pinVobSubVideoOut); if (hr != 0) { Log.Error("VideoPlayerVMR9: could not connect Vobsub's output video pin"); return(null); } Log.Debug("VideoPlayerVMR9: Vobsub's video pins connected"); DirectShowUtil.ReleaseComObject(pinVideoTo); pinVideoTo = null; DirectShowUtil.ReleaseComObject(pinVobSubVideoIn); pinVobSubVideoIn = null; DirectShowUtil.ReleaseComObject(pinVobSubVideoOut); pinVobSubVideoOut = null; DirectShowUtil.ReleaseComObject(pinVideoFrom); pinVideoFrom = null; } Vmr9 = null; return(vob); }
public bool Transcode(TranscodeInfo info, MediaPortal.Core.Transcoding.VideoFormat format, MediaPortal.Core.Transcoding.Quality quality, Standard standard) { if (!Supports(format)) { return(false); } string ext = System.IO.Path.GetExtension(info.file); if (ext.ToLower() != ".dvr-ms" && ext.ToLower() != ".sbe") { Log.Info("DVRMS2DIVX: wrong file format"); return(false); } //disable xvid status window while encoding /* try * { * using (RegistryKey subkey = Registry.CurrentUser.OpenSubKey(@"Software\GNU\XviD", true)) * { * if (subkey != null) * { * Int32 uivalue = 0; * subkey.SetValue("display_status", (Int32)uivalue); * subkey.SetValue("debug", (Int32)uivalue); * subkey.SetValue("bitrate", (Int32)bitrate); * * uivalue = 1; * subkey.SetValue("interlacing", (Int32)uivalue); * } * } * } * catch (Exception) * { * }*/ //Type comtype = null; //object comobj = null; try { graphBuilder = (IGraphBuilder) new FilterGraph(); _rotEntry = new DsROTEntry((IFilterGraph)graphBuilder); Log.Info("DVRMS2DIVX: add filesource"); bufferSource = (IStreamBufferSource) new StreamBufferSource(); IBaseFilter filter = (IBaseFilter)bufferSource; graphBuilder.AddFilter(filter, "SBE SOURCE"); IFileSourceFilter fileSource = (IFileSourceFilter)bufferSource; Log.Info("DVRMS2DIVX: load file:{0}", info.file); int hr = fileSource.Load(info.file, null); /*string strDemuxerMoniker = @"@device:sw:{083863F1-70DE-11D0-BD40-00A0C911CE86}\{AFB6C280-2C41-11D3-8A60-0000F81E0E4A}"; * * mpegDemuxer = Marshal.BindToMoniker(strDemuxerMoniker) as IBaseFilter; * if (mpegDemuxer == null) * { * Log.Error("DVRMS2DIVX:FAILED:unable to add mpeg2 demuxer"); * Cleanup(); * return false; * } * hr = graphBuilder.AddFilter(mpegDemuxer, "MPEG-2 Demultiplexer"); * if (hr != 0) * { * Log.Error("DVRMS2DIVX:FAILED:Add mpeg2 demuxer to filtergraph :0x{0:X}", hr); * Cleanup(); * return false; * }*/ //add mpeg2 audio/video codecs string strVideoCodecMoniker = @"@device:sw:{083863F1-70DE-11D0-BD40-00A0C911CE86}\{39F498AF-1A09-4275-B193-673B0BA3D478}"; string strAudioCodec = "MPC - MPA Decoder Filter"; Log.Info("DVRMS2DIVX: add MPV mpeg2 video decoder"); Mpeg2VideoCodec = Marshal.BindToMoniker(strVideoCodecMoniker) as IBaseFilter; if (Mpeg2VideoCodec == null) { Log.Error("DVRMS2DIVX:FAILED:unable to add MPV mpeg2 video decoder"); Cleanup(); return(false); } hr = graphBuilder.AddFilter(Mpeg2VideoCodec, "MPC - MPEG-2 Video Decoder (Gabest)"); if (hr != 0) { Log.Error("DVRMS2DIVX:FAILED:Add MPV mpeg2 video to filtergraph :0x{0:X}", hr); Cleanup(); return(false); } Log.Info("DVRMS2DIVX: add MPA mpeg2 audio codec:{0}", strAudioCodec); Mpeg2AudioCodec = DirectShowUtil.AddFilterToGraph(graphBuilder, strAudioCodec); if (Mpeg2AudioCodec == null) { Log.Error("DVRMS2DIVX:FAILED:unable to add MPV mpeg2 audio codec"); Cleanup(); return(false); } //connect output #0 of streambuffer source->mpeg2 audio codec pin 1 //connect output #1 of streambuffer source->mpeg2 video codec pin 1 Log.Info("DVRMS2DIVX: connect streambufer source->mpeg audio/video decoders"); IPin pinOut0, pinOut1; IPin pinIn0, pinIn1; pinOut0 = DsFindPin.ByDirection((IBaseFilter)bufferSource, PinDirection.Output, 0); //audio pinOut1 = DsFindPin.ByDirection((IBaseFilter)bufferSource, PinDirection.Output, 1); //video if (pinOut0 == null || pinOut1 == null) { Log.Error("DVRMS2DIVX:FAILED:unable to get pins of source"); Cleanup(); return(false); } pinIn0 = DsFindPin.ByDirection(Mpeg2VideoCodec, PinDirection.Input, 0); //video pinIn1 = DsFindPin.ByDirection(Mpeg2AudioCodec, PinDirection.Input, 0); //audio if (pinIn0 == null || pinIn1 == null) { Log.Error("DVRMS2DIVX:FAILED:unable to get pins of mpeg2 video/audio codec"); Cleanup(); return(false); } hr = graphBuilder.Connect(pinOut0, pinIn1); if (hr != 0) { Log.Error("DVRMS2DIVX:FAILED:unable to connect audio pins :0x{0:X}", hr); Cleanup(); return(false); } hr = graphBuilder.Connect(pinOut1, pinIn0); if (hr != 0) { Log.Error("DVRMS2DIVX:FAILED:unable to connect video pins :0x{0:X}", hr); Cleanup(); return(false); } if (!AddCodecs(graphBuilder, info)) { return(false); } // hr=(graphBuilder as IMediaFilter).SetSyncSource(null); // if (hr!=0) // Log.Error("DVRMS2DIVX:FAILED:to SetSyncSource :0x{0:X}",hr); mediaControl = graphBuilder as IMediaControl; mediaSeeking = bufferSource as IStreamBufferMediaSeeking; mediaEvt = graphBuilder as IMediaEventEx; mediaPos = graphBuilder as IMediaPosition; //get file duration Log.Info("DVRMS2DIVX: Get duration of movie"); long lTime = 5 * 60 * 60; lTime *= 10000000; long pStop = 0; hr = mediaSeeking.SetPositions(new DsLong(lTime), AMSeekingSeekingFlags.AbsolutePositioning, new DsLong(pStop), AMSeekingSeekingFlags.NoPositioning); if (hr == 0) { long lStreamPos; mediaSeeking.GetCurrentPosition(out lStreamPos); // stream position m_dDuration = lStreamPos; lTime = 0; mediaSeeking.SetPositions(new DsLong(lTime), AMSeekingSeekingFlags.AbsolutePositioning, new DsLong(pStop), AMSeekingSeekingFlags.NoPositioning); } double duration = m_dDuration / 10000000d; Log.Info("DVRMS2DIVX: movie duration:{0}", MediaPortal.Util.Utils.SecondsToHMSString((int)duration)); // hr=(graphBuilder as IMediaFilter).SetSyncSource(null); // if (hr!=0) // Log.Error("DVRMS2DIVX:FAILED:to SetSyncSource :0x{0:X}",hr); hr = mediaControl.Run(); if (hr != 0) { Log.Error("DVRMS2DIVX:FAILED:unable to start graph :0x{0:X}", hr); Cleanup(); return(false); } int maxCount = 20; while (true) { long lCurrent; mediaSeeking.GetCurrentPosition(out lCurrent); double dpos = (double)lCurrent; dpos /= 10000000d; System.Threading.Thread.Sleep(100); if (dpos >= 2.0d) { break; } maxCount--; if (maxCount <= 0) { break; } } mediaControl.Stop(); FilterState state; mediaControl.GetState(500, out state); GC.Collect(); GC.Collect(); GC.Collect(); GC.WaitForPendingFinalizers(); graphBuilder.RemoveFilter(aviMuxer); graphBuilder.RemoveFilter(divxCodec); graphBuilder.RemoveFilter(mp3Codec); graphBuilder.RemoveFilter((IBaseFilter)fileWriterFilter); if (!AddCodecs(graphBuilder, info)) { return(false); } // hr=(graphBuilder as IMediaFilter).SetSyncSource(null); // if (hr!=0) // Log.Error("DVRMS2DIVX:FAILED:to SetSyncSource :0x{0:X}",hr); Log.Info("DVRMS2DIVX: start transcoding"); hr = mediaControl.Run(); if (hr != 0) { Log.Error("DVRMS2DIVX:FAILED:unable to start graph :0x{0:X}", hr); Cleanup(); return(false); } } catch (Exception ex) { Log.Error("DVRMS2DIVX:Unable create graph: {0}", ex.Message); Cleanup(); return(false); } return(true); }
public bool Transcode(TranscodeInfo info, VideoFormat format, Quality quality, Standard standard) { try { if (!Supports(format)) { return(false); } string ext = System.IO.Path.GetExtension(info.file); if (ext.ToLowerInvariant() != ".ts" && ext.ToLowerInvariant() != ".mpg") { Log.Info("TSReader2WMV: wrong file format"); return(false); } Log.Info("TSReader2WMV: create graph"); graphBuilder = (IGraphBuilder) new FilterGraph(); _rotEntry = new DsROTEntry((IFilterGraph)graphBuilder); Log.Info("TSReader2WMV: add filesource"); TsReader reader = new TsReader(); tsreaderSource = (IBaseFilter)reader; //ITSReader ireader = (ITSReader)reader; //ireader.SetTsReaderCallback(this); //ireader.SetRequestAudioChangeCallback(this); IBaseFilter filter = (IBaseFilter)tsreaderSource; graphBuilder.AddFilter(filter, "TSReader Source"); IFileSourceFilter fileSource = (IFileSourceFilter)tsreaderSource; Log.Info("TSReader2WMV: load file:{0}", info.file); int hr = fileSource.Load(info.file, null); //add audio/video codecs string strVideoCodec = ""; string strH264VideoCodec = ""; string strAudioCodec = ""; string strAACAudioCodec = ""; using (MediaPortal.Profile.Settings xmlreader = new MediaPortal.Profile.MPSettings()) { strVideoCodec = xmlreader.GetValueAsString("mytv", "videocodec", ""); strAudioCodec = xmlreader.GetValueAsString("mytv", "audiocodec", ""); strAACAudioCodec = xmlreader.GetValueAsString("mytv", "aacaudiocodec", ""); strH264VideoCodec = xmlreader.GetValueAsString("mytv", "h264videocodec", ""); } //Find the type of decoder required for the output video & audio pins on TSReader. Log.Info("TSReader2WMV: find tsreader compatible audio/video decoders"); IPin pinOut0, pinOut1; IPin pinIn0, pinIn1; pinOut0 = DsFindPin.ByDirection((IBaseFilter)tsreaderSource, PinDirection.Output, 0); //audio pinOut1 = DsFindPin.ByDirection((IBaseFilter)tsreaderSource, PinDirection.Output, 1); //video if (pinOut0 == null || pinOut1 == null) { Log.Error("TSReader2WMV: FAILED: unable to get output pins of tsreader"); Cleanup(); return(false); } bool usingAAC = false; IEnumMediaTypes enumMediaTypes; hr = pinOut0.EnumMediaTypes(out enumMediaTypes); while (true) { AMMediaType[] mediaTypes = new AMMediaType[1]; int typesFetched; hr = enumMediaTypes.Next(1, mediaTypes, out typesFetched); if (hr != 0 || typesFetched == 0) { break; } if (mediaTypes[0].majorType == MediaType.Audio && mediaTypes[0].subType == MediaSubType.LATMAAC) { Log.Info("TSReader2WMV: found LATM AAC audio out pin on tsreader"); usingAAC = true; } } bool usingH264 = false; hr = pinOut1.EnumMediaTypes(out enumMediaTypes); while (true) { AMMediaType[] mediaTypes = new AMMediaType[1]; int typesFetched; hr = enumMediaTypes.Next(1, mediaTypes, out typesFetched); if (hr != 0 || typesFetched == 0) { break; } if (mediaTypes[0].majorType == MediaType.Video && mediaTypes[0].subType == AVC1) { Log.Info("TSReader2WMV: found H.264 video out pin on tsreader"); usingH264 = true; } } //Add the type of decoder required for the output video & audio pins on TSReader. Log.Info("TSReader2WMV: add audio/video decoders to graph"); if (usingH264 == false) { Log.Info("TSReader2WMV: add mpeg2 video decoder:{0}", strVideoCodec); VideoCodec = DirectShowUtil.AddFilterToGraph(graphBuilder, strVideoCodec); if (VideoCodec == null) { Log.Error("TSReader2WMV: unable to add mpeg2 video decoder"); Cleanup(); return(false); } } else { Log.Info("TSReader2WMV: add h264 video codec:{0}", strH264VideoCodec); VideoCodec = DirectShowUtil.AddFilterToGraph(graphBuilder, strH264VideoCodec); if (VideoCodec == null) { Log.Error("TSReader2WMV: FAILED:unable to add h264 video codec"); Cleanup(); return(false); } } if (usingAAC == false) { Log.Info("TSReader2WMV: add mpeg2 audio codec:{0}", strAudioCodec); AudioCodec = DirectShowUtil.AddFilterToGraph(graphBuilder, strAudioCodec); if (AudioCodec == null) { Log.Error("TSReader2WMV: FAILED:unable to add mpeg2 audio codec"); Cleanup(); return(false); } } else { Log.Info("TSReader2WMV: add aac audio codec:{0}", strAACAudioCodec); AudioCodec = DirectShowUtil.AddFilterToGraph(graphBuilder, strAACAudioCodec); if (AudioCodec == null) { Log.Error("TSReader2WMV: FAILED:unable to add aac audio codec"); Cleanup(); return(false); } } Log.Info("TSReader2WMV: connect tsreader->audio/video decoders"); //connect output #0 (audio) of tsreader->audio decoder input pin 0 //connect output #1 (video) of tsreader->video decoder input pin 0 pinIn0 = DsFindPin.ByDirection(AudioCodec, PinDirection.Input, 0); //audio pinIn1 = DsFindPin.ByDirection(VideoCodec, PinDirection.Input, 0); //video if (pinIn0 == null || pinIn1 == null) { Log.Error("TSReader2WMV: FAILED: unable to get pins of video/audio codecs"); Cleanup(); return(false); } hr = graphBuilder.Connect(pinOut0, pinIn0); if (hr != 0) { Log.Error("TSReader2WMV: FAILED: unable to connect audio pins :0x{0:X}", hr); Cleanup(); return(false); } hr = graphBuilder.Connect(pinOut1, pinIn1); if (hr != 0) { Log.Error("TSReader2WMV: FAILED: unable to connect video pins :0x{0:X}", hr); Cleanup(); return(false); } string outputFilename = System.IO.Path.ChangeExtension(info.file, ".wmv"); if (!AddWmAsfWriter(outputFilename, quality, standard)) { return(false); } Log.Info("TSReader2WMV: start pre-run"); mediaControl = graphBuilder as IMediaControl; mediaSeeking = tsreaderSource as IMediaSeeking; mediaEvt = graphBuilder as IMediaEventEx; mediaPos = graphBuilder as IMediaPosition; //get file duration long lTime = 5 * 60 * 60; lTime *= 10000000; long pStop = 0; hr = mediaSeeking.SetPositions(new DsLong(lTime), AMSeekingSeekingFlags.AbsolutePositioning, new DsLong(pStop), AMSeekingSeekingFlags.NoPositioning); if (hr == 0) { long lStreamPos; mediaSeeking.GetCurrentPosition(out lStreamPos); // stream position m_dDuration = lStreamPos; lTime = 0; mediaSeeking.SetPositions(new DsLong(lTime), AMSeekingSeekingFlags.AbsolutePositioning, new DsLong(pStop), AMSeekingSeekingFlags.NoPositioning); } double duration = m_dDuration / 10000000d; Log.Info("TSReader2WMV: movie duration:{0}", Util.Utils.SecondsToHMSString((int)duration)); hr = mediaControl.Run(); if (hr != 0) { Log.Error("TSReader2WMV: FAILED: unable to start graph :0x{0:X}", hr); Cleanup(); return(false); } int maxCount = 20; while (true) { long lCurrent; mediaSeeking.GetCurrentPosition(out lCurrent); double dpos = (double)lCurrent; dpos /= 10000000d; System.Threading.Thread.Sleep(100); if (dpos >= 2.0d) { break; } maxCount--; if (maxCount <= 0) { break; } } Log.Info("TSReader2WMV: pre-run done"); Log.Info("TSReader2WMV: Get duration of movie"); mediaControl.Stop(); FilterState state; mediaControl.GetState(500, out state); GC.Collect(); GC.Collect(); GC.Collect(); GC.WaitForPendingFinalizers(); Log.Info("TSReader2WMV: reconnect mpeg2 video codec->ASF WM Writer"); graphBuilder.RemoveFilter(fileWriterbase); if (!AddWmAsfWriter(outputFilename, quality, standard)) { return(false); } Log.Info("TSReader2WMV: Start transcoding"); hr = mediaControl.Run(); if (hr != 0) { Log.Error("TSReader2WMV:FAILED:unable to start graph :0x{0:X}", hr); Cleanup(); return(false); } } catch (Exception e) { // TODO: Handle exceptions. Log.Error("unable to transcode file:{0} message:{1}", info.file, e.Message); return(false); } return(true); }
protected override bool GetInterfaces() { GetInterface = true; try { graphBuilder = (IGraphBuilder) new FilterGraph(); _rotEntry = new DsROTEntry((IFilterGraph)graphBuilder); int hr; filterConfig = GetFilterConfiguration(); filterCodec = GetFilterCodec(); if (filterConfig.bAutoDecoderSettings) { AutoRenderingCheck = true; return(base.GetInterfaces()); } string extension = Path.GetExtension(m_strCurrentFile).ToLowerInvariant(); GUIMessage msg; if (extension == ".mpls" || extension == ".bdmv") { filterConfig.bForceSourceSplitter = false; filterConfig = GetFilterConfigurationBD(); } //Manually add codecs based on file extension if not in auto-settings // switch back to directx fullscreen mode Log.Info("MyAnime3Player: Enabling DX9 exclusive mode"); msg = new GUIMessage(GUIMessage.MessageType.GUI_MSG_SWITCH_FULL_WINDOWED, 0, 0, 0, 1, 0, null); GUIWindowManager.SendMessage(msg); // add the VMR9 in the graph // after enabeling exclusive mode, if done first it causes MediPortal to minimize if for example the "Windows key" is pressed while playing a video if (extension != ".dts" && extension != ".mp3" && extension != ".mka" && extension != ".ac3") { if (g_Player.MediaInfo != null && !g_Player.MediaInfo.MediaInfoNotloaded && !g_Player._mediaInfo.HasVideo) { AudioOnly = true; } else { Vmr9 = new VMR9Util(); Vmr9.AddVMR9(graphBuilder); Vmr9.Enable(false); } } else { AudioOnly = true; } if (filterConfig.strsplitterfilter == LAV_SPLITTER_FILTER_SOURCE && filterConfig.bForceSourceSplitter) { LoadLAVSplitter(LAV_SPLITTER_FILTER_SOURCE); hr = graphBuilder.AddFilter(_interfaceSourceFilter, LAV_SPLITTER_FILTER_SOURCE); DsError.ThrowExceptionForHR(hr); Log.Debug("MyAnime3Player: Add LAVSplitter Source to graph"); IFileSourceFilter interfaceFile = (IFileSourceFilter)_interfaceSourceFilter; hr = interfaceFile.Load(m_strCurrentFile, null); if (hr != 0) { Error.SetError("Unable to play movie", "Unable build graph for VMR9"); Cleanup(); return(false); } } else { _interfaceSourceFilter = filterConfig.bForceSourceSplitter ? DirectShowUtil.AddFilterToGraph(graphBuilder, filterConfig.strsplitterfilter) : null; if (_interfaceSourceFilter == null && !filterConfig.bForceSourceSplitter) { graphBuilder.AddSourceFilter(m_strCurrentFile, null, out _interfaceSourceFilter); } else { try { int result = ((IFileSourceFilter)_interfaceSourceFilter).Load(m_strCurrentFile, null); if (result != 0) { graphBuilder.RemoveFilter(_interfaceSourceFilter); DirectShowUtil.ReleaseComObject(_interfaceSourceFilter); _interfaceSourceFilter = null; graphBuilder.AddSourceFilter(m_strCurrentFile, null, out _interfaceSourceFilter); } } catch (Exception ex) { Log.Error( "MyAnime3Player: Exception loading Source Filter setup in setting in DShow graph , try to load by merit", ex); graphBuilder.RemoveFilter(_interfaceSourceFilter); DirectShowUtil.ReleaseComObject(_interfaceSourceFilter); _interfaceSourceFilter = null; graphBuilder.AddSourceFilter(m_strCurrentFile, null, out _interfaceSourceFilter); } } //Detection of File Source (Async.) as source filter, return true if found IBaseFilter fileSyncbaseFilter = null; DirectShowUtil.FindFilterByClassID(graphBuilder, ClassId.FilesyncSource, out fileSyncbaseFilter); if (fileSyncbaseFilter == null) { graphBuilder.FindFilterByName("File Source (Async.)", out fileSyncbaseFilter); } if (fileSyncbaseFilter != null && filterConfig.bForceSourceSplitter) { FileSync = true; DirectShowUtil.ReleaseComObject(fileSyncbaseFilter); fileSyncbaseFilter = null; if (filterConfig.strsplitterfilefilter == LAV_SPLITTER_FILTER) { LoadLAVSplitter(LAV_SPLITTER_FILTER); hr = graphBuilder.AddFilter(Splitter, LAV_SPLITTER_FILTER); DsError.ThrowExceptionForHR(hr); Log.Debug("MyAnime3Player: Add LAVSplitter to graph"); if (hr != 0) { Error.SetError("Unable to play movie", "Unable build graph for VMR9"); Cleanup(); return(false); } } else { Splitter = DirectShowUtil.AddFilterToGraph(graphBuilder, filterConfig.strsplitterfilefilter); } } } // Add preferred video filters UpdateFilters("Video"); //Add Audio Renderer if (filterConfig.AudioRenderer.Length > 0 && filterCodec._audioRendererFilter == null) { filterCodec._audioRendererFilter = DirectShowUtil.AddAudioRendererToGraph(graphBuilder, filterConfig.AudioRenderer, false); } // Add preferred audio filters UpdateFilters("Audio"); #region Set High Audio //Set High Resolution Output > 2 channels IBaseFilter baseFilter = null; bool FFDShowLoaded = false; graphBuilder.FindFilterByName("WMAudio Decoder DMO", out baseFilter); if (baseFilter != null && filterConfig.wmvAudio != false) //Also check configuration option enabled { //Set the filter setting to enable more than 2 audio channels const string g_wszWMACHiResOutput = "_HIRESOUTPUT"; object val = true; IPropertyBag propBag = (IPropertyBag)baseFilter; hr = propBag.Write(g_wszWMACHiResOutput, ref val); if (hr != 0) { Log.Info("VideoPlayer9: Unable to turn WMAudio multichannel on. Reason: {0}", hr); } else { Log.Info("VideoPlayer9: WMAudio Decoder now set for > 2 audio channels"); } if (!FFDShowLoaded) { IBaseFilter FFDShowAudio = DirectShowUtil.GetFilterByName(graphBuilder, FFDSHOW_AUDIO_DECODER_FILTER); if (FFDShowAudio != null) { DirectShowUtil.ReleaseComObject(FFDShowAudio); FFDShowAudio = null; } else { _FFDShowAudio = DirectShowUtil.AddFilterToGraph(graphBuilder, FFDSHOW_AUDIO_DECODER_FILTER); } FFDShowLoaded = true; } DirectShowUtil.ReleaseComObject(baseFilter); baseFilter = null; } #endregion if (_interfaceSourceFilter != null) { DirectShowUtil.RenderGraphBuilderOutputPins(graphBuilder, _interfaceSourceFilter); } //Test and remove orphelin Audio Renderer //RemoveAudioR(); //remove InternalScriptRenderer as it takes subtitle pin disableISR(); //disable Closed Captions! disableCC(); DirectShowUtil.RemoveUnusedFiltersFromGraph(graphBuilder); //remove orphelin audio renderer RemoveAudioR(); //EnableClock(); if ((Vmr9 == null || !Vmr9.IsVMR9Connected) && !AudioOnly) { Log.Error("MyAnime3Player: Failed to render file -> vmr9"); mediaCtrl = null; Cleanup(); return(false); } mediaCtrl = (IMediaControl)graphBuilder; mediaEvt = (IMediaEventEx)graphBuilder; mediaSeek = (IMediaSeeking)graphBuilder; mediaPos = (IMediaPosition)graphBuilder; basicAudio = (IBasicAudio)graphBuilder; videoWin = (IVideoWindow)graphBuilder; if (Vmr9 != null) { m_iVideoWidth = Vmr9.VideoWidth; m_iVideoHeight = Vmr9.VideoHeight; Vmr9.SetDeinterlaceMode(); } return(true); } catch (Exception ex) { Error.SetError("Unable to play movie", "Unable build graph for VMR9"); Log.Error("MyAnime3Player: Exception while creating DShow graph {0} {1}", ex.Message, ex.StackTrace); Cleanup(); return(false); } }
/// <summary> create the used COM components and get the interfaces. </summary> protected override bool GetInterfaces() { try { graphBuilder = (IGraphBuilder) new FilterGraph(); _rotEntry = new DsROTEntry((IFilterGraph)graphBuilder); // add preferred video & audio codecs int hr; int intFilters = 0; // FlipGer: count custom filters string strVideoCodec = ""; string strH264VideoCodec = ""; string strAudioCodec = ""; string strAACAudioCodec = ""; string strAudiorenderer = ""; string strFilters = ""; // FlipGer: collect custom filters bool wmvAudio; bool autoloadSubtitles; bool bAutoDecoderSettings = false; using (Settings xmlreader = new MPSettings()) { bAutoDecoderSettings = xmlreader.GetValueAsBool("movieplayer", "autodecodersettings", false); strVideoCodec = xmlreader.GetValueAsString("movieplayer", "mpeg2videocodec", ""); strH264VideoCodec = xmlreader.GetValueAsString("movieplayer", "h264videocodec", ""); strAudioCodec = xmlreader.GetValueAsString("movieplayer", "mpeg2audiocodec", ""); strAACAudioCodec = xmlreader.GetValueAsString("movieplayer", "aacaudiocodec", ""); strAudiorenderer = xmlreader.GetValueAsString("movieplayer", "audiorenderer", "Default DirectSound Device"); wmvAudio = xmlreader.GetValueAsBool("movieplayer", "wmvaudio", false); autoloadSubtitles = xmlreader.GetValueAsBool("subtitles", "enabled", false); // FlipGer: load infos for custom filters int intCount = 0; while (xmlreader.GetValueAsString("movieplayer", "filter" + intCount.ToString(), "undefined") != "undefined") { if (xmlreader.GetValueAsBool("movieplayer", "usefilter" + intCount.ToString(), false)) { strFilters += xmlreader.GetValueAsString("movieplayer", "filter" + intCount.ToString(), "undefined") + ";"; intFilters++; } intCount++; } } if (bAutoDecoderSettings) { return(AutoRendering(wmvAudio)); } //Manually add codecs based on file extension if not in auto-settings // switch back to directx fullscreen mode Log.Info("VideoPlayerVMR9: Enabling DX9 exclusive mode"); GUIMessage msg = new GUIMessage(GUIMessage.MessageType.GUI_MSG_SWITCH_FULL_WINDOWED, 0, 0, 0, 1, 0, null); GUIWindowManager.SendMessage(msg); // add the VMR9 in the graph // after enabeling exclusive mode, if done first it causes MediPortal to minimize if for example the "Windows key" is pressed while playing a video Vmr9 = new VMR9Util(); Vmr9.AddVMR9(graphBuilder); Vmr9.Enable(false); IBaseFilter source = null; graphBuilder.AddSourceFilter(m_strCurrentFile, null, out source); string extension = Path.GetExtension(m_strCurrentFile).ToLower(); switch (extension) { case ".wmv": case ".asf": { //strVideoCodec = "WMVideo Decoder DMO"; //allow e.g. ffdshow usage strH264VideoCodec = ""; strAudioCodec = "WMAudio Decoder DMO"; // multichannel audio needs this filter strAACAudioCodec = ""; break; } case ".mkv": case ".m2ts": case ".mp4": { strVideoCodec = ""; break; } default: strH264VideoCodec = ""; strAACAudioCodec = ""; break; } if (!string.IsNullOrEmpty(strVideoCodec)) { DirectShowUtil.AddFilterToGraph(graphBuilder, strVideoCodec); } if (!string.IsNullOrEmpty(strH264VideoCodec) && strVideoCodec != strH264VideoCodec) { DirectShowUtil.AddFilterToGraph(graphBuilder, strH264VideoCodec); } if (!string.IsNullOrEmpty(strAudioCodec)) { DirectShowUtil.AddFilterToGraph(graphBuilder, strAudioCodec); } if (!string.IsNullOrEmpty(strAACAudioCodec) && strAudioCodec != strAACAudioCodec) { DirectShowUtil.AddFilterToGraph(graphBuilder, strAACAudioCodec); } if (strAudiorenderer.Length > 0) { DirectShowUtil.AddAudioRendererToGraph(graphBuilder, strAudiorenderer, false); } //We now add custom filters after the Audio Renderer as AC3Filter failed to connect otherwise. //FlipGer: add custom filters to graph string[] arrFilters = strFilters.Split(';'); for (int i = 0; i < intFilters; i++) { DirectShowUtil.AddFilterToGraph(graphBuilder, arrFilters[i]); } //Set High Resolution Output > 2 channels IBaseFilter baseFilter = null; bool FFDShowLoaded = false; graphBuilder.FindFilterByName("WMAudio Decoder DMO", out baseFilter); if (baseFilter != null && wmvAudio != false) //Also check configuration option enabled { //Set the filter setting to enable more than 2 audio channels const string g_wszWMACHiResOutput = "_HIRESOUTPUT"; object val = true; IPropertyBag propBag = (IPropertyBag)baseFilter; hr = propBag.Write(g_wszWMACHiResOutput, ref val); if (hr != 0) { Log.Info("VideoPlayerVMR9: Unable to turn WMAudio multichannel on. Reason: {0}", hr); } else { Log.Info("VideoPlayerVMR9: WMAudio Decoder now set for > 2 audio channels"); } if (!FFDShowLoaded) { IBaseFilter FFDShowAudio = DirectShowUtil.GetFilterByName(graphBuilder, FFDSHOW_AUDIO_DECODER_FILTER); if (FFDShowAudio != null) { DirectShowUtil.ReleaseComObject(FFDShowAudio); FFDShowAudio = null; } else { _FFDShowAudio = DirectShowUtil.AddFilterToGraph(graphBuilder, FFDSHOW_AUDIO_DECODER_FILTER); } FFDShowLoaded = true; } DirectShowUtil.ReleaseComObject(baseFilter); baseFilter = null; } #region load external audio streams // check if current "File" is a file... it could also be a URL // Directory.Getfiles, ... will other give us an exception if (File.Exists(m_strCurrentFile)) { //load audio file (ac3, dts, mka, mp3) only with if the name matches partially with video file. string[] audioFiles = Directory.GetFiles(Path.GetDirectoryName(m_strCurrentFile), Path.GetFileNameWithoutExtension(m_strCurrentFile) + "*.*"); bool audioSwitcherLoaded = false; foreach (string file in audioFiles) { switch (Path.GetExtension(file)) { case ".mp3": case ".dts": case ".mka": case ".ac3": if (!audioSwitcherLoaded) { IBaseFilter switcher = DirectShowUtil.GetFilterByName(graphBuilder, MEDIAPORTAL_AUDIOSWITCHER_FILTER); if (switcher != null) { DirectShowUtil.ReleaseComObject(switcher); switcher = null; } else { _audioSwitcher = DirectShowUtil.AddFilterToGraph(graphBuilder, MEDIAPORTAL_AUDIOSWITCHER_FILTER); } audioSwitcherLoaded = true; } _AudioSourceFilter = DirectShowUtil.AddFilterToGraph(graphBuilder, FILE_SYNC_FILTER); int result = ((IFileSourceFilter)_AudioSourceFilter).Load(file, null); //Force using LAVFilter _AudioExtSplitterFilter = DirectShowUtil.AddFilterToGraph(graphBuilder, LAV_SPLITTER_FILTER); if (result != 0 || _AudioExtSplitterFilter == null) { if (_AudioSourceFilter != null) { graphBuilder.RemoveFilter(_AudioSourceFilter); DirectShowUtil.ReleaseComObject(_AudioSourceFilter); _AudioSourceFilter = null; } if (_AudioExtSplitterFilter != null) { graphBuilder.RemoveFilter(_AudioExtSplitterFilter); DirectShowUtil.ReleaseComObject(_AudioExtSplitterFilter); _AudioExtSplitterFilter = null; } //Trying Add Audio decoder in graph AddFilterToGraphAndRelease(strAudioCodec); graphBuilder.RenderFile(file, string.Empty); Log.Debug("VideoPlayerVMR9 : External audio file loaded \"{0}\"", file); AudioExternal = true; break; } //Add Audio decoder in graph _AudioExtFilter = DirectShowUtil.AddFilterToGraph(graphBuilder, strAudioCodec); //Connect Filesource with the splitter IPin pinOutAudioExt1 = DsFindPin.ByDirection((IBaseFilter)_AudioSourceFilter, PinDirection.Output, 0); IPin pinInAudioExt2 = DsFindPin.ByDirection((IBaseFilter)_AudioExtSplitterFilter, PinDirection.Input, 0); hr = graphBuilder.Connect(pinOutAudioExt1, pinInAudioExt2); //Connect Splitter with the Audio Decoder IPin pinOutAudioExt3 = DsFindPin.ByDirection((IBaseFilter)_AudioExtSplitterFilter, PinDirection.Output, 0); IPin pinInAudioExt4 = DsFindPin.ByDirection((IBaseFilter)_AudioExtFilter, PinDirection.Input, 0); hr = graphBuilder.Connect(pinOutAudioExt3, pinInAudioExt4); //Render outpin from Audio Decoder DirectShowUtil.RenderUnconnectedOutputPins(graphBuilder, _AudioExtFilter); //Cleanup External Audio (Release) if (_AudioSourceFilter != null) { DirectShowUtil.ReleaseComObject(_AudioSourceFilter); _AudioSourceFilter = null; } if (_AudioExtSplitterFilter != null) { DirectShowUtil.ReleaseComObject(_AudioExtSplitterFilter); _AudioExtSplitterFilter = null; } if (_AudioExtFilter != null) { DirectShowUtil.ReleaseComObject(_AudioExtFilter); _AudioExtFilter = null; } if (pinOutAudioExt1 != null) { DirectShowUtil.ReleaseComObject(pinOutAudioExt1); pinOutAudioExt1 = null; } if (pinInAudioExt2 != null) { DirectShowUtil.ReleaseComObject(pinInAudioExt2); pinInAudioExt2 = null; } if (pinOutAudioExt3 != null) { DirectShowUtil.ReleaseComObject(pinOutAudioExt3); pinOutAudioExt3 = null; } if (pinInAudioExt4 != null) { DirectShowUtil.ReleaseComObject(pinInAudioExt4); pinInAudioExt4 = null; } Log.Debug("VideoPlayerVMR9 : External audio file loaded \"{0}\"", file); AudioExternal = true; break; } } } #endregion DirectShowUtil.RenderUnconnectedOutputPins(graphBuilder, source); if (source != null) { DirectShowUtil.ReleaseComObject(source); source = null; } DirectShowUtil.RemoveUnusedFiltersFromGraph(graphBuilder); if (Vmr9 == null || !Vmr9.IsVMR9Connected) { Log.Error("VideoPlayer9: Failed to render file -> vmr9"); mediaCtrl = null; Cleanup(); return(false); } mediaCtrl = (IMediaControl)graphBuilder; mediaEvt = (IMediaEventEx)graphBuilder; mediaSeek = (IMediaSeeking)graphBuilder; mediaPos = (IMediaPosition)graphBuilder; basicAudio = (IBasicAudio)graphBuilder; videoWin = (IVideoWindow)graphBuilder; m_iVideoWidth = Vmr9.VideoWidth; m_iVideoHeight = Vmr9.VideoHeight; Vmr9.SetDeinterlaceMode(); return(true); } catch (Exception ex) { Error.SetError("Unable to play movie", "Unable build graph for VMR9"); Log.Error("VideoPlayer9: Exception while creating DShow graph {0} {1}", ex.Message, ex.StackTrace); Cleanup(); return(false); } }
public bool Transcode(TranscodeInfo info, MediaPortal.Core.Transcoding.VideoFormat format, MediaPortal.Core.Transcoding.Quality quality, Standard standard) { if (!Supports(format)) { return(false); } string ext = System.IO.Path.GetExtension(info.file); if (ext.ToLower() != ".ts" && ext.ToLower() != ".mpg") { Log.Info("TSReader2MP4: wrong file format"); return(false); } try { graphBuilder = (IGraphBuilder) new FilterGraph(); _rotEntry = new DsROTEntry((IFilterGraph)graphBuilder); Log.Info("TSReader2MP4: add filesource"); TsReader reader = new TsReader(); tsreaderSource = (IBaseFilter)reader; IBaseFilter filter = (IBaseFilter)tsreaderSource; graphBuilder.AddFilter(filter, "TSReader Source"); IFileSourceFilter fileSource = (IFileSourceFilter)tsreaderSource; Log.Info("TSReader2MP4: load file:{0}", info.file); int hr = fileSource.Load(info.file, null); //add audio/video codecs string strVideoCodec = ""; string strH264VideoCodec = ""; string strAudioCodec = ""; string strAACAudioCodec = ""; using (MediaPortal.Profile.Settings xmlreader = new MediaPortal.Profile.MPSettings()) { strVideoCodec = xmlreader.GetValueAsString("mytv", "videocodec", ""); strAudioCodec = xmlreader.GetValueAsString("mytv", "audiocodec", ""); strAACAudioCodec = xmlreader.GetValueAsString("mytv", "aacaudiocodec", ""); strH264VideoCodec = xmlreader.GetValueAsString("mytv", "h264videocodec", ""); } //Find the type of decoder required for the output video & audio pins on TSReader. Log.Info("TSReader2MP4: find tsreader compatible audio/video decoders"); IPin pinOut0, pinOut1; IPin pinIn0, pinIn1; pinOut0 = DsFindPin.ByDirection((IBaseFilter)tsreaderSource, PinDirection.Output, 0); //audio pinOut1 = DsFindPin.ByDirection((IBaseFilter)tsreaderSource, PinDirection.Output, 1); //video if (pinOut0 == null || pinOut1 == null) { Log.Error("TSReader2MP4: FAILED: unable to get output pins of tsreader"); Cleanup(); return(false); } bool usingAAC = false; IEnumMediaTypes enumMediaTypes; hr = pinOut0.EnumMediaTypes(out enumMediaTypes); while (true) { AMMediaType[] mediaTypes = new AMMediaType[1]; int typesFetched; hr = enumMediaTypes.Next(1, mediaTypes, out typesFetched); if (hr != 0 || typesFetched == 0) { break; } if (mediaTypes[0].majorType == MediaType.Audio && mediaTypes[0].subType == MediaSubType.LATMAAC) { Log.Info("TSReader2MP4: found LATM AAC audio out pin on tsreader"); usingAAC = true; } } bool usingH264 = false; hr = pinOut1.EnumMediaTypes(out enumMediaTypes); while (true) { AMMediaType[] mediaTypes = new AMMediaType[1]; int typesFetched; hr = enumMediaTypes.Next(1, mediaTypes, out typesFetched); if (hr != 0 || typesFetched == 0) { break; } if (mediaTypes[0].majorType == MediaType.Video && mediaTypes[0].subType == AVC1) { Log.Info("TSReader2MP4: found H.264 video out pin on tsreader"); usingH264 = true; } } //Add the type of decoder required for the output video & audio pins on TSReader. Log.Info("TSReader2MP4: add audio/video decoders to graph"); if (usingH264 == false) { Log.Info("TSReader2MP4: add mpeg2 video decoder:{0}", strVideoCodec); VideoCodec = DirectShowUtil.AddFilterToGraph(graphBuilder, strVideoCodec); if (VideoCodec == null) { Log.Error("TSReader2MP4: unable to add mpeg2 video decoder"); Cleanup(); return(false); } } else { Log.Info("TSReader2MP4: add h264 video codec:{0}", strH264VideoCodec); VideoCodec = DirectShowUtil.AddFilterToGraph(graphBuilder, strH264VideoCodec); if (VideoCodec == null) { Log.Error("TSReader2MP4: FAILED:unable to add h264 video codec"); Cleanup(); return(false); } } if (usingAAC == false) { Log.Info("TSReader2MP4: add mpeg2 audio codec:{0}", strAudioCodec); AudioCodec = DirectShowUtil.AddFilterToGraph(graphBuilder, strAudioCodec); if (AudioCodec == null) { Log.Error("TSReader2MP4: FAILED:unable to add mpeg2 audio codec"); Cleanup(); return(false); } } else { Log.Info("TSReader2MP4: add aac audio codec:{0}", strAACAudioCodec); AudioCodec = DirectShowUtil.AddFilterToGraph(graphBuilder, strAACAudioCodec); if (AudioCodec == null) { Log.Error("TSReader2MP4: FAILED:unable to add aac audio codec"); Cleanup(); return(false); } } Log.Info("TSReader2MP4: connect tsreader->audio/video decoders"); //connect output #0 (audio) of tsreader->audio decoder input pin 0 //connect output #1 (video) of tsreader->video decoder input pin 0 pinIn0 = DsFindPin.ByDirection(AudioCodec, PinDirection.Input, 0); //audio pinIn1 = DsFindPin.ByDirection(VideoCodec, PinDirection.Input, 0); //video if (pinIn0 == null || pinIn1 == null) { Log.Error("TSReader2MP4: FAILED: unable to get pins of video/audio codecs"); Cleanup(); return(false); } hr = graphBuilder.Connect(pinOut0, pinIn0); if (hr != 0) { Log.Error("TSReader2MP4: FAILED: unable to connect audio pins :0x{0:X}", hr); Cleanup(); return(false); } hr = graphBuilder.Connect(pinOut1, pinIn1); if (hr != 0) { Log.Error("TSReader2MP4: FAILED: unable to connect video pins :0x{0:X}", hr); Cleanup(); return(false); } //add encoders, muxer & filewriter if (!AddCodecs(graphBuilder, info)) { return(false); } //setup graph controls mediaControl = graphBuilder as IMediaControl; mediaSeeking = tsreaderSource as IMediaSeeking; mediaEvt = graphBuilder as IMediaEventEx; mediaPos = graphBuilder as IMediaPosition; //get file duration Log.Info("TSReader2MP4: Get duration of recording"); long lTime = 5 * 60 * 60; lTime *= 10000000; long pStop = 0; hr = mediaSeeking.SetPositions(new DsLong(lTime), AMSeekingSeekingFlags.AbsolutePositioning, new DsLong(pStop), AMSeekingSeekingFlags.NoPositioning); if (hr == 0) { long lStreamPos; mediaSeeking.GetCurrentPosition(out lStreamPos); // stream position m_dDuration = lStreamPos; lTime = 0; mediaSeeking.SetPositions(new DsLong(lTime), AMSeekingSeekingFlags.AbsolutePositioning, new DsLong(pStop), AMSeekingSeekingFlags.NoPositioning); } double duration = m_dDuration / 10000000d; Log.Info("TSReader2MP4: recording duration: {0}", MediaPortal.Util.Utils.SecondsToHMSString((int)duration)); //run the graph to initialize the filters to be sure hr = mediaControl.Run(); if (hr != 0) { Log.Error("TSReader2MP4: FAILED: unable to start graph :0x{0:X}", hr); Cleanup(); return(false); } int maxCount = 20; while (true) { long lCurrent; mediaSeeking.GetCurrentPosition(out lCurrent); double dpos = (double)lCurrent; dpos /= 10000000d; System.Threading.Thread.Sleep(100); if (dpos >= 2.0d) { break; } maxCount--; if (maxCount <= 0) { break; } } mediaControl.Stop(); FilterState state; mediaControl.GetState(500, out state); GC.Collect(); GC.Collect(); GC.Collect(); GC.WaitForPendingFinalizers(); graphBuilder.RemoveFilter(mp4Muxer); graphBuilder.RemoveFilter(h264Encoder); graphBuilder.RemoveFilter(aacEncoder); graphBuilder.RemoveFilter((IBaseFilter)fileWriterFilter); if (!AddCodecs(graphBuilder, info)) { return(false); } //Set Encoder quality & Muxer settings if (!EncoderSet(graphBuilder, info)) { return(false); } //start transcoding - run the graph Log.Info("TSReader2MP4: start transcoding"); //setup flow control //need to leverage CBAsePin, CPullPin & IAsyncReader methods. IAsyncReader synchVideo = null; mediaSample = VideoCodec as IMediaSample; hr = synchVideo.SyncReadAligned(mediaSample); //So we only parse decoder output whent the encoders are ready. hr = mediaControl.Run(); if (hr != 0) { Log.Error("TSReader2MP4: FAILED:unable to start graph :0x{0:X}", hr); Cleanup(); return(false); } } catch (Exception ex) { Log.Error("TSReader2MP4: Unable create graph: {0}", ex.Message); Cleanup(); return(false); } return(true); }
/// <summary> create the used COM components and get the interfaces. </summary> protected override bool GetInterfaces(string filename) { Speed = 1; Log.Info("StreamBufferPlayer9: GetInterfaces()"); //switch back to directx fullscreen mode // Log.Info("StreamBufferPlayer9: switch to fullscreen mode"); Log.Info("StreamBufferPlayer9: Enabling DX9 exclusive mode"); GUIMessage msg = new GUIMessage(GUIMessage.MessageType.GUI_MSG_SWITCH_FULL_WINDOWED, 0, 0, 0, 1, 0, null); GUIWindowManager.SendMessage(msg); //Log.Info("StreamBufferPlayer9: build graph"); try { _graphBuilder = (IGraphBuilder) new FilterGraph(); //Log.Info("StreamBufferPlayer9: add _vmr9"); _vmr9 = new VMR9Util(); _vmr9.AddVMR9(_graphBuilder); _vmr9.Enable(false); int hr; m_StreamBufferConfig = new StreamBufferConfig(); streamConfig2 = m_StreamBufferConfig as IStreamBufferConfigure2; if (streamConfig2 != null) { // setting the StreamBufferEngine registry key IntPtr HKEY = (IntPtr) unchecked ((int)0x80000002L); IStreamBufferInitialize pTemp = (IStreamBufferInitialize)streamConfig2; IntPtr subKey = IntPtr.Zero; RegOpenKeyEx(HKEY, "SOFTWARE\\MediaPortal", 0, 0x3f, out subKey); hr = pTemp.SetHKEY(subKey); hr = streamConfig2.SetFFTransitionRates(8, 32); //Log.Info("set FFTransitionRates:{0:X}",hr); int max, maxnon; hr = streamConfig2.GetFFTransitionRates(out max, out maxnon); streamConfig2.GetBackingFileCount(out _minBackingFiles, out _maxBackingFiles); streamConfig2.GetBackingFileDuration(out _backingFileDuration); } //Log.Info("StreamBufferPlayer9: add sbe"); // create SBE source _bufferSource = (IStreamBufferSource) new StreamBufferSource(); if (_bufferSource == null) { Log.Error("StreamBufferPlayer9:Failed to create instance of SBE (do you have WinXp SP1?)"); return(false); } IBaseFilter filter = (IBaseFilter)_bufferSource; hr = _graphBuilder.AddFilter(filter, "SBE SOURCE"); if (hr != 0) { Log.Error("StreamBufferPlayer9:Failed to add SBE to graph"); return(false); } IFileSourceFilter fileSource = (IFileSourceFilter)_bufferSource; if (fileSource == null) { Log.Error("StreamBufferPlayer9:Failed to get IFileSourceFilter"); return(false); } //Log.Info("StreamBufferPlayer9: open file:{0}",filename); hr = fileSource.Load(filename, null); if (hr != 0) { Log.Error("StreamBufferPlayer9:Failed to open file:{0} :0x{1:x}", filename, hr); return(false); } //Log.Info("StreamBufferPlayer9: add codecs"); // add preferred video & audio codecs string strVideoCodec = ""; string strAudioCodec = ""; string strAudioRenderer = ""; int intFilters = 0; // FlipGer: count custom filters string strFilters = ""; // FlipGer: collect custom filters using (Settings xmlreader = new MPSettings()) { // FlipGer: load infos for custom filters int intCount = 0; while (xmlreader.GetValueAsString("mytv", "filter" + intCount.ToString(), "undefined") != "undefined") { if (xmlreader.GetValueAsBool("mytv", "usefilter" + intCount.ToString(), false)) { strFilters += xmlreader.GetValueAsString("mytv", "filter" + intCount.ToString(), "undefined") + ";"; intFilters++; } intCount++; } strVideoCodec = xmlreader.GetValueAsString("mytv", "videocodec", ""); strAudioCodec = xmlreader.GetValueAsString("mytv", "audiocodec", ""); strAudioRenderer = xmlreader.GetValueAsString("mytv", "audiorenderer", "Default DirectSound Device"); string strValue = xmlreader.GetValueAsString("mytv", "defaultar", "Normal"); GUIGraphicsContext.ARType = Util.Utils.GetAspectRatio(strValue); } if (strVideoCodec.Length > 0) { _videoCodecFilter = DirectShowUtil.AddFilterToGraph(_graphBuilder, strVideoCodec); } if (strAudioCodec.Length > 0) { _audioCodecFilter = DirectShowUtil.AddFilterToGraph(_graphBuilder, strAudioCodec); } if (strAudioRenderer.Length > 0) { _audioRendererFilter = DirectShowUtil.AddAudioRendererToGraph(_graphBuilder, strAudioRenderer, true); } // FlipGer: add custom filters to graph customFilters = new IBaseFilter[intFilters]; string[] arrFilters = strFilters.Split(';'); for (int i = 0; i < intFilters; i++) { customFilters[i] = DirectShowUtil.AddFilterToGraph(_graphBuilder, arrFilters[i]); } // render output pins of SBE DirectShowUtil.RenderOutputPins(_graphBuilder, (IBaseFilter)fileSource); _mediaCtrl = (IMediaControl)_graphBuilder; _mediaEvt = (IMediaEventEx)_graphBuilder; _mediaSeeking = _bufferSource as IStreamBufferMediaSeeking; _mediaSeeking2 = _bufferSource as IStreamBufferMediaSeeking2; if (_mediaSeeking == null) { Log.Error("Unable to get IMediaSeeking interface#1"); } if (_mediaSeeking2 == null) { Log.Error("Unable to get IMediaSeeking interface#2"); } if (_audioRendererFilter != null) { IMediaFilter mp = _graphBuilder as IMediaFilter; IReferenceClock clock = _audioRendererFilter as IReferenceClock; hr = mp.SetSyncSource(clock); } // Set the IBasicAudioInterface _basicAudio = (IBasicAudio)_graphBuilder; // Log.Info("StreamBufferPlayer9:SetARMode"); // DirectShowUtil.SetARMode(_graphBuilder,AspectRatioMode.Stretched); //Log.Info("StreamBufferPlayer9: set Deinterlace"); if (!_vmr9.IsVMR9Connected) { //_vmr9 is not supported, switch to overlay Log.Info("StreamBufferPlayer9: switch to overlay"); _mediaCtrl = null; Cleanup(); return(base.GetInterfaces(filename)); } _pinVmr9ConnectedTo = _vmr9.PinConnectedTo; _vmr9.SetDeinterlaceMode(); return(true); } catch (Exception ex) { Log.Error("StreamBufferPlayer9:exception while creating DShow graph {0} {1}", ex.Message, ex.StackTrace); return(false); } }
/// <summary> create the used COM components and get the interfaces. </summary> protected virtual bool GetDVDInterfaces(string path) { int hr; //Type comtype = null; object comobj = null; _freeNavigator = true; _dvdInfo = null; _dvdCtrl = null; bool useAC3Filter = false; string dvdNavigator = ""; string aspectRatioMode = ""; string displayMode = ""; _videoPref = DvdPreferredDisplayMode.DisplayContentDefault; using (MediaPortal.Profile.Settings xmlreader = new MPSettings()) { dvdNavigator = xmlreader.GetValueAsString("dvdplayer", "navigator", "DVD Navigator"); aspectRatioMode = xmlreader.GetValueAsString("dvdplayer", "armode", "").ToLower(); dvdNavigator = "dslibdvdnav"; if (aspectRatioMode == "crop") { arMode = AspectRatioMode.Crop; } if (aspectRatioMode == "letterbox") { arMode = AspectRatioMode.LetterBox; } if (aspectRatioMode == "stretch") { arMode = AspectRatioMode.Stretched; } //if ( aspectRatioMode == "stretch" ) arMode = AspectRatioMode.zoom14to9; if (aspectRatioMode == "follow stream") { arMode = AspectRatioMode.StretchedAsPrimary; } useAC3Filter = xmlreader.GetValueAsBool("dvdplayer", "ac3", false); displayMode = xmlreader.GetValueAsString("dvdplayer", "displaymode", "").ToLower(); if (displayMode == "default") { _videoPref = DvdPreferredDisplayMode.DisplayContentDefault; } if (displayMode == "16:9") { _videoPref = DvdPreferredDisplayMode.Display16x9; } if (displayMode == "4:3 pan scan") { _videoPref = DvdPreferredDisplayMode.Display4x3PanScanPreferred; } if (displayMode == "4:3 letterbox") { _videoPref = DvdPreferredDisplayMode.Display4x3LetterBoxPreferred; } } try { _dvdGraph = (IDvdGraphBuilder) new DvdGraphBuilder(); hr = _dvdGraph.GetFiltergraph(out _graphBuilder); if (hr < 0) { Marshal.ThrowExceptionForHR(hr); } _rotEntry = new DsROTEntry((IFilterGraph)_graphBuilder); _vmr9Filter = (IBaseFilter) new VideoMixingRenderer9(); IVMRFilterConfig9 config = _vmr9Filter as IVMRFilterConfig9; hr = config.SetNumberOfStreams(1); hr = config.SetRenderingMode(VMR9Mode.Windowless); windowlessCtrl = (IVMRWindowlessControl9)_vmr9Filter; windowlessCtrl.SetVideoClippingWindow(this.panVideoWin.Handle); // config.SetRenderingPrefs(VMR9RenderPrefs. _graphBuilder.AddFilter(_vmr9Filter, "Video Mixing Renderer 9"); // _vmr7 = new VMR7Util(); // _vmr7.AddVMR7(_graphBuilder); try { _dvdbasefilter = DirectShowUtil.AddFilterToGraph(_graphBuilder, dvdNavigator); if (_dvdbasefilter != null) { IDvdControl2 cntl = (IDvdControl2)_dvdbasefilter; if (cntl != null) { _dvdInfo = (IDvdInfo2)cntl; _dvdCtrl = (IDvdControl2)cntl; if (path != null) { if (path.Length != 0) { cntl.SetDVDDirectory(path); } } _dvdCtrl.SetOption(DvdOptionFlag.HMSFTimeCodeEvents, true); // use new HMSF timecode format _dvdCtrl.SetOption(DvdOptionFlag.ResetOnStop, false); AddPreferedCodecs(_graphBuilder); DirectShowUtil.RenderOutputPins(_graphBuilder, _dvdbasefilter); // _videoWin = _graphBuilder as IVideoWindow; _freeNavigator = false; } //DirectShowUtil.ReleaseComObject( _dvdbasefilter); _dvdbasefilter = null; } } catch (Exception ex) { string strEx = ex.Message; } Guid riid; if (_dvdInfo == null) { riid = typeof(IDvdInfo2).GUID; hr = _dvdGraph.GetDvdInterface(riid, out comobj); if (hr < 0) { Marshal.ThrowExceptionForHR(hr); } _dvdInfo = (IDvdInfo2)comobj; comobj = null; } if (_dvdCtrl == null) { riid = typeof(IDvdControl2).GUID; hr = _dvdGraph.GetDvdInterface(riid, out comobj); if (hr < 0) { Marshal.ThrowExceptionForHR(hr); } _dvdCtrl = (IDvdControl2)comobj; comobj = null; } _mediaCtrl = (IMediaControl)_graphBuilder; _mediaEvt = (IMediaEventEx)_graphBuilder; _basicAudio = _graphBuilder as IBasicAudio; _mediaPos = (IMediaPosition)_graphBuilder; _mediaSeek = (IMediaSeeking)_graphBuilder; _mediaStep = (IVideoFrameStep)_graphBuilder; _basicVideo = _graphBuilder as IBasicVideo2; _videoWin = _graphBuilder as IVideoWindow; // disable Closed Captions! IBaseFilter baseFilter; _graphBuilder.FindFilterByName("Line 21 Decoder", out baseFilter); if (baseFilter == null) { _graphBuilder.FindFilterByName("Line21 Decoder", out baseFilter); } if (baseFilter != null) { _line21Decoder = (IAMLine21Decoder)baseFilter; if (_line21Decoder != null) { AMLine21CCState state = AMLine21CCState.Off; hr = _line21Decoder.SetServiceState(state); if (hr == 0) { logger.Info("DVDPlayer:Closed Captions disabled"); } else { logger.Info("DVDPlayer:failed 2 disable Closed Captions"); } } } /* * // get video window * if (_videoWin==null) * { * riid = typeof( IVideoWindow ).GUID; * hr = _dvdGraph.GetDvdInterface( ref riid, out comobj ); * if( hr < 0 ) * Marshal.ThrowExceptionForHR( hr ); * _videoWin = (IVideoWindow) comobj; comobj = null; * } */ // GetFrameStepInterface(); DirectShowUtil.SetARMode(_graphBuilder, arMode); DirectShowUtil.EnableDeInterlace(_graphBuilder); //m_ovMgr = new OVTOOLLib.OvMgrClass(); //m_ovMgr.SetGraph(_graphBuilder); return(true); } catch (Exception) { //MessageBox.Show( this, "Could not get interfaces\r\n" + ee.Message, "DVDPlayer.NET", MessageBoxButtons.OK, MessageBoxIcon.Stop ); CloseDVDInterfaces(); return(false); } finally { if (comobj != null) { DirectShowUtil.ReleaseComObject(comobj); } comobj = null; } }
/// <summary> /// If the url to be played can be buffered before starting playback, this function /// starts building a graph by adding the preferred video and audio render to it. /// This needs to be called on the MpMain Thread. /// </summary> /// <returns>true, if the url can be buffered (a graph was started), false if it can't be and null if an error occured building the graph</returns> public bool?PrepareGraph() { string sourceFilterName = GetSourceFilterName(m_strCurrentFile); if (!string.IsNullOrEmpty(sourceFilterName)) { graphBuilder = (IGraphBuilder) new FilterGraph(); _rotEntry = new DsROTEntry((IFilterGraph)graphBuilder); basicVideo = graphBuilder as IBasicVideo2; Vmr9 = new VMR9Util(); Vmr9.AddVMR9(graphBuilder); Vmr9.Enable(false); // set VMR9 back to NOT Active -> otherwise GUI is not refreshed while graph is building GUIGraphicsContext.Vmr9Active = false; // add the audio renderer using (Settings settings = new MPSettings()) { string audiorenderer = settings.GetValueAsString("movieplayer", "audiorenderer", "Default DirectSound Device"); DirectShowUtil.AddAudioRendererToGraph(graphBuilder, audiorenderer, false); } // set fields for playback mediaCtrl = (IMediaControl)graphBuilder; mediaEvt = (IMediaEventEx)graphBuilder; mediaSeek = (IMediaSeeking)graphBuilder; mediaPos = (IMediaPosition)graphBuilder; basicAudio = (IBasicAudio)graphBuilder; videoWin = (IVideoWindow)graphBuilder; // add the source filter IBaseFilter sourceFilter = null; try { if (sourceFilterName == OnlineVideos.MPUrlSourceFilter.Downloader.FilterName) { sourceFilter = FilterFromFile.LoadFilterFromDll("MPUrlSourceSplitter\\MPUrlSourceSplitter.ax", new Guid(OnlineVideos.MPUrlSourceFilter.Downloader.FilterCLSID), true); if (sourceFilter != null) { Marshal.ThrowExceptionForHR(graphBuilder.AddFilter(sourceFilter, OnlineVideos.MPUrlSourceFilter.Downloader.FilterName)); } } if (sourceFilter == null) { sourceFilter = DirectShowUtil.AddFilterToGraph(graphBuilder, sourceFilterName); } } catch (Exception ex) { Log.Instance.Warn("Error adding '{0}' filter to graph: {1}", sourceFilterName, ex.Message); return(null); } finally { if (sourceFilter != null) { DirectShowUtil.ReleaseComObject(sourceFilter, 2000); } } return(true); } else { return(false); } }
public bool Play(string fileName, Control parent, out string ErrorOrSplitter) { ErrorOrSplitter = ""; int hr; _parentControl = parent; _graphBuilder = (IFilterGraph2) new FilterGraph(); _rotEntry = new DsROTEntry(_graphBuilder); // add the video renderer (evr does not seem to work here) IBaseFilter vmr9Renderer = DirectShowUtil.AddFilterToGraph(_graphBuilder, "Video Mixing Renderer 9"); ((IVMRAspectRatioControl9)vmr9Renderer).SetAspectRatioMode(VMRAspectRatioMode.LetterBox); DirectShowUtil.ReleaseComObject(vmr9Renderer, 2000); // add the audio renderer IBaseFilter audioRenderer = DirectShowUtil.AddAudioRendererToGraph(_graphBuilder, MPSettings.Instance.GetValueAsString("movieplayer", "audiorenderer", "Default DirectSound Device"), false); DirectShowUtil.ReleaseComObject(audioRenderer, 2000); // add the source filter string sourceFilterName = OnlineVideos.MediaPortal1.Player.OnlineVideosPlayer.GetSourceFilterName(fileName); if (string.IsNullOrEmpty(sourceFilterName)) { return(false); } IBaseFilter sourceFilter = null; try { sourceFilter = DirectShowUtil.AddFilterToGraph(_graphBuilder, sourceFilterName); } catch (Exception ex) { ErrorOrSplitter = ex.Message; return(false); } hr = ((IFileSourceFilter)sourceFilter).Load(fileName, null); if (hr != 0) { ErrorOrSplitter = DirectShowLib.DsError.GetErrorText(hr); DirectShowUtil.ReleaseComObject(sourceFilter, 2000); return(false); } // wait for our filter to buffer before rendering the pins OnlineVideos.MPUrlSourceFilter.IFilterState filterState = sourceFilter as OnlineVideos.MPUrlSourceFilter.IFilterState; if (filterState != null) { bool ready = false; while ((!ready) && (hr == 0)) { hr = filterState.IsFilterReadyToConnectPins(out ready); System.Threading.Thread.Sleep(25); } } if (hr != 0) { ErrorOrSplitter = DirectShowLib.DsError.GetErrorText(hr); DirectShowUtil.ReleaseComObject(sourceFilter, 2000); return(false); } OnlineVideos.MediaPortal1.Player.OnlineVideosPlayer.AddPreferredFilters(_graphBuilder, sourceFilter); // try to connect the filters int numConnected = 0; IEnumPins pinEnum; hr = sourceFilter.EnumPins(out pinEnum); if ((hr == 0) && (pinEnum != null)) { pinEnum.Reset(); IPin[] pins = new IPin[1]; int iFetched; int iPinNo = 0; do { iPinNo++; hr = pinEnum.Next(1, pins, out iFetched); if (hr == 0) { if (iFetched == 1 && pins[0] != null) { PinDirection pinDir; pins[0].QueryDirection(out pinDir); if (pinDir == PinDirection.Output) { hr = _graphBuilder.Render(pins[0]); if (hr == 0) { numConnected++; IPin connectedPin; if (pins[0].ConnectedTo(out connectedPin) == 0 && connectedPin != null) { PinInfo connectedPinInfo; connectedPin.QueryPinInfo(out connectedPinInfo); FilterInfo connectedFilterInfo; connectedPinInfo.filter.QueryFilterInfo(out connectedFilterInfo); DirectShowUtil.ReleaseComObject(connectedPin, 2000); IBaseFilter connectedFilter; if (connectedFilterInfo.pGraph.FindFilterByName(connectedFilterInfo.achName, out connectedFilter) == 0 && connectedFilter != null) { var codecInfo = GetCodecInfo(connectedFilter, connectedFilterInfo.achName); if (codecInfo != null) { if (string.IsNullOrEmpty(ErrorOrSplitter)) { ErrorOrSplitter = codecInfo.ToString(); } else { ErrorOrSplitter += ", " + codecInfo.ToString(); } } DirectShowUtil.ReleaseComObject(connectedFilter); } } } } DirectShowUtil.ReleaseComObject(pins[0], 2000); } } } while (iFetched == 1); } DirectShowUtil.ReleaseComObject(pinEnum, 2000); if (numConnected > 0) { _videoWin = _graphBuilder as IVideoWindow; if (_videoWin != null) { _videoWin.put_Owner(_parentControl.Handle); _videoWin.put_WindowStyle((WindowStyle)((int)WindowStyle.Child + (int)WindowStyle.ClipSiblings + (int)WindowStyle.ClipChildren)); _videoWin.SetWindowPosition(_parentControl.ClientRectangle.X, _parentControl.ClientRectangle.Y, _parentControl.ClientRectangle.Width, _parentControl.ClientRectangle.Height); _videoWin.put_Visible(OABool.True); } _mediaCtrl = (IMediaControl)_graphBuilder; hr = _mediaCtrl.Run(); mediaEvents = (IMediaEventEx)_graphBuilder; // Have the graph signal event via window callbacks for performance mediaEvents.SetNotifyWindow(_parentControl.FindForm().Handle, WMGraphNotify, IntPtr.Zero); _parentControl.SizeChanged += _parentControl_SizeChanged; return(true); } else { ErrorOrSplitter = string.Format("Could not render output pins of {0}", sourceFilterName); DirectShowUtil.ReleaseComObject(sourceFilter, 2000); Stop(); return(false); } }
/// <summary> create the used COM components and get the interfaces. </summary> protected override bool GetInterfaces(string filename) { Log.Info("TSReaderPlayer: GetInterfaces()"); try { string strAudioRenderer = ""; int intFilters = 0; // FlipGer: count custom filters string strFilters = ""; // FlipGer: collect custom filters LoadMyTvFilterSettings(ref intFilters, ref strFilters, ref strVideoCodec, ref strAudioCodec, ref strAACAudioCodec, ref strDDPLUSAudioCodec, ref strH264VideoCodec, ref strAudioRenderer, ref enableDVBBitmapSubtitles, ref enableDVBTtxtSubtitles, ref relaxTsReader); _graphBuilder = (IGraphBuilder) new FilterGraph(); _rotEntry = new DsROTEntry((IFilterGraph)_graphBuilder); if (strAudioRenderer.Length > 0) //audio renderer must be in graph before audio switcher { _audioRendererFilter = DirectShowUtil.AddAudioRendererToGraph(_graphBuilder, strAudioRenderer, true); } #region add AudioSwitcher if (enableMPAudioSwitcher) //audio switcher must be in graph before tsreader audiochangecallback { _audioSwitcherFilter = DirectShowUtil.AddFilterToGraph(_graphBuilder, "MediaPortal AudioSwitcher"); if (_audioSwitcherFilter == null) { Log.Error("TSReaderPlayer: Failed to add AudioSwitcher to graph"); } } #endregion #region add TsReader TsReader reader = new TsReader(); _fileSource = (IBaseFilter)reader; _ireader = (ITSReader)reader; _interfaceTSReader = _fileSource; _ireader.SetRelaxedMode(relaxTsReader); // enable/disable continousity filtering _ireader.SetTsReaderCallback(this); _ireader.SetRequestAudioChangeCallback(this); Log.Info("TSReaderPlayer: Add TsReader to graph"); int hr = _graphBuilder.AddFilter((IBaseFilter)_fileSource, "TsReader"); DsError.ThrowExceptionForHR(hr); #endregion #region load file in TsReader IFileSourceFilter interfaceFile = (IFileSourceFilter)_fileSource; if (interfaceFile == null) { Log.Error("TSReaderPlayer: Failed to get IFileSourceFilter"); Cleanup(); return(false); } Log.Info("TSReaderPlayer: Open file: {0}", filename); hr = interfaceFile.Load(filename, null); if (hr != 0) { Log.Error("TSReaderPlayer: Failed to open file:{0} :0x{1:x}", filename, hr); Cleanup(); return(false); } #endregion #region add codecs Log.Info("TSReaderPlayer: Add codecs"); // add preferred video & audio codecs MatchFilters("Video"); MatchFilters("Audio"); // does .ts file contain video? // default is _isRadio=false which prevents recorded radio file playing if (!_videoFormat.IsValid) { _isRadio = true; } if (!_isRadio) { _vmr9 = new VMR9Util(); _vmr9.AddVMR9(_graphBuilder); _vmr9.Enable(false); DirectShowUtil.AddFilterToGraph(_graphBuilder, videoFilter); if (enableDVBBitmapSubtitles) { try { SubtitleRenderer.GetInstance().AddSubtitleFilter(_graphBuilder); } catch (Exception e) { Log.Error(e); } } } DirectShowUtil.AddFilterToGraph(_graphBuilder, audioFilter); // FlipGer: add custom filters to graph string[] arrFilters = strFilters.Split(';'); for (int i = 0; i < intFilters; i++) { DirectShowUtil.AddFilterToGraph(_graphBuilder, arrFilters[i]); } #endregion #region PostProcessingEngine Detection IPostProcessingEngine postengine = PostProcessingEngine.GetInstance(true); if (!postengine.LoadPostProcessing(_graphBuilder)) { PostProcessingEngine.engine = new PostProcessingEngine.DummyEngine(); } #endregion #region render TsReader output pins Log.Info("TSReaderPlayer: Render TsReader outputs"); if (_isRadio) { IEnumPins enumPins; hr = _fileSource.EnumPins(out enumPins); DsError.ThrowExceptionForHR(hr); IPin[] pins = new IPin[1]; int fetched = 0; while (enumPins.Next(1, pins, out fetched) == 0) { if (fetched != 1) { break; } PinDirection direction; pins[0].QueryDirection(out direction); if (direction == PinDirection.Output) { IEnumMediaTypes enumMediaTypes; pins[0].EnumMediaTypes(out enumMediaTypes); AMMediaType[] mediaTypes = new AMMediaType[20]; int fetchedTypes; enumMediaTypes.Next(20, mediaTypes, out fetchedTypes); for (int i = 0; i < fetchedTypes; ++i) { if (mediaTypes[i].majorType == MediaType.Audio) { hr = _graphBuilder.Render(pins[0]); DsError.ThrowExceptionForHR(hr); break; } } } DirectShowUtil.ReleaseComObject(pins[0]); } DirectShowUtil.ReleaseComObject(enumPins); } else { DirectShowUtil.RenderGraphBuilderOutputPins(_graphBuilder, _fileSource); } DirectShowUtil.RemoveUnusedFiltersFromGraph(_graphBuilder); #endregion _mediaCtrl = (IMediaControl)_graphBuilder; _mediaEvt = (IMediaEventEx)_graphBuilder; _mediaSeeking = (IMediaSeeking)_graphBuilder; if (_mediaSeeking == null) { Log.Error("TSReaderPlayer: Unable to get IMediaSeeking interface"); } _audioStream = (IAudioStream)_fileSource; if (_audioStream == null) { Log.Error("TSReaderPlayer: Unable to get IAudioStream interface"); } _audioSelector = new AudioSelector(_audioStream); if (!_isRadio) { if (enableDVBTtxtSubtitles || enableDVBBitmapSubtitles) { try { SubtitleRenderer.GetInstance().SetPlayer(this); _dvbSubRenderer = SubtitleRenderer.GetInstance(); } catch (Exception e) { Log.Error(e); } } if (enableDVBBitmapSubtitles) { _subtitleStream = (ISubtitleStream)_fileSource; if (_subtitleStream == null) { Log.Error("TSReaderPlayer: Unable to get ISubtitleStream interface"); } } if (enableDVBTtxtSubtitles) { //Log.Debug("TSReaderPlayer: Obtaining TeletextSource"); _teletextSource = (ITeletextSource)_fileSource; if (_teletextSource == null) { Log.Error("TSReaderPlayer: Unable to get ITeletextSource interface"); } Log.Debug("TSReaderPlayer: Creating Teletext Receiver"); TeletextSubtitleDecoder ttxtDecoder = new TeletextSubtitleDecoder(_dvbSubRenderer); _ttxtReceiver = new TeletextReceiver(_teletextSource, ttxtDecoder); // regardless of whether dvb subs are enabled, the following call is okay // if _subtitleStream is null the subtitle will just not setup for bitmap subs _subSelector = new SubtitleSelector(_subtitleStream, _dvbSubRenderer, ttxtDecoder); } else if (enableDVBBitmapSubtitles) { // if only dvb subs are enabled, pass null for ttxtDecoder _subSelector = new SubtitleSelector(_subtitleStream, _dvbSubRenderer, null); } } if (_audioRendererFilter != null) { //Log.Info("TSReaderPlayer:set reference clock"); IMediaFilter mp = (IMediaFilter)_graphBuilder; IReferenceClock clock = (IReferenceClock)_audioRendererFilter; hr = mp.SetSyncSource(null); hr = mp.SetSyncSource(clock); //Log.Info("TSReaderPlayer:set reference clock:{0:X}", hr); _basicAudio = (IBasicAudio)_graphBuilder; } if (!_isRadio) { IBaseFilter basefilter; _graphBuilder.FindFilterByName("Line 21 Decoder", out basefilter); if (basefilter == null) { _graphBuilder.FindFilterByName("Line21 Decoder", out basefilter); } if (basefilter == null) { _graphBuilder.FindFilterByName("Line 21 Decoder 2", out basefilter); } if (basefilter != null) { Log.Info("TSreaderPlayer: Line21 Decoder (Closed Captions), in use"); //: {0}", showClosedCaptions); _line21Decoder = (IAMLine21Decoder)basefilter; if (_line21Decoder != null) { AMLine21CCState state = AMLine21CCState.Off; hr = _line21Decoder.SetServiceState(state); if (hr == 0) { Log.Info("TSReaderPlayer: Closed Captions state change successful"); } else { Log.Info("TSReaderPlayer: Failed to change Closed Captions state"); } } } if (!_vmr9.IsVMR9Connected) { Log.Error("TSReaderPlayer: Failed vmr9 not connected"); Cleanup(); return(false); } DirectShowUtil.EnableDeInterlace(_graphBuilder); _vmr9.SetDeinterlaceMode(); } using (MPSettings xmlreader = new MPSettings()) { int lastSubIndex = xmlreader.GetValueAsInt("tvservice", "lastsubtitleindex", 0); Log.Debug("TSReaderPlayer: Last subtitle index: {0}", lastSubIndex); CurrentSubtitleStream = lastSubIndex; } return(true); } catch (Exception ex) { Log.Error("TSReaderPlayer: Exception while creating DShow graph {0}", ex.Message); Cleanup(); return(false); } }
/// <summary> create the used COM components and get the interfaces. </summary> protected override bool GetInterfaces(string path) { int hr; object comobj = null; _freeNavigator = true; _dvdInfo = null; _dvdCtrl = null; _videoWin = null; string dvdDNavigator = "DVD Navigator"; string aspectRatio = ""; string displayMode = ""; bool turnoffDXVA = false; bool showClosedCaptions = false; int codecValue = 0; string codecType = ""; using (Settings xmlreader = new MPSettings()) { showClosedCaptions = xmlreader.GetValueAsBool("dvdplayer", "showclosedcaptions", false); dvdDNavigator = xmlreader.GetValueAsString("dvdplayer", "navigator", "DVD Navigator"); if (dvdDNavigator.ToLower().Contains("cyberlink dvd navigator")) { _cyberlinkDVDNavigator = true; } aspectRatio = xmlreader.GetValueAsString("dvdplayer", "armode", "").ToLower(); if (aspectRatio == "crop") { arMode = AspectRatioMode.Crop; } else if (aspectRatio == "letterbox") { arMode = AspectRatioMode.LetterBox; } else if (aspectRatio == "stretch") { arMode = AspectRatioMode.Stretched; } else if (aspectRatio == "follow stream") { arMode = AspectRatioMode.StretchedAsPrimary; } displayMode = xmlreader.GetValueAsString("dvdplayer", "displaymode", "").ToLower(); if (displayMode == "default") { _videoPref = DvdPreferredDisplayMode.DisplayContentDefault; } else if (displayMode == "16:9") { _videoPref = DvdPreferredDisplayMode.Display16x9; } else if (displayMode == "4:3 pan scan") { _videoPref = DvdPreferredDisplayMode.Display4x3PanScanPreferred; } else if (displayMode == "4:3 letterbox") { _videoPref = DvdPreferredDisplayMode.Display4x3LetterBoxPreferred; } turnoffDXVA = xmlreader.GetValueAsBool("dvdplayer", "turnoffdxva", true); Log.Info("DVDPlayer9:Turn off DXVA value = {0}", turnoffDXVA); if (turnoffDXVA == true) { codecType = xmlreader.GetValueAsString("dvdplayer", "videocodec", ""); Log.Info("DVDPlayer9:Video Decoder = {0}", codecType); if (codecType == "InterVideo Video Decoder") { codecValue = xmlreader.GetValueAsInt("videocodec", "intervideo", 1); if (codecValue == 1) { Log.Info("DVDPlayer9:Turning InterVideo DXVA off"); using ( RegistryKey subkey = Registry.CurrentUser.CreateSubKey(@"Software\InterVideo\Common\VideoDec\MediaPortal")) { subkey.SetValue("DXVA", 0); } } if (codecValue == 0) { Log.Info("DVDPlayer9:InterVideo DXVA already off"); } } if (codecType.StartsWith("CyberLink Video/SP Decoder")) { codecValue = xmlreader.GetValueAsInt("videocodec", "cyberlink", 1); if (codecValue == 1) { Log.Info("DVDPlayer9:Turning CyberLink DXVA off"); using ( RegistryKey subkey = Registry.CurrentUser.CreateSubKey(@"Software\Cyberlink\Common\CLVSD\MediaPortal")) { subkey.SetValue("UIUseHVA", 0); } } if (codecValue == 0) { Log.Info("DVDPlayer9:CyberLink DXVA already off"); } } if (codecType == "NVIDIA Video Decoder") { codecValue = xmlreader.GetValueAsInt("videocodec", "nvidia", 1); if (codecValue == 1) { Log.Info("DVDPlayer9:Turning NVIDIA DXVA off"); using ( RegistryKey subkey = Registry.LocalMachine.CreateSubKey(@"Software\NVIDIA Corporation\Filters\Video")) { subkey.SetValue("EnableDXVA", 0); } } if (codecValue == 0) { Log.Info("DVDPlayer9:NVIDIA DXVA already off"); } } } } Log.Info("DVDPlayer9:Enabling DX9 exclusive mode"); GUIMessage msg = new GUIMessage(GUIMessage.MessageType.GUI_MSG_SWITCH_FULL_WINDOWED, 0, 0, 0, 1, 0, null); GUIWindowManager.SendMessage(msg); try { _dvdGraph = (IDvdGraphBuilder) new DvdGraphBuilder(); hr = _dvdGraph.GetFiltergraph(out _graphBuilder); DsError.ThrowExceptionForHR(hr); _rotEntry = new DsROTEntry((IFilterGraph)_graphBuilder); _vmr9 = new VMR9Util(); _vmr9.AddVMR9(_graphBuilder); _vmr9.Enable(false); try { Log.Info("DVDPlayer9:Add {0}", dvdDNavigator); _dvdbasefilter = DirectShowUtil.AddFilterToGraph(_graphBuilder, dvdDNavigator); if (_dvdbasefilter != null) { AddPreferedCodecs(_graphBuilder); _dvdCtrl = (IDvdControl2)_dvdbasefilter; if (_dvdCtrl != null) { _dvdInfo = (IDvdInfo2)_dvdbasefilter; if (!String.IsNullOrEmpty(path)) { hr = _dvdCtrl.SetDVDDirectory(path); DsError.ThrowExceptionForHR(hr); } _dvdCtrl.SetOption(DvdOptionFlag.HMSFTimeCodeEvents, true); // use new HMSF timecode format _dvdCtrl.SetOption(DvdOptionFlag.ResetOnStop, false); DirectShowUtil.RenderGraphBuilderOutputPins(_graphBuilder, _dvdbasefilter); _freeNavigator = false; } } } catch (Exception ex) { Log.Error("DVDPlayer9:Add {0} as navigator failed: {1}", dvdDNavigator, ex.Message); } if (_dvdInfo == null) { Log.Info("Dvdplayer9:Volume rendered, get interfaces"); hr = _dvdGraph.GetDvdInterface(typeof(IDvdInfo2).GUID, out comobj); DsError.ThrowExceptionForHR(hr); _dvdInfo = (IDvdInfo2)comobj; comobj = null; } if (_dvdCtrl == null) { Log.Info("Dvdplayer9:Get IDvdControl2"); hr = _dvdGraph.GetDvdInterface(typeof(IDvdControl2).GUID, out comobj); DsError.ThrowExceptionForHR(hr); _dvdCtrl = (IDvdControl2)comobj; comobj = null; if (_dvdCtrl != null) { Log.Info("Dvdplayer9:Get IDvdControl2"); } else { Log.Error("Dvdplayer9:Failed to get IDvdControl2"); } } // disable Closed Captions! IBaseFilter basefilter; _graphBuilder.FindFilterByName("Line 21 Decoder", out basefilter); if (basefilter == null) { _graphBuilder.FindFilterByName("Line21 Decoder", out basefilter); } if (basefilter == null) { _graphBuilder.FindFilterByName("Line 21 Decoder 2", out basefilter); } if (basefilter != null) { Log.Info("Dvdplayer9: Line21 Decoder (Closed Captions), in use: {0}", showClosedCaptions); _line21Decoder = (IAMLine21Decoder)basefilter; if (_line21Decoder != null) { AMLine21CCState state = showClosedCaptions ? AMLine21CCState.On : AMLine21CCState.Off; hr = _line21Decoder.SetServiceState(state); if (hr == 0) { Log.Info("DVDPlayer9: Closed Captions state change successful"); } else { Log.Info("DVDPlayer9: Failed to change Closed Captions state"); } } } if (!_vmr9.IsVMR9Connected) { Log.Info("DVDPlayer9:Failed vmr9 not connected"); _mediaCtrl = null; Cleanup(); return(false); } #region PostProcessingEngine Detection IPostProcessingEngine postengine = PostProcessingEngine.GetInstance(true); if (!postengine.LoadPostProcessing(_graphBuilder)) { PostProcessingEngine.engine = new PostProcessingEngine.DummyEngine(); } #endregion _mediaCtrl = (IMediaControl)_graphBuilder; _mediaEvt = (IMediaEventEx)_graphBuilder; _basicAudio = (IBasicAudio)_graphBuilder; _mediaPos = (IMediaPosition)_graphBuilder; _basicVideo = (IBasicVideo2)_graphBuilder; _videoWidth = _vmr9.VideoWidth; _videoHeight = _vmr9.VideoHeight; DirectShowUtil.SetARMode(_graphBuilder, arMode); _vmr9.SetDeinterlaceMode(); _vmr9.Enable(true); Log.Info("Dvdplayer9:Graph created"); _started = true; return(true); } catch (Exception ex) { Log.Error("DvdPlayer9:Exception while creating DShow graph {0} {1}", ex.Message, ex.StackTrace); CloseInterfaces(); return(false); } }
/// <summary> create the used COM components and get the interfaces. </summary> protected bool GetInterfaces() { VMR9Util.g_vmr9 = null; if (IsRadio == false) { Vmr9 = VMR9Util.g_vmr9 = new VMR9Util(); // switch back to directx fullscreen mode Log.Info("RTSPPlayer: Enabling DX9 exclusive mode"); GUIMessage msg = new GUIMessage(GUIMessage.MessageType.GUI_MSG_SWITCH_FULL_WINDOWED, 0, 0, 0, 1, 0, null); GUIWindowManager.SendMessage(msg); } //Type comtype = null; //object comobj = null; DsRect rect = new DsRect(); rect.top = 0; rect.bottom = GUIGraphicsContext.form.Height; rect.left = 0; rect.right = GUIGraphicsContext.form.Width; try { graphBuilder = (IGraphBuilder) new FilterGraph(); Log.Info("RTSPPlayer: add source filter"); if (IsRadio == false) { bool AddVMR9 = VMR9Util.g_vmr9 != null && VMR9Util.g_vmr9.AddVMR9(graphBuilder); if (!AddVMR9) { Log.Error("RTSPPlayer:Failed to add VMR9 to graph"); return(false); } VMR9Util.g_vmr9.Enable(false); } _mpegDemux = (IBaseFilter) new MPEG2Demultiplexer(); graphBuilder.AddFilter(_mpegDemux, "MPEG-2 Demultiplexer"); _rtspSource = (IBaseFilter) new RtpSourceFilter(); int hr = graphBuilder.AddFilter((IBaseFilter)_rtspSource, "RTSP Source Filter"); if (hr != 0) { Log.Error("RTSPPlayer:unable to add RTSP source filter:{0:X}", hr); return(false); } // add preferred video & audio codecs Log.Info("RTSPPlayer: add video/audio codecs"); string strVideoCodec = ""; string strAudioCodec = ""; string strAudiorenderer = ""; int intFilters = 0; // FlipGer: count custom filters string strFilters = ""; // FlipGer: collect custom filters string postProcessingFilterSection = "mytv"; using (Settings xmlreader = new MPSettings()) { if (_mediaType == g_Player.MediaType.Video) { strVideoCodec = xmlreader.GetValueAsString("movieplayer", "mpeg2videocodec", ""); strAudioCodec = xmlreader.GetValueAsString("movieplayer", "mpeg2audiocodec", ""); strAudiorenderer = xmlreader.GetValueAsString("movieplayer", "audiorenderer", "Default DirectSound Device"); postProcessingFilterSection = "movieplayer"; } else { strVideoCodec = xmlreader.GetValueAsString("mytv", "videocodec", ""); strAudioCodec = xmlreader.GetValueAsString("mytv", "audiocodec", ""); strAudiorenderer = xmlreader.GetValueAsString("mytv", "audiorenderer", "Default DirectSound Device"); postProcessingFilterSection = "mytv"; } enableDvbSubtitles = xmlreader.GetValueAsBool("tvservice", "dvbsubtitles", false); // FlipGer: load infos for custom filters int intCount = 0; while (xmlreader.GetValueAsString(postProcessingFilterSection, "filter" + intCount.ToString(), "undefined") != "undefined") { if (xmlreader.GetValueAsBool(postProcessingFilterSection, "usefilter" + intCount.ToString(), false)) { strFilters += xmlreader.GetValueAsString(postProcessingFilterSection, "filter" + intCount.ToString(), "undefined") + ";"; intFilters++; } intCount++; } } string extension = Path.GetExtension(m_strCurrentFile).ToLowerInvariant(); if (IsRadio == false) { if (strVideoCodec.Length > 0) { DirectShowUtil.AddFilterToGraph(graphBuilder, strVideoCodec); } } if (strAudioCodec.Length > 0) { DirectShowUtil.AddFilterToGraph(graphBuilder, strAudioCodec); } if (enableDvbSubtitles == true) { try { _subtitleFilter = SubtitleRenderer.GetInstance().AddSubtitleFilter(graphBuilder); SubtitleRenderer.GetInstance().SetPlayer(this); dvbSubRenderer = SubtitleRenderer.GetInstance(); } catch (Exception e) { Log.Error(e); } } Log.Debug("Is subtitle fitler null? {0}", (_subtitleFilter == null)); // FlipGer: add custom filters to graph string[] arrFilters = strFilters.Split(';'); for (int i = 0; i < intFilters; i++) { DirectShowUtil.AddFilterToGraph(graphBuilder, arrFilters[i]); } if (strAudiorenderer.Length > 0) { audioRendererFilter = DirectShowUtil.AddAudioRendererToGraph(graphBuilder, strAudiorenderer, false); } Log.Info("RTSPPlayer: load:{0}", m_strCurrentFile); IFileSourceFilter interfaceFile = (IFileSourceFilter)_rtspSource; if (interfaceFile == null) { Log.Error("RTSPPlayer:Failed to get IFileSourceFilter"); return(false); } //Log.Info("RTSPPlayer: open file:{0}",filename); hr = interfaceFile.Load(m_strCurrentFile, null); if (hr != 0) { Log.Error("RTSPPlayer:Failed to open file:{0} :0x{1:x}", m_strCurrentFile, hr); return(false); } #region connect rtspsource->demux Log.Info("RTSPPlayer:connect rtspsource->mpeg2 demux"); IPin pinTsOut = DsFindPin.ByDirection((IBaseFilter)_rtspSource, PinDirection.Output, 0); if (pinTsOut == null) { Log.Info("RTSPPlayer:failed to find output pin of tsfilesource"); return(false); } IPin pinDemuxIn = DsFindPin.ByDirection(_mpegDemux, PinDirection.Input, 0); if (pinDemuxIn == null) { Log.Info("RTSPPlayer:failed to find output pin of tsfilesource"); return(false); } hr = graphBuilder.Connect(pinTsOut, pinDemuxIn); if (hr != 0) { Log.Info("RTSPPlayer:failed to connect rtspsource->mpeg2 demux:{0:X}", hr); return(false); } DirectShowUtil.ReleaseComObject(pinTsOut); DirectShowUtil.ReleaseComObject(pinDemuxIn); #endregion #region render demux output pins if (IsRadio) { Log.Info("RTSPPlayer:render audio demux outputs"); IEnumPins enumPins; _mpegDemux.EnumPins(out enumPins); IPin[] pins = new IPin[2]; int fetched = 0; while (enumPins.Next(1, pins, out fetched) == 0) { if (fetched != 1) { break; } PinDirection direction; pins[0].QueryDirection(out direction); if (direction == PinDirection.Input) { continue; } IEnumMediaTypes enumMediaTypes; pins[0].EnumMediaTypes(out enumMediaTypes); AMMediaType[] mediaTypes = new AMMediaType[20]; int fetchedTypes; enumMediaTypes.Next(20, mediaTypes, out fetchedTypes); for (int i = 0; i < fetchedTypes; ++i) { if (mediaTypes[i].majorType == MediaType.Audio) { graphBuilder.Render(pins[0]); break; } } } } else { Log.Info("RTSPPlayer:render audio/video demux outputs"); IEnumPins enumPins; _mpegDemux.EnumPins(out enumPins); IPin[] pins = new IPin[2]; int fetched = 0; while (enumPins.Next(1, pins, out fetched) == 0) { if (fetched != 1) { break; } PinDirection direction; pins[0].QueryDirection(out direction); if (direction == PinDirection.Input) { continue; } graphBuilder.Render(pins[0]); } } #endregion // Connect DVB subtitle filter pins in the graph if (_mpegDemux != null && enableDvbSubtitles == true) { IMpeg2Demultiplexer demuxer = _mpegDemux as IMpeg2Demultiplexer; hr = demuxer.CreateOutputPin(GetTSMedia(), "Pcr", out _pinPcr); if (hr == 0) { Log.Info("RTSPPlayer:_pinPcr OK"); IPin pDemuxerPcr = DsFindPin.ByName(_mpegDemux, "Pcr"); IPin pSubtitlePcr = DsFindPin.ByName(_subtitleFilter, "Pcr"); hr = graphBuilder.Connect(pDemuxerPcr, pSubtitlePcr); } else { Log.Info("RTSPPlayer:Failed to create _pinPcr in demuxer:{0:X}", hr); } hr = demuxer.CreateOutputPin(GetTSMedia(), "Subtitle", out _pinSubtitle); if (hr == 0) { Log.Info("RTSPPlayer:_pinSubtitle OK"); IPin pDemuxerSubtitle = DsFindPin.ByName(_mpegDemux, "Subtitle"); IPin pSubtitle = DsFindPin.ByName(_subtitleFilter, "In"); hr = graphBuilder.Connect(pDemuxerSubtitle, pSubtitle); } else { Log.Info("RTSPPlayer:Failed to create _pinSubtitle in demuxer:{0:X}", hr); } hr = demuxer.CreateOutputPin(GetTSMedia(), "PMT", out _pinPMT); if (hr == 0) { Log.Info("RTSPPlayer:_pinPMT OK"); IPin pDemuxerSubtitle = DsFindPin.ByName(_mpegDemux, "PMT"); IPin pSubtitle = DsFindPin.ByName(_subtitleFilter, "PMT"); hr = graphBuilder.Connect(pDemuxerSubtitle, pSubtitle); } else { Log.Info("RTSPPlayer:Failed to create _pinPMT in demuxer:{0:X}", hr); } } if (IsRadio == false) { if (!VMR9Util.g_vmr9.IsVMR9Connected) { //VMR9 is not supported, switch to overlay Log.Info("RTSPPlayer: vmr9 not connected"); _mediaCtrl = null; Cleanup(); return(false); } VMR9Util.g_vmr9.SetDeinterlaceMode(); } _mediaCtrl = (IMediaControl)graphBuilder; mediaEvt = (IMediaEventEx)graphBuilder; _mediaSeeking = (IMediaSeeking)graphBuilder; mediaPos = (IMediaPosition)graphBuilder; basicAudio = graphBuilder as IBasicAudio; //DirectShowUtil.SetARMode(graphBuilder,AspectRatioMode.Stretched); DirectShowUtil.EnableDeInterlace(graphBuilder); if (VMR9Util.g_vmr9 != null) { m_iVideoWidth = VMR9Util.g_vmr9.VideoWidth; m_iVideoHeight = VMR9Util.g_vmr9.VideoHeight; } if (audioRendererFilter != null) { Log.Info("RTSPPlayer9:set reference clock"); IMediaFilter mp = graphBuilder as IMediaFilter; IReferenceClock clock = audioRendererFilter as IReferenceClock; hr = mp.SetSyncSource(null); hr = mp.SetSyncSource(clock); Log.Info("RTSPPlayer9:set reference clock:{0:X}", hr); } Log.Info("RTSPPlayer: graph build successfull"); return(true); } catch (Exception ex) { Error.SetError("Unable to play movie", "Unable build graph for VMR9"); Log.Error("RTSPPlayer:exception while creating DShow graph {0} {1}", ex.Message, ex.StackTrace); CloseInterfaces(); return(false); } }
public static void AddPreferredFilters(IGraphBuilder graphBuilder, IBaseFilter sourceFilter) { using (Settings xmlreader = new MPSettings()) { bool autodecodersettings = xmlreader.GetValueAsBool("movieplayer", "autodecodersettings", false); if (!autodecodersettings) // the user has not chosen automatic graph building by merits { // bool vc1ICodec,vc1Codec,xvidCodec = false; - will come later bool aacCodec = false; bool h264Codec = false; // check the output pins of the splitter for known media types IEnumPins pinEnum = null; if (sourceFilter.EnumPins(out pinEnum) == 0) { int fetched = 0; IPin[] pins = new IPin[1]; while (pinEnum.Next(1, pins, out fetched) == 0 && fetched > 0) { IPin pin = pins[0]; PinDirection pinDirection; if (pin.QueryDirection(out pinDirection) == 0 && pinDirection == PinDirection.Output) { IEnumMediaTypes enumMediaTypesVideo = null; if (pin.EnumMediaTypes(out enumMediaTypesVideo) == 0) { AMMediaType[] mediaTypes = new AMMediaType[1]; int typesFetched; while (enumMediaTypesVideo.Next(1, mediaTypes, out typesFetched) == 0 && typesFetched > 0) { if (mediaTypes[0].majorType == MediaType.Video && (mediaTypes[0].subType == MediaSubType.H264 || mediaTypes[0].subType == MEDIASUBTYPE_AVC1)) { Logger.Instance.Info("found H264 video on output pin"); h264Codec = true; } else if (mediaTypes[0].majorType == MediaType.Audio && mediaTypes[0].subType == MediaSubType.LATMAAC) { Logger.Instance.Info("found AAC audio on output pin"); aacCodec = true; } } DirectShowUtil.ReleaseComObject(enumMediaTypesVideo); } } DirectShowUtil.ReleaseComObject(pin); } DirectShowUtil.ReleaseComObject(pinEnum); } // add filters for found media types to the graph as configured in MP if (h264Codec) { DirectShowUtil.ReleaseComObject( DirectShowUtil.AddFilterToGraph(graphBuilder, xmlreader.GetValueAsString("movieplayer", "h264videocodec", ""))); } else { DirectShowUtil.ReleaseComObject( DirectShowUtil.AddFilterToGraph(graphBuilder, xmlreader.GetValueAsString("movieplayer", "mpeg2videocodec", ""))); } if (aacCodec) { DirectShowUtil.ReleaseComObject( DirectShowUtil.AddFilterToGraph(graphBuilder, xmlreader.GetValueAsString("movieplayer", "aacaudiocodec", ""))); } else { DirectShowUtil.ReleaseComObject( DirectShowUtil.AddFilterToGraph(graphBuilder, xmlreader.GetValueAsString("movieplayer", "mpeg2audiocodec", ""))); } } } }
public bool Transcode(TranscodeInfo info, VideoFormat format, Quality quality, Standard standard) { try { if (!Supports(format)) { return(false); } string ext = System.IO.Path.GetExtension(info.file); if (ext.ToLower() != ".dvr-ms" && ext.ToLower() != ".sbe") { Log.Info("DVRMS2WMV: wrong file format"); return(false); } Log.Info("DVRMS2WMV: create graph"); graphBuilder = (IGraphBuilder) new FilterGraph(); _rotEntry = new DsROTEntry((IFilterGraph)graphBuilder); Log.Info("DVRMS2WMV: add streambuffersource"); bufferSource = (IStreamBufferSource) new StreamBufferSource(); IBaseFilter filter = (IBaseFilter)bufferSource; graphBuilder.AddFilter(filter, "SBE SOURCE"); Log.Info("DVRMS2WMV: load file:{0}", info.file); IFileSourceFilter fileSource = (IFileSourceFilter)bufferSource; int hr = fileSource.Load(info.file, null); //add mpeg2 audio/video codecs string strVideoCodec = ""; string strAudioCodec = ""; using (MediaPortal.Profile.Settings xmlreader = new MediaPortal.Profile.MPSettings()) { strVideoCodec = xmlreader.GetValueAsString("mytv", "videocodec", "MPC - MPEG-2 Video Decoder (Gabest)"); strAudioCodec = xmlreader.GetValueAsString("mytv", "audiocodec", "MPC - MPA Decoder Filter"); } Log.Info("DVRMS2WMV: add mpeg2 video codec:{0}", strVideoCodec); Mpeg2VideoCodec = DirectShowUtil.AddFilterToGraph(graphBuilder, strVideoCodec); if (hr != 0) { Log.Error("DVRMS2WMV:FAILED:Add mpeg2 video to filtergraph :0x{0:X}", hr); Cleanup(); return(false); } Log.Info("DVRMS2WMV: add mpeg2 audio codec:{0}", strAudioCodec); Mpeg2AudioCodec = DirectShowUtil.AddFilterToGraph(graphBuilder, strAudioCodec); if (Mpeg2AudioCodec == null) { Log.Error("DVRMS2WMV:FAILED:unable to add mpeg2 audio codec"); Cleanup(); return(false); } Log.Info("DVRMS2WMV: connect streambufer source->mpeg audio/video decoders"); //connect output #0 of streambuffer source->mpeg2 audio codec pin 1 //connect output #1 of streambuffer source->mpeg2 video codec pin 1 IPin pinOut0, pinOut1; IPin pinIn0, pinIn1; pinOut0 = DsFindPin.ByDirection((IBaseFilter)bufferSource, PinDirection.Output, 0); //audio pinOut1 = DsFindPin.ByDirection((IBaseFilter)bufferSource, PinDirection.Output, 1); //video if (pinOut0 == null || pinOut1 == null) { Log.Error("DVRMS2WMV:FAILED:unable to get pins of source"); Cleanup(); return(false); } pinIn0 = DsFindPin.ByDirection(Mpeg2VideoCodec, PinDirection.Input, 0); //video pinIn1 = DsFindPin.ByDirection(Mpeg2AudioCodec, PinDirection.Input, 0); //audio if (pinIn0 == null || pinIn1 == null) { Log.Error("DVRMS2WMV:FAILED:unable to get pins of mpeg2 video/audio codec"); Cleanup(); return(false); } hr = graphBuilder.Connect(pinOut0, pinIn1); if (hr != 0) { Log.Error("DVRMS2WMV:FAILED:unable to connect audio pins :0x{0:X}", hr); Cleanup(); return(false); } hr = graphBuilder.Connect(pinOut1, pinIn0); if (hr != 0) { Log.Error("DVRMS2WMV:FAILED:unable to connect video pins :0x{0:X}", hr); Cleanup(); return(false); } string outputFilename = System.IO.Path.ChangeExtension(info.file, ".wmv"); if (!AddWmAsfWriter(outputFilename, quality, standard)) { return(false); } Log.Info("DVRMS2WMV: start pre-run"); mediaControl = graphBuilder as IMediaControl; mediaSeeking = bufferSource as IStreamBufferMediaSeeking; mediaEvt = graphBuilder as IMediaEventEx; mediaPos = graphBuilder as IMediaPosition; //get file duration long lTime = 5 * 60 * 60; lTime *= 10000000; long pStop = 0; hr = mediaSeeking.SetPositions(new DsLong(lTime), AMSeekingSeekingFlags.AbsolutePositioning, new DsLong(pStop), AMSeekingSeekingFlags.NoPositioning); if (hr == 0) { long lStreamPos; mediaSeeking.GetCurrentPosition(out lStreamPos); // stream position m_dDuration = lStreamPos; lTime = 0; mediaSeeking.SetPositions(new DsLong(lTime), AMSeekingSeekingFlags.AbsolutePositioning, new DsLong(pStop), AMSeekingSeekingFlags.NoPositioning); } double duration = m_dDuration / 10000000d; Log.Info("DVRMS2WMV: movie duration:{0}", Util.Utils.SecondsToHMSString((int)duration)); hr = mediaControl.Run(); if (hr != 0) { Log.Error("DVRMS2WMV:FAILED:unable to start graph :0x{0:X}", hr); Cleanup(); return(false); } int maxCount = 20; while (true) { long lCurrent; mediaSeeking.GetCurrentPosition(out lCurrent); double dpos = (double)lCurrent; dpos /= 10000000d; System.Threading.Thread.Sleep(100); if (dpos >= 2.0d) { break; } maxCount--; if (maxCount <= 0) { break; } } Log.Info("DVRMS2WMV: pre-run done"); Log.Info("DVRMS2WMV: Get duration of movie"); mediaControl.Stop(); FilterState state; mediaControl.GetState(500, out state); GC.Collect(); GC.Collect(); GC.Collect(); GC.WaitForPendingFinalizers(); Log.Info("DVRMS2WMV: reconnect mpeg2 video codec->ASF WM Writer"); graphBuilder.RemoveFilter(fileWriterbase); if (!AddWmAsfWriter(outputFilename, quality, standard)) { return(false); } Log.Info("DVRMS2WMV: Start transcoding"); hr = mediaControl.Run(); if (hr != 0) { Log.Error("DVRMS2WMV:FAILED:unable to start graph :0x{0:X}", hr); Cleanup(); return(false); } } catch (Exception e) { // TODO: Handle exceptions. Log.Error("unable to transcode file:{0} message:{1}", info.file, e.Message); return(false); } return(true); }
private void AddFilterToGraphAndRelease(string filter) { var dsFilter = DirectShowUtil.AddFilterToGraph(graphBuilder, filter); DirectShowUtil.ReleaseComObject(dsFilter); }