/// <summary> create the used COM components and get the interfaces. </summary> protected virtual bool GetInterfaces(string filename) { Log.Info("StreambufferPlayer:GetInterfaces()"); //Type comtype = null; object comobj = null; try { _graphBuilder = (IGraphBuilder)new FilterGraph(); _bufferSource = (IStreamBufferSource)new StreamBufferSource(); 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); //Log.Info("get FFTransitionRates:{0} {1} {2:X}",max,maxnon,hr); streamConfig2.GetBackingFileCount(out _minBackingFiles, out _maxBackingFiles); streamConfig2.GetBackingFileDuration(out _backingFileDuration); } IBaseFilter filter = (IBaseFilter)_bufferSource; _graphBuilder.AddFilter(filter, "SBE SOURCE"); IFileSourceFilter fileSource = (IFileSourceFilter)_bufferSource; hr = fileSource.Load(filename, null); // 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()) { _CodecSupportsFastSeeking = xmlreader.GetValueAsBool("debug", "CodecSupportsFastSeeking", false); Log.Debug("BaseStreamBufferPlayer: Codec supports fast seeking = {0}", _CodecSupportsFastSeeking); // 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 outputpins of SBE DirectShowUtil.RenderOutputPins(_graphBuilder, (IBaseFilter)fileSource); _mediaCtrl = (IMediaControl)_graphBuilder; _videoWin = _graphBuilder as IVideoWindow; _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); } _basicVideo = _graphBuilder as IBasicVideo2; _basicAudio = _graphBuilder as IBasicAudio; //Log.Info("StreamBufferPlayer:SetARMode"); DirectShowUtil.SetARMode(_graphBuilder, AspectRatioMode.Stretched); _graphBuilder.SetDefaultSyncSource(); //Log.Info("StreamBufferPlayer: set Deinterlace"); //Log.Info("StreamBufferPlayer: done"); return true; } catch (Exception ex) { Log.Error("StreamBufferPlayer:exception while creating DShow graph {0} {1}", ex.Message, ex.StackTrace); return false; } finally { if (comobj != null) { DirectShowUtil.ReleaseComObject(comobj); } comobj = null; } }
private void DoSetRate(double newRate) { int hr; IMediaControl mc = (IMediaControl)currentFilterGraph; // Stop hr = mc.Stop(); DsError.ThrowExceptionForHR(hr); // Stop ASFWriter hr = currentOutputFilter.Stop(); DsError.ThrowExceptionForHR(hr); if (UsingSBEFilter) { IStreamBufferMediaSeeking mSeek = (IStreamBufferMediaSeeking)currentSBEfilter; DsLong lDouble = DsLong.FromInt64(Convert.ToInt64(newRate)); hr = mSeek.SetRate(lDouble); DsError.ThrowExceptionForHR(hr); } else { // IMediaSeeking is used on the filter graph which distributes the calls IMediaSeeking mSeek = (IMediaSeeking)currentFilterGraph; hr = mSeek.SetRate(newRate); DsError.ThrowExceptionForHR(hr); } // Start ASF hr = currentOutputFilter.Run(0); DsError.ThrowExceptionForHR(hr); // Run again hr = mc.Run(); DsError.ThrowExceptionForHR(hr); }
double ITimeShifting.GetRate() { double rate = 1.0; IStreamBufferMediaSeeking mediaSeeking = this.streamBufferSource as IStreamBufferMediaSeeking; if (mediaSeeking != null) { int hr = mediaSeeking.GetRate(out rate); } return(rate); }
void ITimeShifting.SetPosition(TimeSpan position) { IStreamBufferMediaSeeking mediaSeeking = this.streamBufferSource as IStreamBufferMediaSeeking; if (mediaSeeking != null) { long currentposition = (long)(position.TotalMilliseconds * 10000.0); mediaSeeking.SetPositions(new DsLong(currentposition), AMSeekingSeekingFlags.AbsolutePositioning, null, AMSeekingSeekingFlags.NoPositioning); } }
TimeSpan ITimeShifting.GetPosition() { IStreamBufferMediaSeeking mediaSeeking = this.streamBufferSource as IStreamBufferMediaSeeking; if (mediaSeeking != null) { long currentposition = 0; // Reference time (100-nanosecond units). 100 * 10e-9 = 10e-7 = 10000000 mediaSeeking.GetCurrentPosition(out currentposition); return(TimeSpan.FromMilliseconds(currentposition / 10000)); } return(TimeSpan.Zero); }
void ITimeShifting.SetRate(double rate) { if (rate >= 0 && rate < 0.1) { rate = 0.1; } else if (rate < 0 && rate > -0.1) { rate = -0.1; } int hr = 0; IStreamBufferMediaSeeking2 mediaSeeking2 = this.streamBufferSource as IStreamBufferMediaSeeking2; if (mediaSeeking2 != null) { //mediaSeeking2.SetRateEx(rate, 25); hr = mediaSeeking2.SetRateEx(rate, 25); if (hr == 0) { return; } } IStreamBufferMediaSeeking mediaSeeking1 = this.streamBufferSource as IStreamBufferMediaSeeking; if (mediaSeeking1 != null) { hr = mediaSeeking1.SetRate(rate); if (hr == 0) { return; } } IMediaSeeking mediaSeeking0 = this.graphBuilder2 as IMediaSeeking; if (mediaSeeking0 != null) { hr = mediaSeeking0.SetRate(rate); if (hr == 0) { return; } } }
void ITimeShifting.GetPositions(out TimeSpan start, out TimeSpan stop) { IStreamBufferMediaSeeking mediaSeeking = this.streamBufferSource as IStreamBufferMediaSeeking; if (mediaSeeking != null) { long startPosition = 0; // Reference time (100-nanosecond units). 100 * 10e-9 = 10e-7 = 10000000 long stopPosition = 0; // Reference time (100-nanosecond units). 100 * 10e-9 = 10e-7 = 10000000 mediaSeeking.GetAvailable(out startPosition, out stopPosition); start = TimeSpan.FromMilliseconds(startPosition / 10000); stop = TimeSpan.FromMilliseconds(stopPosition / 10000); } else { start = stop = TimeSpan.Zero; } }
private void Cleanup() { Log.Info("DVRMS2WMV: cleanup"); if (mediaControl != null) { mediaControl.Stop(); mediaControl = null; } mediaSeeking = null; mediaEvt = null; mediaPos = null; mediaControl = null; if (Mpeg2AudioCodec != null) { DirectShowUtil.ReleaseComObject(Mpeg2AudioCodec); } Mpeg2AudioCodec = null; if (Mpeg2VideoCodec != null) { DirectShowUtil.ReleaseComObject(Mpeg2VideoCodec); } Mpeg2VideoCodec = null; if (bufferSource != null) { DirectShowUtil.ReleaseComObject(bufferSource); } bufferSource = null; DirectShowUtil.RemoveFilters(graphBuilder); if (_rotEntry != null) { _rotEntry.SafeDispose(); } _rotEntry = null; if (graphBuilder != null) { DirectShowUtil.ReleaseComObject(graphBuilder); } graphBuilder = null; GC.Collect(); GC.Collect(); GC.Collect(); GC.WaitForPendingFinalizers(); }
// Set the position of the graph to a specified TimeSpan protected void SeekGraphToTime(TimeSpan seekTime) { SendDebugMessage("Seeking graph to time..."); int hr; IMediaControl mc = (IMediaControl)currentFilterGraph; // Stop graph if not stopped FilterState fs; mc.GetState(50, out fs); if (fs != FilterState.Stopped) { if (fs != FilterState.Stopped) { mc.Stop(); } } long timeInSeconds = (long)seekTime.TotalSeconds; DsLong dsTimeIn100NanoSeconds = DsLong.FromInt64(timeInSeconds * 10000000); SendDebugMessage("Setting position to " + dsTimeIn100NanoSeconds.ToInt64().ToString()); long pos; if (UsingSBEFilter) { // IStreamBufferMediaSeeking is used directly on the source filter http://msdn.microsoft.com/en-us/library/dd694950(v=vs.85).aspx IStreamBufferMediaSeeking mSeek = (IStreamBufferMediaSeeking)currentSBEfilter; hr = mSeek.SetPositions(dsTimeIn100NanoSeconds, AMSeekingSeekingFlags.AbsolutePositioning, 0, AMSeekingSeekingFlags.NoPositioning); DsError.ThrowExceptionForHR(hr); mSeek.GetCurrentPosition(out pos); } else { // IMediaSeeking is used on the filter graph which distributes the calls IMediaSeeking mSeek = (IMediaSeeking)currentFilterGraph; hr = mSeek.SetPositions(dsTimeIn100NanoSeconds, AMSeekingSeekingFlags.AbsolutePositioning, 0, AMSeekingSeekingFlags.NoPositioning); DsError.ThrowExceptionForHR(hr); mSeek.GetCurrentPosition(out pos); } SendDebugMessage("New pos is " + pos.ToString()); }
// Seeking - Experimental, non-functional private void DoSeekToTime(TimeSpan seekTime) { int hr; IMediaControl mc = (IMediaControl)currentFilterGraph; // Stop hr = mc.Stop(); DsError.ThrowExceptionForHR(hr); // Stop ASFWriter hr = currentOutputFilter.Stop(); DsError.ThrowExceptionForHR(hr); // Seek Int64 seekTimeNanoSeconds = Convert.ToInt64(seekTime.TotalSeconds * 10000000); DsLong dsTime = DsLong.FromInt64(seekTimeNanoSeconds); if (UsingSBEFilter) { IStreamBufferMediaSeeking mSeek = (IStreamBufferMediaSeeking)currentSBEfilter; // StreamBufferMediaSeeking is used on the Source Filter, NOT the graph - see MSDN hr = mSeek.SetPositions(dsTime, AMSeekingSeekingFlags.AbsolutePositioning, 0, AMSeekingSeekingFlags.NoPositioning); DsError.ThrowExceptionForHR(hr); } else { // IMediaSeeking is used on the filter graph which distributes the calls IMediaSeeking mSeek = (IMediaSeeking)currentFilterGraph; hr = mSeek.SetPositions(dsTime, AMSeekingSeekingFlags.AbsolutePositioning, 0, AMSeekingSeekingFlags.NoPositioning); DsError.ThrowExceptionForHR(hr); } // Start ASF hr = currentOutputFilter.Run(0); DsError.ThrowExceptionForHR(hr); // Run again hr = mc.Run(); DsError.ThrowExceptionForHR(hr); }
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.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); }
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() != ".dvr-ms" && ext.ToLowerInvariant() != ".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 Cleanup() { Log.Info("DVRMS2WMV: cleanup"); if (mediaControl != null) { mediaControl.Stop(); mediaControl = null; } mediaSeeking = null; mediaEvt = null; mediaPos = null; mediaControl = null; if (Mpeg2AudioCodec != null) DirectShowUtil.ReleaseComObject(Mpeg2AudioCodec); Mpeg2AudioCodec = null; if (Mpeg2VideoCodec != null) DirectShowUtil.ReleaseComObject(Mpeg2VideoCodec); Mpeg2VideoCodec = null; if (bufferSource != null) DirectShowUtil.ReleaseComObject(bufferSource); bufferSource = null; DirectShowUtil.RemoveFilters(graphBuilder); if (_rotEntry != null) { _rotEntry.SafeDispose(); } _rotEntry = null; if (graphBuilder != null) DirectShowUtil.ReleaseComObject(graphBuilder); graphBuilder = null; GC.Collect(); GC.Collect(); GC.Collect(); GC.WaitForPendingFinalizers(); }
/// <summary> do cleanup and release DirectShow. </summary> protected virtual void CloseInterfaces() { int hr; if (_graphBuilder == null) { Log.Info("StreamBufferPlayer:grapbuilder=null"); return; } Log.Info("StreamBufferPlayer:cleanup DShow graph"); try { if (_mediaCtrl != null) { hr = _mediaCtrl.Stop(); _mediaCtrl = null; } _state = PlayState.Init; _mediaEvt = null; _isWindowVisible = false; _isVisible = false; _videoWin = null; _mediaSeeking = null; _mediaSeeking2 = null; _basicAudio = null; _basicVideo = null; _bufferSource = null; if (_videoCodecFilter != null) { while ((hr = DirectShowUtil.ReleaseComObject(_videoCodecFilter)) > 0) { ; } _videoCodecFilter = null; } if (_audioCodecFilter != null) { while ((hr = DirectShowUtil.ReleaseComObject(_audioCodecFilter)) > 0) { ; } _audioCodecFilter = null; } if (_audioRendererFilter != null) { while ((hr = DirectShowUtil.ReleaseComObject(_audioRendererFilter)) > 0) { ; } _audioRendererFilter = null; } // FlipGer: release custom filters for (int i = 0; i < customFilters.Length; i++) { if (customFilters[i] != null) { while ((hr = DirectShowUtil.ReleaseComObject(customFilters[i])) > 0) { ; } } customFilters[i] = null; } if (streamConfig2 != null) { while ((hr = DirectShowUtil.ReleaseComObject(streamConfig2)) > 0) { ; } streamConfig2 = null; } m_StreamBufferConfig = null; if (_graphBuilder != null) { DirectShowUtil.RemoveFilters(_graphBuilder); if (_rotEntry != null) { _rotEntry.SafeDispose(); _rotEntry = null; } while ((hr = DirectShowUtil.ReleaseComObject(_graphBuilder)) > 0) { ; } _graphBuilder = null; } _state = PlayState.Init; GUIGraphicsContext.form.Invalidate(true); } catch (Exception ex) { Log.Error("StreamBufferPlayer:exception while cleanuping DShow graph {0} {1}", ex.Message, ex.StackTrace); } //Log.Info("StreamBufferPlayer:cleanup done"); }
private void Configure() { // In order to lock a profile, you have to have at least one stream // connected to the sink. I connect a video thru the DVVideoEnc into // the StreamBufferSink. int hr; IBaseFilter pFilter; ICaptureGraphBuilder2 icgb = (ICaptureGraphBuilder2) new CaptureGraphBuilder2(); StreamBufferSink sbk = new StreamBufferSink(); m_FilterGraph = (IFilterGraph2) new FilterGraph(); DsROTEntry ds = new DsROTEntry(m_FilterGraph); hr = icgb.SetFiltergraph(m_FilterGraph); DsError.ThrowExceptionForHR(hr); hr = m_FilterGraph.AddFilter((IBaseFilter)sbk, "StreamBufferSink"); DsError.ThrowExceptionForHR(hr); DsDevice [] devs = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice); hr = m_FilterGraph.AddSourceFilterForMoniker(devs[0].Mon, null, devs[0].Name, out pFilter); DsError.ThrowExceptionForHR(hr); DVVideoEnc dve = new DVVideoEnc(); IBaseFilter ibfVideoEnc = (IBaseFilter)dve; hr = m_FilterGraph.AddFilter(ibfVideoEnc, "dvenc"); DsError.ThrowExceptionForHR(hr); hr = icgb.RenderStream(null, null, pFilter, ibfVideoEnc, (IBaseFilter)sbk); DsError.ThrowExceptionForHR(hr); IStreamBufferSink isbc = (IStreamBufferSink)sbk; hr = isbc.LockProfile(null); DsError.ThrowExceptionForHR(hr); ((IMediaControl)m_FilterGraph).Run(); // -------------------------- IBaseFilter streamBuffer = null; m_FilterGraph2 = (IFilterGraph2) new FilterGraph(); streamBuffer = (IBaseFilter) new StreamBufferSource(); hr = m_FilterGraph2.AddFilter(streamBuffer, "Stream buffer sink"); DsError.ThrowExceptionForHR(hr); IStreamBufferSource sbsrc = (IStreamBufferSource)streamBuffer; hr = sbsrc.SetStreamSink(isbc); DsError.ThrowExceptionForHR(hr); ((IMediaControl)m_FilterGraph2).Run(); m_sbms = (IStreamBufferMediaSeeking)sbsrc; // -------------------------- Marshal.ReleaseComObject(pFilter); Marshal.ReleaseComObject(icgb); }