Video Treiber für Odroid-N2+ (softhdodroid)

  • Ich habe nun auch Multi PCM Audio repariert. Hierfür wird zwingend das Audio Device "plughw:CARD=AMLAUGESOUND,DEV=3" gebraucht.

    Zumindest bei mir hier in chroot. Ich denke DEV=3 ist hier das wichtige.


    Unter Corelelec direkt ist es wohl surround71:CARD=AMLAUGESOUND,DEV=0

  • Habe gerade bemerkt das das Channelmapping bei Multi PCM noch nicht stimmt. Das werde ich noch korrigieren.

    Ausserdem sollte das Digital Device nicht geändert werden. Also

    -a plughw:CARD=AMLAUGESOUND,DEV=3

    -p plughw:CARD=AMLAUGESOUND,DEV=2

    ist richtig.

  • Klaus Schmidinger's git trees - vdr.git/blob - osd.h


    Um dieses Verhalten bei pixmap layer 0 richtig zu implementieren.

    Das sieht man bei skinlcarsng wenn Beschreibungen eingefadet werden.


    Oder hier: http://git.tvdr.de/?p=vdr.git;…06054bad2a2;hb=HEAD#l1202

  • Leider habe ich nicht so ganz verstanden wo die gebraucht wird.

    OK, ich versuche das nochmal zu erläutern.


    Eine Pixmap mit dem Layer 0 ist beim VDR ein Sonderfall.

    Normalerweise werden Pixmaps gemäß ihrem Layer übereinander gerendert. Je Höher der Layer einer Pixmap, umso weiter oben liegt sie. Wenn jetzt eine Pixmap, die weiter oben liegt, eine Transparenz hat (pixmap->SetAlpha()), dann sieht man die darunter liegende Pixmap entsprechend der Transparenz.

    Eine Pixmap mit dem Layer 0 hat keine Transparenz, auch wenn eine gesetzt wird. D.h. alles was unterhalb einer Pixmap mit Layer 0 liegt, ist nicht mehr zu sehen. Und das soll mit dem Patch korrigiert werden, weil sich bisher die Layer 0 Pixmap genau so verhält, wie die anderen Pixmaps.


    Was liegt unterhalb einer Pixmap mit Layer 0: das OSD selbst.

    Man kann ja vieles, was man mit einer Pixmap machen kann, auch direkt mit dem OSD machen.

    z.B.: pixmap->DrawText() vs. osd->DrawText()

    Gutes Beispiel dafür ist der Skin LCARS, den der VDR selbst mitliefert.

    Ich z.B. habe das im Skin lcarsng bisher übernommen und lasse dann trotzdem für die Anzeige der Beschreibung einer Sendung oder Aufnahme, ein Fenster als Pixmap darüber zeichnen. Das funktioniert nur richtig mit einer Layer 0 Pixmap, weil ich dadurch den Hintergrund weg bekomme und trotzdem das Fullscreen-Video transparent durchscheinen lassen kann. Mit anderen Pixmap Layern funktioniert das nicht, weil dann immer noch der Hintergrund durchscheint.


    Ich habe hier leider kein Gerät zum Testen, das mit Deinem Ausgabedevice zusammenarbeitet.

    Du kannst das aber auch leicht selbst testen, mit dem skinlcarsng.

    Das dort von rell , angehängte Bild zeigt den Fehlerfall (ohne Patch), zu sehen an dem durchgehenden Kursorbalken und den Ecken, an den Rundungen.

    Mit Patch sollte der Kursorbalken im Beschreibungsfenster nicht zu sehen sein und die Ecken auch die Hintergrunfarbe besitzen.

    Das Beschreibungsfenster kannst Du im Setup vom Skin einschalten.


    Grüße

    kamel5

    VDR 2.6.4: ASUS Prime X470-PRO, Ryzen 7 5700X, 64GB, 6TB HD, GT1030, Fedora 38 Kernel 6.6 X86_64, Devicebonding 2 x 1 auf 2, TT6400, DVBSky S952 V3

    Git-Repo: gitlab.com/kamel5

  • Ich habe mir nochmal das Umschalten näher angesehen, weil sporadisch die aktivierte Option BlackPicture ignoriert wird. Beim Kanalwechsel sieht die Reihenfolge der abgearbeiteten Kommandos so aus:


    1. SetPlayMode wird mit 0 (pmNone) aufgerufen
    2. Dort wird das Video schwarz geschaltet (disable_video 1)
    3. Vom vdr wird die Funktion Clear() aufgerufen. Im Plugin wird VideoResetPacket aufgerufen und ClearBuffers = 1 gesetzt
    4. In VideoDecodeInput wird wegen ClearBuffers die Funktion CodecVideoFlushBuffers aufgerufen
    5. CodecVideoFlushBuffers ruft amlReset() auf
    6. amlReset ruft InternalClose auf. Durch das Schließen des devices werden die Buffer in der Hardware gelöscht.
    7. Anschließend ruft amlReset InternalOpen auf. Das device wird wieder geöffnet und dabei das Schwarzbild schon jetzt wieder deaktiviert (disable_video 0).
    8. in VideoDecodeInput wird stream->ClearBuffers auf 0 gesetzt
    9. Jetzt setzt vdr SetPlayMode(1), dabei wird das Schwarzbild erneut deaktiviert (disable_video 0) - was es eigentlich aber schon durch das bereits erfolgte Wiederöffnen des devices ist
    10. in VideoDecodeInput wird wegen AV_CODEC_ID_NONE jetzt jedoch CodecVideoClose aufgerufen
    11. in CodecVideoClose wird InternalClose aufgerufen, wodurch das device wieder geschlossen wird
    12. In VideoDecodeInput wird wegen AV_CODEC_ID_H264 CodecVideoOpen aufgerufen
    13. CodecVideoOpen ruft InternalOpen, wodurch das device wieder geöffnet wird
    14. InternalOpen setzt ein drittes mal disable_video 0

    Die einzelnen Schritte sind nicht alle gegeneinander abgesichert und die Reihenfolge ihrer Ausführung mag schwanken, da hier die Logik von vdr über das frühe Setzen des PlayModes 1 mit reinspielt. Es ist auch möglich, das zu rasch hintereinander erfolgende disable_video-Befehle, die sich gegenseitig aufheben, von der Hardware gar nicht erst verarbeitet werden. Eine weitere Erkenntnis ist, dass unnötigerweise doppelt ein Schließen und Öffnen des devices erfolgt. Man könnte nun in CodecFlushBuffers den Aufruf von amlReset rausnehmen (ja, ich erinnere mich, dass ich selbst der derjenige war, der ihn hier im März reingepatcht hatte...). Eigentlich wäre das aber schon die richtige Stelle, um getriggert durch Clear bzw. ClearBuffers so früh wie möglich den Decoder zu leeren. Ich habe deswegen versucht, in VideoDecodeInput anzusetzen und dort das Schließen zu unterdrücken. Aber selbst wenn ich bei AV_CODEC_ID_NONE das device dort nicht schließen lasse, wird es im darauf folgenden CodecVideoOpen doch gleich wieder geschlossen:

    Code
    if (isOpen && !pip) {
    InternalClose(pip);
    }

    Man müsste da viel tiefer eingreifen. Einstweilen habe ich folgende Vorschläge, die ich hier nicht als Patch reinstelle, sondern Schritt für Schritt erläutere:


    In SetPlayMode rausnehmen:

    Code
    -            if (ConfigVideoBlackPicture) {
    -                amlSetInt("/sys/class/video/disable_video", 0);
    -            }

    In InternalOpen das enablen des Videos bzw. Aufheben des schwarzen Bildes ebenfalls rausnehmen:

    Code
    -    if (!pip)
    -         amlSetInt("/sys/class/video/disable_video",0);

    Dafür in CodecVideoOpen ergänzen:

    Code
    InternalOpen (decoder->HwDecoder,videoFormat, FrameRate);
    +    amlSetInt("/sys/class/video/disable_video",0);

    Reduktion des Codes, der bei jedem Kanalwechsel ausgeführt wird. Dazu aus InternalOpen diesen Block rausnehmen

    und in VideoInit() hinter

    Code
    VideoSetFastSwitch(ConfigVideoFastSwitch);

    velegen. Das sind alles Einstellungen, die nur 1x beim Öffnen des Plugins und beim Attachen ausgeführt werden müssen. Während des Betriebs ändern sich die Einstellungen nicht, es reicht daher, sie einmal zu initialisieren.

    In gleicher Weise sollte auch

    Code
    -    // set the system blackout_policy to leave the last frame showing
    -    amlSetInt("/sys/class/video/blackout_policy", 0);

    von amlReset in VideoInit verlegt werden.


    In CodecVideoFlushBuffers sollte der Aufruf von amlReset() erstmal auskommentiert werden, solange ein tiefgreifenderer Umbau im Plugin nicht stattgefunden hat. Bei einer laufenden Wiedergabe erfolgt dann beim Jumpen (Springen mit den gelben/grünen Tasten) das Clearen des Decoders mittels amlReset ausgelöst in ProcessBuffer.


    Mit all diesen Änderungen habe ich auf der Tanix TX3 (S905X3) ein spürbar schnelleres Umschalten.


    Mir fiel ferner auf, dass beim Beenden des Plugins manchmal das letzte Bild sichtbar bleibt. Dazu habe ich bei mir noch ergänzt:

    Code
    static void StopVideo(void)
    {
    VideoOsdExit();
    +    amlSetInt("/sys/class/video/disable_video", 1);
    //restore decoder default settings
    +    amlSetInt("/sys/class/video/disable_video", 0);

    VDR1: ACT-620, Asus P8B75-M LX, Intel Core i3-3240, 4 GB DDR3 RAM 1600 MHz, passive Geforce GT1030 von MSI, Sandisk 2TB SSD, 2xWinTV DualHD, Atric-IR-Einschalter. SW: Xubuntu 20.04 auf 64GB Sandisk SSD.

    VDR2: Odroid N2+ mit CoreELEC und Ubuntu in chroot, WinTV DualHD

    VDR3: Tanix TX3 mit CoreELEC und Ubuntu in chroot, WinTV DualHD

    Edited 2 times, last by Dr. Seltsam ().

  • Dr. Seltsam Ich habe deine Vorschläge nun mal testweise eingebaut und habe dann aber massive Probleme mit dem Playback von Aufnahmen.

    Bei Sprüngen zwischen Schnittmarken wird das Video nicht mehr (meistens) aktualisiert und nach ein paar Sprüngen geht gar nichts mehr und der VDR hängt sich auf. Ausserdem dauert bei mir das Umschalten nun eher länger als vorher. Ich habe Fastswitch aktiv.


    Ich glaube das es bei dir anders aussieht nur kann ich die Änderungen so leider nicht übernehmen.

  • Fastswitch habe ich auch aktiv. Längere Umschaltzeiten kann ich nicht nachvollziehen. Den großen Geschwindkeitsvorteil merke ich allerdings auch eher bei DVB-C-Sendern. Bei iptv-Sendern (MagentaTV) fällt es weniger deutlich auf, ist aber keinesfalls langsamer.

    Das gelegentliche Nichtaktualisieren der Bildansicht bei Schnittmarken kann ich jetzt nachvollziehen. Was ist, wenn Du in CodeFlushBuffers den amlReset nicht auskommentierst?

    Mit Auskommentierung ist der Ablauf wie folgt:

    1. Clear() ruft VideoResetPacket auf und setzt ClearBuffers = 1
    2. in VideoDecodeInput wird wegen stream->ClearBuffers CodecVideoFlushBuffers aufgerufen
    3. CodecVideoFlushBuffers macht nichts!
    4. in VideoDecodeInput wird stream->ClearBuffers auf 0 gesetzt
    5. SendCodecData ruft vor CheckinPts amlReset auf
    6. amlReset wird ausgeführt, da Status isOpen
    7. amlReset ruft InternalClose mit Parameter 0 auf
    8. InternalClose wird mit pip=0 aufgerufen
    9. amlReset ruft InternalOpen auf

    Der amlReset() wird hier also in SetCodecData durch eine ermittelte pts-Differenz ausgelöst

    Code
            if(lpts  && ((pts & 0xffffffff) + 0x10000 < lpts)) {
                //printf("PTS wrap\n");
                amlReset();
            }

    Möglicherweise klappt das bei eng beieinanderliegenden Schnittmarken nicht zuverlässig. Ich habe ja auch klar gesagt, dass das Leeren der Buffer durch Clear ausgelöst werden sollte, deshalb ist es eine Krücke, das doppelte Leeren dadurch zu unterbinden, dass es an der eigentlich richtigen Stelle nicht ausgeführt wird. Schau doch erstmal, ob die Probleme behoben sind, wenn Du in CodecFlushBuffers den amlReset wieder ausführen lässt. Schick mir sonst auch gerne mal Deine geänderte Source zum Gegenkontrolle.

    VDR1: ACT-620, Asus P8B75-M LX, Intel Core i3-3240, 4 GB DDR3 RAM 1600 MHz, passive Geforce GT1030 von MSI, Sandisk 2TB SSD, 2xWinTV DualHD, Atric-IR-Einschalter. SW: Xubuntu 20.04 auf 64GB Sandisk SSD.

    VDR2: Odroid N2+ mit CoreELEC und Ubuntu in chroot, WinTV DualHD

    VDR3: Tanix TX3 mit CoreELEC und Ubuntu in chroot, WinTV DualHD

  • Was ist, wenn Du in CodeFlushBuffers den amlReset nicht auskommentierst?

    Wenn ich den amlReset da drin lasse dann geht es. Der Ansatz den amlreset über einen PTS Wrap zu erreichen ist falsch. Und das versuche ich ja auch zu verhindern indem ich lpts=0 setze bei einem Streamwechsel. Wobei Sprünge zu Schnittmarken auch Streamwechsel sind.


    Jetzt wo es funktioniert scheint das Umschalten tatsächlich etwas schneller zu sein. Ich hänge mal ein diff hier an damit evtl. andere das auch mal testen können bevor ich es dann veröffentliche.

  • den Abschnitt solltest Du noch ändern:

    Code
    @@ -2008,6 +2008,9 @@ static void StopVideo(void)
         //restore decoder default settings
         amlSetInt("/sys/class/video/blackout_policy", 1);   //do this here to avoid freezing the last frame
         amlSetInt("/sys/class/tsync/slowsync_enable", 1);
    +    amlSetInt("/sys/class/video/disable_video", 1);
    +    //restore decoder default settings
    +    amlSetInt("/sys/class/video/disable_video", 1);

    die letzte Zeile muss den Parameter 0 enthalten. Wenn eine andere Applikation (kodi oder irgendeine X Anwendung - siehe beta-Script- beim Öffnen nicht explizit das Bild enabled, bleibt es schwarz. Ich habe das nachvollzogen - der Parameter bleibt so auch beim Beenden von vdr/softhdodroid auf 1

    VDR1: ACT-620, Asus P8B75-M LX, Intel Core i3-3240, 4 GB DDR3 RAM 1600 MHz, passive Geforce GT1030 von MSI, Sandisk 2TB SSD, 2xWinTV DualHD, Atric-IR-Einschalter. SW: Xubuntu 20.04 auf 64GB Sandisk SSD.

    VDR2: Odroid N2+ mit CoreELEC und Ubuntu in chroot, WinTV DualHD

    VDR3: Tanix TX3 mit CoreELEC und Ubuntu in chroot, WinTV DualHD

  • Sehr schön.


    Ich habe bei mir in void InternalClose noch anstelle des auskommentierten Aufrufs vor dem close

    Code
    //amlClearVideo();

    es so eingetragen, wie es c2play in der gleichnamigen Funktion an der Stelle macht:


    Code
        r = ioctl(cntl_handle, AMSTREAM_IOC_CLEAR_VIDEO, 0);
        if (r < 0)
        {
            printf("AMSTREAM_IOC_CLEAR_VIDEO failed.");
        }

    Ob das noch einen Unterschied macht, will ich nicht beschwören, aber schaden tut es zumindest auch nicht.

    Meine Tanix TX3 (mit angeschlossenem DVB-C-Stick) schaltet inzwischen schneller um als mein großer Nvidia-VDR :]

    Es wäre m.E. übrigens inzwischen angebracht, den FastSwitch-Modus als Standardeinstellung zusetzen:

    Code
    int ConfigVideoFastSwitch = 1;   ///< config enable fast channel switch

    VDR1: ACT-620, Asus P8B75-M LX, Intel Core i3-3240, 4 GB DDR3 RAM 1600 MHz, passive Geforce GT1030 von MSI, Sandisk 2TB SSD, 2xWinTV DualHD, Atric-IR-Einschalter. SW: Xubuntu 20.04 auf 64GB Sandisk SSD.

    VDR2: Odroid N2+ mit CoreELEC und Ubuntu in chroot, WinTV DualHD

    VDR3: Tanix TX3 mit CoreELEC und Ubuntu in chroot, WinTV DualHD

  • Ich habe bei mir in void InternalClose noch anstelle des auskommentierten Aufrufs vor dem close

    Code
    //amlClearVideo();

    es so eingetragen, wie es c2play in der gleichnamigen Funktion an der Stelle macht:


    Code
        r = ioctl(cntl_handle, AMSTREAM_IOC_CLEAR_VIDEO, 0);
        if (r < 0)
        {
            printf("AMSTREAM_IOC_CLEAR_VIDEO failed.");
        }

    Ob das noch einen Unterschied macht, will ich nicht beschwören, aber schaden tut es zumindest auch nicht.

    Das ziehe ich zurück. Nach dem Wechsel von Rückwärtsspulen zu Play läuft das Bild damit unrund. Wahrscheinlich war das der Grund, warum Du es ausprobiert, aber auskommentiert hattest.

    VDR1: ACT-620, Asus P8B75-M LX, Intel Core i3-3240, 4 GB DDR3 RAM 1600 MHz, passive Geforce GT1030 von MSI, Sandisk 2TB SSD, 2xWinTV DualHD, Atric-IR-Einschalter. SW: Xubuntu 20.04 auf 64GB Sandisk SSD.

    VDR2: Odroid N2+ mit CoreELEC und Ubuntu in chroot, WinTV DualHD

    VDR3: Tanix TX3 mit CoreELEC und Ubuntu in chroot, WinTV DualHD

  • ich verwende das Plugin aktuell unter in einer Ubuntu (https://wiki.odroid.com/odroid-n2/os_images/ubuntu/20220622) chroot Umgebung unter CoreELEC - da läuft alles prima.

    Jetzt versuche ich einen weiteren VDR ohne CoreELEC direkt unter oben genannten Ubuntu auszusetzen. Ich bekomme auch kurz Bild und Ton jedoch bleibt der VDR relativ schnell komplett hängen sodass ich nur noch mit einem reboot weiter komme.

    Bevor ich den Fehler näher beschreibe und das log poste erst mal die Frage, hat das jemand so laufen bzw. geht das grundsätzlich oder sollte ich statt der 22.04 die von jojo im git genannte Ubuntu 20.04 verwenden?

    Danke, Grüße Jörg

  • horchi welcher Kernel ist denn bei Ubuntu 22.04. Vermutlich ist da ein libmali Problem.

    Das ganze läuft nur mit dem 4.9er Kernel mit den Odroid erweiterungen. Der ist auch bei CoreELEC dabei.


    Ein Standard Ubuntu Kernel geht da eher nicht.


    Edit:

    Nimm einfach das 20.04 Image. Ich habe nie auf dem 22.04 getestet.

  • 4.9er ist es

    Code
    ~> uname -a
    Linux odroid 4.9.337-33 #1 SMP PREEMPT Thu Jul 20 18:05:01 UTC 2023 aarch64 aarch64 aarch64 GNU/Linux

    okay dann versuche ich es nochmal mit dem 20.04

  • muss es das minimal sein oder geht auch die Version mit Desktop wenn ich zum VDR Betrieb den Desktop und X beende?

    falls es hilft es einzugrenzen, mit der 22.04 bekomme ich das seküdlich im Log:

Participate now!

Don’t have an account yet? Register yourself now and be a part of our community!