private void Cleanup() { Log.Info("TSReader2MP4: cleanup"); if (_rotEntry != null) { _rotEntry.SafeDispose(); } _rotEntry = null; if (mediaControl != null) { mediaControl.Stop(); mediaControl = null; } fileWriterFilter = null; mediaSeeking = null; mediaEvt = null; mediaPos = null; mediaControl = null; if (h264Encoder != null) { DirectShowUtil.ReleaseComObject(h264Encoder); } h264Encoder = null; if (aacEncoder != null) { DirectShowUtil.ReleaseComObject(aacEncoder); } aacEncoder = null; if (mp4Muxer != null) { DirectShowUtil.ReleaseComObject(mp4Muxer); } mp4Muxer = null; if (AudioCodec != null) { DirectShowUtil.ReleaseComObject(AudioCodec); } AudioCodec = null; if (VideoCodec != null) { DirectShowUtil.ReleaseComObject(VideoCodec); } VideoCodec = null; if (tsreaderSource != null) { DirectShowUtil.ReleaseComObject(tsreaderSource); } tsreaderSource = null; DirectShowUtil.RemoveFilters(graphBuilder); if (graphBuilder != null) { DirectShowUtil.ReleaseComObject(graphBuilder); } graphBuilder = null; GC.Collect(); GC.Collect(); GC.Collect(); GC.WaitForPendingFinalizers(); }
void BuildGraph() { int hr; IBaseFilter ppbf, ppFilter; ICaptureGraphBuilder2 icgb2; IFileSinkFilter ppsink; DsDevice [] devs; IGraphBuilder graphBuilder = new FilterGraph() as IGraphBuilder; icgb2 = (ICaptureGraphBuilder2) new CaptureGraphBuilder2(); icgb2.SetFiltergraph(graphBuilder); DsROTEntry ds = new DsROTEntry(graphBuilder); IFilterGraph2 ifg2 = graphBuilder as IFilterGraph2; devs = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice); DsDevice dev = devs[0]; hr = ifg2.AddSourceFilterForMoniker(dev.Mon, null, dev.Name, out ppFilter); DsError.ThrowExceptionForHR(hr); // Get a ICaptureGraphBuilder2 ICaptureGraphBuilder2 icgb = (ICaptureGraphBuilder2) new CaptureGraphBuilder2(); hr = icgb.SetFiltergraph((IGraphBuilder)graphBuilder); DsError.ThrowExceptionForHR(hr); // Use the ICaptureGraphBuilder2 to add the avi mux hr = icgb.SetOutputFileName(MediaSubType.Avi, FileName, out ppbf, out ppsink); DsError.ThrowExceptionForHR(hr); hr = icgb2.RenderStream(PinCategory.Capture, MediaType.Video, ppFilter, null, ppbf); DsError.ThrowExceptionForHR(hr); m_ppsink = ppsink as IFileSinkFilter2; }
private bool AddWmAsfWriter(string fileName, Quality quality, Standard standard) { //add asf file writer IPin pinOut0, pinOut1; IPin pinIn0, pinIn1; Log.Info("DVRMS2WMV: add WM ASF Writer to graph"); string monikerAsfWriter = @"@device:sw:{083863F1-70DE-11D0-BD40-00A0C911CE86}\{7C23220E-55BB-11D3-8B16-00C04FB6BD3D}"; fileWriterbase = Marshal.BindToMoniker(monikerAsfWriter) as IBaseFilter; if (fileWriterbase == null) { Log.Error("DVRMS2WMV:FAILED:Unable to create ASF WM Writer"); Cleanup(); return(false); } int hr = graphBuilder.AddFilter(fileWriterbase, "WM ASF Writer"); if (hr != 0) { Log.Error("DVRMS2WMV:FAILED:Add ASF WM Writer to filtergraph :0x{0:X}", hr); Cleanup(); return(false); } IFileSinkFilter2 fileWriterFilter = fileWriterbase as IFileSinkFilter2; if (fileWriterFilter == null) { Log.Error("DVR2XVID:FAILED:Add unable to get IFileSinkFilter for filewriter"); Cleanup(); return(false); } hr = fileWriterFilter.SetFileName(fileName, null); hr = fileWriterFilter.SetMode(AMFileSinkFlags.OverWrite); Log.Info("DVRMS2WMV: connect audio/video codecs outputs -> ASF WM Writer"); //connect output #0 of videocodec->asf writer pin 1 //connect output #0 of audiocodec->asf writer pin 0 pinOut0 = DsFindPin.ByDirection((IBaseFilter)Mpeg2AudioCodec, PinDirection.Output, 0); pinOut1 = DsFindPin.ByDirection((IBaseFilter)Mpeg2VideoCodec, PinDirection.Output, 0); if (pinOut0 == null || pinOut1 == null) { Log.Error("DVRMS2WMV:FAILED:unable to get outpins of video codec"); Cleanup(); return(false); } pinIn0 = DsFindPin.ByDirection(fileWriterbase, PinDirection.Input, 0); if (pinIn0 == null) { Log.Error("DVRMS2WMV:FAILED:unable to get pins of asf wm writer"); Cleanup(); return(false); } hr = graphBuilder.Connect(pinOut0, pinIn0); if (hr != 0) { Log.Error("DVRMS2WMV:FAILED:unable to connect audio pins :0x{0:X}", hr); Cleanup(); return(false); } pinIn1 = DsFindPin.ByDirection(fileWriterbase, PinDirection.Input, 1); if (pinIn1 == null) { Log.Error("DVRMS2WMV:FAILED:unable to get pins of asf wm writer"); Cleanup(); return(false); } hr = graphBuilder.Connect(pinOut1, pinIn1); if (hr != 0) { Log.Error("DVRMS2WMV:FAILED:unable to connect video pins :0x{0:X}", hr); Cleanup(); return(false); } IConfigAsfWriter config = fileWriterbase as IConfigAsfWriter; IWMProfileManager profileManager = null; IWMProfileManager2 profileManager2 = null; IWMProfile profile = null; hr = WMLib.WMCreateProfileManager(out profileManager); string strprofileType = ""; switch (quality) { case Quality.HiDef: //hr = WMLib.WMCreateProfileManager(out profileManager); if (standard == Standard.Film) { strprofileType = Config.GetFile(Config.Dir.Base, @"Profiles\MPHiDef-FILM.prx"); } if (standard == Standard.NTSC) { strprofileType = Config.GetFile(Config.Dir.Base, @"Profiles\MPHiDef-NTSC.prx"); } if (standard == Standard.PAL) { strprofileType = Config.GetFile(Config.Dir.Base, @"Profiles\MPHiDef-PAL.prx"); } Log.Info("DVRMS2WMV: set WMV HiDef quality profile {0}", strprofileType); break; case Quality.VeryHigh: if (standard == Standard.Film) { strprofileType = Config.GetFile(Config.Dir.Base, @"Profiles\MPVeryHigh-FILM.prx"); } if (standard == Standard.NTSC) { strprofileType = Config.GetFile(Config.Dir.Base, @"Profiles\MPVeryHigh-NTSC.prx"); } if (standard == Standard.PAL) { strprofileType = Config.GetFile(Config.Dir.Base, @"Profiles\MPVeryHigh-PAL.prx"); } Log.Info("DVRMS2WMV: set WMV Very High quality profile {0}", strprofileType); break; case Quality.High: if (standard == Standard.Film) { strprofileType = Config.GetFile(Config.Dir.Base, @"Profiles\MPHigh-FILM.prx"); } if (standard == Standard.NTSC) { strprofileType = Config.GetFile(Config.Dir.Base, @"Profiles\MPHigh-NTSC.prx"); } if (standard == Standard.PAL) { strprofileType = Config.GetFile(Config.Dir.Base, @"Profiles\MPHigh-PAL.prx"); } Log.Info("DVRMS2WMV: set WMV High quality profile {0}", strprofileType); break; case Quality.Medium: if (standard == Standard.Film) { strprofileType = Config.GetFile(Config.Dir.Base, @"Profiles\MPMedium-FILM.prx"); } if (standard == Standard.NTSC) { strprofileType = Config.GetFile(Config.Dir.Base, @"Profiles\MPMedium-NTSC.prx"); } if (standard == Standard.PAL) { strprofileType = Config.GetFile(Config.Dir.Base, @"Profiles\MPMedium-PAL.prx"); } Log.Info("DVRMS2WMV: set WMV Medium quality profile {0}", strprofileType); break; case Quality.Low: if (standard == Standard.Film) { strprofileType = Config.GetFile(Config.Dir.Base, @"Profiles\MPLow-FILM.prx"); } if (standard == Standard.NTSC) { strprofileType = Config.GetFile(Config.Dir.Base, @"Profiles\MPLow-NTSC.prx"); } if (standard == Standard.PAL) { strprofileType = Config.GetFile(Config.Dir.Base, @"Profiles\MPLow-PAL.prx"); } Log.Info("DVRMS2WMV: set WMV Low quality profile {0}", strprofileType); break; case Quality.Portable: if (standard == Standard.Film) { strprofileType = Config.GetFile(Config.Dir.Base, @"Profiles\MPPortable-FILM.prx"); } if (standard == Standard.NTSC) { strprofileType = Config.GetFile(Config.Dir.Base, @"Profiles\MPPortable-NTSC.prx"); } if (standard == Standard.PAL) { strprofileType = Config.GetFile(Config.Dir.Base, @"Profiles\MPPortable-PAL.prx"); } Log.Info("DVRMS2WMV: set WMV Portable quality profile {0}", strprofileType); break; case Quality.Custom: //load custom profile string customBitrate = ""; //Adjust the parameters to suit the custom settings the user has selected. switch (bitrate) { case 0: customBitrate = "100Kbs"; break; case 1: customBitrate = "256Kbs"; break; case 2: customBitrate = "384Kbs"; break; case 3: customBitrate = "768Kbs"; break; case 4: customBitrate = "1536Kbs"; break; case 5: customBitrate = "3072Kbs"; break; case 6: customBitrate = "5376Kbs"; break; } Log.Info("DVRMS2WMV: custom bitrate = {0}", customBitrate); //TODO: get fps values & frame size //TODO: adjust settings required //Call the SetCutomPorfile method to load the custom profile, adjust it's params from user settings & then save it. //SetCutomProfile(videoBitrate, audioBitrate, videoHeight, videoWidth, videoFps); //based on user inputs //We then reload it after as per other quality settings / profiles. strprofileType = Config.GetFile(Config.Dir.Base, @"Profiles\MPCustom.prx"); Log.Info("DVRMS2WMV: set WMV Custom quality profile {0}", strprofileType); break; } //Loads profile from the above quality selection. using (StreamReader prx = new StreamReader(strprofileType)) { String profileContents = prx.ReadToEnd(); profileManager2 = profileManager as IWMProfileManager2; hr = profileManager2.LoadProfileByData(profileContents, out profile); if (hr != 0) { Log.Info("DVRMS2WMV: get WMV profile - FAILED! {0}", hr); Cleanup(); return(false); } } Log.Info("DVRMS2WMV: load profile - SUCCESS!"); //configures the WM ASF Writer to the chosen profile hr = config.ConfigureFilterUsingProfile(profile); if (hr != 0) { Log.Info("DVRMS2WMV: configure profile - FAILED! {0}", hr); Cleanup(); return(false); } Log.Info("DVRMS2WMV: configure profile - SUCCESS!"); //TODO: Add DB recording information into WMV. //Release resorces if (profile != null) { Marshal.ReleaseComObject(profile); profile = null; } if (profileManager != null) { Marshal.ReleaseComObject(profileManager); profileManager = null; } 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 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 void Cleanup() { Log.Info("DVRMS2DIVX: cleanup"); if (_rotEntry != null) { _rotEntry.SafeDispose(); } _rotEntry = null; if (mediaControl != null) { mediaControl.Stop(); mediaControl = null; } fileWriterFilter = null; mediaSeeking = null; mediaEvt = null; mediaPos = null; mediaControl = null; if (divxCodec != null) { DirectShowUtil.ReleaseComObject(divxCodec); } divxCodec = null; if (mp3Codec != null) { DirectShowUtil.ReleaseComObject(mp3Codec); } mp3Codec = null; if (aviMuxer != null) { DirectShowUtil.ReleaseComObject(aviMuxer); } aviMuxer = 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 (graphBuilder != null) { DirectShowUtil.ReleaseComObject(graphBuilder); } graphBuilder = null; GC.Collect(); GC.Collect(); GC.Collect(); GC.WaitForPendingFinalizers(); }
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 void Cleanup() { Log.Info("TSReader2MP4: cleanup"); if (_rotEntry != null) { _rotEntry.SafeDispose(); } _rotEntry = null; if (mediaControl != null) { mediaControl.Stop(); mediaControl = null; } fileWriterFilter = null; mediaSeeking = null; mediaEvt = null; mediaPos = null; mediaControl = null; if (h264Encoder != null) DirectShowUtil.ReleaseComObject(h264Encoder); h264Encoder = null; if (aacEncoder != null) DirectShowUtil.ReleaseComObject(aacEncoder); aacEncoder = null; if (mp4Muxer != null) DirectShowUtil.ReleaseComObject(mp4Muxer); mp4Muxer = null; if (AudioCodec != null) DirectShowUtil.ReleaseComObject(AudioCodec); AudioCodec = null; if (VideoCodec != null) DirectShowUtil.ReleaseComObject(VideoCodec); VideoCodec = null; if (tsreaderSource != null) DirectShowUtil.ReleaseComObject(tsreaderSource); tsreaderSource = null; DirectShowUtil.RemoveFilters(graphBuilder); if (graphBuilder != null) DirectShowUtil.ReleaseComObject(graphBuilder); graphBuilder = null; GC.Collect(); GC.Collect(); GC.Collect(); GC.WaitForPendingFinalizers(); }
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 void Cleanup() { Log.Info("DVRMS2DIVX: cleanup"); if (_rotEntry != null) { _rotEntry.SafeDispose(); } _rotEntry = null; if (mediaControl != null) { mediaControl.Stop(); mediaControl = null; } fileWriterFilter = null; mediaSeeking = null; mediaEvt = null; mediaPos = null; mediaControl = null; if (divxCodec != null) DirectShowUtil.ReleaseComObject(divxCodec); divxCodec = null; if (mp3Codec != null) DirectShowUtil.ReleaseComObject(mp3Codec); mp3Codec = null; if (aviMuxer != null) DirectShowUtil.ReleaseComObject(aviMuxer); aviMuxer = 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 (graphBuilder != null) DirectShowUtil.ReleaseComObject(graphBuilder); graphBuilder = null; GC.Collect(); GC.Collect(); GC.Collect(); GC.WaitForPendingFinalizers(); }