jojo61: Nutzt du beim bauen nicht den cache von ./sources ?
Beiträge von rell
-
-
So, auch ich bin wieder einen Schritt weiter. FFMpeg hat leider keine decodierten frames zurückgegeben. Das lag daran, dass ffmpeg durch das vorherige replay die Anzahl der benötigten frames - bevor das fertige ausgegeben wurde - hochgesetzt hat, da schon mal B-Frames aufgetaucht sind. Macht Sinn. Macht aber keinen Sinn, wenn nur I-Frames kommen. ffmpeg liefert dann "no picture", ergo kein frame.
Wenn ich den Decoder aber mit dem ersten gesendeten Trickspeed schließe und einmalig neu öffne, gibt es den ffmpeg-internen Zähler noch nicht, und ich kann dann auch ganz normal packets senden und frames abrufen, ohne auf die gesendet Anzahl der packets zu achten. Den flush nach einem erhaltenen Frame brauchts trotzdem - zumindest beim Rücklauf. Mal sehen, wie ich das alles zusammenbringe. Danach schaue ich mir an, was ihr oben so herausgefunden habt.
-
Ich denke, ich habs jetzt hinbekommen, zumindest ohne multispeed.
Für meine 3 Beispielstreams sieht es folgendermaßen aus:
MPEG2 576i: send 1 avpkt, send flush packet, receive frame, flush buffers
H264 720p: send 1 avpkt, send flush packet, receive frame, flush buffers
H264 1080i: send 2 avpkts, send flush packet, receive frame, flush buffers
Jetzt wäre nur noch die Frage, wie ich herausfinden kann, dass ich bei dem H264 1080i stream 2 Pakete senden muss.
Momentan greife ich die coded_height ab und treffe die Entscheidung damit. Das funktioniert aber nur, wenn sicher ist, dass alle Streams dem oben beschriebenen Schema folgen!?
Alternativ könnte ich mir avpkt->data abgreifen und solange frames senden, bis wieder eines mit
kommt?
-
Ich bin noch am Kämpfen mit dem ffmpeg decoder. Alle Versuche, das sauber hinzukriegen, sind bislang gescheitert.
Ich möchte ein avpkt senden, von mir aus auch mehrfach, wenns hilft oder einen flush schicken und dann auf das Frame warten. Das klappt teilweise auch.
Bei 1080i, z.B. AnixeHD habe ich aber Probleme und habe mir mal die avpkt->data angesehen. Hier wäre mal so ein Beispielablauf, wenn ich keine avpkt doppelt schicke, sondern nur den decoder fülle und nach jedem send versuche, das frame zu bekommen. Kann mir jemand auf die Sprünge helfen, was es z.B. mit den ersten beiden Paketen auf sich hat, die nur 20ms auseinander sind? Den avpkt->pts und die ersten 10 bytes von avpkt->data gebe ich aus.
Gehören .311 und .331 zusammen und ich brauche beide für ein frame? Bin in den Bitstream noch nicht eingestiegen...
Code
Alles anzeigenOkt 22 10:43:33 rock4plus2 vdr[25033]: [25058] [softhddevice][Trick] CodecVideoSendPacket: send packet 19:41:30.311 6380128067 0x00 0x00 0x01 0x09 0x10 0x00 0x00 0x00 0x01 0x67 0x64 Okt 22 10:43:33 rock4plus2 vdr[25033]: [25058] [softhddevice][Trick] CodecVideoSendPacket: send packet 19:41:30.331 6380129867 0x00 0x00 0x01 0x09 0x30 0x00 0x00 0x00 0x01 0x06 0x01 Okt 22 10:43:33 rock4plus2 vdr[25033]: [25058] [softhddevice][Trick] CodecVideoSendPacket: send packet 19:41:31.431 6380228867 0x00 0x00 0x01 0x09 0x10 0x00 0x00 0x00 0x01 0x67 0x64 Okt 22 10:43:33 rock4plus2 vdr[25033]: [25058] [softhddevice][Trick] CodecVideoSendPacket: send packet 19:41:31.451 6380230667 0x00 0x00 0x01 0x09 0x30 0x00 0x00 0x00 0x01 0x06 0x01 Okt 22 10:43:33 rock4plus2 vdr[25033]: [25058] [softhddevice][Trick] CodecVideoSendPacket: send packet 19:41:32.351 6380311667 0x00 0x00 0x01 0x09 0x10 0x00 0x00 0x00 0x01 0x67 0x64 Okt 22 10:43:33 rock4plus2 vdr[25033]: [25058] [softhddevice][Trick] CodecVideoSendPacket: send packet 19:41:32.371 6380313467 0x00 0x00 0x01 0x09 0x30 0x00 0x00 0x00 0x01 0x06 0x01 Okt 22 10:43:33 rock4plus2 vdr[25033]: [25058] [softhddevice][Trick] CodecVideoReceiveFrame: got frame 19:41:30.311 Okt 22 10:43:33 rock4plus2 vdr[25033]: [25041] [softhddevice][Trick] Frame2Display: ----------------> commit trickspeed frame 19:41:30.311 Okt 22 10:43:34 rock4plus2 vdr[25033]: [25058] [softhddevice][Trick] CodecVideoSendPacket: send packet 19:41:33.591 6380423267 0x00 0x00 0x01 0x09 0x10 0x00 0x00 0x00 0x01 0x67 0x64 Okt 22 10:43:34 rock4plus2 vdr[25033]: [25058] [softhddevice][Trick] CodecVideoSendPacket: send packet 19:41:33.611 6380425067 0x00 0x00 0x01 0x09 0x30 0x00 0x00 0x00 0x01 0x06 0x01 Okt 22 10:43:34 rock4plus2 vdr[25033]: [25058] [softhddevice][Trick] CodecVideoSendPacket: send packet 19:41:34.831 6380534867 0x00 0x00 0x01 0x09 0x10 0x00 0x00 0x00 0x01 0x67 0x64 Okt 22 10:43:34 rock4plus2 vdr[25033]: [25058] [softhddevice][Trick] CodecVideoSendPacket: send packet 19:41:34.851 6380536667 0x00 0x00 0x01 0x09 0x30 0x00 0x00 0x00 0x01 0x06 0x01 Okt 22 10:43:34 rock4plus2 vdr[25033]: [25058] [softhddevice][Trick] CodecVideoSendPacket: send packet 19:41:36.071 6380646467 0x00 0x00 0x01 0x09 0x10 0x00 0x00 0x00 0x01 0x67 0x64 Okt 22 10:43:34 rock4plus2 vdr[25033]: [25058] [softhddevice][Trick] CodecVideoSendPacket: send packet 19:41:36.091 6380648267 0x00 0x00 0x01 0x09 0x30 0x00 0x00 0x00 0x01 0x06 0x01 Okt 22 10:43:34 rock4plus2 vdr[25033]: [25058] [softhddevice][Trick] CodecVideoReceiveFrame: got frame 19:41:33.591 Okt 22 10:43:34 rock4plus2 vdr[25033]: [25041] [softhddevice][Trick] Frame2Display: ----------------> commit trickspeed frame 19:41:33.591
Jedenfalls ist es so, dass das erste avpkt wieder als frame kommt, die anderen 5 gehen unter, weil oben nach dem receive ein decoder flush stattfindet....
-
Kein Problem, so ein Trickspeed-Sammelbecken schadet nicht
-
... für multispeed muss ich wohl doch das frame verdoppeln und nicht avpkt ...
-
Bei meinem Thema bin ich etwas weiter. Ich vervielfache jetzt bereits die ankommenden avpkt und schicke die clone so oft zum decoder, wie es TrickSpeed vorgibt.
Ich probiere gerade aus, wieviel avpkt der decoder bei mpeg2/h264 i/p benötigt, um ein frame auszuwerfen. Wenn zuviel gesendet werden, korrigiert der decoder die Reihenfolge und das ist bei rückwärts schlecht. Wenn gesendete avpkt Anzahl und Zeitpunkt des flush passen, scheint es zu funktionieren. Ich muss es jetzt nur noch zusammenkriegen.
-
Ist wahrscheinlich nur ein temporäres Problem mit der Erreichbarkeit.
Der Link auf https://repo.or.cz/rtmpdump.git/ für den snapshot vom 2021-02-19 ist bis auf http(s) der gleiche.
Ein manueller Download klappt dann irgendwann auch...
-
Klappt schonmal nicht ganz richtig, da muss ich nochmal ran
Mein Ansatz war viel zu kompliziert. Ich habe das Frame während der Darstellung vervielfacht. Das muss ich schon vorher machen und den display thread in Ruhe lassen...
-
Der einzige Grund, warum ich meinen Eintrag nicht aktualisert habe, ist, dass ich nicht drangedacht habe und auch nicht aufdringlich genug daran erinnert wurde. Jetzt ist er wieder aktuell.
Vielleicht wäre es eine Möglichkeit, den Counter so zu lassen, wie er ist und stattdessen an verschiedensten Stellen "Erinnerungen" einzubauen. Z.B. analog zum FB-Anlernen beim ersten Start oder als monatliche OSD-Message, die man auf Dauer abstellen kann oder sich wieder erinnern lassen kann. Kann zwar auch nervig sein, aber diesen einen Klick braucht man ja auch bei der Nach-Hause-Telefonieren-Methode, aber der Datenschutz wäre erledigt.
-
Ich habe den aktuellen Stand mal ins git geschoben: https://github.com/rellla/vdr-…ommits/WIP/trickspeedV02/
Das Grundgerüst sollte funktionieren, aber die Tests mit verschienenen TrickSpeed/Pause/Play/Codec-Kombinationen fehlen noch - auch wie das auf anderen Devices wie dem RPi aussieht. Wenn da alles geht, schau ich mir die Übergänge an.
-
jojo61 Wie hast du die "Wartezeit" festgelegt? https://github.com/jojo61/vdr-…blob/master/video.c#L1299
-
rell: Du kannst Dir ja mal anschauen, wie jojo61 es in softhdodroid gelöst hat. Die entscheidende Stelle ist m.E. in video.c in der Funktion CodecVideoDecode. Wenn es sich um einen Rückwärts-Trickspeed handelt oder um die Stufen 1, 3 oder 6 (=Spulen, keine Zeitlupe) wird ein reset des Decoders mit Leerung der Buffer ausgeführt. Es findet zudem mittels usleep eine kleine Verzögerung statt, deren Dauer von der Art des Trickmodus abhängig ist. Und irgendwas wird da auch mit der PTS gemacht.
Genau sowas passiert jetzt auch hier. Hätte ich mal vorher ansehen sollen Das mit der PTS muss ich mir noch ansehen. Danke für den Tip mit softhdodroid aber da habe ich abgebrochen, als ich zu amlreset gekommen bin. Dachte mit, aha, proprietär und eh ganz anders. Aber dass ein reset einem flush gar nicht so unähnlich ist, da hätte ich auch selber draufkommen können
TrickSpeed aus der Pause kommt als nächstes...
-
Kurze Rückmeldung: Ich habe es vermutlich hinbekommen - allerdings mit dem flush. Und zwar schicke ich nach einem erfolgreichen avcodec_send_packet ein NULL pkt, damit ich mit avcodec_receive_frame das Frame sofort zurück bekomme. Danach muss ich noch ein avcodec_flush_buffers ausführen, sonst bekomme ich eof zurück. Erst dann wird bei Trickspeed das nächste avpkt an den decoder geschickt.
Mit verschiedenen pts und dts habe ich es nicht geschafft. Auch nicht, wenn das gleiche avpkt 3x geschickt wird. Ich bekomme dann zwar das mit dem richtigen pts zurück, aber auch nur, weil auch das dritte gesendete den gleichen pts hat. Testweise habe ich danach ein avcodec_send_packet(decoder, NULL) gemacht und dann kommen nämlich nochmal 2 frames mit dem gleichen pts zurück, die der decoder ja noch im Puffer hat.
Jedenfalls braucht der Decoder bei h264 3 avpkt um ein Frame zu liefern - und das Frame ist bei Rückwärtslauf immer das letzte, das geschickt wurde. Keine Ahnung, wie man das umgeht, ohne an ffmpeg ran zu müssen.
Jedenfalls scheint der flush ein gangbarer Weg und ich versuche das mal in einigermaßen sauberen Code zu kriegen.
Mich wundert immer noch, worin der Unterschied liegt zwischen forward und backward mit gefaketem pts liegt. Evtl. wird der pts auch noch intern geprüft. Wenn ich fertig bin, schaue ich mir den ffmpeg code evtl. mal an.
-
Ja, ich werde das morgen ausprobieren, aber nicht über StillPicture sondern mit einer Schleife in VideoDecodeInput - müsste ja auch gehen.
Was würde der decoder eigentlich sagen, wenn man ihm ein packet schickt mit dts=pts=AV_NOPTS_VALUE ?
-
Stimmt Den Satz habe ich ignoriert. Das wäre die harte Methode, die mich nicht so anlacht...
-
Nochmal ich. Wenn ich https://ffmpeg.org/doxygen/6.1…1e0ac59e27362597e467efff3 richtig lese, dürfte ein avcodec_send_packet(context, NULL) dafür sorgen, dass der decoder gepufferte frames ausliefert. Das könnte man dann bei Trickspeed nach jedem gesendetem avpkt nachen?!
-
Ok, StillPicture sendet anscheinend nur 1 avpkt und wartet auf das frame in einer Schleife. Keine Ahnung, ob das geht. Mal testen.
-
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...
-
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.