怎样获得摄像头的视频流,并将其压缩成mpeg流,最好有mpeg编码压缩的API(100分)

  • 主题发起人 emitsong
  • 开始时间
E

emitsong

Unregistered / Unconfirmed
GUEST, unregistred user!
原理如下:
VFW主要由以下6个模块组成:
●AVICAP.DLL:包含执行视频捕获的函数,它给AVI文件的I/O处理和视频、音频设备驱动程序提供一个高级接口;
●MSVIDEO.DLL:包含一套特殊的DrawDib函数,用来处理屏幕上的视频操作;
●MCIAVI.DRV:包括对VFW的MCI命令解释器的驱动程序;
●AVIFILE.DLL:包含由标准多媒体I/O(mmio)函数提供的更高的命令,用来访问.AVI文件;
●压缩管理器(ICM):用于管理的视频压缩/解压缩的编译码器(Codec);
●音频压缩管理器ACM:提供与ICM相似的服务,适用于波形音频
var
//定义捕获窗句柄
ghCapWnd: THandle;

//可以得到视频数据指针的结构变量,用于回调函数中
VideoStr: LPVIDEOHDR;

//用于设置设备属性的结构变量
CapParms: TCaptureParms;

在Name为“Openvideo”的TButton 的Click事件中写入以下代码:
procedure TForm1.OpenvideoClick(Sender: TObject);

begin

//使用Tpanel控件来创建捕获窗口
ghCapWnd := CapCreateCaptureWindow
( PChar(‘KruwoSoft'), //捕获窗口的名字
WS_CHILD or WS_VISIBLE,//窗口样式
0, //X坐标
0, //Y坐标
gCapVideoArea.Width, //窗口宽
gCapVideoArea.Height, //窗口高
gCapVideoArea.Handle, //窗口句柄
0);
//一般为0
{为了能够捕获视频帧,要启动一个捕获帧回调函数VideoStreamCallBack。捕获一个视频流或当前设备状态时分别使用以下函数:
//捕获一个视频流
CapSetCallbackOnVideoStream;

//得到一个设备错误
CapSetCallbackOnError;

//得到一个设备状态
CapSetCallbackOnStatus
}
//定义一个帧捕获回调函数
CapSetCallbackOnFrame (ghCapWnd,LongInt(@VideoStreamCallBack));

//将一个捕获窗口与一个设备驱程相关联,第二个参数是个序号,当系统中装有多个显视驱动程序时,其值分别依次为0到总个数
CapDriverConnect(ghCapWnd, 0);

//设置设备属性的结构变量
CapParms.dwRequestMicroSecPerFrame:=40000;

CapParms.fLimitEnabled := FALSE;

CapParms.fCaptureAudio := FALSE;
// NO Audio
CapParms.fMCIControl := FALSE;

CapParms.fYield := TRUE;

CapParms.vKeyAbort := VK_ESCAPE;

CapParms.fAbortLeftMouse := FALSE;

CapParms.fAbortRightMouse := FALSE;

//使设置生效
CapCaptureSetSetup(ghCapWnd,LongInt(@CapParms),sizeof(TCAPTUREPARMS));

//设置预览时的比例
CapPreviewScale(ghCapWnd, 1);

//设置预览时的帧频率
CapPreviewRate(ghCapWnd,66);

//如果要捕获视频流,则要使用函数指定不生成文件。否则将会自动生成AVI文件
CapCaptureSequenceNoFile(ghCapWnd);

//指定是否使用叠加模式,使用为1,否则为0
CapOverlay(ghCapWnd, 1);

//打开预览
CapPreview(ghCapWnd, 1);

end;


在Name为“Closevideo”的TButton 的Click事件中写入以下代码:
procedure TForm1.ClosevideoClick(Sender: TObject);

begin

//停止捕获
capCaptureAbort(ghCapWnd);

//将捕获窗同驱动器断开
capDriverDisconnect(ghCapWnd);

end;


定义捕获帧回调函数:
function FrameCallBack(hWnd:HWND;
lpVHdr:LongInt) :LongInt;
stdcall;

var
DataPoint:^byte;

DibLen,RectWidth,RectHeight:integer;

begin

//转换从回调函数中得到的指针
VideoStr:=LPVIDEOHDR(lpVHdr);

//得到返回的数据大小
DibLen:=VideoStr^.dwBufferLength;

GetMem(DataPoint,64000);

//将帧数据COPY到一个内存中,注意DATAPOINT要先分配空间
CopyMemory(DataPoint,VideoStr^.lpData,Diblen);

//一些其他处理
……
end;


//////////////////////////////////////////////////////////////////
///关键问题:流的大小(效率?),mpeg部分的代码(Codec?)///////////////////
//////////////////////////////////////////////////////////////////
 
稍微好一点的采集卡都有MPEG压缩的接口的,不需要自己写压缩的编码器。
只需要调用函数就可以了,而且是硬件压缩,节约cpu的消耗
 
找带有MPEG接口的采集卡比较方便,自己写估计难了一些
 
是用usb接口的摄像头,不是采集卡
 
[8D]Try:
任意 Codec 压缩:
http://www.banasoft.com/AVPhone.htm
 
任意codec压缩:
http://www.avsuper.com

呵呵......不过那些都是调用系统的压缩库进行压缩,没有什么压缩.....
我自己的MPEG4和H263,wavelet都做了,现在正在做MPEG1的压缩,
以及MPEG4的实时压缩,原来的速度没有DIVX快,呵呵....
 
最好有源码,
 
我在这里问一下,怎样能在网络下以1kB的速度传送语音信号?
 
procedure TForm1.InitCompressor;
begin

//m_CV.cbSize:=sizeof(m_CV);
//ICCompressorChoose(handle,0,nil,nil,@m_CV,'Choose a Compressor');
FillMemory(@m_CV,sizeof(TCOMPVARS),0);
m_CV.dwFlags:=ICMF_COMPVARS_VALID;
m_CV.cbSize:=sizeof(m_CV);
m_CV.cbSize:=0;
m_CV.fccHandler:=mmioFOURCC('d','i','v','x');
m_CV.fccType:=ICTYPE_VIDEO;
m_CV.hic:=ICOpen(ICTYPE_VIDEO,mmioFOURCC('d','i','v','x'),ICMODE_COMPRESS);
m_CV.lDataRate:=780;
m_CV.lFrame:=0;
m_CV.lKey:=15;
m_CV.lKeyCount:=0;
m_CV.lpbiIn:=Nil;
m_CV.lpBitsOut:=Nil;
m_CV.lpState:=Nil;
m_CV.lpBitsPrev:=Nil;
m_CV.lQ:=ICQUALITY_DEFAULT;
if (m_CV.hic<>0) then

begin

m_OutFormatSize:=ICCompressGetFormatSize(m_CV.hic,@m_InInfo);
//getmem(@m_pOutInfo,m_OutFormatSize);
//m_pOutInfo:=(BITMAPINFO *)new BYTE[m_OutFormatSize];
//ICCompressGetFormat(m_CV.hic,@m_InInfo,m_pOutInfo);
ICCompressGetFormat(m_CV.hic,@m_InInfo,@m_OutInfo);
m_OutBufferSize:=ICCompressGetSize(m_CV.hic,@m_InInfo,@m_OutInfo);
ICSeqCompressFrameStart(@m_CV,@m_InInfo);
end;

end;


上网down个divx5安装
 
BlackDragon : m_CV 是什么?
 
顶部