Sirber
17th November 2010, 02:47
In a single threaded GUI I use this function to run a cmdline app:
function Tfmain.CliRun(sCmd: string): integer;
var
aOutput: TStringList;
iCpt: integer;
begin
aOutput := TStringList.Create();
// http://wiki.lazarus.freepascal.org/Executing_External_Programs
// http://community.freepascal.org:10000/docs-html/fcl/process/tprocess.execute.html
oCli.CommandLine := sCmd;
oCli.Priority := ppIdle;
oCli.CurrentDirectory := sTemp;
oCli.Options := [poUsePipes, poStderrToOutPut];
{$IFDEF WIN32}oCli.Options := oCli.Options + [poNoConsole];{$ENDIF}
//oCli.ShowWindow := swoHide;
oCli.Execute();
oCliLogs.Clear();
oCliLogs.Add(sCmd);
oCliLogs.Add('');
while (oCli.Active = True) do
begin
// Do stuff!
Application.ProcessMessages();
Sleep(25);
Application.ProcessMessages();
//Look for logs
aOutput.LoadFromStream(oCli.Output);
if (aOutput.Count > 0) then
begin
for iCpt := 0 to aOutput.Count - 1 do
begin
Application.ProcessMessages();
oCliLogs.Add(aOutput.Strings[iCpt]);
end;
Application.ProcessMessages();
txtLog.Text := aOutput.Strings[aOutput.Count - 1];
end;
Application.ProcessMessages();
end;
aOutput.Free;
Result := oCli.ExitStatus;
end;
... and everything works well. I can fetch the text output from ffmpeg and ffmpeg encodes the files proprely.
But when I try to run ffmpeg via a thread, if I use "poUsePipes" ffmpeg hangs and does nothing (0% CPU, no text output).
procedure TMyThread.cliRun(sCmd:string);
var
newStatus: string;
aOutput: TStringList;
iCpt: integer;
begin
fStatusText := 'Warning: real-time logs unavalible in multi-threading mode.. yet.';
Synchronize(@Showstatus);
aOutput := TStringList.Create();
fmain.oCliLogs.Clear();
fmain.oCliLogs.Add(sCmd);
fmain.oCliLogs.Add('');
oCli := TProcess.Create(nil);
oCli.CommandLine := sCmd;
oCli.Priority := ppIdle;
oCli.CurrentDirectory := sTemp;
{fails}
oCli.Options := [poUsePipes, poStderrToOutPut];
{$IFDEF WIN32}oCli.Options := oCli.Options + [poNoConsole];{$ENDIF}
{works}
//oCli.Options := [poWaitOnExit];
//oCli.ShowWindow := swoHide;
oCli.Execute();
repeat
{ Logs }
//aOutput.LoadFromStream(oCli.Output);
{
if (aOutput.Count > 0) then
begin
for iCpt := 0 to aOutput.Count - 1 do
begin
oCliLogs.Add(aOutput.Strings[iCpt]);
end;
newStatus := aOutput.Strings[aOutput.Count - 1];
end;
}
//newStatus := 'encoding';
{ Thread management }
if (fStatusText <> newStatus) then
begin
fStatusText := newStatus;
Synchronize(@Showstatus);
end;
if (Terminated) then
oCli.Terminate(-1);
until not oCli.Running;
iExitCode := oCli.ExitStatus;
fmain.oCliLogs.Add('');
fmain.oCliLogs.Add('Ended with ExitCode: ' + IntToStr(iExitCode));
aOutput.Free;
oCli.Free;
end;
I'm using the latest build from: http://ffmpeg.arrozcru.org/autobuilds/
I don't get it... am I doing something wrong? :(
function Tfmain.CliRun(sCmd: string): integer;
var
aOutput: TStringList;
iCpt: integer;
begin
aOutput := TStringList.Create();
// http://wiki.lazarus.freepascal.org/Executing_External_Programs
// http://community.freepascal.org:10000/docs-html/fcl/process/tprocess.execute.html
oCli.CommandLine := sCmd;
oCli.Priority := ppIdle;
oCli.CurrentDirectory := sTemp;
oCli.Options := [poUsePipes, poStderrToOutPut];
{$IFDEF WIN32}oCli.Options := oCli.Options + [poNoConsole];{$ENDIF}
//oCli.ShowWindow := swoHide;
oCli.Execute();
oCliLogs.Clear();
oCliLogs.Add(sCmd);
oCliLogs.Add('');
while (oCli.Active = True) do
begin
// Do stuff!
Application.ProcessMessages();
Sleep(25);
Application.ProcessMessages();
//Look for logs
aOutput.LoadFromStream(oCli.Output);
if (aOutput.Count > 0) then
begin
for iCpt := 0 to aOutput.Count - 1 do
begin
Application.ProcessMessages();
oCliLogs.Add(aOutput.Strings[iCpt]);
end;
Application.ProcessMessages();
txtLog.Text := aOutput.Strings[aOutput.Count - 1];
end;
Application.ProcessMessages();
end;
aOutput.Free;
Result := oCli.ExitStatus;
end;
... and everything works well. I can fetch the text output from ffmpeg and ffmpeg encodes the files proprely.
But when I try to run ffmpeg via a thread, if I use "poUsePipes" ffmpeg hangs and does nothing (0% CPU, no text output).
procedure TMyThread.cliRun(sCmd:string);
var
newStatus: string;
aOutput: TStringList;
iCpt: integer;
begin
fStatusText := 'Warning: real-time logs unavalible in multi-threading mode.. yet.';
Synchronize(@Showstatus);
aOutput := TStringList.Create();
fmain.oCliLogs.Clear();
fmain.oCliLogs.Add(sCmd);
fmain.oCliLogs.Add('');
oCli := TProcess.Create(nil);
oCli.CommandLine := sCmd;
oCli.Priority := ppIdle;
oCli.CurrentDirectory := sTemp;
{fails}
oCli.Options := [poUsePipes, poStderrToOutPut];
{$IFDEF WIN32}oCli.Options := oCli.Options + [poNoConsole];{$ENDIF}
{works}
//oCli.Options := [poWaitOnExit];
//oCli.ShowWindow := swoHide;
oCli.Execute();
repeat
{ Logs }
//aOutput.LoadFromStream(oCli.Output);
{
if (aOutput.Count > 0) then
begin
for iCpt := 0 to aOutput.Count - 1 do
begin
oCliLogs.Add(aOutput.Strings[iCpt]);
end;
newStatus := aOutput.Strings[aOutput.Count - 1];
end;
}
//newStatus := 'encoding';
{ Thread management }
if (fStatusText <> newStatus) then
begin
fStatusText := newStatus;
Synchronize(@Showstatus);
end;
if (Terminated) then
oCli.Terminate(-1);
until not oCli.Running;
iExitCode := oCli.ExitStatus;
fmain.oCliLogs.Add('');
fmain.oCliLogs.Add('Ended with ExitCode: ' + IntToStr(iExitCode));
aOutput.Free;
oCli.Free;
end;
I'm using the latest build from: http://ffmpeg.arrozcru.org/autobuilds/
I don't get it... am I doing something wrong? :(