2012-06-26 5 views
22

Ich verbringe viel Zeit damit, DTVViewer Probe von DirectShow arbeiten leider ohne Erfolg zu machen. Das Videoformat des DVBT-Netzwerks ist H264 und ich habe festgestellt, dass das IntelliConnect-Verhalten von IFilterGraph das Mpeg2-Videoformat bevorzugt.Mpeg2Demultiplexer zwingen, ffdshow zu verwenden, um H264 Digital TV Video zu rendern

Für diejenigen, die den Code sehen möchten, hier ist es. Wenn Sie nichts über DirectShow wissen, habe ich meine Erfahrung mit diesem Code geteilt. Und das wahrscheinlichste Problem ist in Schritt 5 und 6 des Tutorials beschrieben.

  • Der Code für Hilfsfunktion, die Filter verbindet:

    public static void UnsafeConnectFilters(IFilterGraph2 graph, IBaseFilter source, IBaseFilter dest, Func<AMMediaType, bool> sourceMediaPredicate=null, Func<AMMediaType, bool> destMediaPredicate=null) { 
        foreach(IPin spin in IteratePinsByDirection(source, PinDirection.Output)) { 
         if(IsConnected(spin)) 
          continue; 
         int fetched; 
         AMMediaType[] sourceTypes=GetMajorType(spin, out fetched); 
         if(fetched>0) { 
          Guid sourceType=sourceTypes[0].majorType; 
          try { 
           if(sourceMediaPredicate!=null&&!sourceMediaPredicate(sourceTypes[0])) 
            continue; 
           foreach(IPin pin in IteratePinsByDirection(dest, PinDirection.Input)) { 
            if(IsConnected(pin)) 
             continue; 
            var types=GetMajorType(pin, out fetched); 
            try { 
             if(fetched>0) { 
              Guid destType=types[0].majorType; 
              if(destMediaPredicate!=null&&!destMediaPredicate(types[0])) 
               continue; 
              if(sourceType==destType) { 
               spin.Connect(pin, types[0]); 
               return; 
              } 
             } 
             else { 
              spin.Connect(pin, sourceTypes[0]); 
              return; 
             } 
            } 
            finally { 
            } 
           } 
          } 
          finally { 
          } 
    
         } 
        } 
    } 
    

jemand Kennt über:

  1. Wie soll ich den h264 Pin Verbindung ffdshow?
  2. Wie sollte ich das Diagramm zur Verwendung der h264-Videodekodierung empfehlen?

  • Tutorial und Details

    1. Erstellen Sie das Diagramm

      _graph = (IFilterGraph2)new FilterGraph(); 
      
    2. Wir DVBT-Netzwerk verwenden

      IBaseFilter networkProvider = (IBaseFilter) new DVBTNetworkProvider(); 
      

      ..., die auf 602000KHz abgestimmt werden müssen @ 8 MHz ONID = 1 TSID = 1 SID = 6

      ITuner tuner = (ITuner) networkProvider; 
      IDVBTuningSpace tuningspace = (IDVBTuningSpace) new DVBTuningSpace(); 
      tuningspace.put_UniqueName("DVBT TuningSpace"); 
      tuningspace.put_FriendlyName("DVBT TuningSpace"); 
      tuningspace.put__NetworkType(typeof (DVBTNetworkProvider).GUID); 
      tuningspace.put_SystemType(DVBSystemType.Terrestrial); 
      ITuneRequest request; 
      tuningspace.CreateTuneRequest(out request); 
      ILocator locator = (ILocator) new DVBTLocator(); 
      locator.put_CarrierFrequency(602000); 
      ((IDVBTLocator) locator).put_Bandwidth(8); 
      request.put_Locator(locator); 
      IDVBTuneRequest dvbrequest = (IDVBTuneRequest) request; 
      dvbrequest.put_TSID(1); 
      dvbrequest.put_ONID(1); 
      dvbrequest.put_SID(6); 
      _graph.AddFilter(networkProvider, "Network Provider"); 
      
    3. eine mpeg2 demux Erstellen Sie separate EPG/Vidoe/Audio/Text zu erhalten Ströme aus Einzel TV Stream

      _mpeg2Demultiplexer = (IBaseFilter) new MPEG2Demultiplexer(); 
      _graph.AddFilter(_mpeg2Demultiplexer, "MPEG-2 Demultiplexer"); 
      

      Jetzt suchen wir lokale Filter für BDA Source Filter, die in meinem Fall ist IT9135 BDA Fitler

      DsDevice[] devicesOfCat = 
          DsDevice.GetDevicesOfCat(FilterCategory.BDASourceFiltersCategory); 
      
      IBaseFilter iteDeviceFilter; 
      
      _graph.AddSourceFilterForMoniker(
          devicesOfCat[0].Mon, null, devicesOfCat[0].Name, out iteDeviceFilter); 
      
    4. Sie nun Filter: [DVBT Net. Provider]->[BDA Src Filter]->[MPEG2Demux]-> ...

      UnsafeConnectFilters(_graph, networkProvider, iteDeviceFilter); 
      UnsafeConnectFilters(_graph, iteDeviceFilter, _mpeg2Demultiplexer); 
      

      Zwei Filter verbunden werden müssen, um demuxt, EPG (Programmführer-Daten) zur Verfügung zu stellen. Entschuldigung, ich weiß nicht, was sie speziell sind Doig :P. Sie befinden sich unter Kategorie. Wir versuchen, sie mit Namen zu finden und sie

      DsDevice[] dsDevices = 
          DsDevice.GetDevicesOfCat(FilterCategory.BDATransportInformationRenderersCategory); 
      
      foreach (DsDevice dsDevice in dsDevices) 
      { 
          IBaseFilter filter; 
      
          _graph.AddSourceFilterForMoniker(
           dsDevice.Mon, null, dsDevice.Name, out filter); 
      
          if(dsDevice.Name == "BDA MPEG2 Transport Information Filter") 
           _bdaTIF = filter; 
          else if(dsDevice.Name == "MPEG-2 Sections and Tables") 
          { 
           _mpeg2SectionsAndTables = filter; 
          } 
          UnsafeConnectFilters(_graph, _mpeg2Demultiplexer, filter); 
      } 
      

      Jetzt demux demux sowohl MPEG-2 Sections and Tables verbunden ist und BDA MPEG2 Transport Information Filter.

    5. Jetzt h264 Videotyp erstellen und die Ausgabe eines Ausgangsstift fügen für diese Art

      AMMediaType h264 = new AMMediaType(); 
      h264.formatType = FormatType.VideoInfo2; 
      h264.subType = MediaSubType.H264; 
      h264.majorType = MediaType.Video; 
      IPin h264pin; 
      ((IMpeg2Demultiplexer) _mpeg2Demultiplexer).CreateOutputPin(h264, "h264", out h264pin); 
      

      Below zu demux habe ich versucht, für ffdshow Video Decoder zu suchen, die der Verarbeitung H264 fähig ist und unter DirectShow Filters Kategorie (wie in GraphStudio).

      DsDevice[] directshowfilters = 
          DsDevice.GetDevicesOfCat(FilterCategory.LegacyAmFilterCategory); 
      
      IBaseFilter ffdshow = null; 
      foreach (DsDevice directshowfilter in directshowfilters) 
      { 
          if(directshowfilter.Name == "ffdshow Video Decoder") 
          { 
           _graph.AddSourceFilterForMoniker(
            directshowfilter.Mon, null, directshowfilter.Name, 
            out ffdshow); 
      
           break; 
          } 
      } 
      
    6. ein Video-Renderer Erstellen Sie für die Videoausgabe ...

      _videoRenderer = new VideoRendererDefault(); 
      _graph.AddFilter((IBaseFilter)_videoRenderer, "Video Renderer"); 
      

      ... und Audio ...

      DsDevice defaultDirectSound = 
          DsDevice.GetDevicesOfCat(FilterCategory.AudioRendererCategory)[0]; 
      
      _graph.AddSourceFilterForMoniker(
          defaultDirectSound.Mon, null, defaultDirectSound.Name, 
          out _audioRender); 
      

      Hier habe ich versucht, h264 Ausgangsstift zu verbinden von demux zu ffdshow. Dieser Methodenaufruf schlägt mit AccessViolationException fehl. Ich bin nicht sicher, wie man diese zwei zusammen verbindet :(.

      Das Kommentieren dieser Zeile führt zu einem Diagramm, das gestartet wird, obwohl ein getrennter ffdshowVideoDecoder-Filter in der Grafik nichts anzeigt. IntelliConnect verbindet den Mpeg2-Videoausgang mit einem lokal verfügbaren Video-Decoder und wie gesagt wird nichts angezeigt.

      // UnsafeConnectFilters(_graph, _mpeg2Demultiplexer, ffdshow, type => type.majorType == MediaType.Video && type.subType == MediaSubType.H264); 
      
    7. ConnectFilters aus DTVViewer Probe von directshowlib

      entlehnt
      ConnectFilters(); 
      

      ich hier tatsächlich Tuning

      bewegt
      tuner.put_TuningSpace(tuningspace); 
      tuner.put_TuneRequest(request); 
      
    8. die Grafik starten und für einige Ton- oder Video wünschen

      angezeigt werden
      int hr = (_graph as IMediaControl).Run(); 
      DsError.ThrowExceptionForHR(hr); 
      
    9. Scheck, der die Grafik läuft ...

      FilterState pfs; 
      hr = (_graph as IMediaControl).GetState(1000, out pfs); 
      DsError.ThrowExceptionForHR(hr); 
      

      und es sagt, dass der Graph läuft.

+0

... Und ich würde besser sagen, dass ich Windows XP verwende :) – Bakhshi

+0

Können Sie das Diagramm manuell mit GraphEdit erstellen? Wenn ja, fügen Sie bitte das manuelle Diagramm als Screenshot bei. – Odys

+0

@odyodyodys Ich arbeite nicht mehr an diesem Projekt. aber ich konnte das Diagramm nicht nur mit GraphEdit erstellen. Es erfordert eine Vielzahl von Port-Konfigurationen, die in GE nicht möglich sind. Ich habe schließlich die TeamMediaPortal-Komponente verwendet, die ich aus den Quellcodes extrahiert habe. – Bakhshi

Antwort

1

Haben Sie überprüfen, ob Ihre ffdshow für H264/AVC aktiviert ist? Öffnen Sie die Filtereigenschaften und im Abschnitt "Codecs" sollte das H264/AVC-Format aktiviert sein (Sie können den Mpeg2-Decoder auch deaktivieren, um sicherzustellen, dass er dieses Format nicht bevorzugt).

Eine andere Sache, können Sie versuchen, einen anderen Mpeg2 Demultiplexer zu verwenden. Der standardmäßige "MPEG-2-Demultiplexer" verhält sich in verschiedenen Umgebungen nicht identisch. Es gibt viele andere Filter, die TS deinstallieren können und wenn Sie etwas Geld investieren können, würde ich MainConcept oder Elecard empfehlen.

+0

danke fürs vorbeikommen. Ja, das H262 wurde in ffdshow Eigenschaften aktiviert. Über die Verwendung anderer Demuxes bin ich mir nicht sicher, ob ich sie getestet habe oder nicht. Es ist eine Weile her. Wie auch immer, wenn du etwas rennst, kannst du deine Erfahrungen hier teilen, damit andere etwas daraus lernen können? Vielen Dank – Bakhshi

Verwandte Themen