TrickSpeed - Verständnisfrage

  • Hallo zusammen,


    ein paar Infos zu TrickSpeed hab ich in verschiedenen Threads gefunden, trotzdem fehlt mir der Durchblick.

    In softhddevice-drm-gles funktioniert der Vor- und Rücklauf nicht oder nicht richtig und ich möchte das korrigieren, deshalb meine Fragen.


    Wenn ich in einer laufenden Aufnahme KEY_RIGHT drücke, wird device->TrickSpeed getriggert, was die Wiedergabegeschwindigkeit steuert.

    Jetzt kenne ich http://git.tvdr.de/?p=vdr.git;…5dbebf286f07;hb=HEAD#l762 mit den verschiedenen Zahlen.

    Angenommen ich drücke jetzt 1x KEY_RIGHT, dann wäre ich doch bei FastForward 1x und dem Wert 6. Wenn ich den Kommentar richtig lese, heißt das, dass dieses Frame 6x so lange angezeigt werden soll wie normal, also nicht mehr z.B. 20ms, sondern 120ms.

    Wenn das Frame durch ist, welches Frame soll dann angezeigt werden? Das kann ja nicht das mit dem nächsten PTS sein, sonst würde die Aufnahme ja 6x langsamer laufen als im normalen replay? Kümmert sich VDR drum, das richtige Frame zu schicken, oder muss das Ausgabeplugin Frames überspringen?


    Das wäre mal die grundsätzliche Frage, bevor ich weiter frage ;)


    Aktuell gibt es im Ausgabedevice ein usleep im DisplayThread, was aber dann entsprechend blockiert und auch nicht richtig funktioniert.

    Die anderen Ausgabedevices bauen das anders ein. Soweit ich verstanden habe, wird bei TrickSpeed mit TrickCounter zurückgezählt und solange der nicht 0 ist, wird das aktuelle Frame weiter dargestellt, d.h. z.B. 6x. Wenn TrickCounter auf 0 ist, wird das nächste Frame geholt und TrickCounter wieder zurückgestellt.


    Ich hoffe, meine Frage ist nicht zu kompliziert und jemand kann Licht ins Dunkel bringen. Ich möchte das richtig einbauen...


    Danke

    Andreas

  • Danke dir, das erklärt es. Habe die Stelle im dvbplayer gefunden. Ich denke, das Prinzip habe ich erstmal verstanden, denn FastForward und Backward funktioniert jetzt soweit bei progressivem Material. Vor und zurück aus der Pause noch nicht und interlaced auch noch nicht, wie es aussieht.

    Ich glaube, ich muss da die ganzen Möglichkeiten abgrasen ...

  • Was mir noch nicht klar ist: Schickt vdr bei einfacher Zeitlupe rückwärts jetzt 63 mal das gleiche i-frame, oder ist es Aufgabe des Ausgabedevices, ein einzelnes angeliefertes i-frame 63 mal zu wiederholen?

    Das kommt ja noch aus der Zeit der FF Karten und wurde im dvbsddevice-Plugin so umgesetzt, dass speed (also hier die 63) ein Parameter für das av7110-soezifische ioctl ist, der die Anzahl der Wiederholungen festlegt. Demnach vermute ich, dass letzteres zutrifft.

    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

  • Ja, so verstehe ich es. Der VDR schickt das Frame nur 1x, das Ausgabeplugin muss dafür sorgen, dass es oft genug angezeigt wird.

    VDR sorgt in dvbplayer (http://git.tvdr.de/?p=vdr.git;…31aa7822d01a;hb=HEAD#l501) dafür, dass nächste ausgelieferte Frame stimmt.

  • Ein weiteres Problem ist die unterschiedliche GOP-Länge. Ich zitiere mal jojo61:

    Quote

    VDR sendet tatsählich nur I-Frames beim spulen. Dazu wird dann Trickspeed gesetzt um anzuzeigen wie oft das Frame wiederholt werden soll. Bei MPEG2 funktioniert das auch ganz nett. Aber bei H264 sind die I-Frames doch recht weit auseinander und da rennt dann das Bild sehr schnell. Grund hierfür ist das Trickspeed auf 1 sitzt wenn man kein Multi Speed aktiviert hat. Mit aktiven Multispeed sieht es besser aus weil da Trickspeed mit 6 anfängt (d.h. jedes I-Frame wird 120ms angezeigt) und damit ergibt sich eine sinnvolle Zeitlupe.

    Eigentlich müsste Trickspeed an die Frequenz der I-Frames angepasst werden. D.h. bei Mpeg2 anders als bei h264 sein, wenn man die gleiche Zeitlupe oder Zeitraffer haben will

    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

  • Ok. Aber das wäre dann Feintuning, denn prinzipiell funktioniert es ja.

    Wenn man möchte, dass das Spulen immer gleich schnell läuft, müsste wohl der VDR core erst etwas rechnen und die Parameter dann an device->TrickSpeed mitgeben, damit das Ausgabedevice richtig darstellt. Dem Ausgabedevice sind ja die GOP-Längen erstmal nicht bekannt.

  • Ich komme mit Trickspeed nicht recht weiter und bin mittlerweile auf der ffmpeg Ebene angelangt.

    Das Problem bei mir ist die backward Trickspeed. Es klappt mit MPEG2/576i aber H264 - ob interlaced oder progressive - macht Probleme. Dazu folgendes gekürztes Log:

    VideoEnqueue legt wie bei den anderen softhddevice Varianten die Daten, die von VDR kommen in einem Ringbuffer ab.

    An den pts sieht man, dass VDR die schön in der richtigen Rückwärts-Reihenfolge liefert. Ein extra Thread holt sich in VideoDecodeInput das nächste avpkt aus dem Ringbuffer und schickt es mit CodecVideoSendPacket (avcodec_send_packet) an ffmpeg. Gleich danach versucht CodecVideoReceiveFrame ein fertiges Frame zu holen.

    Hier ist es jetzt so, dass das erste Frame erst geholt werden kann, wenn 3 Aufrufe von avcodec_send_packet geschickt wurden.

    Allerdings kommt nicht das Frame zurück, das zuerst geschickt wurde, sondern das mit dem kleinsten pts.


    Ich frage mich jetzt, ob die beiden anderen Frames noch irgendwo liegen, ob ffmpeg da beim avcodec_receive_frame zuerst den pts aufsteigend sortiert und dann zurückgibt etc. Irgendwie habe ich das Gefühl, dass da bei ffmpeg was durcheinander kommt. Ob das am Ende die Ursache ist, weiß ich nicht.

    Gibt es irgendwelche flags, die ich übersehe? Darf ich bei trickspeed backwards erst ein neues avpkt an ffmpeg schicken, wenn das letzte Frame fertig ist?


    Bei MPEG2 kommt das erste "richtige" Frame zurück, nachdem 2 avpkt gesendet wurden. Hier stimmt die Reihenfolge.


    Wäre top, wenn mir jemand eine Meinung hat ;)


    Ein Beispiel ffmpeg log beim kaputten backward:

    Das "ooo" bei no picture soll out-of-order heißen. FFMpeg ist die LE-Version für Rockchip, daher nicht mainstream.


    Funktionierendes forward sieht so aus:

    Auch bei forward werden 3 avpkt geschickt, bevor das erste frame zurück kommt. Auch hier das mit dem kleinsten pts - aber bei forward passt es ja.

  • Hier ist es jetzt so, dass das erste Frame erst geholt werden kann, wenn 3 Aufrufe von avcodec_send_packet geschickt wurden.

    Ist bei H.264 notwendig, weil es B-Frames geben kann, die vor das letzte I-Frame verweisen. Bei MPGEG2 gibt es die nicht.

    Allerdings kommt nicht das Frame zurück, das zuerst geschickt wurde, sondern das mit dem kleinsten pts.

    Ist normal. Aufgabe des Decoders ist es, die Decoding Reihenfolge in die Darstellungsreihenfolge umzusortieren. Also kleines PTS zuerst. An Rückwärts abspielen hat da wohl keiner gedacht. Interessant, dass das den MPG2 Decoder nicht interessiert. Vermutlich weil er eh nicht umsortieren muss.

    Ich kenne kein Flag, das dem Decoder sagen kann, er soll rückwärts die Daten hergeben.

    Ich sehe da nur zwei (wilde) Ansätze:

    - Entweder du baust vor dem Decodieren die PTS/DTS so um, dass es für den Decoder so aussieht, als ob er vorwärts decodiert.

    - Oder du flashed nach jedem Frame die Decoder Queue (av_send_packet(..., nullptr). Danach muss du aber den Decoder neu initialisieren.

    Das nächste Problem wird H.264 interlaced werden, mir ist es in markad nicht gelungen, da nur I-Frames zu dekodieren. Wenn du nur die die Pakete decodierst, die das Key Flag gesetzt haben, bekommst du nur Halbbilder.

    Edited once, last by kfb77 ().

  • Danke für deine Antwort. Am einfachsten wird es wohl sein, wenn ich mal versuche, bei TrickSpeed den pts zu faken... Nach dem bei TrickSpeed kein Sync stattfindet, sollte ich mit dem Frame für die Darstellung kein Problem haben.... Ich probier das mal.

  • Hm, so einfach wars nicht. Auch mit gefaketem pts wird erste das frame zum dritten avpkt zurückgegeben. Ich glaube, ich muss da im ffmpeg mehr suchen und mein Hirnschmalz weiter bemühen. Wenn vom VDR nur I-Frames kommen, dürfte doch jedes avpkt, das ich an ffmpeg schicke, keine Referenzen für ein fertiges frame benötigen?

  • Wenn vom VDR nur I-Frames kommen, dürfte doch jedes avpkt, das ich an ffmpeg schicke, keine Referenzen für ein fertiges frame benötigen?

    Richtig. Aber der Decoder weiß ja nicht, dass du nur I-Frame schicken willst und hält diese zurück, weil ja noch B-Frames kommen könnten, die ein PTS vor dem I-Frame haben. Erst wenn der PTS Abstand zu groß wird, in deinem Fall wohl 3 I-Frames (wie auch immer der Decoder entscheidet, wann das der Fall ist), gibt er dir das älteste I-Frame zurück.

  • Ok. Dass er erst nach 3 send ein frame schickt, ist auch ok. Jetzt muss ich nur schauen, warum nicht das erste frame kommt bzw. das mit dem ältesten PTS. Ich bekomme beim receive danach nur EAGAIN zurück, egal wie oft ich ein avpkt sende. Ich muss mal die Codestelle in ffmpeg suchen, wo die frames zurückgegeben werden. Komisch nur, dass es bei forward klappt... Irgendwas scheint hier zu blockieren.

  • DTS hast du auch angepasst ? Muss streng monoton steigend und vor PTS sein.

  • Ah. Nein. Probier ich. Was heißt streng monoton steigend?

  • Jeder Wert muss größer sein, als der zuvor. Üblicherweise ist der DTS Abstand im Video Stream gleich avpkt->duration.

  • DTS hast du auch angepasst ?

    DTS wird von den meisten Decodern nicht benutzt. Im softhddevice-drm ist das immer leer.


    In Stillpicture wird in einer Schleife so oft das selbe Packet in den Decoder geschoben bis ein Frame rauskommt. Die Stillpicture funktion wird doch auch bei Trickspeed genutzt, oder?

  • Nein, VDR schickt hier die Daten mit PlayVideo ans Device.

    Klaus Schmidinger's git trees - vdr.git/blob - dvbplayer.c

    Und das muss dafür sorgen, dass es TrickSpeed-mal angezeigt wird.

  • Ja, könnten. Die Frage ist nur, obs da geht. Habe mir StillPicture noch nicht angeschaut, aber die Vorhehensweise, wie avpkts an ffmpeg geschickt werden und das frame abgeholt wird dürfte ja gleich sein. Der VideoRenderFrame bzw. Frame2Display Teil funktioniert ja bereits sobald es ein fertiges Frame gibt. Es hakt "nur" daran, dass CodecVideoReceiveFrame kein Frame mehr liefert sondern ein ständiges EAGAIN, obwohl mit CodecVideoSendPacket erfolgreich weiter avpkt geschickt werden. Daher vermute ich den Fehler an ffmpeg und pts/dts...

Participate now!

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