![]() |
selbstgebastelter webcam stream
Hallo,
ich programmiere gerade einen ferngesteuerten webcam client mit Delphi 7 Enterprise. Dazu nutze ich Directx für die Webcam und IdTCPClient und Server für die Verbindung. das ding ist eine dreieckstruktur. ich habe ein client-server-system und dazu einen webserver. der server sendet die configuration an den webserver. der client liest die config vom webserver und arbeitet dem entsprechend alles ab. und sendet zumbeispiel den webcam stream an den server. den webserver schalte ich zwischen aufgrund der hohen erreichbarkeit. so kann ich indirekt den client abschalten etc. ohne dass eine direkte verbindung besteht. die webcam greife ich über directx ab. siehe ![]() per timer grabbe ich einzelne frames und übertrage die per indy an den server. hier die prozedur des clients zum senden.
Delphi-Quellcode:
procedure TForm1.sendStream(pic:TBitmap);
var MStream:TMemoryStream; begin MStream:=TMemoryStream.Create; try pic.SaveToStream(MStream); MStream.Position:=0; try IdTCPClient1.Socket.Write(MStream,0,true); except end; finally MStream.Free; end; end; das gebe ich dann einfach beim server aus. Es funktioniert alles wunderbar. Mein Problem: ich will natürlich keine Bitmaps versenden, aufgrund der dateigröße. deshalb habe ich bereits jpg und png genutzt. das funktioniert auch. allerdings ist dementsprechend die cpu auslastung beim client dauerhaft bei über 15% und springt auch mal auf 40%, (bei Bitmap logischerweise 0-1%) ich suche deshalb eine praktikable kompression zum übertragen der frames. Hoffe da hat jemand was parat :roll: |
Re: selbstgebastelter webcam stream
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
Delphi-Quellcode:
lg. Astatuses ZLibEx; procedure CompressBitmap_Slow(bmp: TBitmap; var Data: string); var ms : TMemoryStream; buf : pointer; size : integer; begin ms := TMemoryStream.Create; bmp.SaveToStream(ms); ZCompress(ms.Memory, ms.Size, buf, size); SetLength(Data, size); Move(buf^, Data[1], size); FreeMem(buf); ms.Free; end; procedure CompressBitmap(bmp: TBitmap; var Data: string); var cs: TZCompressionStream; ms: TMemoryStream; begin ms := TMemoryStream.Create; cs := TZCompressionStream.Create(ms,zcDefault); // clDefault ist schneller als clMax bmp.SaveToStream(cs); cs.Free; SetLength(Data, ms.Size); Move(ms.Memory^, Data[1], ms.Size); ms.Free; end; procedure UnCompressBitmap(const Data: string; bmp: TBitmap); var ms : TMemoryStream; buf : pointer; size : integer; outsize:integer; begin try size:=0; outsize:=Length(Data) * 3; ZDecompress(@Data[1], Length(Data), buf,outsize, size); except on E: Exception do begin E.Message := Format('Error Decompressing Buffer (Len = %d):'#13#10'%s', [Length(Data), e.Message]); raise; end; end; ms := TMemoryStream.Create; ms.Write(buf^, outSize); FreeMem(buf); ms.Position := 0; Assert(bmp <> nil); bmp.LoadFromStream(ms); ms.Free; end; |
Re: selbstgebastelter webcam stream
hab mir deinen code angeschaut, versteh ihn aber nicht ganz.
wozu ist der parameter Data da ? kannste den quelltext bitte en bischen erläutern ? Edit: ich habs jetz so verstanden: die komprimierte bmp liegt im ms und wird dann in data geschrieben. da kann ich ja gleich den ms per indy verschicken oder nicht ? |
Re: selbstgebastelter webcam stream
So ich habs ma probiert umzusetzen:
hier der client:
Delphi-Quellcode:
procedure TForm1.sendStream(pic:TBitmap);
var MStream:TMemoryStream; data:string; begin MStream:=TMemoryStream.Create; CompressBitmap(pic,data); try MStream.WriteBuffer(data,Length(Data)); MStream.Position:=0; try IdTCPClient1.Socket.Write(MStream,0,true); except end; finally MStream.Free; end; end; hier der server:
Delphi-Quellcode:
procedure TForm2.IdTCPServer1Execute(AContext: TIdContext);
var data:string; FStream:TMemoryStream; bmp:TBitmap; begin FStream:=TMemoryStream.Create; try AContext.Connection.Socket.ReadStream(FStream); FStream.Position:=0; finally try FStream.Read(data,1000000); finally //bmp.LoadFromStream(FStream); FStream.Free; end; end; UnCompressBitmap(data,bmp); end; sooo der client schickt anscheinend was, zumindest ist data gefüllt beim server kommt Connection closed Gracefully. |
Re: selbstgebastelter webcam stream
Zitat:
Delphi-Quellcode:
ZCompress(ms.Memory, ms.Size, buf, size); send(ASocket, buf^, size) Da die komprimierten Daten in buf liegen. lg. Astat |
Re: selbstgebastelter webcam stream
ähm ich arbeite mit CompressBitmap, nicht mit CompressBitmap_slow ;)
|
Re: selbstgebastelter webcam stream
Hallo!
Da existiert noch eine andere Möglichkeit, allerdings ist mein WebCam Code noch nicht 100%ig darauf vorbereitet: Unter Umständen sind Deine Bilder von der Kamera eh schon komprimiert: YUY2, MJPG etc. Wenn Du im aktuellen Beispielcode der Unit VFrames.pas nachsiehst, findest Du dort die Routine, welche Dir die Bitmaps liefert: TVideoImage.GetBitmap(BMP: TBitmap). Diese Routine wiederum ruft UnpackFrame(..) auf. Das heißt, falls Deine Kamera beispielsweise MJPG Daten liefert (was unterm Strich schon fertige JPG Bilder sind), dann packt diese Routine das Ding aus in ein Bitmap, und Du machst es dann wieder klein, um es zu verschicken. Es könnte sich also lohnen, die Originaldaten zu holen (Also Pointer fImagePtr[fImagePtrIndex], welcher auf fImagePtrSize[fImagePtrIndex] Bytes zeigt), diese zu verschicken, und das Auspacken auf Empfänger-Seite zu erledigen. Da mußt Du allerdings noch ein bissl was einbauen ;) Allerding: Das hilft natürlich nur, wenn Deine Kamera schon eine solche Datenkompression anbietet. Ist es von vorneherein entpackt, dann hilft mein Vorschlag hier nicht weiter... Gruß Michael |
Re: selbstgebastelter webcam stream
du hast recht, ich mach das so :D
ich gehe über getBitmap(); allerdings habe ich mit dem hintergrund noch nicht beschäftigt ^^ muss mir dat erstma anschaun oder du hast noch paar anhaltspunkte |
Re: selbstgebastelter webcam stream
Zitat:
Delphi-Quellcode:
lg. Astatprocedure TForm1.sendStream(pic: TBitmap); var MStream:TMemoryStream; pOutBuf : pointer; cbOutSize:integer; begin pOutBuf := nil; cbOutSize := 0; MStream := TMemoryStream.Create; try pic.SaveToStream(MStream); ZCompress(MStream.memory, MStream.size, pOutBuf, cbOutSize, zcMax); finally MStream.Free; end; if (pOutBuf <> nil) and (cbOutSize > 0) then begin IdTCPClient1.Socket.Write(pOutBuf, cbOutSize, 0); FreeMem(pOutBuf); end else raise exception.Create('u should never see this.'); end; |
Re: selbstgebastelter webcam stream
ich schaue mir beide ansätze an, da erster flexibler ist.
ich bin gespannt wie nacher die unterschiede bei cpu last und speicherverbrauch sind. aber schreibt ruhig mehr :D |
Re: selbstgebastelter webcam stream
Ich möchte noch etwas kurz einwerfen:
Es ist nicht intelligent Webcam Livebilder über TCP (wegen Handshake, FlowControl, ..) zu übertragen. Besser geeignet ist in diesem Fall UDP. |
Re: selbstgebastelter webcam stream
Zitat:
1. UDP verwenden, ist bedeutend schneller. EDIT: zu spät! :cry: 2. Nur die Pixel übertragen, die sich geändert haben (Different Screening) 3. Andere Kompression verwenden, wenn Bitmap Kompression notwendig, das wesentlich performantere paszlib anstatt ZLib*.obj Files verwenden. lg. Astat |
Re: selbstgebastelter webcam stream
da
Zitat:
|
Re: selbstgebastelter webcam stream
ich hab mir grad ma ne to do list geschrieben :D
|
Re: selbstgebastelter webcam stream
Nu, vielleicht aktiviert Du ja alle Methoden!
Zu den Web-Cam Kompressionen: In dem Dialog, in dem Du die Größe deiner Videos auswählen kannst, bietet Dir der Treiber in der Regel noch unterschiedliche Kompressionen: RGB 24 beispielsweise ist der unkomprimierte Datenstrom, 3 Bytes pro Pixel, das wären dann bei 640x480 Pixel großen Bilder schon 921600 Bytes. Andere wären YUY2 (2 Bytes pro Pixel, 33% Ersparnis), MJPEG (Jedes Bild als JPG), I420 (eineinhalb Bytes pro Pixel, 50% Ersparnis). Die so komprimierten Bilder kann man mit DirectX zu normalen Bitmaps auspacken. Das war mir aber etwas zu kompliziert, deshalb habe ich für einige Kompressionen eigene Entpacker in den Code eingebaut (sind natürlich nicht so performant wie die DirectX Dinger). Wenn man ein Bild mit GetBitmap() abholt, entpacke ich den Datenstrom (UnpackFrame). Mein Code sollte YUY2 (=YUYV, YUNV), MJPG, I420 (=YV12, IYUV) unterstützen. Falls also Deine Webcam einige der Kompressionsformate beherrscht, könntest Du neben GetBitmap() ja noch eine andere Funktion basteln ala GetFrameData(), welche Dir einen Zeiger auf die Originaldaten (samt deren Größe und den FourCC code) zurückliefert. Maximal simpel so:
Delphi-Quellcode:
Die kopierst du dann gleich weg und schickst sie an den anderen Rechner (oder zippst sie vorher, solange es kein MJPEG war, weil da zippt sich nicht mehr viel).
procedure TVideoImage.GetFrameData(VAR FrameData: pointer; VAR FrameDataSize: integer; VAR FourCC : cardinal);
begin FrameData := fImagePtr[fImagePtrIndex]; FrameDataSize := fImagePtrSize[fImagePtrIndex]; FourCC := fFourCC; end; Auf dem Rechner, der die Daten empfängt, baust Du dann eine angepaßte UnpackFrame(..) Routine (siehe VFrames.pas) ein, um an Dein Bitmap zu kommen. Dieser angepaßten Routine müssen halt der FourCC code (der gibt an, welche Kompression verwendet wurde) und das Zielbitmap mit übergeben werden (momentan verwendet die ja irgendwelche Object-internen Variablen)... Gruß Michael |
Re: selbstgebastelter webcam stream
jop
ich hab mir das ma angeschaut. ich hol mir einfach die daten vom pointer in den stream und verschicke die. nebenbei muss ich dem server denn sagen welche kompression etc... und die dekompressionsfunktionen sind ja alle inner VSamples.pas vorhanden. die kann ich ja dem server einfach hinzufügen. die manuelle kompression ist trotzdem interessant, da ich ne funktion habe zur darstellung des desktops |
Re: selbstgebastelter webcam stream
sooo da bin ich mal wieder
folgendes hat sich getan: ich hol mir jetz das komprimierte und bild und verschicke es per UDP vom Client an den Server. Der server hat die nötige prozedur zur dekomprimierung der daten. hier mal quelltext: Die Client Methoden: Holen der Daten vom VideoImage
Delphi-Quellcode:
procedure TVideoImage.GetFrameData(VAR FrameData: pointer; VAR FrameDataSize: integer; VAR FourCC : cardinal; VAR Width,Height:integer);
begin FrameData := fImagePtr[fImagePtrIndex]; FrameDataSize := fImagePtrSize[fImagePtrIndex]; FourCC := fFourCC; //codec Width:=fWidth; Height:=fHeight; end; Verschicken der Daten
Delphi-Quellcode:
procedure TForm1.sendStream;
var MStream:TMemoryStream; Data:string; FrPointer:Pointer; FrSize,fWidth,fHeight,bSize:integer; Codec:Cardinal; begin fVideoImage.GetFrameData(FrPointer,FrSize,Codec,fWidth,fHeight); FrSize:=FrSize+3; setLength(Data,8192); //#0#13#0 try Move(FrPointer^,Data[1],8192); // Data:=IntToStr(8192); WebcamStream.Client.Send(Data); except end; while FrSize>8192 do begin try Data:=''; setLength(Data,8192); Move(FrPointer^,Data[1],8192); WebcamStream.Client.Send(Data); except end; FrSize:=FrSize-8192; end; Data:=''; setLength(Data,FrSize); try Move(FrPointer^,Data[1],FrSize); Data:=Data+#0#13#0; WebcamStream.Client.Send(Data); except end; end; Server methoden: Empfangen der Daten
Delphi-Quellcode:
procedure TForm1.IdUDPServer1UDPRead(AThread: TIdUDPListenerThread;
AData: TIdBytes; ABinding: TIdSocketHandle); var i:integer; buffer,data:string; MStream:TMemoryStream; bmp:TBitmap; begin //MStream:=TMemoryStream.Create; buffer:=AThread.Server.ReceiveString(-1); data:=buffer; while(Pos(#0#13#0,buffer)<1) do begin buffer:=AThread.Server.ReceiveString(-1); data:=data+buffer; end; //buffer //MStream.Read(buffer,Length(buffer)); Decoder.DecodeFrame(data); //Form2.Image1.Picture.Bitmap.LoadFromStream(MStream); //if Pos(#0#13#0,buffer)>0 then Showmessage('okkk'); //MStream.Free; end; dekomprimieren der daten
Delphi-Quellcode:
procedure TDecoder.DecodeFrame(Bitmap:TBitmap;Data:String);
var fp:^string; begin fp:=@Data; YUY2_to_RGB(fp,Data); end;
Delphi-Quellcode:
procedure TDecoder.YUY2_to_RGB(pData: pointer;data:string);
// [url]http://msdn.microsoft.com/en-us/library/ms893078.aspx[/url] // [url]http://en.wikipedia.org/wiki/YCbCr[/url] type TFour = ARRAY[0..3] OF byte; VAR L, X, Y : integer; ps : pbyte; pf : ^TFour; FrPointer:Pointer; FrSize,fWidth,fHeight,i:integer; Codec:Cardinal; bmp:TBitmap; begin bmp:=TBitmap.Create; bmp.PixelFormat:=pf24Bit; pf:=pData; //fVideoImage.GetFrameData(FrPointer,FrsIze,Codec,fWidth,fHeight); fWidth:=640; fHeight:=480; bmp.Width:=fWidth; bmp.Height:=fHeight; Showmessage(IntToStr(Length(Data))); PrepareTables; FOR Y := 0 TO bmp.Height-1 DO BEGIN ps := bmp.ScanLine[Y]; FOR X := 0 TO (bmp.Width div 2)-1 DO begin L := ValueY_298[pf^[0]]; // HIER KOMMT DER FEHLER ps^ := ValueClip[(L + ValueU_516[pf^[1]] ) div 256]; Inc(ps); ps^ := ValueClip[(L + ValueU_100[pf^[1]] + ValueV_208[pf^[3]]) div 256]; Inc(ps); ps^ := ValueClip[(L + ValueV_409[pf^[3]]) div 256]; Inc(ps); L := ValueY_298[pf^[2]]; ps^ := ValueClip[(L + ValueU_516[pf^[1]] ) div 256]; Inc(ps); ps^ := ValueClip[(L + ValueU_100[pf^[1]] + ValueV_208[pf^[3]]) div 256]; Inc(ps); ps^ := ValueClip[(L + ValueV_409[pf^[3]]) div 256]; Inc(ps); Inc(pf); end; END; Form2.Image1.Picture.Assign(bmp); bmp.Free; end; so ich hänge jetzt an der letzten funktion. Diese berechnet das bild zurück Die Value Arrays enthalten umrechnungszahlen für die einzelnen pixel. der pointer pf soll auf die Data zeigen. Das Problem ist jetzt, dass ich bei der letzten funktion ne access violation kriege, siehe Kommentar im quelltext. Die kommt allerdings erst nach etwa dem 20. durchlauf der For schleife mit Y. Raised exception class C000005 hat jemand ne Idee ? |
Re: selbstgebastelter webcam stream
Hallo!
Beim Zugriff auf ValueY_298 kanns ja kaum sein, denn das ist ein array von 0 bis 255. Ergo kein Rangecheck. Sieht also eher so aus, als ob es das byte "pf^[0]" nicht gibt. (access violation). Dazu hätt' ich ein paar Kandidaten: 1. Das Übergeben der Daten als string. Schlägt da nicht irgendwo vielleicht doch eine raffinierte Routine durch, die eine 0 in den Bilddaten findet und dann dort einfach den string abschneidet? 2. Die Datenübertragung läuft bis zu einem #0#13#0. Es ist natürlich schon möglich, daß dieses #0#13#0 schon in den Bilddaten selbst vorkommt! Dann würdest Du mit einem unvollständigen Bild in die Auspack-Routine gehen. 3. Hat das Übergebene Bild überhaupt 640*480 Pixel? Nicht, daß das viel kleiner ist! fWidth und fHeight werden ja explizit auf diese festen Werte gesetzt in YUY2_to_RGB. Klappt die Übergabe für RGB24 kodierte Bilder? Da hätten alle Frames wenigstens dieselbe Größe: Width*Height*3 und Du könntest in der Routine prüfen, ob der übergebene Speicher tatsächlich so groß ist. Obwohl, YUY2 Bilder haben auch immer eine feste Größe, da könnte man also auch leicht prüfen, ob die Höhe und Breite zur Menge der übergebenen Bytes paßt. Gruß Michael |
Re: selbstgebastelter webcam stream
also
ich hab natürlich bevor ich die dekomprimierung in den server ausgelagert habe, die dekomprimierung direkt beim client getestet und hat wunderbar gefunzt. das mit der string terminierung ist schon ne idee. das komische ist nur: mein string ist etwa 3mal so groß wie die erwartete datenmenge und die länge von Data variiert. die Höhe und Breite sind okay, da ich zur zeit nur meine cam nutze und die ist 100% auf 640*480 Edit: ich sehe gerade der Pointer ist vom typ:
Delphi-Quellcode:
und versuche diesem pointer jetzt einen string zu zuweisen
TFour = ARRAY[0..3] OF byte;
weiß aber nicht genau weiter ^^ |
Re: selbstgebastelter webcam stream
Nach ewigem rumprobieren bin ich immer noch nicht weiter.
Ich bekomme alle Daten wunderbar in meinen string eingelesen beim server. Die Stringlänge ist auch aufs Byte genau richtig. Ich weiß jetzt bloß nicht wie den string ins richtige format kriege damit der pointer ordentlich drauf zugreifen kann. bzw eine möglichkeit diesen pointer zu umgehen. Hat jemand nen Plan, bin mit Pointern nicht gerade der geschickteste Edit: irgendwas haut nicht hin, wenn ich während des aufrufs von UDPServerRead ein Showmessage mache, ändert sich komischer weise willkürlich die fenstergröße der dialogbox. mal ist sie normal groß, manchmal breiter als der bildschirm... :gruebel: :wall: |
Re: selbstgebastelter webcam stream
Sooo
ich habs jetz hinbekommen. allerdings schnippelt er mir das bild aufm server falsch zusammen. bei jedem bild sieht'S anders aus. manchmal ist es richtig. manchmal malt er was nach links gehört in die mitte, sodass sich das bild verschiebt und der überstehende teil steht dann wieder vorne |
Re: selbstgebastelter webcam stream
Zitat:
Deutet alles auf ein nicht vorhandenes Protokoll hin. UDP stellt einen verbindungslosen, nicht-zuverlässigen Übertragungsdienst bereit. Das bedeutet, es gibt keine Garantie, dass ein einmal gesendetes Paket auch ankommt, dass Pakete in der gleichen Reihenfolge ankommen, in der sie gesendet wurden, oder dass ein Paket nur einmal beim Empfänger eintrifft. Eine Anwendung, die UDP nutzt, muss daher gegenüber verlorengegangenen und unsortierten Paketen unempfindlich sein oder selbst entsprechende Korrekturmaßnahmen beinhalten. Ich würde, bevor du auf die Fehlersuche nach den Ursachen gehst, vorerst mal auf TCP umstellen. Erst wenn du da ein brauchbares TCP Protokoll entwickelt hast, solltest du dich auf den steinigen Weg zu UDP begeben. lg. Astat |
Re: selbstgebastelter webcam stream
Hey Habs jetz hinbekommen :D
Client sendet:
Delphi-Quellcode:
procedure TWebcamStream.Send(Data:string);
var FrSize:integer; begin Data:=Data+#255#1#2#3#4#5#6; //terminierung FrSize:=Length(Data); while FrSize>8192 do begin try Client.Send(Copy(Data,1,8192)); Delete(Data,1,8192); except end; FrSize:=FrSize-8192; end; try Client.Send(Data); except end; end; der server empfängt:
Delphi-Quellcode:
procedure TForm1.IdUDPServer1UDPRead(AThread: TIdUDPListenerThread;
AData: TIdBytes; ABinding: TIdSocketHandle); var i,size,counter:integer; buffer1,buffer2,data:string; MStream:TMemoryStream; bmp:TBitmap; begin buffer1:=BytesToString(AData); while Pos(#255#1#2#3#4#5#6,buffer2)<1 do begin buffer2:=AThread.Server.ReceiveString(); buffer1:=buffer1+buffer2; end; data:=Copy(buffer1,1,Pos(#255#1#2#3#4#5#6,buffer1)-1); Decoder.DecodeFrame(data); end; funzt jetz wunderbar :D hab auch das problem mit der dekodierung gelöst:
Delphi-Quellcode:
procedure TDecoder.YUY2_to_RGB(data:string);
// [url]http://msdn.microsoft.com/en-us/library/ms893078.aspx[/url] // [url]http://en.wikipedia.org/wiki/YCbCr[/url] type TFour = ARRAY[0..3] OF byte; VAR L, X, Y : integer; ps : pbyte; arr :array of TFour; pf : ^TFour; FrPointer:Pointer; FrSize,fWidth,fHeight,i:integer; Codec:Cardinal; bmp:TBitmap; begin i:=0; bmp:=TBitmap.Create; bmp.PixelFormat:=pf24Bit; //pf:=pData; //fVideoImage.GetFrameData(FrPointer,FrsIze,Codec,fWidth,fHeight); fWidth:=640; fHeight:=480; bmp.Width:=fWidth; bmp.Height:=fHeight; //Showmessage(IntToStr(Length(Data))+'----'+IntToStr(round(640*480))); PrepareTables; FOR Y := 0 TO bmp.Height-1 DO BEGIN ps := bmp.ScanLine[Y]; FOR X := 0 TO (bmp.Width div 2)-1 DO begin L := ValueY_298[Byte(data[i*4+1])]; ps^ := ValueClip[(L + ValueU_516[Byte(data[i*4+2])] ) div 256]; Inc(ps); ps^ := ValueClip[(L + ValueU_100[Byte(data[i*4+2])] + ValueV_208[Byte(data[i*4+4])]) div 256]; Inc(ps); ps^ := ValueClip[(L + ValueV_409[Byte(data[i*4+4])]) div 256]; Inc(ps); L := ValueY_298[Byte(data[i*4+3])]; ps^ := ValueClip[(L + ValueU_516[Byte(data[i*4+2])] ) div 256]; Inc(ps); ps^ := ValueClip[(L + ValueU_100[Byte(data[i*4+2])] + ValueV_208[Byte(data[i*4+4])]) div 256]; Inc(ps); ps^ := ValueClip[(L + ValueV_409[Byte(data[i*4+4])]) div 256]; Inc(ps); //Inc(pf); Inc(i); end; END; Form2.Image1.Picture.Assign(bmp); bmp.Free; end; 4 bytes gehören immer zu einem pixel ich lasse einfach i hochzählen und suche mir damit das richtige element des strings habs jetz allerdings ein neues komisches problem :D ich hab jetz die prozedur zum senden in meine klasse eingebettet, und darin läuft ein Timer der halt das grabben und sender der frames übernimmt. das problem ich kriege den timer nicht aktiviert. ich kann die prozedur für das OnTimer Event manuel aufrufen aus dem hauptprogramm, aber der Timer ruft sie nicht selber auf;
Delphi-Quellcode:
constructor Create;
begin RunTimer:=TTimer.Create(nil); RunTimer.Name:='RunTimer'; RunTimer.OnTimer:=Run; RunTimer.Interval:=10; RunTimer.Enabled:=true; end; procedure TWebcamStream.Run(Sender:TObject) begin bla end; Edit so nebenbei: CPU Auslastung liegt bei 8%, speicherverbrauch 20mb Edit2: wenn nötig schreib ich mir ma nen ordentliches protokoll, aber so reichts erstma fürn Localhorst |
Alle Zeitangaben in WEZ +1. Es ist jetzt 17:29 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz