Jump to content

Plugin-API DVBViewer (Media Server)


t5b6_de

Recommended Posts

Hallo zusammen, 

 

ich möchte für den DVBViewer und den Media Server plugins schreiben die  (im ersten Schritt Daten im TS-Datenstrom abgreifen, später dann auch manipulieren)
 

Gibt es irgendwo ein Projektbeispiel für Visual Studio in c++ oder c?

Ich konnte leider keines finden, oder war nicht in der Lage einen passenden Suchbegriff zu formulieren.

 

Grüße

Thomas

Link to comment

Danke, ich schaue mir das die Tage mal an.
Sollte das so funktionieren wie ich hoffe, stelle ich gerne ein SDK mit den Einsprungspunkten und ggf. Beispielen hier zur Verfügung.

Link to comment

Das ist allerdings für das COM Interface. Zum Abgreifen von TS Paketen braucht es die, nennen wir die Api mal Low-Level Api. Ich glaube die Beispiele sollten im Mitgliederbereich zu finden sein. Ist schon etliche Jahre her. Ich suche morgen am PC mal passende Schnipsel.

Link to comment

Danke dir!

 

Dass das die COM-Api ist, habe ich auch gerade bemerkt, dafür habe ich bereits vor einiger Zeit ein Projekt in C# geschrieben.

Bin jetzt erst dazu gekommen.


Ich möchte aber tatsächlich eben an den Stream dran. 

 

Und ja, eine chm gab es, allerdings war die glaube ich nicht ganz vollständig, und die Einsprungpunkte wurden nur in Delphi angegeben.

 

Grüße

 

Nachtrag: tatsächlich benötige ich mehr Infos.
Leider weiß ich nicht wie die Typen aufgebaut sind, was da drin steckt, in TTuner usw.

 

Nachtrag2: Habe gesehen, dass die Infos in dem Delphi-Beispiel stehen. Ich versuche die nächste Zeit wenn ich zu komme mal mein Glück.

Edited by t5b6_de
nachtrag 2
Link to comment

Ich habe nun ein Plugin angelegt in Visual Studio 2019, allerdings wird es nicht vom DVBViewer geladen, geschweige denn angefasst.
Gibt es bestimmte Compiler/Linker-Flags, damit der DVBViewer die Dateien überhaupt anfässt?

Quellcode im Anhang. 
 

 

Nachtrag:

declspec(dllexport) vergessen - das ist punkt1

aber wenn ich dann rein schaue in die dll werden alle Funktionen mit einem underscore exportiert.

 

_copyright
_PluginName

 

usw.

 

dann findet der DVBViewer die einnsprungpunkte nicht.

 

Edited by t5b6_de
Link to comment

Anbei die dll,

 

wird nicht gehen, weil ich den Compiler/Linker nicht dazu überredet bekomme den underscore wegzulassen.

 

Nachtrag:

Das sog. name mangling and decoration muss abgeschaltet werden.

 

so wird aus _Execute@8 -> _Execute

wie das geht habe ich aber noch nicht herausgefunden.

 

def-datei mit Exports drin, zack stimmt es übrein.

 

Im Anhang ist eine lib, die der DVBViewer jetzt endlich lädt und auch blockiert, wenn der offen ist, aber immer  noch nicht funktioniert.

Unter Hilfe -> Info.. taucht das ding nicht auf.

 

Blockiert aber den DVBViewer, es lässt sich nichts abspielen. Ich teste mal weiter.

 

 

 

 

dvbvplugintest.zip

Edited by t5b6_de
Link to comment

Das Teil ist offensichtlich im Debug-Mode kompiliert (daher VCRUNTIME140D.dll nötig statt VCRUNTIME140.dll). Von daher wäre auch die Debug-Version der VC-Runtime erforderlich, auf dem Rechner mit VS2019 ist die natürlich mit installiert und zum freien Download gibt es die nicht.

Link to comment

Ich finde keine DLL. Mit .h und .cpp Dateien kann ich noch so ungefähr etwas anfangen (d.h. sie lesen), aber der Rest sagt mir überhaupt nichts.

 

Die Sprachbarriere macht sich hier ziemlich bemerkbar ;)

 

Link to comment

Drecks Antivierensoftware, blockiert den Zugriff auf die dll beim Zippen (facepalm)


Also soweit bin ich schon, ich habe mir von dem Plugin eine Log schreiben lassen, die Funktionen werdne in der Reihenfolge (und Häufigkeit) ausgeführt:
 

init
libtype
libtype
libtype
pluginname
pluginname
pluginname
pluginname
pluginname
pluginname
apphandle
--> Version 1537

 

Version 1537 hol ich mir über das SendMessage über hwnd, heißt die parameter (zumindest der fensterhandle) werden korrekt übergeben.

 

Dass der DVBViewer die Plugin-geschichten nicht frisst könnte ich mir vorstellen, dass pchar bei Delphi anders aufgebaut ist, als ein char* bei C/C++

 

Die Frage ist hier nun wo der Unterschied liegt.
Ich denke ich komme dem näher wenn ich ein funktionierendes Plugin einmal in einem C++ Programm lade und mir die rückgabe der Funktionen anschaue und es mit meinem Plugin vergleiche.

 

Nachtrag: das sieht soweit alles identisch aus. Habe mir die Plugins reingeholt und die Funktionen libtyp, pluginname usw. geholt.  vom Aufbau der Daten ist das identisch. Keine Ahnung warum der DVBViewer das Plugin nicht frisst.

 

 

dll.zip

Edited by t5b6_de
Link to comment

Alles klar, 

 

so langsam komme ich dem auf die Schliche. Der DVBViewer führt die Calls wie angegeben aus. Warum das Plugin dennoch nicht unter Hilfe usw. sichtbar ist weiß ich nicht.

Execute wird ausgeführt. Boolean-Typen von c++ und delphi passen nicht, return 0 scheint zu klappen.
 

 

Bezüglich der CHM-Datei -> Die habe ich im öffentlichen Bereich unter Plugin SDK gefunden, allerdings scheint die tatsächlich stark veraltet zu sein.

 

 

Nachtrag:

Ich komme nun an den Transportstream ran, die EventMsg Funktion wird jedoch nie aufgerufen.
Meinem Verständnis nach müsste der DVBViewer die aber mindestens mehrfach aufrufen, bei Init,  Channel Tune, etc.
Jedoch passiert das nicht.

 

Ich gehe nun ins Bett, euch eine gute Nacht falls ihr das heute noch lesen solltet.

Wenn alles wie gewünscht funktioniert, dann stelle ich hier ein Plugin-SDK Online und versuche es so gut wie möglich zu dokumentieren
 

Edited by t5b6_de
Link to comment
Am 22.9.2019 um 22:20 schrieb t5b6_de:

Warum das Plugin dennoch nicht unter Hilfe usw. sichtbar ist weiß ich nicht.

 

Weil der DVBViewer bei der Anzeige unter Hilfe -> Info die Dateiversion mit GetFileVersionInfo abfragt und keine bekommt.

 

Am 22.9.2019 um 22:20 schrieb t5b6_de:

Ich komme nun an den Transportstream ran, die EventMsg Funktion wird jedoch nie aufgerufen.

 

Um sowas mit dem Debugger zu überprüfen, brauche ich immer eine DLL.

 

  • Thanks 1
Link to comment

Danke euch!

 

EventMsg wird nun aufgerufen, mein Fehler, hab es in den exports vergessen.

 

Gibt es irgendwo eine aktuelle Liste mit den Events die da durchlaufen?
Bekomme da elendig lange liste
u.a. 11 und 1000 kann ich nicht zuordnen (werde ich aber vielleicht nicht benötigen)
 

Weitere Frage:

Müssen die Methoden Threadsafe sein? Heißt kann es vorkommen, dass bestimmte Methoden parallel aufgerufen werden von mehreren Threads?

 

Gruß

Edited by t5b6_de
weitere frage
Link to comment
  • 2 weeks later...

Wenn ich nun bestimmte Packets oder gar ganze Sections beeinflussen möchte, muss ich mehrere packets teilweise anpassen.

 

der PidCallback wird jedoch nur einzeln, singlethreaded aufgerufen.

 

 

wenn ich eine Section anpasse muss  ich packetübergreifend den kram anpassen. Gibt es ein bestimmtes Zeitfenster währenddessen die Packets weiter durch Plugins angepasst werden können? Wenn der PidCallback durchgelaufen ist, muss ich davon ausgehen, dass die Packets weiter durch den DVBViewer(Media Server) verarbeitet werden?


Das Plugin soll später im Recording-Service genutzt werden.

 

Nachtrag: Selbst RawTsCall liefert mir den Stream päckchenweise, aber da bekomme ich dann tatsächlich jedes einzelne päckchen.

Ich muss mir wohl was einfallen lasssen.

 

Edited by t5b6_de
Link to comment

Anbei das versprochene Plugin-SDK in Visual Studio 2019 Community.

 

Anders als ursprünglich versprochen ist das ein C# Plugin mit Unmanaged Exports.


Läuft soweit im DVBViewer.

Assembly-Informationen werden in den Projekteigenschaften festgelegt und werden bei Laufzeit an den DVBViewer weitergegeben.

 

der rest sollte Selbsterklärend sein insb. wenn man sich den oben verlinkten Thread anschaut.

 

DvbviewerPluginSDK.zip

Link to comment
  • 1 month later...

Ich habe nooch eine Frage zu dem Event.

Was ist 1001 für ein Event und 1000
Der Mediaserver sendet kein Remove Channel, dafür aber 1001 Ist das ein "neues" Removechannel?

Link to comment

Die Aufrufe in Plugins beim Ein/Umschalten von Sendern im DVBViewer-Hauptfenster in Reihenfolge:

  1. Execute(@Tuner,...): Ermöglicht Plugins, das Ein/Umschalten zu verhindern, nachdem der DVBViewer eigene diesbezügliche Bedingungen überprüft hat).
  2. EventBroadcast(evDisableTuner, nil) mit evDisableTuner = 1001: Kommt nur,  falls ein Plugin die Ein/Umschaltung verhindert .
  3. EventMsg(evEnableTuner, nil) mit evEnableTuner = 1000: Wird nach der erfolgreichen Anforderung von DVB-Hardware für den (neuen) Sender gesendet, wenn zuvor keine DVB-Hardware in Betrieb war,
  4. EventMsg(evRemoveChannel, @Tuner) mit evRemoveChannel = 998: Wird gesendet, falls bereits ein Sender wiedergegeben wird und übergibt einen Zeiger auf dessen Tuner-Datensatz. Kündigt an, dass dieser jetzt abgeräumt wird. Direkt danach werden sämtliche Streams für diesen Sender aus den internen PID-Filtern entfernt und gegebenenfalls die DVB-Hardware freigegeben, sofern sie nicht für den nächsten Sender weiterverwendet wird.
  5.  StopGraph: Wird aufgerufen, bevor der bisher verwendete DirectShow-Filtergraph abgeräumt wird (er kann eventuell auch für den neuen Sender weiterverwendet werden).
  6. EventMsg(evTuneChannel, @Tuner) mit evTuneChannel = 999: Übergibt einen Zeiger auf die Tuner-Struktur des neuen Senders.
  7. SetGraph(Renderer.Graph, false, nil): Übergibt das IFilterGraph2 Interface des (neuen) aktiven DirectShow-Filtergraphen.
  8. EventMsg(evFinishSetChannel, nil) mit evFinishSetChannel = 10: Gibt bekannt, dass die Senderumschaltung abgeschlossen ist, d.h. die Wiedergabe formal gesehen läuft (was nicht zwangsläufig bedeutet, dass der Anwender schon ein Bild sieht).

Speziell beim Beenden der Wiedergabe im Hauptfenster, egal welcher, eventuell sogar wenn noch gar keine läuft, kommt es immer zu

  1. EventBroadcast(evDisableTuner, nil) und EventMsg(evRemoveChannel, nil)

Schlichter geht es beim Ein/Umschalten von Bild-in-Bild-Sendern zu:

  1. EventMsg(evDisableTuner, nil) und EventMsg(evEnableTuner, nil): Werden nach der erfolgreichen Anforderung von DVB-Hardware für einen (neuen) Sender gesendet, aber auch bei Freigabe des Bild-in-Bild-Objekts, in dem Fall gefolgt von einem StopGraph (Zweck unbekannt, Plugins können nicht auf den Bild-in-Bild-Filtergraphen zugreifen).
  2. EventMsg(evTuneChannel, @Tuner) und EventMsg(evFinishSetChannel, nil): Werden nach dem Tunen, aber vor dem Start der Wiedergabe gesendet.

Bei Aufnahmen im DVBViewer, wo es keine Senderumschaltung wie bei der Wiedergabe gibt, sieht es so aus:

  1. EventMsg(evTuneChannel, @Tuner) und EventMsg(evFinishSetChannel, nil) nach dem Start einer Aufnahme.
  2. EventMsg(evDisableTuner, nil), EventMsg(evEnableTuner, nil) und StopGraph nach dem Beenden einer Aufnahme.

Beim DMS sehe ich folgendes:

  1. EventMsg(evTuneChannel, @Tuner), EventMsg(evEnableTuner, @Tuner) sowie EventMsg(evFinishSetChannel, nil): Werden generell nach einem Tunen gesendet, wobei es sich nicht zwangsläufig um ein Hardware-Tunen handelt. Es kann auch eine Umschaltung innerhalb des selben Transponders sein.
  2. EventMsg(evEnableTuner, nil) und EventMsg(evDisableTuner, nil): Werden bei einer Geräte-Freigabe sowie vor dem Tunen eines anderen Senders gesendet.

Generell erscheint mir das ganze ziemlich chaotisch ;) Es entstammt wohl einer kreativen "rapid prototype" Phase, in der ohne konsistentes Konzept fröhlich drauflos programmiert wurde.

 

Für mich sieht es so aus, dass EventMsg(evDisableTuner, nil) und  EventMsg(evEnableTuner, nil) die gleiche Bedeutung haben, nämlich dass der bislang verwendete Tunerdatensatz ungültig wird. Die beiden kommen fast immer direkt hintereinander, wobei die Reihenfolge variiert. Nur bei der Senderumschaltung im DVBViewer-Hauptfenster werden die beiden Events anders behandelt und hängen von bestimmten Bedingungen ab (s.o.), was mir nicht wirklich logisch bzw. stimmig erscheint.

 

EventMsg(evRemoveChannel,...) haut in die gleiche Kerbe. Den Event gibt es nur im DVBViewer und nur mit Bezug auf die Wiedergabe im Hauptfenster. Wenn der Data-Pointer nicht nil ist, verweist er auf den zuletzt verwendeten Tuner-Datensatz.

 

EventMsg(evEnableTuner, @Tuner), also mit einem Data-Pointer ungleich nil, scheint einen neuen Tuner-Datensatz anzuzeigen. Das gibt es nur im DMS und ist offenbar gleichbedeutend mit dem im DVBViewer und DMS verwendeten EventMsg(evTuneChannel, @Tuner).

 

Soweit meine Versuche, das Durcheinander zu entwirren...  :wacko:

 

Link to comment
  • 2 weeks later...
  • 2 weeks later...

Sorry, dass ich da nochmal anfrage, und zwar habe ich ein seltsames verhalten erzwingen können:
Setup
3 Tuner, alle gemeinsamer LNB am DVBViewer Media Server.

Client 1 schaltet 1 Sender ein, client 2 schaltet auch einen sender auf einem anderen Transponder ein im selben Band. 
Client 1 schaltet Bild in Bild ein und wechselt den Kanal auf einen anderen Tansponder, sodass alle 3 transponder in Verwendung sind.

 

Client 2 schaltet nun mehrfach hin und her, zwischen verschiedenen Sendern (auch auf welche die nicht verfügbar sind)
und ab da scheint es anzufangen, manchmal auch schon auf verfügbaren kanälen: 
Bei der Plugin-Instanz die für Client2 verwendet wird, erhalte ich nun im einfachen TS-Callback (der mit addpid und delpid) gesteuert werden kann Pakete von allen aktiven Tunern die die gleiche PID übermitteln.

Wenn ich z.B. mit die PMT abrufe erhalte ich (weil diese auf vielen Transpondern im selben Nummernkreis liegen) die Tables von 2 verschiedenen Programmen und kann damit nicht mehr weiterarbeiten.

 

Plugins sind abgelegt in plugins1, plugins2 und plugins3


Hat eine weile gedauert bis ich das nachstellen konnte.

Heißt ich bekomme nicht mehr brauchbaren Datenmüll.

 

Nachtrag: Zuverlässigste Konstelleation sind im Hauptbild an Client 1 RTL HD und PIP Pro7 Maxx HD

Auf Client 2 kommt dann z.B. bei der "PidCallback" funktion im Plugin nur noch die PMT von Sat1 HD auf dem Transponder vom PIP-Bild.
obwohl ich im Plugin nachweislich ein EventMsg für den Sender z.B. Disney Channel HD hatte. die PMT Pid ist die gleiche (96) die Service-ID ist eine andere.

Verwendet wird der DMS 2.1.5.1

 

Nachtrag:
die Daten vom falschen Stream kommen erst im Callback an, den man durch AddTsCallback startet, und im normalen PidCallback.
Im RawTsCallback sind diese noch nicht, da kommt alles richtig.

 

Grüße

Thomas

Edited by t5b6_de
ergänzung.
Link to comment

Das Thema ist schwierig zu behandeln, da bei den Bezeichnern ein heilloses Chaos herrscht. Insbesondere sind die von Lars hier angegebenen MSG_XXX Konstanten andere als die im DVBViewer/DMS Code bzw. haben eine andere Bedeutung.  Um das zu entwirren, musste ich erst langwierig  recherchieren, und um in der Hinsicht kommunizieren zu können, müssen wir uns erst mal auf eine gemeinsame Basis einigen.

 

Ich nehme an, dass du die von Lars geposteten MSG_XXX Bezeichner verwendest. Im DVBViewer/DMS Code sieht es so aus:

///(1) whole TS received from hardware as buffer content, individual per plugin callback
  MSG_ADDTSCALL = $2214; //Lars: MSG_ADDRAWTSCALL
  MSG_DELTSCALL = $2215; //Lars: MSG_DELRAWTSCALL

//(2) whole TS received from hardware as single packets, individual per plugin callback 
  MSG_ADDCALL = $2210; //Lars: MSG_ADDTSCALL
  MSG_DELCALL = $2211; //Lars: MSG_DELTSCALL
  
//(3) single PID, individual per plugin callback
  MSG_STARTPIDCALLBACK = $45104; //Lars: same
  MSG_STOPPIDCALLBACK = $45105; //Lars: same  

//(4) single PID, common PidCallback for all plugins, DVBViewer only
 MSG_STARTFILTER = $2120; //not mentioned by Lars
 MSG_STOPFILTER = $2130; //not mentioned by Lars

Offensichtlich hat Lars die Bezeichner zwischen 2008 und 2013, als ich den Code geerbt habe, geändert, warum auch immer... ;) Ich würde empfehlen, die aktuell im DVBViewer/DMS verwendeten zu übernehmen, damit man nicht jedesmal umdenken muss.

 

On 11/28/2019 at 11:35 AM, t5b6_de said:

die Daten vom falschen Stream kommen erst im Callback an, den man durch AddTsCallback startet, und im normalen PidCallback.
Im RawTsCallback sind diese noch nicht, da kommt alles richtig.

 

Ich nehme an, dass du dich auf die Bezeichner aus Lars' Forum-Post beziehst. Solange ein Plugin den TS von nur einer Hardware-Instanz bezieht, ist es  faktisch unmöglich, dass es dauerhaft Daten von verschiedenen Transpondern erhält - sei denn, die Hardware (also ein virtuelles RTSP Network Device) liefert das bereits so an.

 

Aber auch wenn man annimmt, das bereits der DMS die ungesunde Mischung erzeugt, ist das, was du beschreibst, unmöglich weil die Callbacks aus der selben Datenquelle gespeist und nacheinander in der oben angegebenen Reihenfolge bedient werden, d.h. nur Pakete, die bei (1) ankommen, stehen (2) und (3) zur Verfügung.

 

Zu erklären wäre es nur dadurch, dass die Callbacks (2) und (3) Daten aus einer anderen (zusätzlichen) Quelle als (1) erhalten, z.B. weil das Entfernen des vorherigen Callbacks nicht stattgefunden hat.

 

Oder es handelt sich um einen kurzzeitigen Effekt bei der Umschaltung auf einen anderen Transponder. Manche DVB-Geräte liefern noch nach dem Tunen Restdaten des vorherigen Transponders aus ihren Puffern. Das macht insbesondere beim Suchlauf erhebliche Probleme, weil sich das Programm zuerst die PAT anschaut. Und wenn die falsche eintrifft, kann man den Rest vergessen. Es gibt im DVBViewer und in TransEdit umfangreiche Maßnahmen gegen diesen Effekt, z.B. durch Erkennen eines PAT-Wechsels während eines Transponder-Scans, um ihn dann umgehend neu zu starten.

 

Link to comment

Hi, bin kurz angebunden.
Ja es ist nur der Fall wenn 2 oder mehrere Tuner gleichzeitig aktiv sind.

Bei dem gibts Probleme:

//(4) single PID, common PidCallback for all plugins, DVBViewer only
 MSG_STARTFILTER = $2120; //not mentioned by Lars
 MSG_STOPFILTER = $2130; //not mentioned by Lars

 

und bei dem Gibts probleme:
 

//(2) whole TS received from hardware as single packets, individual per plugin callback 
  MSG_ADDCALL = $2210; //Lars: MSG_ADDTSCALL
  MSG_DELCALL = $2211; //Lars: MSG_DELTSCALL

 

den nutze ich derzeit, da läuft alles glatt, den nutze ich nun ausschließlich für mein Plugin
Habe mir einen eigenen high performance Pid-Filter gebaut, sodass ich da keine einbußen oder zusätzliche CPU-Last habe.

///(1) whole TS received from hardware as buffer content, individual per plugin callback
  MSG_ADDTSCALL = $2214; //Lars: MSG_ADDRAWTSCALL
  MSG_DELTSCALL = $2215; //Lars: MSG_DELRAWTSCALL

 

ich entferne grundsätzlich immer alle Pids aus den filtern, etc. sodass ich da eine Wiederverwendung bestimmter Filter ausschließen kann.

Generell scheint mir das ganze tatsächlich großes Kuddelmuddel zu sein, ich würde hier das ganze für zukünftige Versionen auf den Raw-TS-Callback (1) reduzieren.

 

nachtrag: (3) habe ich nicht getestet.

 

Edited by t5b6_de
Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...