-
Создайте график
_graph = (IFilterGraph2)new FilterGraph();
-
Мы используем сеть DVBT
IBaseFilter networkProvider = (IBaseFilter) new DVBTNetworkProvider();
... который должен быть настроен на 602000 кГц при 8 МГц 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 demux для получения отдельных потоков EPG/Vidoe/Audio/Text из одного телевизионного потока.
_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);
Два фильтра должны быть подключены к demux, чтобы обеспечить epg (данные программы). извините, я не знаю, что они конкретно делают doig :P
. Они расположены в категории BDATransportInformationRenderersCategory
. Мы пытаемся найти их по имени и подключить их к 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);
}
Теперь demux подключается как к 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 демультиплексирования к ffdshow. Этот вызов метода не выполняется с AccessViolationException. Я не уверен, как соединить эти два вместе :(
.
Комментирование этой строки приведет к запуску графика, хотя на графике есть отключенный фильтр ffdshowVideoDecoder, ничего не покажет. IntelliConnect подключает видеовыход Mpeg2 к локально доступному видеодекодеру, и, как я уже сказал, он ничего не отобразит.
// UnsafeConnectFilters(_graph, _mpeg2Demultiplexer, ffdshow, type => type.majorType == MediaType.Video && type.subType == MediaSubType.H264);
-
ConnectFilters
заимствован из образца DTVViewer directshowlib
ConnectFilters();
Я перевел реальную настройку здесь
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);
и он говорит, что график запущен.