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:
- Wie soll ich den h264 Pin Verbindung ffdshow?
- Wie sollte ich das Diagramm zur Verwendung der h264-Videodekodierung empfehlen?
Tutorial und Details
Erstellen Sie das Diagramm
_graph = (IFilterGraph2)new FilterGraph();
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");
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);
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 sieDsDevice[] 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 undBDA MPEG2 Transport Information Filter
.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 inGraphStudio
).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; } }
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);
entlehntConnectFilters
aus DTVViewer Probe von directshowlibConnectFilters();
ich hier tatsächlich Tuning
bewegttuner.put_TuningSpace(tuningspace); tuner.put_TuneRequest(request);
die Grafik starten und für einige Ton- oder Video wünschen
angezeigt werdenint hr = (_graph as IMediaControl).Run(); DsError.ThrowExceptionForHR(hr);
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.
... Und ich würde besser sagen, dass ich Windows XP verwende :) – Bakhshi
Können Sie das Diagramm manuell mit GraphEdit erstellen? Wenn ja, fügen Sie bitte das manuelle Diagramm als Screenshot bei. – Odys
@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