procedure TVideoPanel.SetActive(value: boolean);
begin
if FActive <> Value then
begin
FActive := Value;
if Factive = true then
initVideo;
if Factive = False then
begin
{关闭视频} 出现问题的地方
if FCapture = True then
SetCapture(False);
CapCaptureAbort(FCapWnd);
CapDriverDisconnect(FCapWnd);
end;
end;
end;
-------------
这是我目前研究写的一个视频捕捉程序,但是在关闭视频的时候出现一个问题
如果我将关闭捕捉,和关闭视频分开写在两个事件中 ,分别按照顺序执行,没有什么问题,但是如果放在一个过程里执行,则出现视频捕捉动作能停止,而视频窗口却不能关闭我把我的程序源码贴上,各位帮忙看看怎么解决这个问题
-----------------------------------程序源码-------------------------------------
unit VideoPanel;interfaceuses
SysUtils, Classes, Controls, ExtCtrls, VFW, VideoCoDec, YUVConverts, windows,
Messages, Graphics, Dialogs;type
TPlayRange = (Rg160x120, Rg176x144, Rg352x288, Rg320x240, Rg640x480);
type
PFrameData = ^TFrameData;
TFrameData = packed record
Size: Cardinal;
KeyFrame: Boolean;
Data: Pointer;
end;
type
TOnCapture = procedure(Sender: TObject; CaptureFrame: pointer; KeyFrame: boolean; Size: Cardinal) of object; //
TVideoPanel = class(TCustomControl)
private
{ Private declarations }
FActive: Boolean;
FPlayRange: TPlayRange;
FFrameOfSecond: integer;
FCapture: boolean;
CaptureWidth: integer;
CaptureHeight: integer;
FOnCapture: TOnCapture;
//FColor:TColor;
//---------视频播放参数-----------
vsc: TVideoCoDec;
// lastBmp: TBitmap;
Initialized: Boolean;
lpFrame: PFrameData; { Private-Deklarationen }
FCapWnd: HWnd; // AVICapture window handle
FDriverCaps: TCAPDRIVERCAPS; // Driver caps
FCapStatus: TCAPSTATUS; // Capture status FCaptureBIHSize: Integer; // Size of capture bmp format info
FCaptureBIH: PBitmapInfoHeader; // capture bmp format info
FStreamBIHSize: Integer; // Size of stream bmp format info
FStreamBIH: PBitmapInfoHeader; // stream bmp format info
FFrameStream: TMemoryStream; // stream for read a frame
FPixelPointer: PByte; // Pointer to pixel data in FFrameStream
FVideoCodec: TVideoYUVCodec; FFrameBitmap: TBitmap; // bitmap contain the last frame FFrameBitmap1: TBitmap; // bitmap contain the last frame
FFrameStream1: TMemoryStream; // stream for read a frame
FPixelPointer1: PByte; // Pointer to pixel data in FFrameStream
procedure Init(hBmp: HBITMAP);
{capture }
procedure WMMove(var Message: TWMMove); message WM_MOVE;
// Status Callbacks
procedure StatusCallback(nID: Integer; lpsz: PChar);
procedure ErrorCallback(nID: Integer; lpsz: PChar);
// Callback for single frame and capture
procedure FrameCallback(hCapWnd: HWND; lpVHDR: PVideoHdr);
procedure VideoStreamCallback(hCapWnd: HWND; lpVHDR: PVideoHdr);
procedure DisplayVideo(AEnable: Boolean);
procedure GetDriverCaps;
procedure GetCaptureStatus;
procedure VideoFormatChanged;
procedure StartSequence(ToFile: Boolean);
//-------------------------------------------------------------
function GetActive: boolean;
procedure SetActive(value: boolean);
function GetPlayRange: TPlayRange;
procedure SetPlayRange(Value: TPlayRange);
function GetCapture: Boolean;
procedure SetCapture(value: boolean);
function GetFrameOfSecond: integer;
procedure SetFrameOfSecond(value: integer);
protected
{ Protected declarations }
procedure InitVideo;
public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
{ Published declarations }
property Active: Boolean read GetActive write SetActive; //是否激活设备
property Color;
property PlayRange: TplayRange read GetPlayRange write SetPlayRange;
//播放区域大小
property FrameOfSecond: integer read GetFrameOfSecond write SetFrameOfSecond;
//每秒采集帧数
property Capture: Boolean read GetCapture write SetCapture;
//是否进行视频捕捉
property OnCapture: TOnCapture read FOnCapture write FOnCapture;
end;const
CaptureColorDepth = 24;
procedure Register;implementationprocedure Register;
begin
RegisterComponents('ActiveX', [TVideoPanel]);
end;
//------------------------------------------------------------function WidthBytes(I: LongInt): LongInt;
begin
Result := ((I + 31) div 32) * 4;
end;procedure CreateBmpHeader(var bmih: TBitmapInfoHeader;
AWidth, AHeight, ABitsPerPixel: Integer);
begin
with bmih do
begin
biSize := SizeOf(TBitmapInfoHeader);
biWidth := AWidth;
biHeight := round(AHeight);
biPlanes := 1;
biBitCount := ABitsPerPixel;
biCompression := BI_RGB;
biSizeImage := WidthBytes(biWidth * biBitCount) * biHeight * biPlanes;
biXPelsPerMeter := 0;
biYPelsPerMeter := 0;
biClrUsed := 0;
biClrImportant := 0;
end;
end;function ErrorCallback(hCapWnd: HWnd; nID: Integer; lpsz: PChar): DWord;
stdcall;
far;
var
OwnerForm: TVideoPanel;
begin
OwnerForm := TVideoPanel(capGetUserData(hCapWnd));
if (OwnerForm <> nil) and (OwnerForm is TVideoPanel) then
OwnerForm.ErrorCallback(nID, lpsz);
Result := 1;
end;function StatusCallback(hCapWnd: HWnd; nID: Integer; lpsz: PChar): DWord;
stdcall; far;
var
OwnerForm: TVideoPanel;
begin
OwnerForm := TVideoPanel(capGetUserData(hCapWnd));
if (OwnerForm <> nil) and (OwnerForm is TVideoPanel) then
OwnerForm.StatusCallback(nID, lpsz);
Result := 1;
end;function FrameCallback(hCapWnd: HWnd; lpVHDR: PVideoHdr): DWord; stdcall; far;
var
OwnerForm: TVideoPanel;
begin
OwnerForm := TVideoPanel(capGetUserData(hCapWnd));
if (OwnerForm <> nil) and (OwnerForm is TVideoPanel) then
OwnerForm.FrameCallBack(hCapWnd, lpVHDR);
Result := 1;
end;function VideoStreamCallback(hCapWnd: HWND; lpVHDR: PVideoHdr): UINT; stdcall;
far;
var
OwnerForm: TVideoPanel;
begin
OwnerForm := TVideoPanel(capGetUserData(hCapWnd));
if (OwnerForm <> nil) and (OwnerForm is TVideoPanel) then
OwnerForm.VideoStreamCallBack(hCapWnd, lpVHDR);
Result := 1;
end;procedure SetCallbacks(ACapWnd: HWnd);
begin
if ACapWnd = 0 then
Exit;
capSetCallbackOnStatus(ACapWnd, @StatusCallback);
capSetCallbackOnVideoStream(ACapWnd, @VideoStreamCallback);
end;procedure ClearCallbacks(ACapWnd: HWnd);
begin
if ACapWnd = 0 then
Exit;
capSetCallbackOnError(ACapWnd, nil);
capSetCallbackOnStatus(ACapWnd, nil);
capSetCallbackOnYield(ACapWnd, nil);
capSetCallbackOnFrame(ACapWnd, nil);
capSetCallbackOnVideoStream(ACapWnd, nil);
capSetCallbackOnWaveStream(ACapWnd, nil);
capSetCallbackOnCapControl(ACapWnd, nil);
end;function MillisecondsToStr(Value: DWord): string;
var
hour, min, sec, msec: Integer;
begin
msec := Value mod 1000;
Value := Value div 1000;
sec := Value mod 60;
Value := Value div 60;
min := Value mod 60;
hour := Value div 60;
Result := Format('%.2d:%.2d:%.2d.%.3d', [hour, min, sec, msec]);
end;procedure StopCapture(HwndC: HWnd);
begin
if HwndC <> 0 then
SendMessage(hWndC, WM_CAP_STOP, 0, 0);
end;
////////////////////////////////////////////////////////
begin
if FActive <> Value then
begin
FActive := Value;
if Factive = true then
initVideo;
if Factive = False then
begin
{关闭视频} 出现问题的地方
if FCapture = True then
SetCapture(False);
CapCaptureAbort(FCapWnd);
CapDriverDisconnect(FCapWnd);
end;
end;
end;
-------------
这是我目前研究写的一个视频捕捉程序,但是在关闭视频的时候出现一个问题
如果我将关闭捕捉,和关闭视频分开写在两个事件中 ,分别按照顺序执行,没有什么问题,但是如果放在一个过程里执行,则出现视频捕捉动作能停止,而视频窗口却不能关闭我把我的程序源码贴上,各位帮忙看看怎么解决这个问题
-----------------------------------程序源码-------------------------------------
unit VideoPanel;interfaceuses
SysUtils, Classes, Controls, ExtCtrls, VFW, VideoCoDec, YUVConverts, windows,
Messages, Graphics, Dialogs;type
TPlayRange = (Rg160x120, Rg176x144, Rg352x288, Rg320x240, Rg640x480);
type
PFrameData = ^TFrameData;
TFrameData = packed record
Size: Cardinal;
KeyFrame: Boolean;
Data: Pointer;
end;
type
TOnCapture = procedure(Sender: TObject; CaptureFrame: pointer; KeyFrame: boolean; Size: Cardinal) of object; //
TVideoPanel = class(TCustomControl)
private
{ Private declarations }
FActive: Boolean;
FPlayRange: TPlayRange;
FFrameOfSecond: integer;
FCapture: boolean;
CaptureWidth: integer;
CaptureHeight: integer;
FOnCapture: TOnCapture;
//FColor:TColor;
//---------视频播放参数-----------
vsc: TVideoCoDec;
// lastBmp: TBitmap;
Initialized: Boolean;
lpFrame: PFrameData; { Private-Deklarationen }
FCapWnd: HWnd; // AVICapture window handle
FDriverCaps: TCAPDRIVERCAPS; // Driver caps
FCapStatus: TCAPSTATUS; // Capture status FCaptureBIHSize: Integer; // Size of capture bmp format info
FCaptureBIH: PBitmapInfoHeader; // capture bmp format info
FStreamBIHSize: Integer; // Size of stream bmp format info
FStreamBIH: PBitmapInfoHeader; // stream bmp format info
FFrameStream: TMemoryStream; // stream for read a frame
FPixelPointer: PByte; // Pointer to pixel data in FFrameStream
FVideoCodec: TVideoYUVCodec; FFrameBitmap: TBitmap; // bitmap contain the last frame FFrameBitmap1: TBitmap; // bitmap contain the last frame
FFrameStream1: TMemoryStream; // stream for read a frame
FPixelPointer1: PByte; // Pointer to pixel data in FFrameStream
procedure Init(hBmp: HBITMAP);
{capture }
procedure WMMove(var Message: TWMMove); message WM_MOVE;
// Status Callbacks
procedure StatusCallback(nID: Integer; lpsz: PChar);
procedure ErrorCallback(nID: Integer; lpsz: PChar);
// Callback for single frame and capture
procedure FrameCallback(hCapWnd: HWND; lpVHDR: PVideoHdr);
procedure VideoStreamCallback(hCapWnd: HWND; lpVHDR: PVideoHdr);
procedure DisplayVideo(AEnable: Boolean);
procedure GetDriverCaps;
procedure GetCaptureStatus;
procedure VideoFormatChanged;
procedure StartSequence(ToFile: Boolean);
//-------------------------------------------------------------
function GetActive: boolean;
procedure SetActive(value: boolean);
function GetPlayRange: TPlayRange;
procedure SetPlayRange(Value: TPlayRange);
function GetCapture: Boolean;
procedure SetCapture(value: boolean);
function GetFrameOfSecond: integer;
procedure SetFrameOfSecond(value: integer);
protected
{ Protected declarations }
procedure InitVideo;
public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
{ Published declarations }
property Active: Boolean read GetActive write SetActive; //是否激活设备
property Color;
property PlayRange: TplayRange read GetPlayRange write SetPlayRange;
//播放区域大小
property FrameOfSecond: integer read GetFrameOfSecond write SetFrameOfSecond;
//每秒采集帧数
property Capture: Boolean read GetCapture write SetCapture;
//是否进行视频捕捉
property OnCapture: TOnCapture read FOnCapture write FOnCapture;
end;const
CaptureColorDepth = 24;
procedure Register;implementationprocedure Register;
begin
RegisterComponents('ActiveX', [TVideoPanel]);
end;
//------------------------------------------------------------function WidthBytes(I: LongInt): LongInt;
begin
Result := ((I + 31) div 32) * 4;
end;procedure CreateBmpHeader(var bmih: TBitmapInfoHeader;
AWidth, AHeight, ABitsPerPixel: Integer);
begin
with bmih do
begin
biSize := SizeOf(TBitmapInfoHeader);
biWidth := AWidth;
biHeight := round(AHeight);
biPlanes := 1;
biBitCount := ABitsPerPixel;
biCompression := BI_RGB;
biSizeImage := WidthBytes(biWidth * biBitCount) * biHeight * biPlanes;
biXPelsPerMeter := 0;
biYPelsPerMeter := 0;
biClrUsed := 0;
biClrImportant := 0;
end;
end;function ErrorCallback(hCapWnd: HWnd; nID: Integer; lpsz: PChar): DWord;
stdcall;
far;
var
OwnerForm: TVideoPanel;
begin
OwnerForm := TVideoPanel(capGetUserData(hCapWnd));
if (OwnerForm <> nil) and (OwnerForm is TVideoPanel) then
OwnerForm.ErrorCallback(nID, lpsz);
Result := 1;
end;function StatusCallback(hCapWnd: HWnd; nID: Integer; lpsz: PChar): DWord;
stdcall; far;
var
OwnerForm: TVideoPanel;
begin
OwnerForm := TVideoPanel(capGetUserData(hCapWnd));
if (OwnerForm <> nil) and (OwnerForm is TVideoPanel) then
OwnerForm.StatusCallback(nID, lpsz);
Result := 1;
end;function FrameCallback(hCapWnd: HWnd; lpVHDR: PVideoHdr): DWord; stdcall; far;
var
OwnerForm: TVideoPanel;
begin
OwnerForm := TVideoPanel(capGetUserData(hCapWnd));
if (OwnerForm <> nil) and (OwnerForm is TVideoPanel) then
OwnerForm.FrameCallBack(hCapWnd, lpVHDR);
Result := 1;
end;function VideoStreamCallback(hCapWnd: HWND; lpVHDR: PVideoHdr): UINT; stdcall;
far;
var
OwnerForm: TVideoPanel;
begin
OwnerForm := TVideoPanel(capGetUserData(hCapWnd));
if (OwnerForm <> nil) and (OwnerForm is TVideoPanel) then
OwnerForm.VideoStreamCallBack(hCapWnd, lpVHDR);
Result := 1;
end;procedure SetCallbacks(ACapWnd: HWnd);
begin
if ACapWnd = 0 then
Exit;
capSetCallbackOnStatus(ACapWnd, @StatusCallback);
capSetCallbackOnVideoStream(ACapWnd, @VideoStreamCallback);
end;procedure ClearCallbacks(ACapWnd: HWnd);
begin
if ACapWnd = 0 then
Exit;
capSetCallbackOnError(ACapWnd, nil);
capSetCallbackOnStatus(ACapWnd, nil);
capSetCallbackOnYield(ACapWnd, nil);
capSetCallbackOnFrame(ACapWnd, nil);
capSetCallbackOnVideoStream(ACapWnd, nil);
capSetCallbackOnWaveStream(ACapWnd, nil);
capSetCallbackOnCapControl(ACapWnd, nil);
end;function MillisecondsToStr(Value: DWord): string;
var
hour, min, sec, msec: Integer;
begin
msec := Value mod 1000;
Value := Value div 1000;
sec := Value mod 60;
Value := Value div 60;
min := Value mod 60;
hour := Value div 60;
Result := Format('%.2d:%.2d:%.2d.%.3d', [hour, min, sec, msec]);
end;procedure StopCapture(HwndC: HWnd);
begin
if HwndC <> 0 then
SendMessage(hWndC, WM_CAP_STOP, 0, 0);
end;
////////////////////////////////////////////////////////
begin
inherited Create(AOwner);
FPlayrange := Rg352x288;
FrameOfSecond := 15;
CaptureWidth := 160;
CaptureHeight := 120;
self.Color := clblack;
self.Height := CaptureHeight;
self.Width := CaptureWidth;
end;destructor TVideoPanel.Destroy;
begin
inherited Destroy;
if FCapWnd <> 0 then
begin
capCaptureStop(FCapWnd);
ClearCallbacks(FCapWnd);
capDriverDisconnect(FCapWnd);
DestroyWindow(FCapWnd);
FCapWnd := 0;
end;
FPixelPointer := nil;
FFrameStream.Free;
FFrameBitmap.Free;
if (FStreamBIHSize > 0) and (FStreamBIH <> nil) then
FreeMem(FStreamBIH, FStreamBIHSize);
if (FCaptureBIHSize > 0) and (FCaptureBIH <> nil) then
FreeMem(FCaptureBIH, FCaptureBIHSize);
end;function TVideoPanel.GetActive: Boolean;
begin
Result := FActive;
end;procedure TVideoPanel.SetActive(value: boolean);
begin
if FActive <> Value then
begin
FActive := Value;
if Factive = true then
initVideo;
if Factive = False then
begin
if FCapture = True then
SetCapture(False);
CapCaptureAbort(FCapWnd);
CapDriverDisconnect(FCapWnd);
end;
end;
end;function TVideoPanel.GetPlayRange: TplayRange;
begin
Result := FPlayrange;
end;procedure TVideoPanel.SetPlayRange(value: TPlayRange);
var temp: boolean;
begin
temp := false;
if FPlayRange <> Value then
FPlayRange := value;
case FPlayrange of
Rg160x120:
begin
self.width := 160;
self.Height := 120;
end;
Rg176x144:
begin
self.Width := 176;
self.Height := 144;
end;
Rg352x288:
begin
self.Width := 352;
self.Height := 288;
end;
Rg320x240:
begin
self.Width := 320;
self.Height := 240;
end;
Rg640x480:
begin
self.Width := 640;
self.Height := 480;
end;
end;
if FActive = true then
begin
CapCaptureAbort(FCapWnd);
CapDriverDisconnect(FCapWnd);
temp := true;
end;
CaptureWidth := self.width;
CaptureHeight := self.height;
if temp = true then
initVideo;
end;function TVideoPanel.GetCapture;
begin
Result := FCapture;
end;procedure TVideoPanel.SetCapture(value: boolean);
begin
if FCapture <> Value then
FCapture := Value;
if FActive = False then
begin
FCapture := False;
exit;
end;
if FCapture = true then
StartSequence(False);
if FCapture = False then
StopCapture(FCapWnd);
end;function TVideoPanel.GetFrameOfSecond: integer;
begin
result := FFrameOfSecond;
end;procedure TVideoPanel.SetFrameOfSecond(value: integer);
begin
if FFrameOfSecond <> value then
if Value > 30 then
FFrameOfSecond := 30
else if Value < 1 then
FFrameOfSecond := 1
else
FFrameOfSecond := value;
end;
//-----------------------------------------------procedure TVideoPanel.WMMove(var Message: TWMMove);
begin
inherited;
// after move of form
if FCapWnd = 0 then
Exit;
ShowWindow(FCapWnd, SW_HIDE);
ShowWindow(FCapWnd, SW_SHOW);
end;
begin
if FCapWnd = 0 then
Exit;
// CapParms.
if AEnable then
begin
capPreviewRate(FCapWnd, 100 div FFrameOfSecond);
capOverlay(FCapWnd, true);
capPreview(FCapWnd, True);
end
else
begin
capOverlay(FCapWnd, False);
capPreview(FCapWnd, False);
end;
GetCaptureStatus;
end;procedure TVideoPanel.GetDriverCaps;
begin
if FCapWnd = 0 then
Exit;
capDriverGetCaps(FCapWnd, @FDriverCaps, SizeOf(FDriverCaps));
end;procedure TVideoPanel.StatusCallback(nID: Integer; lpsz: PChar);
begin
GetCaptureStatus;
end;procedure TVideoPanel.ErrorCallback(nID: Integer; lpsz: PChar);
begin
end;procedure TVideoPanel.StartSequence(ToFile: Boolean);
var
CaptureParms: TCaptureParms;
begin
if FCapWnd = 0 then
Exit;
capCaptureGetSetup(FCapWnd, @CaptureParms, SizeOf(CaptureParms));
with CaptureParms do
begin
// frame rate
dwRequestMicroSecPerFrame := 1000000 div FFrameOfSecond;
// *Micro* seconds!
// background capture
fYield := true;
// abort by mouse click
fAbortLeftMouse := false; //True;
fAbortRightMouse := false; //True;
fLimitEnabled := false
end;
capCaptureSetSetup(FCapWnd, @CaptureParms, SizeOf(CaptureParms));
if ToFile then
capCaptureSequence(FCapWnd)
else
capCaptureSequenceNoFile(FCapWnd);
GetCaptureStatus;
end;procedure TVideoPanel.FrameCallback(hCapWnd: HWND; lpVHDR: PVideoHdr);
begin
GetCaptureStatus;
end;procedure TVideoPanel.VideoStreamCallback(hCapWnd: HWND; lpVHDR: PVideoHdr);
var
NewFrame: Pointer;
begin
case FVideoCodec of
vcUnknown: Exit; //图像数据,关键帧(T/F),大小; newFrame:压缩后数据
vcRGB: newFrame := vsc.PackFrame(lpVHDR^.lpData, lpFrame^.KeyFrame,
lpFrame^.Size); // 14侦/s
else
begin
MYYUV12toRGB(lpVHDR^.lpData, FPixelPointer, FCaptureBIH^.biWidth,
FCaptureBIH^.biHeight); // I420, IYUV
newFrame := vsc.PackFrame(FPixelPointer, lpFrame^.KeyFrame,
lpFrame^.Size);
end;
end;
//返回 newFrame,newFrame^.KeyFrame, newFrame^.Size if Assigned(FOnCapture) then
FOncapture(self, Newframe, lpFrame^.Keyframe, lpFrame^.size);end;
{===============================================}procedure TVideoPanel.Init(hBmp: HBITMAP);
var
fccHandler: TFourCC;
DIB: TDibSection;
bmiIn: TbitmapInfo;
bmiOut: TBitmapInfo;
begin fccHandler.AsString := 'divx'; GetObject(hBmp, SizeOf(DIB), @DIB);
FillChar(bmiIn, SizeOf(TBitmapInfo), 0);
FillChar(bmiOut, SizeOf(TBitmapInfo), 0); bmiIn.bmiHeader := DIB.dsBmih;
bmiOut.bmiHeader := DIB.dsBmih;
if fccHandler.AsString = 'divx' then
bmiOut.bmiHeader.biCompression := fccHandler.AsCardinal
else
bmiOut.bmiHeader.biCompression := 861292868; // 以后改为设置 Quality=50 * 100, KeyRate=10
Initialized := vsc.Init(bmiIn, bmiOut, 5000, 10); // 含义??????????????
if not Initialized then
exit;
vsc.SetDataRate(30, 100 * 1000, 1); // 含义??????????????
vsc.Start;
Initialized := true;
end;procedure TVideoPanel.GetCaptureStatus;
begin
if FCapWnd = 0 then
Exit;
capGetStatus(FCapWnd, @FCapStatus, SizeOf(FCapStatus));
end;procedure TVideoPanel.VideoFormatChanged;
const
BITexts: array[BI_RGB..BI_BITFIELDS] of string =
('RGB', 'RLE8', 'RLE4', 'BITFIELDS');
var
s: string;
BmpFileHeader: TBitmapFileHeader;
begin
if FCapWnd = 0 then
Exit; // read the really capture format
FCaptureBIHSize := capGetVideoFormatSize(FCapWnd);
GetMem(FCaptureBIH, FCaptureBIHSize);
capGetVideoFormat(FCapWnd, FCaptureBIH, FCaptureBIHSize); FVideoCodec := BICompressionToVideoCodec(FCaptureBIH^.biCompression); case FVideoCodec of
vcRGB:
begin // RGB format
// Copy header
if FStreamBIHSize <> FCaptureBIHSize then
begin
FStreamBIHSize := FCaptureBIHSize;
ReAllocMem(FStreamBIH, FStreamBIHSize);
end;
Move(FCaptureBIH^, FStreamBIH^, FStreamBIHSize);
end;
vcYUY2..High(TVideoYUVCodec):
begin
// 32 Bit!
CreateBmpHeader(FStreamBIH^, FCaptureBIH^.biWidth,
FCaptureBIH^.biHeight, 32);
end;
end; // prepare Stream for Frame
FFrameStream.Size := SizeOf(BmpFileHeader) + FStreamBIHSize +
Integer(FStreamBIH^.biSizeImage);
// Fill the Header
FillChar(BmpFileHeader, SizeOf(BmpFileHeader), 0);
with BmpFileHeader do
begin
bfType := $4D42; // 'BM'
bfSize := FFrameStream.Size;
bfOffBits := SizeOf(BmpFileHeader) + FStreamBIHSize;
end;
FFrameStream.Position := 0;
FFrameStream.WriteBuffer(BmpFileHeader, SizeOf(BmpFileHeader));
FFrameStream.WriteBuffer(FStreamBIH^, FStreamBIHSize);
FPixelPointer := FFrameStream.Memory;
Inc(FPixelPointer, BmpFileHeader.bfOffBits); FFrameStream1.Size := SizeOf(BmpFileHeader) + FStreamBIHSize +
Integer(FStreamBIH^.biSizeImage);
// Fill the Header
FillChar(BmpFileHeader, SizeOf(BmpFileHeader), 0);
with BmpFileHeader do
begin
bfType := $4D42; // 'BM'
bfSize := FFrameStream.Size;
bfOffBits := SizeOf(BmpFileHeader) + FStreamBIHSize;
end;
FFrameStream1.Position := 0;
FFrameStream1.WriteBuffer(BmpFileHeader, SizeOf(BmpFileHeader));
FFrameStream1.WriteBuffer(FStreamBIH^, FStreamBIHSize);
FPixelPointer1 := FFrameStream1.Memory;
Inc(FPixelPointer1, BmpFileHeader.bfOffBits); // 初始化bitmap 和 Vsc
FFrameStream.Position := 0;
FFrameBitmap.LoadFromStream(FFrameStream);
Init(FFrameBitmap.Handle); FFrameBitmap1.LoadFromStream(FFrameStream); // Display
if FCaptureBIH^.biCompression in [BI_RGB..BI_BITFIELDS] then
s := BITexts[FCaptureBIH^.biCompression]
else
SetString(s, PChar(@FCaptureBIH^.biCompression), 4);
end;procedure TVideoPanel.InitVideo;
begin
// create frame bitmap
FFrameBitmap := TBitmap.Create;
FFrameBitmap1 := TBitmap.Create; // compressor
vsc := TVideoCodec.Create;
New(lpFrame);
FFrameStream := TMemoryStream.Create;
FFrameStream1 := TMemoryStream.Create; FCaptureBIHSize := 0;
FCaptureBIH := nil; // bitmap info header for frame grab
FStreamBIHSize := SizeOf(TBitmapInfoHeader);
GetMem(FStreamBIH, FStreamBIHSize);
// create capture window
FCapWnd := capCreateCaptureWindow('Capture Window', WS_CHILD or WS_VISIBLE,
0, 0, CaptureWidth, CaptureHeight, Handle, 0);
if FCapWnd <> 0 then
begin
// the second parameter is the driver index
if capDriverConnect(FCapWnd, 0) then
begin
GetDriverCaps;
// create header for half size pal with true color
CreateBmpHeader(FStreamBIH^, CaptureWidth, CaptureHeight,
CaptureColorDepth);
capSetVideoFormat(FCapWnd, FStreamBIH, FStreamBIHSize);
VideoFormatChanged;
DisplayVideo(True);
// set callback
if capSetUserData(FCapWnd, LongInt(Self)) then
SetCallbacks(FCapWnd);
end
else
begin // no connect to driver
DestroyWindow(FCapWnd);
FCapWnd := 0;
end;
end;
GetCaptureStatus;
end;end.