Menü innerhalb des Plugins schliessen

  • Ich bin gerade dabei einen Bug aus vdr-mpv zu entfernen, und zwar wenn das OSD beim beenden noch geöffnet ist, versucht VDR es weiterhin darzustellen.


    Ich habe gerade schon im VDR Code gesucht, aber leider finde ich nichts um dem VDR mitzuteilen das er einfach das derzeit offene Menü schliessen möchte. Einen Pointer auf das Menü habe ich leider auch nicht. Nur eine Instanz von cOsd die das ganze über die mpv API ausgibt (was natürlich beim Beenden fehlschlägt da mpv dabei beendet wird).


    Hat jemand einen Tip wo ich hier weiter suchen kann?

  • Spontan fällt mir da auch nichts ein.


    Aber kannst du nicht in deinem OsdProvider ein Flag setzen, so dass es weiß, dass mpv beendet werden soll, damit er keine Aufrufe mehr durchreicht, sondern einfach "Erfolg" zurück gibt?


    Lars.

  • Das Problem im OsdProvider ist, das er vorher schon weg ist, die cOsd Instanz aber unabhängig davon weiterläuft. Ich hab auch schon versucht mir die Handles in der cOsdProvider Instanz zu speichern und bei aktivem Osd und gültigem Handle ein delete aufzurufen, dann wird das cOsd auch beendet, leider gibt es teilweise trotzdem noch einen Segfault. Aus mir unerfindlcihen Gründen gibts dann aber auch keinen core Dump, obwohl die Ausgabe kommt das er erstellt wurde und VDR auch als root lief. Eventuell liegt das irgendwo an systemd, generell werden da aber auch coredumps im Journal abgelegt.
    Ohne aktives OSD komme ich immer sauber zum VDR zurück.


    osEnd im ProcessKey bei kStop habe ich drin, allerdings habe ich nur das ProcessKey con cControl und nicht das des Menüs, und da bewirkt er anscheinend nichts.

  • Das Größenlimit ist es auch nicht, ich hab jetzt einfach temporär das coredump Verhalten geändert, so dass sie einfach im lokalen Verzeichnis landen.


    Auch wenn cOsd beendet wird, versucht der VDR weiterhin das Menü zu zeichnen. Was dann in dem Segfault endet, da cOsd dann bereits fehlt.


  • Aktuell fehlt z.B. bei kBack ein Aufruf von Hide()

    vdr-2.6.7

    softhddevice, dbus2vdr, dvd, epgsearch, femon, graphtftng, web, menuorg,
    osdteletext, radio, recsearch, satip, tvguide, vnsiserver

    ubuntu focal, yavdr-ansible, linux-5.15 ,AsRock J4105, CIne CT-V7 DVB-C

  • Das Hide() schliesst leider nur das DisplayReplay, ist aber mittlerweile sowieso in den Dekonstruktor gewandelt und kBack ist jetzt, bis auf aktives DiscNav, mit kStop gleichgesetzt.


    Ich verhindere jetzt als Workaround erstmal den Zugriff auf nicht mehr existierende Objekte, so dass es zumindest keinen Segfault mehr gibt. Dadurch bleibt aber ein unsichtbares Menü vorhanden, was mir noch nicht wirklich gefällt.

  • Anderer Ansatz. Ich kann prüfen ob das OSD offen ist, kann ich auch irgendwo rausbekommen das ein Menü offen ist? Dann könnte ich über cRemote einfach nochmal kMenu senden und gucken ob es dann zu ist.


    Aktuell fällt mir nur ein IsOpen prüfen, wenn true kMenu senden, IsOpen wieder prüfen, wenn immer noch offen nochmal kMenu senden. Ist nicht die schönste Möglichkeit könnte aber funktionieren.

  • Klingt doof. Evtl. sollte Klaus da mal ran, der ist aber erst mal im Urlaub. Außerdem funktioniert das bestimmt nur, wenn man den vdr so konfiguriert hat, dass Menu auch das Menu schließt?


    Lars

  • kBack müsste auch gehen, ich muss nur prüfen ob das eventuell irgendwelche neuen Probleme verursachen kann, da es ja an die weiteren ProcessKeys durchgereicht wird im Gegensatz zu kMenu.


    Wobei, wenn es ohne Nebenwirkungen klappt, es im Code recht einfach sein sollte:


    Code
    while (cOsd::IsOpen())
      cRemote::Put(cKey::FromString("kBack");


    Eventuell noch ein kleines Sleep mit rein damit, wenn das OSD einen Moment zum schliessen braucht, der VDR nicht mit Tastendrücken geflutet wird.

  • Das Ganze erscheint mir hier etwas "verquer" (vielleicht verstehe ich aber auch den ganzen Zusammenhang nicht so ganz).
    Tatsache ist folgendes: wer ein cOsd anlegt, der muß es auch wieder löschen. Nur der, der es anlegt, hat einen Pointer darauf, und daher kann und muß auch nur der es löschen.


    Klaus

  • Hierbei geht es um das VDR Main Menu, es wird beim drücken der Menü Taste angelegt. Das geschieht ausserhalb des Plugins. Das Plugin stellt nur den cOsdProvider zur Verfügung und liefert eine Instanz meiner cOsd Klasse um das Menü darzustellen.
    Wenn der Player im Plugin beendet wird, wechselt der cOsdProvider wieder auf den das Ausgabe_plugins zurück (gelöst über ein cOsdProvider::Shutdown und cDevice::MakePrimary).


    Allerdings ist das Menü dabei im Hintergrund immernoch aktiv und nutzt weiterhin die cOsd Klasse des mpv Plugins.


    Ich möchte das Menü nun schliessen, wenn der Dekonstruktor meiner cControl Klasse aufgerufen wird. Allerdings konnte ich noch keinen Weg finden zu prüfen ob derzeit ein Menü geöffnet ist, und wenn ja dieses zu schliessen.

  • Weil das OSD, während mpv etwas abspielt, nicht über das VDR Ausgabe-Plugin ausgegeben wird, sondern ich in einer eigenen cOsd-Klasse das ganze in die API von mpv schreibe. Das OSD wird dadurch von mpv dargestellt.


    mpv startet mit einem cControl mit pmExternal.

  • Aha, das ist also ein Player, der nicht überall läuft, wo VDR drauf läuft, sondern nur da, wo mpv auch läuft.


    Und wieso genau bleibt jetzt da ein Menü offen, dessen cOsd aus dem VDR cOsdProvider stammt?
    Ich vermute mal, der Ablauf ist so, daß der Benutzer über das VDR-OSD das Hauptmenü des Plugins aufruft, dort etwas auswählt und dadurch dann dein Player gestartet wird. Einen Player startet man mit cControl::Launch(), was dafür sorgt, daß der Player im nächsten Durchlauf der Hauptschleife an das Primary-Device gehängt wird. Wenn du in deinem Menü 'osEnd' zurückgibst, dann müsste das komplette Menü geschlossen werden, bevor dein Player startet. Das Ersetzen des VDR-cOsdProvider durch deinen eigenen solltest du dann triggern, wenn die Activate()-Funktion deines Players aufgerufen wird.


    Soweit die Theorie. Versuch's mal so.


    Klaus

  • Das Problem tritt genauso auf, wenn man das Primary Device wechselt.


    Z.b. vom SoftHdDevice zum Xine und zurück.


    Wenn man glücklich ist, dann gibt es keinen Crash. Wenn es keinen Crash gibt, dann hat man zumindest kein OSD mehr. Bis man das Menu verlässt und wiederaufruft.


    Habe einfach mal softhdevice nach softhddevice2 kopiert.

    Code
    while true; do svdrpsend plug softhddevice prim; sleep 20s; svdrpsend plug softhddevice2 prim; sleep 20s; done


    Johns

    Sag mir, wo die Developer sind. Wo sind sie geblieben? . . . . . . . . . . . . . . . . . . . . SoftHdDevice - A software and GPU emulated HD output device plugin.
    Sag mir, wo die Developer sind. Was ist geschehn?


    Client0: Crown CW02 MSI_C847MS-E33 Zotac_GT640_passiv Cine-S2 iMon-MCE / streamdev softhddevice
    Client1: Lian_Li_PC-Q09FB ASRock_H67M-ITX/HT I3-2100 ASUS_ENGT520_passiv / streamdev softhddevice
    Test: Lian_Li_PC-Q09R Asus C60M1-I / streamdev
    Server0: Dockstar TT-S2-3600-USB / streamdev
    Server2: Lian_Li_PC-Q07R Intel_DH61DL G620 WD20EARX 90W PicoPSU Cine-S2+DuoFlex-S2+DuoFlex-CT / streamdev / 22 Watt Verbrauch

  • Genau, so mache ich es. Das Menü nach der Auswahl und Start des Players wird geschlossen, hier gebe ich auch ein osEnd zurück.


    Das Problem ist der Rückweg. Also wenn der Benutzer den Player wieder stoppt und dabei ein Menü auf hat. In der cControl::ProccessKey gebe ich zwar osEnd zurück, das kommt aber vermutlich nicht im cMenu::ProcessKey an, so dass das Menü geöffnet bleibt. Nur habe ich noch keinen Weg gefunden entweder an die aktuelle cMenu Instanz zu kommen um es zu schliessen oder cMenu zu informieren das es das aktuelle Menü schliessen soll.

  • Komischerweise dauert das schließen des OSD mit kMenu im cControl Dekonstruktor trotzdem ca 6-7 Sekunden. Getestet mit dem Classic Skin von VDR, skindesigner hat die gleiche Zeit.


    Edit: Und wenn ich nachdem Senden von kMenu einfach warten will bis cOsd::IsOpen == false ist, bleibe ich in einer Endlosschleife hängen. kMenu wird anscheinend erst vollständig abgearbeitet nachdem der Dekonstruktor vollständig abgearbeitet ist. Das würde auch die 6-7 Sekunden erklären.


    Edit 2: Auch wenn ich das senden von kMenu in cControl::ProcessKeys verschiebe wird das OSD nicht sofort geschlossen.

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!