[Patch] Fehler bei Timeraufnahmen durch Lock der "Channels" in cRecordControls::Start()

  • Ausgehend von hier betreffend fehlerhafter Timeraufnahmen:


    'cRecordControls::Start()' in 'menu.c' hält einen Read-Lock auf die "Channels". Beim Erzeugen der cRecordControls kann es vorkommen, dass GetEvent() für den Event erst auf die EPG Daten warten muss, was bis zu 4 Sekunden dauern kann - und genau so lange bleibt der Lock auf "Channels".

    Das hat unter anderem zur Folge, das in pat.c die PMT mancher Programme nicht eingelesen wird, und damit - wenn es der erste Zugriff auf den Transponder war - die CaDescriptoren der verschlüsselten Programme nicht bekannt sind. Aufnahmen solcher Programme enden daher mit einem Emergency Exit.


    Der 1.Patch im Anhang löst nun den Lock schon bevor die cRecordControl erzeugt werden, und im 2. Patch wird in pat.c das Timeout für GetChannelsWrite() von 10ms auf 20ms erhöht. Das genügt um bei mir alle PMTs korrekt einzulesen - ist aber vom Gefühl her noch nicht die beste Lösung für 'pat.c'.
    Helmut

  • Es dürfte auch noch etwas Anderes das zuverlässige Einlesen der PMT verhindern:

    Helmut

    HelmutB passed unfortunately away on July 21, 2022 ... RIP 🖤

  • Du hast recht, das 'ChangeState()' sollte bleiben, das habe ich irrtümlich mit rausgelöscht.

    Ich bin mir aber nicht sicher, ob dieser Patch auch tatsächlich das Problem von Fourty2 löst. Er wird eher nur bei einer "Sofortaufnahme" auf einem vorher nocht nie getunten Transponder helfen, aber nicht bei einer normalen Timeraufnahme, da dabei schon bis zu 60 Sek. vor Aufnahmestart - ohne RecordControls - auf den Transponder geschalten wird. Damit sollte der CaDescriptor bei Start der Aufnahme schon bekannt sein.

    LG Helmut

    HelmutB passed unfortunately away on July 21, 2022 ... RIP 🖤

  • Mir scheint, Teil des Problems ist, daß viele Plugins auf die "Bereit" Meldung des VDR warten und sich dann um die Ressourcen "prügeln".


    Hatte gestern noch bemerkt, das ein Teil der GetChannelsWrite an den EPGSearch Threads hingen, die beim Start loslaufen. Ein Delay von 20s für die Suchtimer- und Konfliktcheck-Thread behob das (meist).

    Denke, es bräuchte Plugin-Start-Prioritäten / - Delays oder sowas in der Art.


    VDR mit GIT-epgsearch:


    Mit 20s Delay:



    Problem ist allerdings, daß es mal klappt, mal nicht. Also eher eine Race-Condition, denke ich.


    Man kann die Versuche des "GetChannelsWrite" zwar erhöhen, wenn es bei 5 Versuchen nicht geklappt hat, geht es schief.


    Stefan

  • Nochmal zum gucken den Patch von Helmut an das Klaus'sche diff angepaßt:




    "Gefühlt" wird GetChannelsWrite jetzt häufiger aufgerufen, als ohne diff, aber es scheitert nicht mehr entgültig.


    Grüße und Danke,

    Stefan

  • kls : Dein 'vdr-2-4-5-pat-lock-channels-early-diff' ist schon eine gute Lösung um keine PMT zu verpassen, ich habe keine Nachteile bemerkt. Und wie es aussieht, löst das auch die Probleme von Fourty2.

    Eine Frage zum StateKey.Remove() - sollte hier vielleicht doch ein 'false' mitgegeben werden - als Ersatz für 'ChannelsModified' ?

    LG Helmut

    HelmutB passed unfortunately away on July 21, 2022 ... RIP 🖤

  • Bei genauerer Betrachtung wird beim 'vdr-2.4.5-pat-lock-channels-early.diff' die meiste Zeit ein unnötiger Lock auf 'Channels geholt' weil sich die PMTs nicht geändert haben.

    Hier doch noch eine Variante, die den Lock wie zuvor erst nach der Überprüfung auf neue Daten durch 'PmtVersionChanged()' holt, und im Lock-Fehlerfall die SID auf "noch nicht gesehen" zurücksetzt.


    Und dann ist mir noch ein kleiner Fehler bei shared PMTs aufgefallen, der nach dem ersten Durchlauf nicht mehr alle SIDs einer PMT-Pid prüft.


    Fourty2 - vielleicht kannst du diesen Patch auch noch testen.

    LG Helmut

  • HelmutB :

    Teste ich nach 22:15


    Bisher sieht der ...early-02 sehr gut aus:

    bei zwei laufenden CI-Timern kann ich nun sogar einen Aktiven löschen und damit Livebild-Umschalten (nächster CI-Timer) riskieren, ohne daß der VDR die VDSB-Grätsche macht. Fein.


    Die Aufnahmen hatten auch keine TS-Fehler.


    Stefan

  • HelmutB :

    Restart mit zwei aktiven CI-Timern:


    Fängt sich zwar nach einer halben Ewigkeit, aber ... irgendwas klemmt da mehr als bei Klaus' Fix.

    (Läuft auch beim zweiten Versuch in das Problem)


    Log per PN.


    Stefan

  • HelmutB Noch eine Frage:

    Mir ist der Parameter SetNewVersion in


    bool cPatFilter::PmtVersionChanged(int PmtPid, int Sid, int Version, bool SetNewVersion)


    nicht ganz klar. Es gibt nur *eine* Aufrufstelle dieser Funktion, und an der wird 'true' übergeben. Der (Defaut-)Wert 'false' kommt nie zum Tragen. Ausserdem hat PmtVersionChanged() einiges an Seiteneffekten, die über die bloße Abfrage, ob sich die Version geändert hat, weit hinausgehen. War da mit 'SetNewVersion = false' mal eine reine Abfrage geplant?


    An der Aufrufstelle hängt die Entscheidung, ob 'return' gemacht wird, ja nur davon ab, ob sich die Version geändert hat.

    Könnte man das Ganze eventuell etwas "entwirren" und die Channels erst dann zu locken versuchen, wenn man weiß, dass kein 'return' ausgeführt wird, und die Seiteneffekte erst nach erfolgreichem Locken der Channels ausführen?

  • vdr-2.4.4-pat-fix-shared-pmt.diff ist davon aber unabhängig richtig, oder

    Ja, das ist unabhängig, und eine Fehlerkorrektur, da sonst ab dem zweiten "Umlauf" bei shared PMT-Pids schon nach der ersten SID auf die nächsten PMT-Pid geswitched wird.


    Das "bool SetNewVersion" hat keine Funktion mehr. Es wurde bei VDR-2.4.2 verwendet und ich habe es damals belassen, weil ich nicht sicher war, ob es nicht doch doch irgendwann gebraucht wird. Jetzt kann man es eigentlich entfernen.


    Und entwirren könnte man es vielleicht so (noch mit dem SetNewVersion Parameter);

    Das habe ich jetzt aber nur in einem Texteditor erstellt. Selbst testen kann ich es erst später.

    Helmut

    HelmutB passed unfortunately away on July 21, 2022 ... RIP 🖤

  • Jetzt fällt es mir gerade wieder ein - das "bool SetNewVersion" war so eine Art "query" Parameter, mit dem nur ein PMT Versionswechsel abgefragt, aber nichts geändert wurde, Den könnte man jetzt vielleicht für die Entscheidung ob ein "GetChannelsWrite()" überhaupt notwendig ist verwenden.

    In PmtVersionChanged() so vielleicht:

    Code
    bool cPatFilter::PmtVersionChanged(int PmtPid, int Sid, int Version, bool SetNewVersion)
    {
      int i = 0;
      for (cPmtSidEntry *se = pmtSidList.First(); se; se = pmtSidList.Next(se), i++) {
          if (se->Sid() == Sid && se->Pid() == PmtPid) {
             if (!SetNewVersion)
                return se->Version() != Version; //++++
             if (!se->Received()) {
    ....

    Helmut

    HelmutB passed unfortunately away on July 21, 2022 ... RIP 🖤

Jetzt mitmachen!

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