Subversion Repositories alarming

Compare Revisions

Regard whitespace Rev 1 → Rev 2

/trunk/Delphi Client/MJPEGDecoderThread.pas
0,0 → 1,164
{
MJPEG Decoder Class
Copyright 2006, Steve Blinch
http://code.blitzaffe.com
 
This script is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.
 
This script is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details.
 
You should have received a copy of the GNU General Public License along
with this script; if not, write to the Free Software Foundation, Inc.,
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
}
 
unit MJPEGDecoderThread;
 
{$M+} // Added VTS 06.05.2019 to supress compiler warning
 
interface
 
uses Classes,IdTCPClient;
 
const
MSG_MJPEG_FRAME = 1;
MSG_MJPEG_ERROR = 2;
MSG_MJPEG_MESSAGE = 3;
 
ERROR_MJPEG_BADFRAME = 1;
ERROR_MJPEG_EXCEPT = 2;
ERROR_MJPEG_DISCONNECT = 3;
 
Type
TMJPEGDecoderMsg = class(TObject)
public
Msg: String;
end;
 
TMJPEGDecoderThread = class(TThread)
private
FClient: TIdTCPClient;
FActive: Boolean;
FNotifyWindow: THandle;
 
procedure Info(S: String);
function CheckConnected: Boolean;
public
constructor Create(TCPClient: TIdTCPClient; NotifyWindow: THandle);
procedure Execute; override;
published
property Active: Boolean read FActive;
end;
 
implementation
 
uses SysUtils,Windows,Messages;
 
constructor TMJPEGDecoderThread.Create(TCPClient: TIdTCPClient; NotifyWindow: THandle);
begin
FActive:=False;
FClient:=TCPClient;
FNotifyWindow:=NotifyWindow;
inherited Create(True);
FreeOnTerminate:=True;
end;
 
function TMJPEGDecoderThread.CheckConnected: Boolean;
begin
if not FClient.Connected then
begin
PostMessage(FNotifyWindow,WM_USER,MSG_MJPEG_ERROR,ERROR_MJPEG_DISCONNECT);
Terminate;
end;
Result:=FClient.Connected;
end;
 
procedure TMJPEGDecoderThread.Execute;
var
S: String;
CLength: Integer;
JPEG: TMemoryStream;
begin
FActive:=True;
try
try
 
CLength:=0;
Info('Decoder thread starting execution loop');
while (not Terminated) do
begin
if not CheckConnected then break;
 
// grab a header
Info('Waiting for data...');
try
S:=Trim(LowerCase(FClient.IOHandler.ReadLn));
except
if (not CheckConnected) then break;
PostMessage(FNotifyWindow,WM_USER,MSG_MJPEG_ERROR,ERROR_MJPEG_EXCEPT);
Terminate;
break;
end;
Info('Data: '+S);
 
if not CheckConnected then break;
 
// if it's a content-length line, record the content length
if (Copy(S,1,15)='content-length:') then
begin
Delete(S,1,15);
S:=Trim(S);
CLength:=StrToIntDef(S,0);
Info('Next frame content length: '+IntToStr(CLength));
end;
 
// if it's a blank line and we have a content-length, then we're good to receive the stream
if (Length(S)=0) and (CLength>0) then
begin
Info('Receiving frame');
JPEG:=TMemoryStream.Create;
JPEG.SetSize(CLength);
try
FClient.IOHandler.ReadStream(JPEG,CLength);
PostMessage(FNotifyWindow,WM_USER,MSG_MJPEG_FRAME,Integer(JPEG));
except
PostMessage(FNotifyWindow,WM_USER,MSG_MJPEG_ERROR,ERROR_MJPEG_BADFRAME);
Terminate;
break;
end;
Info('Frame received');
CLength:=0;
end;
 
end;
Info('Decoder thread execution loop complete');
except
on E: Exception do
begin
PostMessage(FNotifyWindow,WM_USER,MSG_MJPEG_ERROR,ERROR_MJPEG_EXCEPT);
end;
end;
finally
FActive:=False;
end;
 
end;
 
procedure TMJPEGDecoderThread.Info(S: String);
var Msg: TMJPEGDecoderMsg;
begin
exit;
Msg:=TMJPEGDecoderMsg.Create;
Msg.Msg:=S;
PostMessage(FNotifyWindow,WM_USER,MSG_MJPEG_MESSAGE,Integer(Msg));
end;
 
end.