Also, ist bei mir das gleiche, die Qualität ist mieß, und mit dndi_first_frame = 0 hängt er sich komplett auf.
QuoteDie Frage ist warum 20? Man muß vielleicht doch die gesamte Buchserie lesen.
Aktuell werden die aktuelle Surface zweimal übergeben.
Das Ergebnis zweimal. Bei beiden gibt es ja zwei Planes.
Und 1x der obige beschriebene STMM und History Puffer zum schreiben.Da nun gesagt wird, dies ist die erste Frame, wird die vorherige Surface und STMM nicht gelesen
Und nur eine Deinterlace Fläche geschrieben.
Ich hab nichts gefunden zu diesen surface index, vielleicht nennen die das in dem Buch anders. Ich konnte auch keinen logischen zusammenhang zwischen den gen7 surface index und den für gen6 finden. Im Moment ist es auch bei gen7 so aus das beide input surfaces das gleiche bild sind und beide output surfaces ebenfalls (welchen sinn macht das denn?). Dazu wird STMM noch wieder in das input-surface geschrieben, obwohl in dem buch drinsteht das man genau das nicht machen soll.
QuoteIm Moment wird ja nur 1 Bild aus 1 Bild produziert. Siehe Handbuch Seite 69 "4.7.6.2 First Frame Special Case".
Ich rufe mit 50 Hz die Funktion auf.
Beim erstenmal mit TOP, beim nächsten mal mit BOT.
Das erklärt auch das unerträglich wacklige Bild, das ist ja ziemlicher murks.
QuoteDie neue libva API siehe va_vpp.h unterstützt die Übergabe von Referenzframes,
aber nicht die Ausgabe von gleich 2 Frames.Also muß man auf jeden Fall im Treiber tricksen. Alle 2 Frames den Deinterlacer aufrufen-
Ich weiß nicht ob das sinnvoll ist, wenn man in 4.7.6.1 auf Seite 67 schaut sollen die denoisten fields gespeichert für den nächsten aufruf. es ist daher vermutlich sinnvoller das referenz-surface innerhalb pp_context zu speichern, wie auch das stmm. Das Problem ist wie zwei surfaces zurückgeben? Wäre es eine Möglichkeit die Funktion abwechselnd mit einem surface und null aufzurufen dazu müssten beide surfaces intern gecacht werden (frame1 (zeitlich erstes bild), frame2 (zeitlich zweites bild))?
Immer wenn ein surface kommt wird das zweite field von der referenz ausgegeben und das input-surface die neue referenz (frame1=frame2; frame2 = in; deinterlace(); out = frame1.second_field), bei null wird nichts gemacht, sondern nur das erste field des zweiten frames zurückgegeben?
Beim ersten aufruf bekomme ich nur einen frame, rückgabe ist das erste field aus diesem frame. Das surface wandert in den cache. Beim nächsten Aufruf kommt null, das gleiche surface kommt nochmal zurück, dann kommt wieder ein surface und das zweite field des alten surfaces kommt zurück und so weiter. Nachvollziehbar? Damit sollte es möglich sein entweder aus 50 fields/sec 25 frames/sec zu machen (jeder aufruf mit surface) oder aus 50 fields/sec 50 frames/sec (abwechselnd surface/null). Das ganze wird eine Latenz von 20ms mit sich bringen (der erste frame kommt doppelt). Die Frage ist nun ob man es schafft irgendwie eine null bis zu der funktion zu bekommen.
Nachtrag:
Hab mir das ganze nochmal genauer angesehen, das null als src übergeben ist doch nicht so gut, weil das output surface nach dem src erstellt wird lange bevor man am deinterlacer ist, da müsste man relativ viel hacken. Bessere Idee: Neben den top/bottom flags einfach noch ein "DOUBLE_RATE" flag und ein "SECOND_FRAME" flag:
Im Treiber müssen diese flags weitergegeben werden: Wenn DOUBLE_RATE aktiv ist weiß der deinterlacer, dass er das zweite surface zwsichenspeichern muss (innerhalb von pp_context), sonst wirft er das weg. Wenn dann ein aufruf mit "SECOND_FRAME" kommt, gibt er einfach das zweite Bild zurück. Problem ist noch das erstellen der surfaces: Je nachdem brauch der deinterlacer 1, 2 oder auch 0 neue out surfaces. Entweder die surfaces werden im deinterlacer erzeugt oder man muss zuerst abfragen wieviel gebraucht werden und das zweite surface dann über filter_param übergeben. Beides keine wirklich tollen Lösungen, denke aber die erste ist besser, damit verhält sich der deinterlacer aber dann anders als die anderen Filter. Das sollte aber nicht das ganz große Problem sein, da es nur genau eine Stelle gibt wo der Deinterlacer aufgerufen wird. Was ich noch nicht ganz verstanden ist dieser filter_param, anscheinend wird der von der vaapi definiert, so sieht das zumindest für den denoiser aus, für den deinterlacer ist da auch schon irgendwo was ("VAProcFilterParameterBufferDeinterlacing"), wird aber nie verwendet (es wird nichts ausgewertet und auch immer null übergeben). Enthält nur die unterschiedlichen deinterlacing-verfahren. Hier könnte man "DOUBLE_RATE" auch sinnvoll unterbringen, nur muss man es dann noch implementieren das man das von softhddevice bis zu pp_nv12_dndi_initialize bekommt.
Bezüglich diesen surface ids, auf seite 173/174 steht etwas das damit zutun haben könnte, eine genaue verbindung konnte ich aber nicht herstellen. Bist du da schon weitergekommen?