2012-06-26 3 views
22

Я трачу много времени, пытаясь сделать образ DTVViewer работы DirectShow, к сожалению, без успеха. Видеоформат DVBT-сети - H264, и я обнаружил, что поведение IntelliConnect IFilterGraph предпочитает использовать формат видео Mpeg2.Принуждение Mpeg2Demultiplexer для использования ffdshow для рендеринга H264 Digital TV Video

Для тех, кто хочет видеть код, вот оно. Если вы ничего не знаете о 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. Как следует подключить h264 булавку FFDShow?
  2. Как рекомендую использовать график декодирования видео h264?

  • Учебник и детали

    1. Создать график

      _graph = (IFilterGraph2)new FilterGraph(); 
      
    2. Мы используем DVBT сети

      IBaseFilter networkProvider = (IBaseFilter) new DVBTNetworkProvider(); 
      

      ... который должен быть настроен на 602000KHz @ 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"); 
      
    3. Создать mpeg2 демультиплексор, чтобы получить отдельный ЭПП/Vidoe/Аудио/Text потоки из одиночный поток TV

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

      Сейчас мы ищем локальные фильтры для BDA Source Filter, который в моем случае это IT9135 BDA Fitler

      DsDevice[] devicesOfCat = 
          DsDevice.GetDevicesOfCat(FilterCategory.BDASourceFiltersCategory); 
      
      IBaseFilter iteDeviceFilter; 
      
      _graph.AddSourceFilterForMoniker(
          devicesOfCat[0].Mon, null, devicesOfCat[0].Name, out iteDeviceFilter); 
      
    4. Теперь подключить фильтры: [DVBT Net. Provider]->[BDA Src Filter]->[MPEG2Demux]-> ...

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

      Два фильтра должны быть подключены к демультиплексируете, чтобы обеспечить ЭПП (данные программы передач). жаль, что я не знаю, что они конкретно делают doig :P. Они расположены под категорией BDATransportInformationRenderersCategory. Мы пытаемся найти их по имени и подключить их к демультиплексируете

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

      Теперь демультиплексора подключен к обоим MPEG-2 Sections and Tables и BDA MPEG2 Transport Information Filter.

    5. Теперь создайте h264 тип видео и добавить в выходной выходной булавку DeMUX для этого типа

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

      Ниже я попытался найти FFDShow Video Decoder, который способен обрабатывать H264 видео и расположенный под категорией 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; 
          } 
      } 
      
    6. Создание видео-визуализации для вывода видео ...

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

      ... и аудио ...

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

      Здесь я попытался соединить h264 выходной контакт demux to ffdshow. Этот вызов метода не выполняется с AccessViolationException. Я не уверен, как связать эти два вместе :(.

      Комментарий к этой строке приведет к запуску графика, хотя на графике отсутствует отключенный фильтр ffdshowVideoDecoder, ничего не будет отображаться. IntelliConnect подключает видеовыход Mpeg2 к локально доступному видеодекодеру, и, как я уже сказал, он ничего не отобразит.

      // UnsafeConnectFilters(_graph, _mpeg2Demultiplexer, ffdshow, type => type.majorType == MediaType.Video && type.subType == MediaSubType.H264); 
      
    7. ConnectFilters заимствовано из DTVViewer образца directshowlib

      ConnectFilters(); 
      

      я переехал фактической настройки здесь

      tuner.put_TuningSpace(tuningspace); 
      tuner.put_TuneRequest(request); 
      
    8. начать график и пожелать какой-то звук или видео, которое будет отображаться

      int hr = (_graph as IMediaControl).Run(); 
      DsError.ThrowExceptionForHR(hr); 
      
    9. проверить, что граф работает ...

      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 Demultiplexer» не ведет себя одинаково в разных средах. Есть много других фильтров, которые могут использовать demux TS, и если вы можете инвестировать немного денег, я бы рекомендовал использовать MainConcept или Elecard.

+0

спасибо за прохождение мимо. Да, H262 был включен в свойствах ffdshow. Об использовании других демультиплексов я не уверен, тестировал ли я их или нет. Прошло много времени. в любом случае, если у вас что-то работает, можете ли вы поделиться своим опытом здесь, чтобы другие могли чему-то научиться? благодаря – Bakhshi