AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Multimedia Delphi selbstgebastelter webcam stream
Thema durchsuchen
Ansicht
Themen-Optionen

selbstgebastelter webcam stream

Ein Thema von jokerfacehro · begonnen am 5. Feb 2010 · letzter Beitrag vom 16. Feb 2010
Antwort Antwort
Seite 1 von 3  1 23      
Benutzerbild von jokerfacehro
jokerfacehro

Registriert seit: 13. Feb 2007
306 Beiträge
 
Delphi 7 Enterprise
 
#1

selbstgebastelter webcam stream

  Alt 5. Feb 2010, 12:31
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
"Never touch a running system administrator !"
  Mit Zitat antworten Zitat
Astat

Registriert seit: 2. Dez 2009
Ort: München
320 Beiträge
 
Lazarus
 
#2

Re: selbstgebastelter webcam stream

  Alt 5. Feb 2010, 12:58
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
Angehängte Dateien
Dateityp: rar zlib1.2.3_751.rar (36,1 KB, 33x aufgerufen)
Lanthan Astat
06810110811210410503210511511603209711003210010110 9032084097103
03211611111604403209711003210010110903210010510103 2108101116122
11610103209010110510810103206711110010103210511003 2068101108112
10410503210310111509910411410510109810111003211910 5114100046
  Mit Zitat antworten Zitat
Benutzerbild von jokerfacehro
jokerfacehro

Registriert seit: 13. Feb 2007
306 Beiträge
 
Delphi 7 Enterprise
 
#3

Re: selbstgebastelter webcam stream

  Alt 5. Feb 2010, 13:16
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 ?
"Never touch a running system administrator !"
  Mit Zitat antworten Zitat
Benutzerbild von jokerfacehro
jokerfacehro

Registriert seit: 13. Feb 2007
306 Beiträge
 
Delphi 7 Enterprise
 
#4

Re: selbstgebastelter webcam stream

  Alt 5. Feb 2010, 13:43
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.
"Never touch a running system administrator !"
  Mit Zitat antworten Zitat
Astat

Registriert seit: 2. Dez 2009
Ort: München
320 Beiträge
 
Lazarus
 
#5

Re: selbstgebastelter webcam stream

  Alt 5. Feb 2010, 13:47
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
Lanthan Astat
06810110811210410503210511511603209711003210010110 9032084097103
03211611111604403209711003210010110903210010510103 2108101116122
11610103209010110510810103206711110010103210511003 2068101108112
10410503210310111509910411410510109810111003211910 5114100046
  Mit Zitat antworten Zitat
Benutzerbild von jokerfacehro
jokerfacehro

Registriert seit: 13. Feb 2007
306 Beiträge
 
Delphi 7 Enterprise
 
#6

Re: selbstgebastelter webcam stream

  Alt 5. Feb 2010, 13:53
ähm ich arbeite mit CompressBitmap, nicht mit CompressBitmap_slow
"Never touch a running system administrator !"
  Mit Zitat antworten Zitat
grizzly

Registriert seit: 10. Dez 2004
150 Beiträge
 
Delphi XE4 Professional
 
#7

Re: selbstgebastelter webcam stream

  Alt 5. Feb 2010, 14:00
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
  Mit Zitat antworten Zitat
Benutzerbild von jokerfacehro
jokerfacehro

Registriert seit: 13. Feb 2007
306 Beiträge
 
Delphi 7 Enterprise
 
#8

Re: selbstgebastelter webcam stream

  Alt 5. Feb 2010, 14:07
du hast recht, ich mach das so

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
"Never touch a running system administrator !"
  Mit Zitat antworten Zitat
Astat

Registriert seit: 2. Dez 2009
Ort: München
320 Beiträge
 
Lazarus
 
#9

Re: selbstgebastelter webcam stream

  Alt 5. Feb 2010, 14:10
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
Lanthan Astat
06810110811210410503210511511603209711003210010110 9032084097103
03211611111604403209711003210010110903210010510103 2108101116122
11610103209010110510810103206711110010103210511003 2068101108112
10410503210310111509910411410510109810111003211910 5114100046
  Mit Zitat antworten Zitat
Benutzerbild von jokerfacehro
jokerfacehro

Registriert seit: 13. Feb 2007
306 Beiträge
 
Delphi 7 Enterprise
 
#10

Re: selbstgebastelter webcam stream

  Alt 5. Feb 2010, 14:15
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
"Never touch a running system administrator !"
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:43 Uhr.
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