Я трачу много времени, пытаясь сделать образ 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 { } } } }
Кто-нибудь знает о:
- Как следует подключить h264 булавку FFDShow?
- Как рекомендую использовать график декодирования видео h264?
Учебник и детали
Создать график
_graph = (IFilterGraph2)new FilterGraph();
Мы используем 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");
Создать 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);
Теперь подключить фильтры:
[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
.Теперь создайте 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; } }
Создание видео-визуализации для вывода видео ...
_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);
ConnectFilters
заимствовано из DTVViewer образца directshowlibConnectFilters();
я переехал фактической настройки здесь
tuner.put_TuningSpace(tuningspace); tuner.put_TuneRequest(request);
начать график и пожелать какой-то звук или видео, которое будет отображаться
int hr = (_graph as IMediaControl).Run(); DsError.ThrowExceptionForHR(hr);
проверить, что граф работает ...
FilterState pfs; hr = (_graph as IMediaControl).GetState(1000, out pfs); DsError.ThrowExceptionForHR(hr);
, и он говорит, что граф работает.
... И я бы сказал, что я использую Windows XP :) – Bakhshi
Можете ли вы создать график вручную с помощью GraphEdit? Если да, включите ручную диаграмму в качестве снимка экрана. – Odys
@odyodyodys Я больше не работаю над этим проектом. но мне не удалось создать график, используя только GraphEdit. Это требует большой конфигурации портов, что невозможно в GE. Наконец, я использовал компонент TeamMediaPortal, который я извлек из исходных кодов. – Bakhshi