Autor Beitrag
dragi
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 88



BeitragVerfasst: Sa 03.12.05 10:33 
Hallo,

ich habe den oben abgebildeten Code im Forum gefunden mal ausprobiert, bekomme aber eine Exception (Lesen von Adresse 000000) bei der Methode

ausblenden Delphi-Quelltext
1:
2:
  
SetBitmapBits(FBitmap.Handle,PicWidth*PicHeight*SizeOf(DWord),@Buf1);


in der Funktion FrameCallbackFunction. Kann mir vielleicht jemand sagen wo bei mir der Fehler ist?
Hier mein Versuch den gefundenen Code in eine Unit zu packen:


ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
  
unit frm_MTMain; 

interface 

uses 
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
  Dialogs, YUVConverts, ExtCtrls; 

const 
  WM_CAP_DRIVER_CONNECT           = WM_USER + 10; 
  WM_CAP_EDIT_COPY                = WM_USER + 30; 
  WM_CAP_SET_PREVIEW              = WM_USER + 50; 
  WM_CAP_SET_OVERLAY              = WM_USER + 51; 
  WM_CAP_SET_PREVIEWRATE          = WM_USER + 52; 
  WM_CAP_GRAB_FRAME_NOSTOP        = WM_User + 61; 
  WM_CAP_SET_CALLBACK_FRAME       = WM_User + 5; 
  WM_CAP_DLG_VIDEOFORMAT          = WM_USER+41;   //Formatauswahl 
  WM_CAP_DLG_VIDEOSOURCE          = WM_USER+42;   //Einstellungen 
  WM_CAP_DLG_VIDEOCOMPRESSION     = WM_USER+46;   //Kompression 
  PicWidth                        = 640; 
  PicHeight                       = 480; 

type 
  TForm1 = class(TForm) 
    Panel1: TPanel; 
    Timer1: TTimer; 
    procedure Timer1Timer(Sender: TObject); 
    procedure FormDestroy(Sender: TObject); 
    procedure FormCreate(Sender: TObject); 
  private 
    { Private-Deklarationen } 
  public 
  end; 

type 
  DWordDim = array[1..PicWidth] of DWord; 

Type 
  TVIDEOHDR = record  // lpVHdr, aus dem INet herausgefischt 
  lpData : Pointer; // address of video buffer 
  dwBufferLength : DWord; // size, in bytes, of the Data buffer 
  dwBytesUsed : DWord; // see below 
  dwTimeCaptured : DWord; // see below 
  dwUser : DWord; // user-specific data 
  dwFlags : DWord; // see below 
  dwReserved1, dwReserved2, dwReserved3 : DWord; // reserved; do not use 
end; 
  TVIDEOHDRPtr = ^TVideoHDR; 

var 
  Form1: TForm1; 
  VHandle : THandle; 
  GrabFrameFlag : Boolean; 
  Buf1,Buf2 : array[1..PicHeight] of DWordDim; 
  FBitmap : TBitmap; 

implementation 

{$R *.dfm} 

function capCreateCaptureWindow(lpszWindowName: LPCSTR; 
    dwStyle: DWORD; 
    x, y, 
    nWidth, 
    nHeight: integer; 
    hwndParent: HWND; 
    nID: integer): HWND; stdcall; 
    external 'AVICAP32.DLL' name 'capCreateCaptureWindowA'; 

function FrameCallbackFunction(AHandle : hWnd; VIDEOHDR : TVideoHDRPtr): bool; stdcall; 
var I : integer; 
  AColor : array[1..4] of byte; 
begin 
  result := true; 
  // da diese Callback-Funktion sonst bei jedem Preview-Frame ganz durchlaufen werden würde: 
  if GrabFrameFlag = false then exit; 
  GrabFrameFlag := false; 
  // dekomprimieren der Frame-Rohdaten 
  { TVideoCodec = (vcUnknown, vcRGB, vcYUY2, vcUYVY, vcBTYUV, vcYVU9, vcYUV12, vcY8, vcY211); } 
  ConvertCodecToRGB(vcYUV12,VideoHDR^.lpData,@Buf2,PicWidth,PicHeight); 
  // da zu einem bottom-up-bitmap dekomprimiert wird, drehe ich die Daten nochmal rum 
  for I := 1 to PicHeight do Buf1[I] := Buf2[PicHeight -(I-1)]; 
  // laden der fertigen Pixel-Daten nach FBitmap 
  SetBitmapBits(FBitmap.Handle,PicWidth*PicHeight*SizeOf(DWord),@Buf1); 
end; 

procedure TForm1.FormCreate(Sender: TObject); 
begin 
  VHandle := capCreateCaptureWindow('Video',ws_child+ws_visible, 0, 0, 
  PicWidth, PicHeight, Panel1.Handle, 1); 
  SendMessage(VHandle, WM_CAP_DRIVER_CONNECT, 0, 0); 
  SendMessage(VHandle, WM_CAP_SET_PREVIEWRATE, 15, 0); 
  sendMessage(VHandle, WM_CAP_SET_OVERLAY, 1, 0); 
  SendMessage(VHandle, wm_cap_set_preview, 1, 0); 
  SendMessage(VHandle, WM_CAP_SET_CALLBACK_FRAME, 0, integer(@FrameCallbackFunction)); 
  SendMessage(VHandle,WM_CAP_DLG_VIDEOFORMAT,1,0); 
  FBitmap := TBitmap.Create; 
  FBitmap.Width := PicWidth; 
  FBitmap.Height := PicHeight; 
  FBitmap.PixelFormat := pf32Bit; 
  GrabFrameFlag := false; 
end; 

procedure TForm1.FormDestroy(Sender: TObject); 
begin 
  FBitmap.free; 
end; 

procedure TForm1.Timer1Timer(Sender: TObject); 
begin 
  GrabFrameFlag := true; 
  SendMessage(VHandle, WM_CAP_GRAB_FRAME_NOSTOP, 1, 0); // für die Hintergrundlaufbarkeit 
end;


end.

Moderiert von user profile iconUGrohne: Code- durch Delphi-Tags ersetzt
digi_c
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1905

W98, XP
D7 PE, Lazarus, WinAVR
BeitragVerfasst: Mo 05.12.05 08:30 
Vermutlich fehlt da irgendwo die Initialisierung eines Objektes bzw. das Reservieren von Speicherplatz.

Wo steht den der Debugger nach der Meldung.