DSow视频开发,欢迎大家都来讨论 (140分)

A

arcore

Unregistered / Unconfirmed
GUEST, unregistred user!
为了大家都能清楚明了的表达自己的观点及编程思想,我先把我的应用程序中有关
视频开发部分的功能需求说一说吧。
简单的说,应用程序中的视频部分的功能需求主要是“视频采集”- “压缩存储”
(分为单帧图像的存储和视频流的存储) - “解压回放”(是指对视频数据流而言,在回
放过程中要保存单帧图像)这三个小块。
小弟目前的进度:我的开发环境为Win98 + Delphi5 + MS SQL Server 7。电脑上面
装有一块视频采集卡。此卡在VFW下支持的分辨率有192 X 144、384 X 288 及 768 X 576
三种。由于小弟是在Win98下面做开发,所以就用VFW模式。用VFW模式实现时,在三种分
辨率下保存单帧图像都没有问题。保存视频流时,在192 X 144与384 X 288下基本不丢帧,
可以很流畅的实现,在768 X 576分辨率下采集时,丢帧很厉害,而且显示器上的采集窗
口不能同步显示视频。举例说,我用一台VCD作为视频输入,在768 X 576分辨率下,视频
采集窗口上的图像静止不动。
基于上述现像,不难看出我现在的问题:怎样在768 X 576分辨率下实现流畅的视频流
采集?如果我要实现在全屏模式下(即分辨率达到显示器的当前分辨率)采集,能否办到?
由于VFW有其局限性,所以,我打算采用DShow现实。由于以前没有接触过DX开发,只
好自己看相关资料,逐步探索。当然,做DX开发,用VC++做OCX是较好的选择,但小弟以
前从未接触过VC++,如果现在去啃,老BOSS不会给我充余的时间的。所以,我打算仍然用
Delphi来做。这段时间,小弟在网上查了些资料,也找到了Delphi下的DShow接口单元,
并对DShow有了一定的了解,但所知有限。在所有的DSow资料中,小弟觉得
在http://www.progdigy.com/里面下的DSPack2.3相比而言要好一些,因为在DSPack2.3里
面提供了很多对象,这些对象很好的封装了DShow里面的接口对象,易于开发,并且还有
源码。感兴趣的朋友可以到http://www.progdigy.com/上去下载。
现在,我想让大家讨论的是:当采集卡以768 X 576分辨率下工作时,用DShow实现
768 X 576分辨率和全屏模式下(即分辨率达到显示器的当前分辨率)下视频流的采集、压
缩存储以及解压回放等技术。当然,Win2000的驱动模式为WDM,如果采用DShow,是否必
须到Win2000下开发?如果不,在VFW与WDM二者之间要注意哪些问题?
问题可能有点难度(至少对于小弟是如此),所以,占用大家一些宝贵的时间,请大
家认真的把我上述的问题看清楚,并给出观点看法,小弟感激不尽。鉴于职业道德,小弟
也不想被老BOSS骂,因此请大家不要问我在做什么项目,也不要问我采集卡是什么牌子,
这其中为难之处,请大家谅解!当然,我也不想让大家给出源代码什么的,我只是想大家
都来讨论一下DShow技术,以及它在Delphi下的实现,这对大家都有好处吧。
小弟QQ:26965829,欢迎加入在线交流。
 
小弟所余的分不多,只有这么多了。但我想,这个问题是一个大讨论,是想和大家
交流技术,分数应该不重要。当然,如果哪位朋友对分看得很重,说一声,我会去
挣足分给他的。
 

我们也在做这个,不过才刚开始,不知道网络传输采用RTP/RTCP dirctshow支持不
关注
 
98下也可以做wdm的开发,只要你在98下的驱动是wdm。
 
不推荐用Full尺寸进行采集,用CIF足够了.
显示和回放的时候把CIF的图象放大到Full的质量是可以接受的.
 
请教如何利用DSPack实现像WebCam1-2-3这样的网页浏览方式,有人知道吗?
 
用RTCP可以做的
呵呵'先把视频用DS抓下来然后调用DIV压缩
然后用RTCP传输即可.
//Global variable
#define DST_ADDR "234.2.3.4" //传送RTP封包目的位址
#define DST_PORT 8888 //传送RTP封包目的Port
#define SRC_PORT 6000 //指定本地端Port
#define CAPBUFLEN 3
#define PACKCNT 10
#define BUFSIZE 1024*PACKCNT
#define PACKSIZE BUFSIZE+50

....
DWORD __stdcall Send1kDate(void* pParameter)
{
size_t bufRead = 0;
BYTE buffer[BUFSIZE];
//nPT --- 定义传送RTP封包的payload type
//nTSTAMP --- 定义传送RTP封包的timestamp
int nPT,nTSTAMP;


//read 1k Data
bufRead = fread(buffer, sizeof(BYTE), BUFSIZE, source );

//last thread haven't finish---->Give UP!!!
if(fSessionUsed==false)
{
//stop this thread()no need return
to<<"0";
return 0;
}
else

{
if(bufRead==0)
{
//eof--------->setevent for next file ,return 1
fSessionUsed=true;
SetEvent(hSendEvent);
return 1;
}
//catch the priority,block the session
fSessionUsed=false;
}
to<<"2";
nPT=rand()%64+1; //产生random payload type
nTSTAMP=rand()%1000+1; //产生random timestamp
//send package
sess.SendPacket(buffer,BUFSIZE,nPT,bfMark,nTSTAMP); //传送RTP封包
bfMark=false;
//not new tmp file
//thread finish -->set flag
fSessionUsed=true;
return 1;
}
..
void CCcdView::OnMenuitemdivx()
{
// TODO: Add your command handler code here
if(this->m_bdivmp4Com)
this->m_bdivmp4Com=false;
else

{
if(this->m_bmsavCom)
this->m_bmsavCom=false;

this->m_bdivmp4Com=true;
this->ShowFilterProperPage(this->m_piBFdivmp4Com);
}
}
..
void CCcdView::OnUpdateMenuitemdivx(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
if(this->m_bdivmp4Com)
pCmdUI->SetCheck(1);
else

pCmdUI->SetCheck(0);

if(this->m_bStart||(this->m_piBFdivmp4Com==NULL))
pCmdUI->Enable(false);
else

pCmdUI->Enable(true);

}
...

typedef unsigned short RTPuint16;
typedef unsigned long RTPuint32;

struct RTPHeader
{
#ifdef RTP_BIG_ENDIAN
unsigned char version:2;
unsigned char padding:1;
unsigned char extension:1;
unsigned char cc:4;
unsigned char marker:1;
unsigned char payloadtype:7;
#else
// little endian
unsigned char cc:4;
unsigned char extension:1;
unsigned char padding:1;
unsigned char version:2;
unsigned char payloadtype:7;
unsigned char marker:1;
#endif
RTPuint16 seqnum;
RTPuint32 timestamp;
RTPuint32 ssrc;
};

struct RTPHeaderExtension
{
RTPuint16 userdefined;
RTPuint16 length;
};

struct RTCPHeader
{
#ifdef RTP_BIG_ENDIAN
unsigned char version:2;
unsigned char padding:1;
unsigned char blockcount:5;
#else
// little endian
unsigned char blockcount:5;
unsigned char padding:1;
unsigned char version:2;
#endif
unsigned char packettype;
RTPuint16 length;
};

struct SSRCPrefix
{
RTPuint32 ssrc;
};

struct RTCPSenderInfo
{
RTPuint32 NTPmsw;
RTPuint32 NTPlsw;
RTPuint32 rtptimestamp;
RTPuint32 senderpacketcount;
RTPuint32 senderoctetcount;
};

struct RTCPReportBlock
{
RTPuint32 ssrc;
unsigned char fractionlost;
unsigned char packetslost[3];
RTPuint32 exthsnr;
// extended highest sequence number received
RTPuint32 jitter;
RTPuint32 lsr;
// last SR timestamp
RTPuint32 dlsr;
// delay since last SR
};

struct SDESPrefix
{
unsigned char sdestype;
unsigned char length;
};

struct RTCPAPPPrefix
{
RTPuint32 src;
unsigned char name[4];
};
 
To jingtao:谢谢,我的应用只要求在单机上采集回放就可以了,不过,你的代码也能给我很多启发,再次感谢!

请大家继续发言。。。。
 
看看
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1996469
 
To jemyzhang:
请问,在98下面怎么用wdm?98下的驱动不是wdm的。
 
小弟用DSPack在Win2000、D7下已经可以做到以上工作了,但是在98下面,却不行,因为98的驱动模式是Vxd,不是WDM。

请教高手,有没有什么好的解决办法?
 
请继续发言。。。请继续发言。。。请继续发言。。。
 
报个到,偶昨天开始进入这个阵营。暂时抱着学习的态度。如果有高手愿意共享经验,偶
有分,随便取。
 
偶想先知道,USB接口的不行吗?非得视频采集卡?
 
是否必须到Win2000下开发?=No
SetUp Direct9-OK
USB接口=OK
非得视频采集卡?=No
 
Go On。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
 
各位大哥,怎么不发言了?请大家帮帮忙,小弟再加分。

小弟以前用VFW时,调用VFW的设置视频格式的对话框,设置分辨率为768 X 576,它采集得到的图像也是768 X 576。现在用DSHOW,分辨率是352*288(CIF尺寸),如果拉伸显示(比如扩大到768 X 576或是Full),图像效果肯定没有原尺寸好。有没有办法更改Dshow采集时的分辨率,而不是拉伸显示?
 
另外,用DSHOW采集的话,程序在98下面就用不起来。这是否是采集卡驱动的关系?也就是说,如果采集卡生产商为Win98提供的驱动是WDM模式的,就可以用DSHOW,如果为win98提供的是Vxd模式的驱动,就不能用DShow?
 
采样分辨率应该是调用设备驱动程序吧?
偶刚开始研究。
 
不知道这段话对你是否有帮助?

http://www.copathway.com/cndevforum/subject_view.asp?subject_id=45144&amp;forum_id=28
主题 如何改变视频捕捉中视频的分辨率

总算解决了 得到 cap filter 的 outpin pCapout
IAMStreamConfig *pConfig = NULL;
// Query the output pin for IAMStreamConfig (not shown).
hr=pCapOut->QueryInterface(IID_IAMStreamConfig, (void **)&amp;pConfig);
int numss,sizess;
//numss支持的分辨率 种类数

pConfig->GetNumberOfCapabilities(&amp;numss,&amp;sizess);

AM_MEDIA_TYPE *pmt = NULL;
VIDEO_STREAM_CONFIG_CAPS scc;
hr=pConfig->GetStreamCaps(0,&amp;pmt,reinterpret_cast<BYTE*>(&amp;scc));
//第一个参数为 所支持的第 n个分辨率 ;(0---numss)
hr=pConfig->SetFormat(pmt);
if (SUCCEEDED(hr))
{

DeleteMediaType(pmt);
}
pConfig->Release();


另外,从VIS H.323 DLL Lib version 1.0 beta我发现,可以从列表中选择一个驱动。
http://www.115studio.com/listsoft.asp
 

Similar threads

D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
D
回复
0
查看
2K
DelphiTeacher的专栏
D
顶部