Vor- und Nachlauf bei Aufnahmen

  • Ich möchte mal ein konkretes (nachvollziehbares) Beispiel sehen, wo sich ein Problem ergibt.

    Also, folgende Steps:

    1. Ich gehe auf den Sender "RTL Television"
    2. Ich gehe ins EPG und navigiere zu 18:45 RTL Aktuell
    3. Ich drücke die rote Taste (Aufnehmen). VDR legt einen Timer an.

    Am nächsten Tag schaue ich mir die Aufzeichnung an, und wundere mich, dass ein Teil fehlt.

    Ja klar, RTL war mal wieder um 5 Minuten verspätet :( .

    Aber Moment, steht bei mir nicht in den Einstellungen -> Aufnahme -> Nachlauf am Timer-Ende: 15 min?

    Dann müsste doch alles aufgenommen sein, auch wenn sich RTL um 5 Minuten verspätet.

    Client1: ASUS P5QC, Dual Core 3G, Cine S2, Ext. Board von TBE, Xubuntu 20.04, VDR 2.6x

    Client2: RPI3

    Server: RPI4, Sundtek SkyTV Dual 2x

  • Code
    @@ -274,6 +274,7 @@ void cTimer::CalcMargins(int &MarginStar
     {
       MarginStart = Setup.MarginStart * 60;
       MarginStop  = Setup.MarginStop * 60;
    +  return;
       // To make sure the timer gets assigned to the correct event, we must
       // make sure that this is the only event that overlaps 100%:
       if (const cEvent *e = dynamic_cast<const cEvent *>(Event->Prev()))

    Macht seit über 2 Jahren was ich will.

  • Anbei ein Lösungsvorschlag.

    Das neue Timer-Flag tfEvent wird gesetzt, wenn ein Timer aus dem EPG-Menu heraus für einen bestimmten Event erzeugt wird. Ist dieses Flag gesetzt, wird in cTimer::Matches() dafür gesorgt, dass die Margins auf die tatsächlichen Start-/Stopzeiten des Events draufgeschlagen werden. In einem schnellen Test mit dem Beispiel von MarkusE hat das wie erwartet funktioniert.

    Falls der Benutzer die Start- bzw. Stopzeit des Timers im Menü verändert, wird das Flag gelöscht und der Timer verhält sich wieder wie bisher. Das ist nötig, damit man einen Timer anlegen kann, der zu ganz bestimmten Zeiten aufnimmt.

    Die Abfragen bzgl. Margin und Directly lassen sich sicher noch vereinheitlichen, aber ich möchte erstmal erfahren, ob dieser Ansatz überhaupt "taucht".

    Bitte mal testen und kommentieren.

  • Ich finde den Ansatz im Prinzip gut.

    Wenn ich nun Feedback zu der Implementierung geben soll, möchte ich zunächst mal aufschreiben, was aus meiner Sicht wichtig ist:

    1. Das Event muss mit den Daten, die im Timer gespeichert sind, möglichst oft und eindeutig identifizierbar sein. Mir ist natürlich klar, dass das nicht immer möglich ist. Dies ist aus meiner Sicht das wichtigste Kriterium
    2. Aus Sicht des Anwenders sollte sich möglichst wenig ändern
    3. Die Plugins sollten möglichst gut damit zurechtkommen. Das unwichtigste Kriterium, ein Plugin kann ja auch das neue Timer-Flag tfEvent abfragen.

    Passt das für Euch so, oder seht ihr andere Kriterien/Prioritäten?

    Client1: ASUS P5QC, Dual Core 3G, Cine S2, Ext. Board von TBE, Xubuntu 20.04, VDR 2.6x

    Client2: RPI3

    Server: RPI4, Sundtek SkyTV Dual 2x


    1. Das Event muss mit den Daten, die im Timer gespeichert sind, möglichst oft und eindeutig identifizierbar sein. Mir ist natürlich klar, dass das nicht immer möglich ist. Dies ist aus meiner Sicht das wichtigste Kriterium

    Passt das für Euch so, oder seht ihr andere Kriterien/Prioritäten?

    Punkt 1 ist für mich als Anwender auch am Wichtigsten.

    VDR zwei drei
    • VDR 01 (Server): 2.7.4/6 4 x TT Budget S2-3200
      Plugins: [channellists - control - epgsearch - live - markad - streamdev-server - tvscraper]
    • VDR 02 (Client): 2.6.9 1 x TT Premium S2-6400 (HDMI an TV), 1 x softhddevice (HDMI an TV); TV Grundig 40 VLE 8160 SL; TFT-Display Origen AE 16T
      Plugins: [channellists - control - dvbhddevice - epgsync - graphtftng - mpv - osd2web - osdteletext - skinnopacity - softhddevice - streamdev-client - svdrpservice]
  • MarkusE

    zu 1.:Daran ändert sich durch diesen Patch nichts.

    zu 2.: Das Einzige, was sich ändert, ist, dass in Fällen, wo der Event vor bzw. nach dem aufzunehmenden Event kürzer ist, als die Vor- bzw. Nachlaufzeit, trotz entsprechend angepasster Start- bzw. Stopzeit des Timers die volle Vor- bzw. Nachlaufzeit aufgenommen wird.

    zu 3.: Auf Plugins sollte sich das überhaupt nicht auswirken.

    Dann werde ich das mal so in die nächste Version übernehmen.

  • > zu 1.:Daran ändert sich durch diesen Patch nichts.

    das heißt aber nicht, dass es gut gelöst ist. Und vor diesem Patch war die korrekte Zuordnung "nice to have", mit dem Patch führt eine falsche Zuordnung zu einer falschen Aufzeichnung.

    Wenn z.B. in meinem Beispiel "RTL Television" das EPG komplett um 5 min nach hinten verschiebt, scheitert die Zuordnung.

    Eine bessere Lösung für den Fall, dass tfEvent gesetzt ist, wäre:

    1. Event start + Event stop werden im Timer gespeichert. Z.B. in startTime, stopTime
    2. Zum Suchen des korrekten Events zu einem Timer werden alle Events betrachtet, die im Zeitraum startTime-1 Stunde, stopTime + 1 Stunde liegen.
    3. Zu jedem dieser Events wird ein Score berechnet, der von der Abweichung der Start Zeit und von der Abweichung der Länge des Events abhängt. Letztere Abweichung wird hoch gewichtet. Grund: normalerweise ändert sich die Länge des Events nicht, es wird eher verschoben.
    4. Das Event mit dem besten Score wird dem Timer zugeordnet, wenn der Score hoch genug ist. Andernfalls, oder falls kein Event gefunden wird: Dem Timer wird kein Event zugeordnet.

    Client1: ASUS P5QC, Dual Core 3G, Cine S2, Ext. Board von TBE, Xubuntu 20.04, VDR 2.6x

    Client2: RPI3

    Server: RPI4, Sundtek SkyTV Dual 2x

  • Event start + Event stop werden im Timer gespeichert. Z.B. in startTime, stopTime

    startTime und stopTime sind temporäre Größen. Gespeichert wird nur "start" und "stop".

    Zum Suchen des korrekten Events zu einem Timer werden alle Events betrachtet, die im Zeitraum startTime-1 Stunde, stopTime + 1 Stunde liegen.
    Zu jedem dieser Events wird ein Score berechnet, der von der Abweichung der Start Zeit und von der Abweichung der Länge des Events abhängt. Letztere Abweichung wird hoch gewichtet. Grund: normalerweise ändert sich die Länge des Events nicht, es wird eher verschoben.
    Das Event mit dem besten Score wird dem Timer zugeordnet, wenn der Score hoch genug ist. Andernfalls, oder falls kein Event gefunden wird: Dem Timer wird kein Event zugeordnet.

    Dann schlag doch bitte mal ein entsprechend geändertes cTimer::SetEventFromSchedule() vor.

  • Hi,

    Anbei ein Patch, wie ich mir das vorstelle. Hinweise:

    1. Erst den Patch von Klaus anwenden, dann meinen Patch
    2. Den Timer aus dem VDR EPG anlegen, mit aus live angelegten Timern funktioniert das noch nicht
    3. Die Anfangs/Endzeit des Timers ist identisch mit den Zeiten des EPG Events. Die Margins werden später bei der Aufzeichnung berücksichtigt.

    Bitte testen.

    Frage: Warum sind die Anfangs/Endzeit des Timers ist identisch mit den Zeiten des EPG Events?

    Antwort:

    Wegen der oben definierten Anforderung "Das Event muss mit den Daten, die im Timer gespeichert sind, möglichst oft und eindeutig identifizierbar sein":

    Ich habe ein Objekt (Event), das sich möglicherweise leicht verändern wird. Ich möchte in der Lage sein, das Objekt auch nach kleinen Veränderungen noch zu identifizieren. Das geht am Besten, wenn ich alle bekannten Attribute des Originalobjektes exakt abspeichere.

    ~Markus

  • MarkusE

    cTimer::Set_startTime_stopTime() dupliziert Code aus cTimer::Matches(time t, ...), ich sehe aber nicht, dass in Matches() diese neue Funktion aufgerufen würde. Wenn schon der Code auch woanders gebraucht wird, dann bitte nicht einfach duplizieren.

    Warum musste überhaupt cTimer::Set_startTime_stopTime() eingeführt werden?

    Das mit des "Scores" klingt interessant, ich würde mir nur eine etwas ausführlichere Beschreibung wünschen, was dieser Score genau macht. Wie kommst du auf "sqrt(x) / 2" bzw. "1 - 1 / (x + 1)"?

    Statt "acceptableStartTimeDeviation" sollte es vielleicht besser "acceptableTimeDeviation" heißen, denn es wird ja bei Start und Stop verwendet ;-).

  • > Warum musste überhaupt cTimer::Set_startTime_stopTime() eingeführt werden?

    Ich habe das eingeführt, um auf Fehler reagieren zu können.

    In cTimer::Matches(time t, ...) wird im Fehlerfall (if (!startTime) ) die startTime auf eine Woche in der Zukunft gesetzt. Ich wollte vermeiden, dass dann ein falsches, eine Woche in der Zukunft liegendes Event zugeordnet wird.

    Aber klar, cTimer::Matches(time t, ...) sollte natürlich cTimer::Set_startTime_stopTime() verwenden.

    > ausführlichere Beschreibung wünschen, was "double normScore(double x)" macht

    Eingabe x: eine Zahl zwischen 0 und unendlich (na ja, halt das größte, was mit double darstellbar ist).

    Ausgabe: normScore(x): eine Zahl zwischen 0 und 1, so dass normScore(a) < normScore(b) falls a < b. Und normScore(1) = 0.5 .

    Könnte man sicher auch anders implementieren.


    > Statt "acceptableStartTimeDeviation" sollte es vielleicht besser "acceptableTimeDeviation" heißen, denn es wird ja bei Start und Stop verwendet ;-).

    Klar, kann man umbenennen

    ~ Markus

    Client1: ASUS P5QC, Dual Core 3G, Cine S2, Ext. Board von TBE, Xubuntu 20.04, VDR 2.6x

    Client2: RPI3

    Server: RPI4, Sundtek SkyTV Dual 2x

  • Anbei ein Update des Patches, mit kleineren Verbesserungen

    Edit: Dieser Patch ist fehlerhaft, bitte nicht produktiv verwenden. Ein Update wird kommen, ich teste aber erst noch ...

    Files

    Client1: ASUS P5QC, Dual Core 3G, Cine S2, Ext. Board von TBE, Xubuntu 20.04, VDR 2.6x

    Client2: RPI3

    Server: RPI4, Sundtek SkyTV Dual 2x

    Edited once, last by MarkusE (September 14, 2024 at 10:01 PM).

  • Anbei der Update des Patches.

    Um das ganze so kompatibel zu machen wie möglich, könnte man

    Code
    cTimer::cTimer(const cEvent *Event, const char *FileName, const cTimer *PatternTimer)

    um einen optionalen bool Parameter erweitern. Und tfEvent nur denn setzen, wenn dieser neue Parameter true ist. Und andernfalls

    Code
      tstart -= Setup.MarginStart * 60;
      tstart += Setup.MarginStop * 60;

    ausführen.

    Was meint ihr?

  • Ich mache hier jetzt noch einen Versuch, mit einem weiteren Patch für 2.7.3, der folgende kleinen Änderungen macht:

    1. Timer, die nicht spawned sind (also HasFlags(tfSpawned) == false) und auch keine VPS Timer sind: Hier werden immer die vom Anwender vorgegebenen Margins verwendet. Auch dann, wenn der Timer dadurch mehr als ein Event umfasst, also 2 oder mehr Events vollständig im Zeitraum [Start, Stop) liegen.
    2. Timer, die spawned sind (also HasFlags(tfSpawned) == true): Keine Änderung zum Verhalten von VDR 2.7.3
    3. VPS Timer: Keine Änderung zum Verhalten von VDR 2.7.3

    Begründung für 1:

    Damit wird das Verhalten von VDR für "nicht Pattern Timer", wie es vor Einführung der Pattern Timer war, wieder hergestellt :)

    Durch diese Änderung tritt der Fehler, der hier im 1. Post beschrieben wurde, nicht mehr auf :)

    Falls diese Änderung dazu führen sollte, dass einem Timer etwas öfter ein falsches Event zugeordnet wird: Das wäre jetzt nicht soo schlimm, weil VDR die Events dieser Timer nicht für kritische Aktionen verwendet.

    Begründung für 2:

    Da spawned Timer im Zeitraum [event->start - margin, event->stop() + margin) aufzeichnen führt die Verkürzung der beim Timer selbst verwendeten Margins nicht zu einer kürzeren Aufnahmezeit.

    ~ Markus

  • Ich war in letzter Zeit mit anderem beschäftigt, daher hast du von mir hier nichts gehört.

    Soll timer_margins.txt zusätzlich zu timer_event_v2.txt angewendet werden, oder anstatt?

    Anstatt.

    Das sind komplett unterschiedliche Lösungsansätze

    Client1: ASUS P5QC, Dual Core 3G, Cine S2, Ext. Board von TBE, Xubuntu 20.04, VDR 2.6x

    Client2: RPI3

    Server: RPI4, Sundtek SkyTV Dual 2x

Participate now!

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