x264 infos mit Delphi auslesen

  • Hallo,

    ich versuche schon länger mit meinem bescheidenen Delphi Kentnissen die Infos (z.B: schon encodete Frames, also aktuelle Position) beim x264 während des encodes mit Delphi abzugreifen. Ziel ist eine Progressbar...

    Probiert hab ich das mit DosCommand und diversen andern functions die ich gefunden haben, aber immer habe ich die Infos erst am ende des encodes erhalten.

    Hat den jemand schon mal nen Gui programmiert wo er ähnliches verwirklicht hat oder weiß wie das (am einfachsten ;)) geht?
    Oder gibt es andere Möglichkeiten das abzufangen?

    Thx im vorraus

  • ich versuche schon länger mit meinem bescheidenen Delphi Kentnissen die Infos (z.B: schon encodete Frames, also aktuelle Position) beim x264 während des encodes mit Delphi abzugreifen. Ziel ist eine Progressbar...


    Ich weiß nicht, wie Du das Encoding aufrufst bzw die aufgerufene Anwendung arbeitet, aber prinzipiell gibt es verschiedene Möglichkeiten.

    Entweder Du rufst eine Anwendung commandline auf und wertest die Konsolenausgaben der Anwendung aus. Eine Möglichkeit findest Du in dem Link von LigH. Dort musst Du dann noch die Auswertung ergänzen. In SVCDPal2DVD und faRoboGUI verwende ich ähnliche Routinen.

    Oder die Anwendung verwendet eine Callback-Routine, mit welcher sie Messages sendet, welche Du dann auswerten kannst.

    Gruß Frank

  • Also ExecConsole liefert mir auch die Ausgabe erst nachdem x264 seine arbeit beendet hat. Mit sachen wie "cmd /c dir" klappt das ja wunderbar, weil das dort Zeile für Zeile kommt. Da konnte ich auch mit Doscommand wunderbar jede zeile abgreifen, nur bringt mir das ja mit "cmd /c dir" ncht viel....

  • Der Grund, warum du nicht immer alles sehen wirst:

    Programme benutzen nicht immer nur das Dateihandle 1 (STDOUT) zur Ausgabe von Informationen, sondern manchmal auch das Dateihandle 2 (STDERR). Du musst also sozusagen zwei Ausgaben auf die selbe Konsole überwachen.

    Und wenn alte "echte DOS-Programme" gar direkt in den vermeitlichen Textbereich des "Grafikkartenspeichers" schreiben wollen, dann sieht man mit Pipes auch nichts davon.

  • So klingt das durchaus erfolgversprechend.

    Jetzt musst du nur noch intelligent die übergebenen Zeichen auswerten (d.h. u.U. einige davon ignorieren).

    Sich selbst überschreibende Bildschirmausgaben erreicht man oft leicht durch die Verwendung der Steuerzeichen ^H / #8 (Rückschritt / Backspace) und einzelner ^M / #13 (Wagenrücklauf / Carriage return) -- ohne ^J / #10 (Zeilenvorschub / Line Feed).

  • So etwas?

    Gruß Frank

  • Ich komme einfach nicht weiter....
    Ich hab mal diese function (GetConsoleOutput) genommen: Link

    Der liefert aber nur folgendes, wenn ich die errors variable ausgebe:

    Code
    avis [info]: 704x480 @ 23.98 fps (672 frames)x264 [info]: using cpu capabilities: MMX MMXEXT SSE SSE2 x264 [info]: slice I:44    Avg QP:18.16  size: 35843  PSNR Mean Y:50.05 U:54.49 V:54.48 Avg:50.88 Global:49.27x264 [info]: slice P:628   Avg QP:21.36  size:  3624  PSNR Mean Y:47.93 U:51.91 V:51.90 Avg:48.82 Global:46.88x264 [info]: mb I  I16..4: 34.8%  0.0% 65.2%x264 [info]: mb P  I16..4:  6.2%  0.0%  3.7%  P16..4: 21.8%  7.7%  2.2%  0.0%  0.0%    skip:58.5%x264 [info]: SSIM Mean Y:0.9929485x264 [info]: PSNR Mean Y:48.071 U:52.082 V:52.067 Avg:48.957 Global:47.000 kb/s:1099.73
    Code
    a  := 'x264 --crf 22 --output video.264 "a.avs"';
      output:=TStringList.Create;
      try
        errors:=TStringList.Create;
        if GetConsoleOutput(a, output, errors) then  // Output liefert nix
          Memo1.Lines.AddStrings(errors);
      finally
        output.free;
        errors.free;
      end;


    Außerdem hängt sich die Anwendung auf und reagiert erst nach dem encodeende

    Man kann das bestimmt auch mit DosCommand hinbekommen, aber ich weiß nciht wie. DosCommand Link

  • Code
    a  := 'x264 --crf 22 --output video.264 "a.avs"';
      output:=TStringList.Create;
      try
        errors:=TStringList.Create;
        if GetConsoleOutput(a, output, errors) then  // Output liefert nix
          Memo1.Lines.AddStrings(errors);
      finally
        output.free;
        errors.free;
      end;


    Außerdem hängt sich die Anwendung auf und reagiert erst nach dem encodeende


    Da es nach dem Encoden wieder reagiert, hat es sich nicht aufgehängt! Das es bis dahin nicht reagiert ist logisch, da Du eine TStringList benutzt. Du musst entweder einen Buffer oder einen TFileStream verwenden. In der Delphipraxis gibt es zu Pipes etliche Beispiele. Und auch ich habe Dir oben zwei Programme (Consolenaufruf 1x als Klasse, 1x als Ansi- und 1x als Unicodefunction) genannt bei denen Du Dich bedienen könntest. Aus diesen stammt auch die Auswerteroutine.

    Meine Routinen basieren auf dem Source von Sprint aus http://www.softgames.de/forum/viewtopic.php?t=24225.

    Gruß Frank

  • Dann verwendet x264 vielleicht doch "direkte" Bildschirmfunktionen zum Updaten der Statuszeile. Das ist dann nicht abzufangen, außer ebenso direkt, indem man den Textbereich des "Grafikkartenspeichers" (den virtuellen freilich) auslesen würde. Ich glaube, das war unter Delphi eines der Seg####-Konstanten als Selektor. Aber gut möglich, dass das alles andere als einfach ist.
    __

    Oder Frank hat recht.

  • Was ich aber nicht verstehe ist, dass über ne Batch datei mit zusätlichem 2>log.txt das ganze so aussieht:

    Fr_An
    Aber alle funktionen oder Prozeduren die ich bisher gefunden habe, (ähnl. wie z.B. RunConsoleApp und Functions die mit Buffer oder einen TFileStream gearbeitet haben, waren auch dabei ) funktionieren im Grunde ja ganz gut ... Nur wie schon gesagt ich bekomme die ganzen Infos erst nach dem Encode :/
    Das ist eigentlich das einzige Problem was ich habe.

  • Das kann ich irgendwie nicht nachvollziehen. In den Routinen, die ich getestet habe, kommen die Ausgaben genauso an, wie auf der Konsole. Unterschied ist nur, dass manche die Ausgabe immer eine Zeile zurücksetzen. Sieht dann so aus, als würde immer in die selbe Zeile geschrieben und im TMemo oder TRichEdit hat man stattdessen viele Zeilen.

    In der Delphipraxis gab es ein Pipesbeispiel, bei dem die Konsole in ein Formular geholt wurde. Das hat nur einen Fehler beim eingestellten CHARSET. Da Du hier fragst, nehme ich mal, das Du dort nicht registriert bist. Deshalb hier das Archiv (Habe es gerade wiedergefunden).

  • Ich habe grade einen Fehler bei meinen tests gefunden, ich habe in Delphi den x264 immer ohne --progress gestartet :wall:
    Fr_An das sieht gut aus mit dem Programm, die Ausgabe unterscheidet sich zwar etwas vom windows cmd, aber das ist ja nicht schlim :) (Da werden alle Zeilen hintereinander ausgegeben, beim Windows cmd aktualiesiert sich die Zeile immer selbst.)


    Dann habe auch mal xvid_encraw getestet, da werden dann die Progress Infos zwar angezeigt aber auch nur ganz am Ende...

    edit:
    Mit RunConsoleApp wird jetzt auch die Memo1 gefüllt. *freu*
    Jetzt müsste das nur noch mit xvid_encraw klappen ^^

  • Dann habe auch mal xvid_encraw getestet, da werden dann die Progress Infos zwar angezeigt aber auch nur ganz am Ende...


    Zur Not kann man bei einer NTFS Partition auch die zu erwartende Dateigröße schätzen und fortlaufend mit der tatsächlichen vergleichen.

    Gruß Frank

  • Ich denke so mache ich das dann auch...
    Dateigröße schätzen und berechnen + ExitCode des Programms, hört sich gut an :)
    Und ich habe mal testweise xvid_encraw auch mit 2>log.txt ausprobiert, hier wird die Audgabe selbst vom CMD, erst am ende ausgegeben. Tja kann man wohl nix machen.

  • Kann leider kein C#

    Aber ich habs doch noch geschafft etwas brauchbares bei Xvid_encraw auszulesen. Komischerweise muss ich hier ohne den Parameter "-progress" Ausführen :ja:, dann kann ich über den STDOUT Stream auslesen.
    So sieht das dann aus:

    Das Video hat 672 Frames, was sollen dann die -1 am ende?

Jetzt mitmachen!

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