Subversion Repositories alarming

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 daniel-mar 1
{
2
MJPEG Decoder Class
3
Copyright 2006, Steve Blinch
4
http://code.blitzaffe.com
5
 
6
This script is free software; you can redistribute it and/or modify it under the
7
terms of the GNU General Public License as published by the Free Software
8
Foundation; either version 2 of the License, or (at your option) any later
9
version.
10
 
11
This script is distributed in the hope that it will be useful, but WITHOUT ANY
12
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13
FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
14
details.
15
 
16
You should have received a copy of the GNU General Public License along
17
with this script; if not, write to the Free Software Foundation, Inc.,
18
59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
}
20
 
21
unit MJPEGDecoderThread;
22
 
23
{$M+} // Added VTS 06.05.2019 to supress compiler warning
24
 
25
interface
26
 
27
uses Classes,IdTCPClient;
28
 
29
const
30
  MSG_MJPEG_FRAME   = 1;
31
  MSG_MJPEG_ERROR   = 2;
32
  MSG_MJPEG_MESSAGE = 3;
33
 
34
  ERROR_MJPEG_BADFRAME    = 1;
35
  ERROR_MJPEG_EXCEPT      = 2;
36
  ERROR_MJPEG_DISCONNECT  = 3;
37
 
38
Type
39
  TMJPEGDecoderMsg = class(TObject)
40
      public
41
        Msg: String;
42
    end;
43
 
44
  TMJPEGDecoderThread = class(TThread)
45
    private
46
      FClient: TIdTCPClient;
47
      FActive: Boolean;
48
      FNotifyWindow: THandle;
49
 
50
      procedure Info(S: String);
51
      function CheckConnected: Boolean;
52
    public
53
      constructor Create(TCPClient: TIdTCPClient; NotifyWindow: THandle);
54
      procedure Execute; override;
55
    published
56
      property Active: Boolean read FActive;
57
    end;
58
 
59
implementation
60
 
61
uses SysUtils,Windows,Messages;
62
 
63
constructor TMJPEGDecoderThread.Create(TCPClient: TIdTCPClient; NotifyWindow: THandle);
64
begin
65
  FActive:=False;
66
  FClient:=TCPClient;
67
  FNotifyWindow:=NotifyWindow;
68
 
69
  inherited Create(True);
70
  FreeOnTerminate:=True;
71
end;
72
 
73
function TMJPEGDecoderThread.CheckConnected: Boolean;
74
begin
75
  if not FClient.Connected then
76
    begin
77
      PostMessage(FNotifyWindow,WM_USER,MSG_MJPEG_ERROR,ERROR_MJPEG_DISCONNECT);
78
      Terminate;
79
    end;
80
  Result:=FClient.Connected;
81
end;
82
 
83
procedure TMJPEGDecoderThread.Execute;
84
var
85
  S: String;
86
  CLength: Integer;
87
  JPEG: TMemoryStream;
88
begin
89
  FActive:=True;
90
  try
91
    try
92
 
93
      CLength:=0;
94
      Info('Decoder thread starting execution loop');
95
      while (not Terminated) do
96
        begin
97
          if not CheckConnected then break;
98
 
99
          // grab a header
100
          Info('Waiting for data...');
101
          try
102
            S:=Trim(LowerCase(FClient.IOHandler.ReadLn));
103
          except
104
            if (not CheckConnected) then break;
105
            PostMessage(FNotifyWindow,WM_USER,MSG_MJPEG_ERROR,ERROR_MJPEG_EXCEPT);
106
            Terminate;
107
            break;
108
          end;
109
          Info('Data: '+S);
110
 
111
          if not CheckConnected then break;
112
 
113
          // if it's a content-length line, record the content length
114
          if (Copy(S,1,15)='content-length:') then
115
            begin
116
              Delete(S,1,15);
117
              S:=Trim(S);
118
              CLength:=StrToIntDef(S,0);
119
              Info('Next frame content length: '+IntToStr(CLength));
120
            end;
121
 
122
          // if it's a blank line and we have a content-length, then we're good to receive the stream
123
          if (Length(S)=0) and (CLength>0) then
124
            begin
125
              Info('Receiving frame');
126
              JPEG:=TMemoryStream.Create;
127
              JPEG.SetSize(CLength);
128
              try
129
                FClient.IOHandler.ReadStream(JPEG,CLength);
130
                PostMessage(FNotifyWindow,WM_USER,MSG_MJPEG_FRAME,Integer(JPEG));
131
              except
132
                PostMessage(FNotifyWindow,WM_USER,MSG_MJPEG_ERROR,ERROR_MJPEG_BADFRAME);
133
                Terminate;
134
                break;
135
              end;
136
              Info('Frame received');
137
              CLength:=0;
138
            end;
139
 
140
        end;
141
      Info('Decoder thread execution loop complete');
142
    except
143
      on E: Exception do
144
        begin
145
          PostMessage(FNotifyWindow,WM_USER,MSG_MJPEG_ERROR,ERROR_MJPEG_EXCEPT);
146
        end;
147
    end;
148
  finally
149
    FActive:=False;
150
  end;
151
 
152
end;
153
 
154
procedure TMJPEGDecoderThread.Info(S: String);
155
var Msg: TMJPEGDecoderMsg;
156
begin
157
  exit;
158
  Msg:=TMJPEGDecoderMsg.Create;
159
  Msg.Msg:=S;
160
  PostMessage(FNotifyWindow,WM_USER,MSG_MJPEG_MESSAGE,Integer(Msg));
161
end;
162
 
163
end.
164