public ITranscode GetTranscoder(TranscodeInfo info, VideoFormat format) { string ext = System.IO.Path.GetExtension(info.file).ToLower(); if (ext == ".dvr-ms") return new Dvrms2Mpeg(); else { if (format == VideoFormat.Wmv) return new DVRMS2WMV(); } return null; }
public ITranscode GetTranscoder(TranscodeInfo info, VideoFormat format) { string ext = System.IO.Path.GetExtension(info.file).ToLowerInvariant(); if (ext == ".dvr-ms") { return(new Dvrms2Mpeg()); } else { if (format == VideoFormat.Wmv) { return(new DVRMS2WMV()); } } return(null); }
private bool EncoderSet(IGraphBuilder graphBuilder, TranscodeInfo info) { //Add methods here to set encoder parameters return(true); }
private bool AddCodecs(IGraphBuilder graphBuilder, TranscodeInfo info) { //TODO: Add de-interlacing probably by filter int hr; Log.Info("TSReader2MP4: add h264 video encoder to graph"); //Lead H264 Encoder (4.0) string monikerH264 = @"@device:sw:{083863F1-70DE-11D0-BD40-00A0C911CE86}\{E2B7DF52-38C5-11D5-91F6-00104BDB8FF9}"; h264Encoder = Marshal.BindToMoniker(monikerH264) as IBaseFilter; if (h264Encoder == null) { Log.Error("TSReader2MP4: FAILED: Unable to create h264 video encoder"); Cleanup(); return(false); } hr = graphBuilder.AddFilter(h264Encoder, "h264 video encoder"); if (hr != 0) { Log.Error("TSReader2MP4: FAILED: h264 video encoder to filtergraph :0x{0:X}", hr); Cleanup(); return(false); } Log.Info("TSReader2MP4: add aac audio encoder to graph"); //Monograph AAC Encoder //string monikerAAC = @"@device:sw:{083863F1-70DE-11D0-BD40-00A0C911CE86}\{88F36DB6-D898-40B5-B409-466A0EECC26A}"; //Lead AAC Encoder string monikerAAC = @"@device:sw:{083863F1-70DE-11D0-BD40-00A0C911CE86}\{E2B7DD70-38C5-11D5-91F6-00104BDB8FF9}"; aacEncoder = Marshal.BindToMoniker(monikerAAC) as IBaseFilter; if (aacEncoder == null) { Log.Error("TSReader2MP4: FAILED: Unable to create aac audio encoder"); Cleanup(); return(false); } hr = graphBuilder.AddFilter(aacEncoder, "aac audio encoder"); if (hr != 0) { Log.Error("TSReader2MP4: FAILED: Add aac audio encoder to filtergraph :0x{0:X}", hr); Cleanup(); return(false); } // dump filter ???? //add filewriter Log.Info("TSReader2MP4: add FileWriter to graph"); string monikerFileWrite = @"@device:sw:{083863F1-70DE-11D0-BD40-00A0C911CE86}\{8596E5F0-0DA5-11D0-BD21-00A0C911CE86}"; IBaseFilter fileWriterbase = Marshal.BindToMoniker(monikerFileWrite) as IBaseFilter; if (fileWriterbase == null) { Log.Error("TSReader2MP4: FAILED: Unable to create FileWriter"); Cleanup(); return(false); } fileWriterFilter = fileWriterbase as IFileSinkFilter2; if (fileWriterFilter == null) { Log.Error("TSReader2MP4: FAILED: Add unable to get IFileSinkFilter for filewriter"); Cleanup(); return(false); } hr = graphBuilder.AddFilter(fileWriterbase, "FileWriter"); if (hr != 0) { Log.Error("TSReader2MP4: FAILED: Add FileWriter to filtergraph :0x{0:X}", hr); Cleanup(); return(false); } //set output filename string outputFileName = System.IO.Path.ChangeExtension(info.file, ".mp4"); Log.Info("TSReader2MP4: set output file to :{0}", outputFileName); hr = fileWriterFilter.SetFileName(outputFileName, null); if (hr != 0) { Log.Error("TSReader2MP4: FAILED: unable to set filename for filewriter :0x{0:X}", hr); Cleanup(); return(false); } // add mp4 muxer Log.Info("TSReader2MP4: add MP4 Muxer to graph"); //Lead ISO Multiplexer string monikermp4Muxer = @"@device:sw:{083863F1-70DE-11D0-BD40-00A0C911CE86}\{990D1978-E48D-43AF-B12D-24A7456EC89F}"; mp4Muxer = Marshal.BindToMoniker(monikermp4Muxer) as IBaseFilter; if (mp4Muxer == null) { Log.Error("TSReader2MP4: FAILED: Unable to create MP4Mux"); Cleanup(); return(false); } hr = graphBuilder.AddFilter(mp4Muxer, "MP4Mux"); if (hr != 0) { Log.Error("TSReader2MP4: FAILED: Add MP4Mux to filtergraph :0x{0:X}", hr); Cleanup(); return(false); } //connect output of audio codec to aac encoder IPin pinOut, pinIn; Log.Info("TSReader2MP4: connect audio codec->aac encoder"); pinIn = DsFindPin.ByDirection(aacEncoder, PinDirection.Input, 0); if (pinIn == null) { Log.Error("TSReader2MP4: FAILED: cannot get input pin of aac encoder:0x{0:X}", hr); Cleanup(); return(false); } pinOut = DsFindPin.ByDirection(AudioCodec, PinDirection.Output, 0); if (pinOut == null) { Log.Error("TSReader2MP4: FAILED: cannot get output pin of audio codec :0x{0:X}", hr); Cleanup(); return(false); } hr = graphBuilder.Connect(pinOut, pinIn); if (hr != 0) { Log.Error("TSReader2MP4: FAILED: unable to connect audio codec->aac encoder: 0x{0:X}", hr); Cleanup(); return(false); } //connect output of video codec to h264 encoder Log.Info("TSReader2MP4: connect video codec->h264 encoder"); pinIn = DsFindPin.ByDirection(h264Encoder, PinDirection.Input, 0); if (pinIn == null) { Log.Error("TSReader2MP4: FAILED: cannot get input pin of h264 encoder:0x{0:X}", hr); Cleanup(); return(false); } pinOut = DsFindPin.ByDirection(VideoCodec, PinDirection.Output, 0); if (pinOut == null) { Log.Error("TSReader2MP4: FAILED: cannot get output pin of video codec :0x{0:X}", hr); Cleanup(); return(false); } hr = graphBuilder.Connect(pinOut, pinIn); if (hr != 0) { Log.Error("TSReader2MP4: FAILED: unable to connect video codec->h264 encoder :0x{0:X}", hr); Cleanup(); return(false); } //connect output of aac encoder to pin#0 of mp4mux Log.Info("TSReader2MP4: connect aac encoder->mp4mux"); pinOut = DsFindPin.ByDirection(aacEncoder, PinDirection.Output, 0); if (pinOut == null) { Log.Error("TSReader2MP4: FAILED: cannot get input pin of aac encoder:0x{0:X}", hr); Cleanup(); return(false); } pinIn = DsFindPin.ByDirection(mp4Muxer, PinDirection.Input, 0); if (pinIn == null) { Log.Error("TSReader2MP4: FAILED: cannot get input pin#1 of mp4 muxer :0x{0:X}", hr); Cleanup(); return(false); } hr = graphBuilder.Connect(pinOut, pinIn); if (hr != 0) { Log.Error("TSReader2MP4: FAILED: unable to connect aac encoder->mp4mux: 0x{0:X}", hr); Cleanup(); return(false); } //connect output of h264 encoder to pin#1 of mp4mux Log.Info("TSReader2MP4: connect h264 encoder->mp4mux"); pinOut = DsFindPin.ByDirection(h264Encoder, PinDirection.Output, 0); if (pinOut == null) { Log.Error("TSReader2MP4: FAILED: cannot get input pin of h264 encoder :0x{0:X}", hr); Cleanup(); return(false); } pinIn = DsFindPin.ByDirection(mp4Muxer, PinDirection.Input, 1); if (pinIn == null) { Log.Error("TSReader2MP4: FAILED: cannot get input#0 pin of mp4mux :0x{0:X}", hr); Cleanup(); return(false); } hr = graphBuilder.Connect(pinOut, pinIn); if (hr != 0) { Log.Error("TSReader2MP4: FAILED: unable to connect h264 encoder->mp4mux :0x{0:X}", hr); Cleanup(); return(false); } // dump filter?? //connect mp4 muxer out->filewriter Log.Info("TSReader2MP4: connect mp4mux->filewriter"); pinOut = DsFindPin.ByDirection(mp4Muxer, PinDirection.Output, 0); if (pinOut == null) { Log.Error("TSReader2MP4: FAILED: cannot get output pin of avimux:0x{0:X}", hr); Cleanup(); return(false); } pinIn = DsFindPin.ByDirection(fileWriterbase, PinDirection.Input, 0); if (pinIn == null) { Log.Error("TSReader2MP4: FAILED: cannot get input pin of filewriter :0x{0:X}", hr); Cleanup(); return(false); } hr = graphBuilder.Connect(pinOut, pinIn); if (hr != 0) { Log.Error("TSReader2MP4: FAILED: connect mp4 muxer->filewriter :0x{0:X}", hr); Cleanup(); 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") return false; //Type comtype = null; //object comobj = null; try { Log.Info("DVR2MPG: create graph"); graphBuilder = (IGraphBuilder)new FilterGraph(); _rotEntry = new DsROTEntry((IFilterGraph)graphBuilder); Log.Info("DVR2MPG: add streambuffersource"); bufferSource = (IStreamBufferSource)new StreamBufferSource(); IBaseFilter filter = (IBaseFilter)bufferSource; graphBuilder.AddFilter(filter, "SBE SOURCE"); Log.Info("DVR2MPG: load file:{0}", info.file); IFileSourceFilter fileSource = (IFileSourceFilter)bufferSource; int hr = fileSource.Load(info.file, null); Log.Info("DVR2MPG: Add Cyberlink MPEG2 multiplexer to graph"); string monikerPowerDvdMuxer = @"@device:sw:{083863F1-70DE-11D0-BD40-00A0C911CE86}\{7F2BBEAF-E11C-4D39-90E8-938FB5A86045}"; powerDvdMuxer = Marshal.BindToMoniker(monikerPowerDvdMuxer) as IBaseFilter; if (powerDvdMuxer == null) { Log.Warn("DVR2MPG: FAILED:Unable to create Cyberlink MPEG Muxer (PowerDVD)"); Cleanup(); return false; } hr = graphBuilder.AddFilter(powerDvdMuxer, "PDR MPEG Muxer"); if (hr != 0) { Log.Warn("DVR2MPG: FAILED:Add Cyberlink MPEG Muxer to filtergraph :0x{0:X}", hr); Cleanup(); return false; } //add filewriter Log.Info("DVR2MPG: Add FileWriter to graph"); string monikerFileWrite = @"@device:sw:{083863F1-70DE-11D0-BD40-00A0C911CE86}\{3E8868CB-5FE8-402C-AA90-CB1AC6AE3240}"; IBaseFilter fileWriterbase = Marshal.BindToMoniker(monikerFileWrite) as IBaseFilter; if (fileWriterbase == null) { Log.Warn("DVR2MPG: FAILED:Unable to create FileWriter"); Cleanup(); return false; } fileWriterFilter = fileWriterbase as IFileSinkFilter; if (fileWriterFilter == null) { Log.Warn("DVR2MPG: FAILED:Add unable to get IFileSinkFilter for filewriter"); Cleanup(); return false; } hr = graphBuilder.AddFilter(fileWriterbase, "FileWriter"); if (hr != 0) { Log.Warn("DVR2MPG: FAILED:Add FileWriter to filtergraph :0x{0:X}", hr); Cleanup(); return false; } //connect output #0 of streambuffer source->powerdvd audio in //connect output #1 of streambuffer source->powerdvd video in Log.Info("DVR2MPG: connect streambuffer->multiplexer"); IPin pinOut0, pinOut1; IPin pinIn0, pinIn1; pinOut0 = DsFindPin.ByDirection((IBaseFilter)bufferSource, PinDirection.Output, 0); pinOut1 = DsFindPin.ByDirection((IBaseFilter)bufferSource, PinDirection.Output, 1); pinIn0 = DsFindPin.ByDirection(powerDvdMuxer, PinDirection.Input, 0); pinIn1 = DsFindPin.ByDirection(powerDvdMuxer, PinDirection.Input, 1); if (pinOut0 == null || pinOut1 == null || pinIn0 == null || pinIn1 == null) { Log.Warn("DVR2MPG: FAILED:unable to get pins of muxer&source"); Cleanup(); return false; } bool usingAc3 = false; AMMediaType amAudio = new AMMediaType(); amAudio.majorType = MediaType.Audio; amAudio.subType = MediaSubType.Mpeg2Audio; hr = pinOut0.Connect(pinIn1, amAudio); if (hr != 0) { amAudio.subType = MediaSubType.DolbyAC3; hr = pinOut0.Connect(pinIn1, amAudio); usingAc3 = true; } if (hr != 0) { Log.Warn("DVR2MPG: FAILED: unable to connect audio pins: 0x{0:X}", hr); Cleanup(); return false; } if (usingAc3) Log.Info("DVR2MPG: using AC3 audio"); else Log.Info("DVR2MPG: using MPEG audio"); AMMediaType amVideo = new AMMediaType(); amVideo.majorType = MediaType.Video; amVideo.subType = MediaSubType.Mpeg2Video; hr = pinOut1.Connect(pinIn0, amVideo); if (hr != 0) { Log.Warn("DVR2MPG: FAILED: unable to connect video pins: 0x{0:X}", hr); Cleanup(); return false; } //connect output of powerdvd muxer->input of filewriter Log.Info("DVR2MPG: connect multiplexer->filewriter"); IPin pinOut, pinIn; pinOut = DsFindPin.ByDirection(powerDvdMuxer, PinDirection.Output, 0); if (pinOut == null) { Log.Warn("DVR2MPG: FAILED:cannot get output pin of Cyberlink MPEG muxer :0x{0:X}", hr); Cleanup(); return false; } pinIn = DsFindPin.ByDirection(fileWriterbase, PinDirection.Input, 0); if (pinIn == null) { Log.Warn("DVR2MPG: FAILED:cannot get input pin of Filewriter :0x{0:X}", hr); Cleanup(); return false; } AMMediaType mt = new AMMediaType(); hr = pinOut.Connect(pinIn, mt); if (hr != 0) { Log.Warn("DVR2MPG: FAILED:connect muxer->filewriter :0x{0:X}", hr); Cleanup(); return false; } //set output filename string outputFileName = System.IO.Path.ChangeExtension(info.file, ".mpg"); Log.Info("DVR2MPG: set output file to :{0}", outputFileName); mt.majorType = MediaType.Stream; mt.subType = MediaSubTypeEx.MPEG2; hr = fileWriterFilter.SetFileName(outputFileName, mt); if (hr != 0) { Log.Warn("DVR2MPG: FAILED:unable to set filename for filewriter :0x{0:X}", hr); Cleanup(); return false; } mediaControl = graphBuilder as IMediaControl; mediaSeeking = graphBuilder as IMediaSeeking; mediaEvt = graphBuilder as IMediaEventEx; Log.Info("DVR2MPG: start transcoding"); hr = mediaControl.Run(); if (hr != 0) { Log.Warn("DVR2MPG: FAILED:unable to start graph :0x{0:X}", hr); Cleanup(); return false; } } catch (Exception ex) { Log.Error("DVR2MPG: Unable create graph: {0}", ex.Message); Cleanup(); 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); }
private bool AddCodecs(IGraphBuilder graphBuilder, TranscodeInfo info) { int hr; Log.Info("DVRMS2DIVX: add ffdshow (Divx) codec to graph"); string monikerXVID = @"@device:sw:{33D9A760-90C8-11D0-BD43-00A0C911CE86}\ffdshow video encoder"; divxCodec = Marshal.BindToMoniker(monikerXVID) as IBaseFilter; if (divxCodec == null) { Log.Error("DVRMS2DIVX:FAILED:Unable to create Divx MPEG-4 Codec"); Cleanup(); return(false); } hr = graphBuilder.AddFilter(divxCodec, "ffdshow video encoder"); if (hr != 0) { Log.Error("DVRMS2DIVX:FAILED:Add DivX MPEG-4 Codec to filtergraph :0x{0:X}", hr); Cleanup(); return(false); } Log.Info("DVRMS2DIVX: add MPEG3 codec to graph"); string monikerMPEG3 = @"@device:cm:{33D9A761-90C8-11D0-BD43-00A0C911CE86}\85MPEG Layer-3"; mp3Codec = Marshal.BindToMoniker(monikerMPEG3) as IBaseFilter; if (mp3Codec == null) { Log.Error("DVRMS2DIVX:FAILED:Unable to create MPEG Layer-3 Codec"); Cleanup(); return(false); } hr = graphBuilder.AddFilter(mp3Codec, "MPEG Layer-3"); if (hr != 0) { Log.Error("DVRMS2DIVX:FAILED:Add MPEG Layer-3 to filtergraph :0x{0:X}", hr); Cleanup(); return(false); } //add filewriter Log.Info("DVRMS2DIVX: add FileWriter to graph"); string monikerFileWrite = @"@device:sw:{083863F1-70DE-11D0-BD40-00A0C911CE86}\{8596E5F0-0DA5-11D0-BD21-00A0C911CE86}"; IBaseFilter fileWriterbase = Marshal.BindToMoniker(monikerFileWrite) as IBaseFilter; if (fileWriterbase == null) { Log.Error("DVRMS2DIVX:FAILED:Unable to create FileWriter"); Cleanup(); return(false); } fileWriterFilter = fileWriterbase as IFileSinkFilter2; if (fileWriterFilter == null) { Log.Error("DVRMS2DIVX:FAILED:Add unable to get IFileSinkFilter for filewriter"); Cleanup(); return(false); } hr = graphBuilder.AddFilter(fileWriterbase, "FileWriter"); if (hr != 0) { Log.Error("DVRMS2DIVX:FAILED:Add FileWriter to filtergraph :0x{0:X}", hr); Cleanup(); return(false); } //set output filename //AMMediaType mt = new AMMediaType(); string outputFileName = System.IO.Path.ChangeExtension(info.file, ".avi"); Log.Info("DVRMS2DIVX: set output file to :{0}", outputFileName); hr = fileWriterFilter.SetFileName(outputFileName, null); if (hr != 0) { Log.Error("DVRMS2DIVX:FAILED:unable to set filename for filewriter :0x{0:X}", hr); Cleanup(); return(false); } // add avi muxer Log.Info("DVRMS2DIVX: add AVI Muxer to graph"); string monikerAviMuxer = @"@device:sw:{083863F1-70DE-11D0-BD40-00A0C911CE86}\{E2510970-F137-11CE-8B67-00AA00A3F1A6}"; aviMuxer = Marshal.BindToMoniker(monikerAviMuxer) as IBaseFilter; if (aviMuxer == null) { Log.Error("DVRMS2DIVX:FAILED:Unable to create AviMux"); Cleanup(); return(false); } hr = graphBuilder.AddFilter(aviMuxer, "AviMux"); if (hr != 0) { Log.Error("DVRMS2DIVX:FAILED:Add AviMux to filtergraph :0x{0:X}", hr); Cleanup(); return(false); } //connect output of mpeg2 codec to xvid codec Log.Info("DVRMS2DIVX: connect mpeg2 video codec->divx codec"); IPin pinOut, pinIn; pinIn = DsFindPin.ByDirection(divxCodec, PinDirection.Input, 0); if (pinIn == null) { Log.Error("DVRMS2DIVX:FAILED:cannot get input pin of divx codec:0x{0:X}", hr); Cleanup(); return(false); } pinOut = DsFindPin.ByDirection(Mpeg2VideoCodec, PinDirection.Output, 0); if (pinOut == null) { Log.Error("DVRMS2DIVX:FAILED:cannot get output pin of mpeg2 video codec :0x{0:X}", hr); Cleanup(); return(false); } hr = graphBuilder.Connect(pinOut, pinIn); if (hr != 0) { Log.Error("DVRMS2DIVX:FAILED:unable to connect mpeg2 video codec->divx:0x{0:X}", hr); Cleanup(); return(false); } //connect output of mpeg2 audio codec to mpeg3 codec Log.Info("DVRMS2DIVX: connect mpeg2 audio codec->mp3 codec"); pinIn = DsFindPin.ByDirection(mp3Codec, PinDirection.Input, 0); if (pinIn == null) { Log.Error("DVRMS2DIVX:FAILED:cannot get input pin of mp3 codec:0x{0:X}", hr); Cleanup(); return(false); } pinOut = DsFindPin.ByDirection(Mpeg2AudioCodec, PinDirection.Output, 0); if (pinOut == null) { Log.Error("DVRMS2DIVX:FAILED:cannot get output pin of mpeg2 audio codec :0x{0:X}", hr); Cleanup(); return(false); } hr = graphBuilder.Connect(pinOut, pinIn); if (hr != 0) { Log.Error("DVRMS2DIVX:FAILED:unable to connect mpeg2 audio codec->mpeg3:0x{0:X}", hr); Cleanup(); return(false); } //connect output of mpeg3 codec to pin#0 of avimux Log.Info("DVRMS2DIVX: connect mp3 codec->avimux"); pinOut = DsFindPin.ByDirection(mp3Codec, PinDirection.Output, 0); if (pinOut == null) { Log.Error("DVRMS2DIVX:FAILED:cannot get input pin of mp3 codec:0x{0:X}", hr); Cleanup(); return(false); } pinIn = DsFindPin.ByDirection(aviMuxer, PinDirection.Input, 0); if (pinIn == null) { Log.Error("DVRMS2DIVX:FAILED:cannot get output pin of mpeg2 audio codec :0x{0:X}", hr); Cleanup(); return(false); } hr = graphBuilder.Connect(pinOut, pinIn); if (hr != 0) { Log.Error("DVRMS2DIVX:FAILED:unable to connect mpeg3 codec->avimux:0x{0:X}", hr); Cleanup(); return(false); } //connect output of xvid codec to pin#1 of avimux Log.Info("DVRMS2DIVX: connect divx codec->avimux"); pinOut = DsFindPin.ByDirection(divxCodec, PinDirection.Output, 0); if (pinOut == null) { Log.Error("DVRMS2DIVX:FAILED:cannot get input pin of mp3 codec:0x{0:X}", hr); Cleanup(); return(false); } pinIn = DsFindPin.ByDirection(aviMuxer, PinDirection.Input, 1); if (pinIn == null) { Log.Error("DVRMS2DIVX:FAILED:cannot get output#1 pin of avimux :0x{0:X}", hr); Cleanup(); return(false); } hr = graphBuilder.Connect(pinOut, pinIn); if (hr != 0) { Log.Error("DVRMS2DIVX:FAILED:unable to connect divx codec->avimux:0x{0:X}", hr); Cleanup(); return(false); } //connect avi mux out->filewriter in Log.Info("DVRMS2DIVX: connect avimux->filewriter"); pinOut = DsFindPin.ByDirection(aviMuxer, PinDirection.Output, 0); if (pinOut == null) { Log.Error("DVRMS2DIVX:FAILED:cannot get output pin of avimux:0x{0:X}", hr); Cleanup(); return(false); } pinIn = DsFindPin.ByDirection(fileWriterbase, PinDirection.Input, 0); if (pinIn == null) { Log.Error("DVRMS2DIVX:FAILED:cannot get input pin of Filewriter :0x{0:X}", hr); Cleanup(); return(false); } hr = graphBuilder.Connect(pinOut, pinIn); if (hr != 0) { Log.Error("DVRMS2DIVX:FAILED:connect muxer->filewriter :0x{0:X}", hr); Cleanup(); return(false); } return(true); }
private bool AddCodecs(IGraphBuilder graphBuilder, TranscodeInfo info) { int hr; Log.Info("DVRMS2DIVX: add ffdshow (Divx) codec to graph"); string monikerXVID = @"@device:sw:{33D9A760-90C8-11D0-BD43-00A0C911CE86}\ffdshow video encoder"; divxCodec = Marshal.BindToMoniker(monikerXVID) as IBaseFilter; if (divxCodec == null) { Log.Error("DVRMS2DIVX:FAILED:Unable to create Divx MPEG-4 Codec"); Cleanup(); return false; } hr = graphBuilder.AddFilter(divxCodec, "ffdshow video encoder"); if (hr != 0) { Log.Error("DVRMS2DIVX:FAILED:Add DivX MPEG-4 Codec to filtergraph :0x{0:X}", hr); Cleanup(); return false; } Log.Info("DVRMS2DIVX: add MPEG3 codec to graph"); string monikerMPEG3 = @"@device:cm:{33D9A761-90C8-11D0-BD43-00A0C911CE86}\85MPEG Layer-3"; mp3Codec = Marshal.BindToMoniker(monikerMPEG3) as IBaseFilter; if (mp3Codec == null) { Log.Error("DVRMS2DIVX:FAILED:Unable to create MPEG Layer-3 Codec"); Cleanup(); return false; } hr = graphBuilder.AddFilter(mp3Codec, "MPEG Layer-3"); if (hr != 0) { Log.Error("DVRMS2DIVX:FAILED:Add MPEG Layer-3 to filtergraph :0x{0:X}", hr); Cleanup(); return false; } //add filewriter Log.Info("DVRMS2DIVX: add FileWriter to graph"); string monikerFileWrite = @"@device:sw:{083863F1-70DE-11D0-BD40-00A0C911CE86}\{8596E5F0-0DA5-11D0-BD21-00A0C911CE86}"; IBaseFilter fileWriterbase = Marshal.BindToMoniker(monikerFileWrite) as IBaseFilter; if (fileWriterbase == null) { Log.Error("DVRMS2DIVX:FAILED:Unable to create FileWriter"); Cleanup(); return false; } fileWriterFilter = fileWriterbase as IFileSinkFilter2; if (fileWriterFilter == null) { Log.Error("DVRMS2DIVX:FAILED:Add unable to get IFileSinkFilter for filewriter"); Cleanup(); return false; } hr = graphBuilder.AddFilter(fileWriterbase, "FileWriter"); if (hr != 0) { Log.Error("DVRMS2DIVX:FAILED:Add FileWriter to filtergraph :0x{0:X}", hr); Cleanup(); return false; } //set output filename //AMMediaType mt = new AMMediaType(); string outputFileName = System.IO.Path.ChangeExtension(info.file, ".avi"); Log.Info("DVRMS2DIVX: set output file to :{0}", outputFileName); hr = fileWriterFilter.SetFileName(outputFileName, null); if (hr != 0) { Log.Error("DVRMS2DIVX:FAILED:unable to set filename for filewriter :0x{0:X}", hr); Cleanup(); return false; } // add avi muxer Log.Info("DVRMS2DIVX: add AVI Muxer to graph"); string monikerAviMuxer = @"@device:sw:{083863F1-70DE-11D0-BD40-00A0C911CE86}\{E2510970-F137-11CE-8B67-00AA00A3F1A6}"; aviMuxer = Marshal.BindToMoniker(monikerAviMuxer) as IBaseFilter; if (aviMuxer == null) { Log.Error("DVRMS2DIVX:FAILED:Unable to create AviMux"); Cleanup(); return false; } hr = graphBuilder.AddFilter(aviMuxer, "AviMux"); if (hr != 0) { Log.Error("DVRMS2DIVX:FAILED:Add AviMux to filtergraph :0x{0:X}", hr); Cleanup(); return false; } //connect output of mpeg2 codec to xvid codec Log.Info("DVRMS2DIVX: connect mpeg2 video codec->divx codec"); IPin pinOut, pinIn; pinIn = DsFindPin.ByDirection(divxCodec, PinDirection.Input, 0); if (pinIn == null) { Log.Error("DVRMS2DIVX:FAILED:cannot get input pin of divx codec:0x{0:X}", hr); Cleanup(); return false; } pinOut = DsFindPin.ByDirection(Mpeg2VideoCodec, PinDirection.Output, 0); if (pinOut == null) { Log.Error("DVRMS2DIVX:FAILED:cannot get output pin of mpeg2 video codec :0x{0:X}", hr); Cleanup(); return false; } hr = graphBuilder.Connect(pinOut, pinIn); if (hr != 0) { Log.Error("DVRMS2DIVX:FAILED:unable to connect mpeg2 video codec->divx:0x{0:X}", hr); Cleanup(); return false; } //connect output of mpeg2 audio codec to mpeg3 codec Log.Info("DVRMS2DIVX: connect mpeg2 audio codec->mp3 codec"); pinIn = DsFindPin.ByDirection(mp3Codec, PinDirection.Input, 0); if (pinIn == null) { Log.Error("DVRMS2DIVX:FAILED:cannot get input pin of mp3 codec:0x{0:X}", hr); Cleanup(); return false; } pinOut = DsFindPin.ByDirection(Mpeg2AudioCodec, PinDirection.Output, 0); if (pinOut == null) { Log.Error("DVRMS2DIVX:FAILED:cannot get output pin of mpeg2 audio codec :0x{0:X}", hr); Cleanup(); return false; } hr = graphBuilder.Connect(pinOut, pinIn); if (hr != 0) { Log.Error("DVRMS2DIVX:FAILED:unable to connect mpeg2 audio codec->mpeg3:0x{0:X}", hr); Cleanup(); return false; } //connect output of mpeg3 codec to pin#0 of avimux Log.Info("DVRMS2DIVX: connect mp3 codec->avimux"); pinOut = DsFindPin.ByDirection(mp3Codec, PinDirection.Output, 0); if (pinOut == null) { Log.Error("DVRMS2DIVX:FAILED:cannot get input pin of mp3 codec:0x{0:X}", hr); Cleanup(); return false; } pinIn = DsFindPin.ByDirection(aviMuxer, PinDirection.Input, 0); if (pinIn == null) { Log.Error("DVRMS2DIVX:FAILED:cannot get output pin of mpeg2 audio codec :0x{0:X}", hr); Cleanup(); return false; } hr = graphBuilder.Connect(pinOut, pinIn); if (hr != 0) { Log.Error("DVRMS2DIVX:FAILED:unable to connect mpeg3 codec->avimux:0x{0:X}", hr); Cleanup(); return false; } //connect output of xvid codec to pin#1 of avimux Log.Info("DVRMS2DIVX: connect divx codec->avimux"); pinOut = DsFindPin.ByDirection(divxCodec, PinDirection.Output, 0); if (pinOut == null) { Log.Error("DVRMS2DIVX:FAILED:cannot get input pin of mp3 codec:0x{0:X}", hr); Cleanup(); return false; } pinIn = DsFindPin.ByDirection(aviMuxer, PinDirection.Input, 1); if (pinIn == null) { Log.Error("DVRMS2DIVX:FAILED:cannot get output#1 pin of avimux :0x{0:X}", hr); Cleanup(); return false; } hr = graphBuilder.Connect(pinOut, pinIn); if (hr != 0) { Log.Error("DVRMS2DIVX:FAILED:unable to connect divx codec->avimux:0x{0:X}", hr); Cleanup(); return false; } //connect avi mux out->filewriter in Log.Info("DVRMS2DIVX: connect avimux->filewriter"); pinOut = DsFindPin.ByDirection(aviMuxer, PinDirection.Output, 0); if (pinOut == null) { Log.Error("DVRMS2DIVX:FAILED:cannot get output pin of avimux:0x{0:X}", hr); Cleanup(); return false; } pinIn = DsFindPin.ByDirection(fileWriterbase, PinDirection.Input, 0); if (pinIn == null) { Log.Error("DVRMS2DIVX:FAILED:cannot get input pin of Filewriter :0x{0:X}", hr); Cleanup(); return false; } hr = graphBuilder.Connect(pinOut, pinIn); if (hr != 0) { Log.Error("DVRMS2DIVX:FAILED:connect muxer->filewriter :0x{0:X}", hr); Cleanup(); 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.ToLowerInvariant() != ".ts" && ext.ToLowerInvariant() != ".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; }
private bool AddCodecs(IGraphBuilder graphBuilder, TranscodeInfo info) { //TODO: Add de-interlacing probably by filter int hr; Log.Info("TSReader2MP4: add h264 video encoder to graph"); //Lead H264 Encoder (4.0) string monikerH264 = @"@device:sw:{083863F1-70DE-11D0-BD40-00A0C911CE86}\{E2B7DF52-38C5-11D5-91F6-00104BDB8FF9}"; h264Encoder = Marshal.BindToMoniker(monikerH264) as IBaseFilter; if (h264Encoder == null) { Log.Error("TSReader2MP4: FAILED: Unable to create h264 video encoder"); Cleanup(); return false; } hr = graphBuilder.AddFilter(h264Encoder, "h264 video encoder"); if (hr != 0) { Log.Error("TSReader2MP4: FAILED: h264 video encoder to filtergraph :0x{0:X}", hr); Cleanup(); return false; } Log.Info("TSReader2MP4: add aac audio encoder to graph"); //Monograph AAC Encoder //string monikerAAC = @"@device:sw:{083863F1-70DE-11D0-BD40-00A0C911CE86}\{88F36DB6-D898-40B5-B409-466A0EECC26A}"; //Lead AAC Encoder string monikerAAC = @"@device:sw:{083863F1-70DE-11D0-BD40-00A0C911CE86}\{E2B7DD70-38C5-11D5-91F6-00104BDB8FF9}"; aacEncoder = Marshal.BindToMoniker(monikerAAC) as IBaseFilter; if (aacEncoder == null) { Log.Error("TSReader2MP4: FAILED: Unable to create aac audio encoder"); Cleanup(); return false; } hr = graphBuilder.AddFilter(aacEncoder, "aac audio encoder"); if (hr != 0) { Log.Error("TSReader2MP4: FAILED: Add aac audio encoder to filtergraph :0x{0:X}", hr); Cleanup(); return false; } // dump filter ???? //add filewriter Log.Info("TSReader2MP4: add FileWriter to graph"); string monikerFileWrite = @"@device:sw:{083863F1-70DE-11D0-BD40-00A0C911CE86}\{8596E5F0-0DA5-11D0-BD21-00A0C911CE86}"; IBaseFilter fileWriterbase = Marshal.BindToMoniker(monikerFileWrite) as IBaseFilter; if (fileWriterbase == null) { Log.Error("TSReader2MP4: FAILED: Unable to create FileWriter"); Cleanup(); return false; } fileWriterFilter = fileWriterbase as IFileSinkFilter2; if (fileWriterFilter == null) { Log.Error("TSReader2MP4: FAILED: Add unable to get IFileSinkFilter for filewriter"); Cleanup(); return false; } hr = graphBuilder.AddFilter(fileWriterbase, "FileWriter"); if (hr != 0) { Log.Error("TSReader2MP4: FAILED: Add FileWriter to filtergraph :0x{0:X}", hr); Cleanup(); return false; } //set output filename string outputFileName = System.IO.Path.ChangeExtension(info.file, ".mp4"); Log.Info("TSReader2MP4: set output file to :{0}", outputFileName); hr = fileWriterFilter.SetFileName(outputFileName, null); if (hr != 0) { Log.Error("TSReader2MP4: FAILED: unable to set filename for filewriter :0x{0:X}", hr); Cleanup(); return false; } // add mp4 muxer Log.Info("TSReader2MP4: add MP4 Muxer to graph"); //Lead ISO Multiplexer string monikermp4Muxer = @"@device:sw:{083863F1-70DE-11D0-BD40-00A0C911CE86}\{990D1978-E48D-43AF-B12D-24A7456EC89F}"; mp4Muxer = Marshal.BindToMoniker(monikermp4Muxer) as IBaseFilter; if (mp4Muxer == null) { Log.Error("TSReader2MP4: FAILED: Unable to create MP4Mux"); Cleanup(); return false; } hr = graphBuilder.AddFilter(mp4Muxer, "MP4Mux"); if (hr != 0) { Log.Error("TSReader2MP4: FAILED: Add MP4Mux to filtergraph :0x{0:X}", hr); Cleanup(); return false; } //connect output of audio codec to aac encoder IPin pinOut, pinIn; Log.Info("TSReader2MP4: connect audio codec->aac encoder"); pinIn = DsFindPin.ByDirection(aacEncoder, PinDirection.Input, 0); if (pinIn == null) { Log.Error("TSReader2MP4: FAILED: cannot get input pin of aac encoder:0x{0:X}", hr); Cleanup(); return false; } pinOut = DsFindPin.ByDirection(AudioCodec, PinDirection.Output, 0); if (pinOut == null) { Log.Error("TSReader2MP4: FAILED: cannot get output pin of audio codec :0x{0:X}", hr); Cleanup(); return false; } hr = graphBuilder.Connect(pinOut, pinIn); if (hr != 0) { Log.Error("TSReader2MP4: FAILED: unable to connect audio codec->aac encoder: 0x{0:X}", hr); Cleanup(); return false; } //connect output of video codec to h264 encoder Log.Info("TSReader2MP4: connect video codec->h264 encoder"); pinIn = DsFindPin.ByDirection(h264Encoder, PinDirection.Input, 0); if (pinIn == null) { Log.Error("TSReader2MP4: FAILED: cannot get input pin of h264 encoder:0x{0:X}", hr); Cleanup(); return false; } pinOut = DsFindPin.ByDirection(VideoCodec, PinDirection.Output, 0); if (pinOut == null) { Log.Error("TSReader2MP4: FAILED: cannot get output pin of video codec :0x{0:X}", hr); Cleanup(); return false; } hr = graphBuilder.Connect(pinOut, pinIn); if (hr != 0) { Log.Error("TSReader2MP4: FAILED: unable to connect video codec->h264 encoder :0x{0:X}", hr); Cleanup(); return false; } //connect output of aac encoder to pin#0 of mp4mux Log.Info("TSReader2MP4: connect aac encoder->mp4mux"); pinOut = DsFindPin.ByDirection(aacEncoder, PinDirection.Output, 0); if (pinOut == null) { Log.Error("TSReader2MP4: FAILED: cannot get input pin of aac encoder:0x{0:X}", hr); Cleanup(); return false; } pinIn = DsFindPin.ByDirection(mp4Muxer, PinDirection.Input, 0); if (pinIn == null) { Log.Error("TSReader2MP4: FAILED: cannot get input pin#1 of mp4 muxer :0x{0:X}", hr); Cleanup(); return false; } hr = graphBuilder.Connect(pinOut, pinIn); if (hr != 0) { Log.Error("TSReader2MP4: FAILED: unable to connect aac encoder->mp4mux: 0x{0:X}", hr); Cleanup(); return false; } //connect output of h264 encoder to pin#1 of mp4mux Log.Info("TSReader2MP4: connect h264 encoder->mp4mux"); pinOut = DsFindPin.ByDirection(h264Encoder, PinDirection.Output, 0); if (pinOut == null) { Log.Error("TSReader2MP4: FAILED: cannot get input pin of h264 encoder :0x{0:X}", hr); Cleanup(); return false; } pinIn = DsFindPin.ByDirection(mp4Muxer, PinDirection.Input, 1); if (pinIn == null) { Log.Error("TSReader2MP4: FAILED: cannot get input#0 pin of mp4mux :0x{0:X}", hr); Cleanup(); return false; } hr = graphBuilder.Connect(pinOut, pinIn); if (hr != 0) { Log.Error("TSReader2MP4: FAILED: unable to connect h264 encoder->mp4mux :0x{0:X}", hr); Cleanup(); return false; } // dump filter?? //connect mp4 muxer out->filewriter Log.Info("TSReader2MP4: connect mp4mux->filewriter"); pinOut = DsFindPin.ByDirection(mp4Muxer, PinDirection.Output, 0); if (pinOut == null) { Log.Error("TSReader2MP4: FAILED: cannot get output pin of avimux:0x{0:X}", hr); Cleanup(); return false; } pinIn = DsFindPin.ByDirection(fileWriterbase, PinDirection.Input, 0); if (pinIn == null) { Log.Error("TSReader2MP4: FAILED: cannot get input pin of filewriter :0x{0:X}", hr); Cleanup(); return false; } hr = graphBuilder.Connect(pinOut, pinIn); if (hr != 0) { Log.Error("TSReader2MP4: FAILED: connect mp4 muxer->filewriter :0x{0:X}", hr); Cleanup(); return false; } return true; }
private bool EncoderSet(IGraphBuilder graphBuilder, TranscodeInfo info) { //Add methods here to set encoder parameters 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() != ".ts" && ext.ToLower() != ".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; }
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; }
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, 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); }
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); }
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.ToLowerInvariant() != ".dvr-ms" && ext.ToLowerInvariant() != ".sbe") { return(false); } //Type comtype = null; //object comobj = null; try { Log.Info("DVR2MPG: create graph"); graphBuilder = (IGraphBuilder) new FilterGraph(); _rotEntry = new DsROTEntry((IFilterGraph)graphBuilder); Log.Info("DVR2MPG: add streambuffersource"); bufferSource = (IStreamBufferSource) new StreamBufferSource(); IBaseFilter filter = (IBaseFilter)bufferSource; graphBuilder.AddFilter(filter, "SBE SOURCE"); Log.Info("DVR2MPG: load file:{0}", info.file); IFileSourceFilter fileSource = (IFileSourceFilter)bufferSource; int hr = fileSource.Load(info.file, null); Log.Info("DVR2MPG: Add Cyberlink MPEG2 multiplexer to graph"); string monikerPowerDvdMuxer = @"@device:sw:{083863F1-70DE-11D0-BD40-00A0C911CE86}\{7F2BBEAF-E11C-4D39-90E8-938FB5A86045}"; powerDvdMuxer = Marshal.BindToMoniker(monikerPowerDvdMuxer) as IBaseFilter; if (powerDvdMuxer == null) { Log.Warn("DVR2MPG: FAILED:Unable to create Cyberlink MPEG Muxer (PowerDVD)"); Cleanup(); return(false); } hr = graphBuilder.AddFilter(powerDvdMuxer, "PDR MPEG Muxer"); if (hr != 0) { Log.Warn("DVR2MPG: FAILED:Add Cyberlink MPEG Muxer to filtergraph :0x{0:X}", hr); Cleanup(); return(false); } //add filewriter Log.Info("DVR2MPG: Add FileWriter to graph"); string monikerFileWrite = @"@device:sw:{083863F1-70DE-11D0-BD40-00A0C911CE86}\{3E8868CB-5FE8-402C-AA90-CB1AC6AE3240}"; IBaseFilter fileWriterbase = Marshal.BindToMoniker(monikerFileWrite) as IBaseFilter; if (fileWriterbase == null) { Log.Warn("DVR2MPG: FAILED:Unable to create FileWriter"); Cleanup(); return(false); } fileWriterFilter = fileWriterbase as IFileSinkFilter; if (fileWriterFilter == null) { Log.Warn("DVR2MPG: FAILED:Add unable to get IFileSinkFilter for filewriter"); Cleanup(); return(false); } hr = graphBuilder.AddFilter(fileWriterbase, "FileWriter"); if (hr != 0) { Log.Warn("DVR2MPG: FAILED:Add FileWriter to filtergraph :0x{0:X}", hr); Cleanup(); return(false); } //connect output #0 of streambuffer source->powerdvd audio in //connect output #1 of streambuffer source->powerdvd video in Log.Info("DVR2MPG: connect streambuffer->multiplexer"); IPin pinOut0, pinOut1; IPin pinIn0, pinIn1; pinOut0 = DsFindPin.ByDirection((IBaseFilter)bufferSource, PinDirection.Output, 0); pinOut1 = DsFindPin.ByDirection((IBaseFilter)bufferSource, PinDirection.Output, 1); pinIn0 = DsFindPin.ByDirection(powerDvdMuxer, PinDirection.Input, 0); pinIn1 = DsFindPin.ByDirection(powerDvdMuxer, PinDirection.Input, 1); if (pinOut0 == null || pinOut1 == null || pinIn0 == null || pinIn1 == null) { Log.Warn("DVR2MPG: FAILED:unable to get pins of muxer&source"); Cleanup(); return(false); } bool usingAc3 = false; AMMediaType amAudio = new AMMediaType(); amAudio.majorType = MediaType.Audio; amAudio.subType = MediaSubType.Mpeg2Audio; hr = pinOut0.Connect(pinIn1, amAudio); if (hr != 0) { amAudio.subType = MediaSubType.DolbyAC3; hr = pinOut0.Connect(pinIn1, amAudio); usingAc3 = true; } if (hr != 0) { Log.Warn("DVR2MPG: FAILED: unable to connect audio pins: 0x{0:X}", hr); Cleanup(); return(false); } if (usingAc3) { Log.Info("DVR2MPG: using AC3 audio"); } else { Log.Info("DVR2MPG: using MPEG audio"); } AMMediaType amVideo = new AMMediaType(); amVideo.majorType = MediaType.Video; amVideo.subType = MediaSubType.Mpeg2Video; hr = pinOut1.Connect(pinIn0, amVideo); if (hr != 0) { Log.Warn("DVR2MPG: FAILED: unable to connect video pins: 0x{0:X}", hr); Cleanup(); return(false); } //connect output of powerdvd muxer->input of filewriter Log.Info("DVR2MPG: connect multiplexer->filewriter"); IPin pinOut, pinIn; pinOut = DsFindPin.ByDirection(powerDvdMuxer, PinDirection.Output, 0); if (pinOut == null) { Log.Warn("DVR2MPG: FAILED:cannot get output pin of Cyberlink MPEG muxer :0x{0:X}", hr); Cleanup(); return(false); } pinIn = DsFindPin.ByDirection(fileWriterbase, PinDirection.Input, 0); if (pinIn == null) { Log.Warn("DVR2MPG: FAILED:cannot get input pin of Filewriter :0x{0:X}", hr); Cleanup(); return(false); } AMMediaType mt = new AMMediaType(); hr = pinOut.Connect(pinIn, mt); if (hr != 0) { Log.Warn("DVR2MPG: FAILED:connect muxer->filewriter :0x{0:X}", hr); Cleanup(); return(false); } //set output filename string outputFileName = System.IO.Path.ChangeExtension(info.file, ".mpg"); Log.Info("DVR2MPG: set output file to :{0}", outputFileName); mt.majorType = MediaType.Stream; mt.subType = MediaSubTypeEx.MPEG2; hr = fileWriterFilter.SetFileName(outputFileName, mt); if (hr != 0) { Log.Warn("DVR2MPG: FAILED:unable to set filename for filewriter :0x{0:X}", hr); Cleanup(); return(false); } mediaControl = graphBuilder as IMediaControl; mediaSeeking = graphBuilder as IMediaSeeking; mediaEvt = graphBuilder as IMediaEventEx; Log.Info("DVR2MPG: start transcoding"); hr = mediaControl.Run(); if (hr != 0) { Log.Warn("DVR2MPG: FAILED:unable to start graph :0x{0:X}", hr); Cleanup(); return(false); } } catch (Exception ex) { Log.Error("DVR2MPG: Unable create graph: {0}", ex.Message); Cleanup(); return(false); } return(true); }