Пример #1
0
 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;
 }
Пример #2
0
    private bool AddWmAsfWriter(string fileName, Quality quality, Standard standard)
    {
      //add asf file writer
      IPin pinOut0, pinOut1;
      IPin pinIn0, pinIn1;
      Log.Info("TSReader2WMV: 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("TSReader2WMV:FAILED:Unable to create ASF WM Writer");
        Cleanup();
        return false;
      }
      int hr = graphBuilder.AddFilter(fileWriterbase, "WM ASF Writer");
      if (hr != 0)
      {
        Log.Error("TSReader2WMV: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("TSReader2WMV: 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)AudioCodec, PinDirection.Output, 0);
      pinOut1 = DsFindPin.ByDirection((IBaseFilter)VideoCodec, PinDirection.Output, 0);
      if (pinOut0 == null || pinOut1 == null)
      {
        Log.Error("TSReader2WMV:FAILED:unable to get outpins of video codec");
        Cleanup();
        return false;
      }
      pinIn0 = DsFindPin.ByDirection(fileWriterbase, PinDirection.Input, 0);
      if (pinIn0 == null)
      {
        Log.Error("TSReader2WMV:FAILED:unable to get pins of asf wm writer");
        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;
      }
      pinIn1 = DsFindPin.ByDirection(fileWriterbase, PinDirection.Input, 1);
      if (pinIn1 == null)
      {
        Log.Error("TSReader2WMV:FAILED:unable to get pins of asf wm writer");
        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;
      }
      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("TSReader2WMV: 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("TSReader2WMV: 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("TSReader2WMV: 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("TSReader2WMV: 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("TSReader2WMV: 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("TSReader2WMV: 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("TSReader2WMV: 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("TSReader2WMV: 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("TSReader2WMV: get WMV profile - FAILED! {0}", hr);
        Cleanup();
        return false;
      }
      Log.Info("TSReader2WMV: load profile - SUCCESS!");
      //configures the WM ASF Writer to the chosen profile
      hr = config.ConfigureFilterUsingProfile(profile);
      if (hr != 0)
      {
        Log.Info("TSReader2WMV: configure profile - FAILED! {0}", hr);
        Cleanup();
        return false;
      }
      Log.Info("TSReader2WMV: 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;
    }
Пример #3
0
 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;
 }