Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi selbstgebastelter webcam stream (https://www.delphipraxis.net/147307-selbstgebastelter-webcam-stream.html)

jokerfacehro 5. Feb 2010 12:31


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 http://www.delphipraxis.net/internal...webcam+directx



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:

Astat 5. Feb 2010 12:58

Re: selbstgebastelter webcam stream
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von jokerfacehro
Hoffe da hat jemand was parat

Hallo jokerfacehro, hatte dies mal in Verwendung. Errorbehandlung musst Du nachziehn, ist damals etwas dürftig ausgefallen.

Delphi-Quellcode:

uses
  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;
lg. Astat

jokerfacehro 5. Feb 2010 13:16

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 ?

jokerfacehro 5. Feb 2010 13:43

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.

Astat 5. Feb 2010 13:47

Re: selbstgebastelter webcam stream
 
Zitat:

Zitat von jokerfacehro
..da kann ich ja gleich den ms per indy verschicken oder nicht ?

Hallo jokerfacehro, natürlich, aber nicht dem ms, sondern

Delphi-Quellcode:
 
ZCompress(ms.Memory, ms.Size, buf, size);
send(ASocket, buf^, size)

Da die komprimierten Daten in buf liegen.

lg. Astat

jokerfacehro 5. Feb 2010 13:53

Re: selbstgebastelter webcam stream
 
ähm ich arbeite mit CompressBitmap, nicht mit CompressBitmap_slow ;)

grizzly 5. Feb 2010 14:00

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

jokerfacehro 5. Feb 2010 14:07

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

Astat 5. Feb 2010 14:10

Re: selbstgebastelter webcam stream
 
Zitat:

Zitat von jokerfacehro
ähm ich arbeite mit CompressBitmap, nicht mit CompressBitmap_slow ;)

Hallo jokerfacehro, da war ich wohl mit meinen Gedanken schneller als im Code stand, sorry, meinte dies in etwa so.

Delphi-Quellcode:

procedure 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;
lg. Astat

jokerfacehro 5. Feb 2010 14:15

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


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:26 Uhr.
Seite 1 von 3  1 23      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz