2012-06-26 16 views
22

DTVViewerのDirectShowサンプルを残念ながら成功させるために多くの時間を費やしています。 DVBTネットワークのビデオフォーマットはH264であり、IntelliConnectの動作がIFilterGraphであることが、Mpeg2ビデオフォーマットを使用することが好ましいことがわかりました。Mpeg2Demultiplexerでffdshowを使用してH264デジタルテレビビデオをレンダリングする

コードを見たい人は、ここをクリックしてください。 DirectShowについて何も知らないのであれば、このコードで私の経験を共有しました。そしておそらく問題はチュートリアルのステップ5と6に記載されています。

  • フィルタを接続しているヘルパー関数のコード:

    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 { 
          } 
    
         } 
        } 
    } 
    

は約誰を知っています:

  1. 私はffdshowをするH264ピンを接続する必要がありますどのように?
  2. グラフをh264ビデオデコードを使用するにはどうすればよいですか?

  • チュートリアルや詳細

    1. はグラフ

      _graph = (IFilterGraph2)new FilterGraph(); 
      
    2. を作成 私たちは、DVB-Tネットワークを使用している
    3. KHz @ 8MHzの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"); 
      
    4. 別のEPG/Vidoe /オーディオ/テキストを取得するには、MPEG2デマルチプレクサを作成するために調整されなければならない

      IBaseFilter networkProvider = (IBaseFilter) new DVBTNetworkProvider(); 
      

      は...外のストリーム単一のTVストリーム

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

      今、私たちは私の場合にはIT9135 BDA Fitler

      DsDevice[] devicesOfCat = 
          DsDevice.GetDevicesOfCat(FilterCategory.BDASourceFiltersCategory); 
      
      IBaseFilter iteDeviceFilter; 
      
      _graph.AddSourceFilterForMoniker(
          devicesOfCat[0].Mon, null, devicesOfCat[0].Name, out iteDeviceFilter); 
      
    5. であるBDAソースフィルタのためのローカルフィルタを検索
    6. は今のフィルタを接続します[DVBT Net. Provider]->[BDA Src Filter]->[MPEG2Demux]-> ...

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

      二つのフィルタは、EPG(番組表データ)を提供するために、デマルチプレクサに接続しなければなりません。申し訳ありませんが、私は彼らが具体的にdoigであるか分からない:P。それらはBDATransportInformationRenderersCategoryカテゴリの下にあります。私たちは、名前でそれらを見つけるとMPEG-2 Sections and TablesBDA MPEG2 Transport Information Filterの両方に接続されている今、DEMUX

      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); 
      } 
      

      をデマルチプレクサするためにそれらを接続してみてください。

    7. 今すぐH264ビデオタイプを作成して、このタイプの下

      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); 
      

      のためにデマルチプレクサする出力ピンを出力を追加し、私はH264ビデオを処理することが可能であるとされffdshowのビデオデコーダを検索してみましたDirectShow Filtersカテゴリの下にあります(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; 
          } 
      } 
      
    8. ... ...ビデオ出力ため

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

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

      ...とオーディオをビデオレンダラを作成し、私はH264出力ピンを接続しようとしましたdemuxからffdshowへこのメソッド呼び出しは、AccessViolationExceptionで失敗します。私はどのようにこれら2つを一緒に接続するか分からない:(

      この行にコメントすると、グラフに接続されていないffdshowVideoDecoderフィルタがありますが、実行を開始するグラフが表示されます。何も表示されません。 IntelliConnectはMpeg2ビデオ出力をローカルで利用可能なビデオデコーダに接続し、私は何も表示しないと言った。

      // UnsafeConnectFilters(_graph, _mpeg2Demultiplexer, ffdshow, type => type.majorType == MediaType.Video && type.subType == MediaSubType.H264); 
      
    9. ConnectFilters私は

      を表示するためにここに

      tuner.put_TuningSpace(tuningspace); 
      tuner.put_TuneRequest(request); 
      
    10. グラフを起動して、いくつかの音や映像をご希望の実際のチューニングを移動directshowlib

      ConnectFilters(); 
      

      のDTVViewerサンプルから借りています

      int hr = (_graph as IMediaControl).Run(); 
      DsError.ThrowExceptionForHR(hr); 
      
    11. グラフが実行されていることを確認...

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

      、それはグラフが実行されていることを述べています。

+0

...そして私はWindows XPを使っているといいでしょう:) – Bakhshi

+0

GraphEditを使って手動でグラフを作成できますか?もしそうなら、マニュアルグラフをスクリーンショットとして含めてください。 – Odys

+0

@odyodyodys私はもはやそのプロジェクトに取り組んでいません。 GraphEditだけでグラフを作成することはできませんでした。 GEでは不可能な多くのポート構成が必要です。私は最終的に私がソースコードから抽出したTeamMediaPortalコンポーネントを使用しました。 – Bakhshi

答えて

1

あなたはffdshowのは、H264/AVCのために有効になっていることを確認しましたか?フィルタのプロパティを開き、 "コーデック"セクションでH264/AVCフォーマットを有効にする必要があります(このフォーマットが好まれないことを確認するためにMpeg2デコーダを無効にすることもできます)。

別のこととして、別のMpeg2デマルチプレクサを使用してみることもできます。デフォルトの「MPEG-2デマルチプレクサ」は、異なる環境で同じ動作をしません。 TSをデマルチプレクサにすることができる他の多くのフィルタがあります。お金を投資することができれば、MainConceptまたはElecardの使用をお勧めします。

+0

お越しいただきありがとうございます。うん、H262はffdshowのプロパティで有効になっていた。他のデマルチプレクサの使用については、テストしたかどうかわかりません。それはしばらくしています。とにかく、走っているものがあればここであなたの経験を共有できるので、他の人が何かを学ぶことができますか?ありがとう – Bakhshi

関連する問題