Tut sich hier denn gar nix mehr, oder was :-)

Schon seit einiger Zeit schiebe ich es vor mir her, etwas zur nächsten Version 3.1 von DVB.NET und VCR.NET zu schreiben. Da mich heute Morgen ein Anwender mal gezielt darauf angesprochen hat, will ich doch jetzt mal erzählen, was ich denn (in dem Teil meiner Freizeit, die mir für DVB.NET / VCR.NET bleibt) so tue.

Grundsätzlich ist es bei jeder neuen Version so, dass ich mir einige Features überlege, die ich einbauen möchte – seit einiger Zeit natürlich auch getrieben durch die Anwender, die vor allem (aber nicht nur) VCR.NET produktiv nutzen. Aber beide Projekte bleiben immer noch meine Spielfelder, um Neues zu lernen und (Microsoft) Technologie auch mal auszuprobieren. Für die 3.1 wollte ich versuchen, mir für einige Wünsche erst einmal klar zu werden, ob und in welchem Umfang sie für mich im Rahmen meiner (vor allem zeitlichen) Möglichkeiten realisierbar sind – bevor ich im Forum die bereits seit mehreren Version bekannten Listen mit soll gemacht werden und ist bereits gemacht anlege und pflege. In dieser Phase bin ich jetzt.

Dazu einige Details. 3.1 wird im Zeichen von DVB.NET stehen, daher zuerst zu VCR.NET – das natürlich von Verbesserungen in DVB.NET profitiert, aber das ist dann mehr ein Seiteneffekt. Das Kernfeature hier soll es sein, die ASP.NET 2.0 Web Anwendung freier optisch gestalten zu können. Da fallen Begriffe wie Themes, Skins und Styles. Meine Absicht ist es, nahe an den Möglichkeiten von ASP.NET 2.0 zu bleiben und da weiß ich einfach im Moment zu wenig – ok, Personalisierung wird bereits in VCR.NET 3.0 genutzt, hat aber mit der optischen Gestaltung eher am Rande zu tun. VCR.NET 3.1 wird es voraussichtlich weiterhin nur in Deutsch geben, Lokalisierung / Globalisierung wird Thema für eine der späteren Versionen sein, ich hoffe aber schon, dass es 3.2 wird.

Im Schnittpunkt zu DVB.NET 3.1 stehen der Zapping Client und die Möglichkeit, die laufende Aufzeichnung zu betrachten (LIVE oder Timeshift). Für DVB.NET 3.1 hoffe ich, die beiden Quick Record Varianten durch ein neues Tool abzulösen (Arbeitstitel DVB.NET Viewer, vermutlich eigenständiges Setup), das vor allem nicht mehr auf VLC, sondern auf DirectShow Graphen basiert. Genau hier fließt im Moment meine Zeit hinein. Wobei ich mich um den Kernbereich noch etwas drücke, nämlich die fehlerfreie Darstellung von Bild und Ton über DirectShow – es ruckelt noch, AC3, H.264 und Radio gehen [noch] nicht und so weiter. Aber es geht schon grundsätzlich ein bißchen was und zur Zeit habe ich einen Stand erreicht, bei dem das Tool entweder die lokale Hardware anspricht und die Quick Records praktisch vollständig (echtes Manko bisher: kein Hardware Modus mehr für die Nexus / TechnoTrend Premium) und bis auf das Preview eines zweiten Senders auch den Zapping Client ersetzen kann. Zusätzlich gibt es erste Schritte in die Richtung, die laufende Aufzeichnung im VCR.NET zu betrachten (kein Timeshift). Im Gegensatz zu den bisherigen Tools wird es (bis auf wenige Ausnahmen im Bereich der Konfiguration) auch eine vollständige Steuerung über die Tastatur (und damit vermutlich auch die Fernbedienung via Girder) erlauben. Wenn die Kernfeatures im DVB.NET Viewer stehen (ohne AC3, H.264, Radio) werde ich eine Beta Homepage machen und ein technisches Preview erstellen mit dem man mal schauen kann, ob das Konzept passen könnte – für mich tut es das auf jeden Fall, i.e. geben wird es den DVB.NET Viewer auf jeden Fall, allerdings ist die Frage, ob die alten Tools dann noch weiterentwickelt werden müssen oder nicht. Zeitplan: sobald wie möglich, kann sich aber noch in Wochen rechnen!

Ok, nächstes großes Thema für DVB.NET 3.1 ist das EPG der englischen Sender BBC / ITV / …, das anders angelegt ist als das konventionelle EPG (PID 0x12). Hier weiß ich noch zu wenig und muß mir ein ziemlich genaues Bild machen, damit es sich lohnt, dieses Feature anzukündigen. Für mich wäre es sehr schade, wenn es nicht käme, denn die Programmierung über EPG ist nun mal um vieles einfacher als manuell – ok, es gibt ja noch die Alternative TV Browser, aber ob das aktueller als das echte (Sky)EPG ist, möchte ich mal bezweifeln.

Der letzte größere Punkt in DVB.NET 3.1 ist Fleiß und muß nicht evaluiert werden. Dabei geht es um die Senderlisten und den Sendersuchlauf. Bereits jetzt (heißt hier lokal) unterstützt DVB.NET 3.1 mehrere AC3 Tonspuren oder einen inkrementellen Suchlauf. Geplant sind Nachbearbeitungsscripts, die etwa helfen, Sendernamen stabil zu halten.

Alles andere für VCR.NET und DVB.NET 3.1 ist mehr oder weniger in der Lösung klar. Da muß ich aus den ca. 50 offenen Punkten nur die heraussuchen, die zeitlich machbar sind oder es erscheinen. Ich kann mir im Moment etwa gut vorstellen, dass es möglich sein wird, eigene Programme beim Beenden von Aufzeichnungen zu starten oder die Oberfläche eine bessere Unterstützung von Mehrkanalaufzeichnungen anbietet. Unwahrscheinlich ist im Moment die Unterstützung von DVB-C via BDA – aber auch im Endeffekt nur Fleiß, so wie es aussieht.

So, dass muss jetzt für ein paar Tage reichen 🙂 Wenn die Entwicklung wirklich losgeht, hoffe ich wirklich mal wieder alle paar Tage ein kleines Fenster aufmachen zu können – aber so ist das halt mit den guten Vorsätzen, gelle!

In diesem Sinne

Jochen

VCR.NET Live oder so…

Mal was anderes: mein Kollege Roland Weigelt, der sich sehr im Bereich .NET Entwicklung engagiert, hat es mir ermöglicht, ein bißchen über VCR.NET zu erzählen. Dabei geht es allerdings nicht um das, was der Recording Service tut (nämlich aufzeichnen), sondern vielmehr darum, wie er es macht. In Fokus steht dabei die Client / Server Architektur und die Frage, wie ein Anwender denn mit einem unsichtbaren Windows Dienst kommunizieren kann. Wer VCR.NET über die Jahre verfolgt hat, der weiß, dass es da eine Menge Veränderungen im Laufe der Zeit gegeben hat.

Da bin ich mal gespannt, ob ich das einigermaßen spannend ‘rüberbringe.

Jochen

Neuer Downloadbereich

Da mein Hoster (1&1) den bestehenden Vertrag ohne Mehrkosten erheblich erweitert hat, stehen mir jetzt 1 GB Web Space zur Verfügung. Daher kann ich auch wieder die alten DVB.NET und VCR.NET Versionen zum direkten Download anbieten. In diesem Zuge habe ich mich entschlossen, http://downloads.psimarron.net als eigenen Downloadbereich anzulegen, den ich in den nächsten Woche mit Inhalt füllen werde – so viel ist es nicht, aber durch den Kleinkram gibt es schon einen gewissen Wildwuchs.

Die neue Site wird keine Homepage bekommen, sondern direkt auf Verzeichnisebene abrufbar sein. Vielleicht (vermutlich aber eher nicht) werde ich mal ein paar (HTML) ReadMe’s ergänzen.

Viel Spaß

Jochen

COM Wars – wenn .NET zu schlau ist…

Im Rahmen von DVB.NET 3.1 möchte ich in einen DirectShow (COM basiert) Filtergraphen eine .NET Klasse einbinden. Die Klasse klemmt sich in den Datenstrom zwischen einen TS Capture Filter und einen Demultiplexer – nicht wirklich ein Problem. Auf der Eingangsseite (Input Pin) der .NET Klasse werden über eine COM Schnittstelle IMemInputPin so genannte Media Samples (IMediaSample) entgegengenommen. Die Klasse macht damit was und gibt sie dann unverändert an die gleichartige Schnittstelle des Demultiplexers an der Ausgangsseite (Output Pin) weiter. Es kommt ein Fehler 0x80040155 (REGDB_E_IIDNOTREG)!

Dieser Fehler ist ein COM Marshalling Fehler. Er bedeutet, dass COM versucht hat, eine Schnittstelle aus einem Apartment in ein anderes zu transferieren, dabei aber keinen Eintrag in der Registery (HKCR\Interface) für die Schnittstelle gefunden hat und die betroffenen COM Klasse auch kein Custom Marshalling anbietet (IMarshal).

Nun gut, was könnte also hier passieren? Der Filtergraph wird im Hauptprogramm, einer Windows Form, angelegt, damit auch alle Filter (COM Komponenten). Der Natur der Sache nach wird dazu ein Single-Threaded-Apartment (STA) verwendet. Durch die Gegebenheiten in einem DirectShow Graphen muss ich allerdings die Weitergabe der Media Samples auf einem eigene Thread machen (sonst blockiert der Graph). Das kann natürlich nie dasselbe Apartment sein, wie das Heimatapartment der Komponenten.

Nun, wie macht Microsoft das? Ein Blick in das DirectShow SDK zeigt, dass in Graphen COM Regeln wohl etwas lockerer gesehen werden. Das Infinite Tee Beispiel von Microsoft nimmt COM Schnittstellen wie sie kommen und nutzt sie ohne eine Marshalling gnadenlos auf einem anderen Thread. Nun gut, machen wir das mit .NET. Geht aber nicht (so einfach)!

Der erste Versuch, die .NET Schnittstelle einfach im anderen Thread zu verwenden, hatten wir oben schon. Auch der Trick, im STA ein Marshal.QueryInterface zu machen, fruchtet nicht. Man erhält hier tatsächlich eine IntPtr auf die COM Schnittstelle zum direkten Zugriff. Packt man diese in dem Worker Thread aber via Marshal.GetObjectFor IUnknown aus, ist .NET wieder so clever, ein Marshalling anzustossen. Böse Falle.

Ok, es geht doch, aber was jetzt kommt ist zumindest verboten 🙂 Also mit Vorsicht geniessen! Das ganz fängt mit folgendem Code Fragment an (da gab es einige Zwischenschritte bis zu genau dieser Lösung, die es tut – Details erspare ich hier mal):


private delegate void MediaSampleSink(IntPtr classPointer, IntPtr[] sampleArray, Int32 sampleCount, out Int32 processed);

private MediaSampleSink m_MemSink = null;
private IntPtr m_MemPin = IntPtr.Zero;

m_MemPin = Marshal.GetComInterfaceForObject(m_Connected, typeof(Interfaces.IMemInputPin));

IntPtr comFunctionTable = Marshal.ReadIntPtr(m_MemPin);
IntPtr receiveMultiple = Marshal.ReadIntPtr(comFunctionTable, 28);

m_MemSink = (MediaSampleSink)Marshal.GetDelegateForFunctionPointer(receiveMultiple, typeof(MediaSampleSink));

Aus der Eingangsadresse des anderen Filters (m_Connected ist der IMemInputPin) wird die COM Schnittstelle ermittelt. Dann relativ trivial die Adresse der Funktionentablle und schließlich die Adresse der 7ten Methode (IMemInputPin:ReceiveMultiple). Der erstellte Delegate berücksichtig dabei, dass bei einem COM Aufruf der zusätzliche, normalerweise unsichtbare, erste Parameter die Adresse des COM Objektes ist.

Nun funktioniert folgender Aufruf wie gewünscht:

IntPtr[] toProcess = ...;
Int32 processed;
m_MemSink(m_MemPin, toProcess, toProcess.Length, out processed);

Wie gesagt: eigentlich werden hier COM Regeln auf das übelste verletzt. Es fragt sich allerdings, ob in einem DirectShow Graphen nicht wirklich andere Regeln gelten, bei denen COM Schnittstellen nur zur Zerlegung in Komponenten verwendet werden, Apartments aber keine Rolle spielen. Müßte ich mal recherchieren – ich hoffe im Moment einfach mal, dass es so ist (zudem alle Microsoft DirectShow Beispiele es auch so handhaben).

Immerhin, ein kleiner Schritt in Richtung DVB.NET 3.1!

Viel Spaß

Jochen