太容易得到的东西。。往往不会太珍惜

计划跟佳哥去华为实验室练习交换机及路由器的配置。。去了几次。发现佳哥都是在跟老婆聊Q。。这是令我很不理解的。。要不我在网络中心。。华为实验室根本进不去的。里边有许多型号的交换机和路由器供做实验用。。我想。如果到了外边。就见不着这些东西了。应该好好利用一下。学点知识。。万一以后有用得着的地方就赚了。。呵呵。。机会往往给有准备的人。。

可能是因为佳哥太容易的得到了这些东西。。就不会去珍惜了。。人性的弱点吧。

太容易得到的东西。往往不会珍惜!

希望佳哥看到这篇日志后有点醒悟!

胸怀的五种表现

胸怀的五种表现

务实: 接受无法改变的人和事,为自己而生活,而不是怨天尤人

宽恕:善于发现他人的优点,有度量容忍他人的缺点,宰相肚里成撑船

自律:懂得控制自己的情绪,不被情绪左右做出过激或错误的行为

尊重:允许别人表达或保留不同意见,”我不同意你,但我支持你”

涵养:荣辱不惊,置得失于度外,不因一时的利益或一人一事的欲求而自乱方

天津之行两三事

五月六日的疯狂的想法。。嚣张不可一世的我。。从五点起床。脑袋中闪到一个去天津玩的念头。。到七点决定去天津。。九点到客运中心。。十一点到天津。。我真的太疯狂了。从来没有的疯狂。一辈子有这么一次疯狂的旅行也够了。。呵呵。。

到了天津。。万哥去接我。从学校到客运中心得一个多小时。。辛苦万里同学。。下午去他们学校上的课。。感受一下河工大和河大的区别。。晚上整两瓶啤酒。几个小菜。。胡侃乱侃一气。。哈。。高兴的一晚上。。又跟万里同学在学校里转了一圈。。聊昨天。。今天。。明天。。发发牢骚。。说说郁闷事。。哈哈一笑。全部忘掉。。

第二天的目的地是外滩。。万里同学没出过门。。不知道怎么去外滩的路。。真失败。。都上两年了。竟然没出去转转。。在地铁上问一个天津本地人。很热情的回答了我们。。哈哈。。天津人还是很热心的。。公交。。地铁。。再次公交。。轻轨。终于到了塘沽。。真不容易。。转悠了洋货市场。。我看跟沙河的冒贸街差不多。。嘿嘿。。

又转了大半天到了海河外滩公园。。嗨。。真好玩。真大气。边玩边说。边说边笑。吹着海风。还瞅着火箭和湖人的比赛。。舒服。。享受。。。。

玩够了。。想去海边转转。一个青年就过来对我们说。海边。。一人十五。。时间还早。。下定决定就去了。。先写到这。。有空继续。。哈

话说一个青年司机让我们去海边。。跟万里同学一商量。。去。。时间应该差不多够。。还没见过海长啥样呢。。呵呵。司机说最多半个小时到。。跑了二十分钟。。堵车了。。青年司机胸有成竹的说。。换条道继续走。。大概又跑了十分钟。。到了另一条道。。结果依然堵车。。等了二十分钟还是过不去。司机很郁闷。。又换了第三条道。。其实生活中跟这司机一样的人大有人在。做事之前。拍着胸脯保证。。肯定可以搞定。结果做起来后。就傻了眼。。我们是人。不是神。。事情做完后才算做完。。只凭我们主观的想像。是不行的。。毕竟有很多未知的因素在里面。。

到了海边。。有点失望。。跟想像中的不一样。小时候去过秦皇岛。。那海才叫海。。有海滩玩。。有贝壳拾。。这一PO海。。没有退潮。。看不着沙滩。。只有一望无边的海。一眼望不到头。捡着别人不要的贝壳。。呵。。总得带点东西回去吧。。随便吼两声。。把郁闷和不高兴撒向大海。。哈。。石头太坏了。。石头要做一个拥有大海胸怀的人。。虽然现在没有。。

四点多到了塘沽。。本以为回去要一个半小时。。结果车跑了两个多小时。。我那个郁闷呀。。赶不上回去的车了。。高客六点就停了。。还得回同学学校住一晚上。。河工大太远。。不想去。。呵呵。这时路边停着一个车。普客。。天津-保定。。一咬牙。一跺脚。上车走人。。

PO车晃摇了三个小时。。晚上十点五十到保定。。打的回的学校。。宿舍大门刚好要锁。。幸亏及时赶到。。哈哈。。

嚣张而疯狂的行动。疯狂且嚣张的石头!

爱情的二十种面目

(一)

开始的开始总是甜蜜的

后来就有了厌倦、习惯、背弃、寂寞、绝望和冷笑

曾经渴望与一个人长相厮守,后来,多么庆幸自己离开了

曾几何时,在一段短暂的时光里,

我们以为自己深深的爱着的一个人。

后来,我们才知道

那不是爱,那只是对自己说谎。


(二)


你以为不可失去的人,原来并非不可失去,

你流干了眼泪,自有另一个人逗你欢笑,

你伤心欲绝,然后发现不爱你的人,

根本不值得你为之伤心,

今天回首,何尝不是一个喜剧?

情尽时,自有另一番新境界,

所有的悲哀也不过是历史。


(三)


爱情总是想象比现实美丽,

相逢如是,告别亦如是。

我们以为爱得很深、很深,

来日岁月,会让你知道,它不过很浅、很浅。

最深最重的爱,必须和时日一起成长。


(四)


因为爱情的缘故,

两个陌生人可以突然熟络到睡在同一张床上。

然而,相同的两个人,在分手时却说,我觉得你越来越陌生。

爱情将两个人由陌生变成熟悉,又由熟悉变成陌生。

爱情正是一个将一对陌生人变成情侣,又将一对情侣变成陌生人的游戏。


(五)


相信爱情可以令一个人改变,

是年轻的好处,也是年轻的悲哀。

浪子永远是浪子。令男人改变的,

也许是上帝的爱或者佛祖的慈悲,但绝对不会是女人。

最不宜结婚的是浪子,最适宜结婚的也是浪子。

往往不是女人改变一个浪子,而是女人在浪子想改变的时候刚好出现。


(六)


想男人的一生,不过对女人做两件事:

超乎她想象的好和超乎她想象的坏。

女人用他的好来原谅他的坏。

如果有一天他们不能在一起,不是他太坏,而是她太好。

我们一生之中,要牢记和要忘记的东西一样多。

记忆存在细胞里,在身体里面,与肉体永不分离,要摧毁它,等于玉石俱焚。

然而,有些事情必须忘记,忘记痛苦,忘记最爱的人对你的伤害,只好如此。


(七)


时间会让你了解爱情,时间能够证明爱情,也能够把爱推翻。

没有一种悲伤是不能被时间减轻的。

如果时间不可以令你忘记那些不该记住的人,我们失去的岁月又有什么意义?

如果所有的悲哀、痛苦、失败都是假的,那该多好?

可惜,世上有很多假情假义,自己的痛苦、失败、悲哀,却偏偏总是真的。


(八)


他纵有千个优点,但他不爱你,

这是一个你永远无法说服自己去接受的缺点。

一个人最大的缺点不是自私、多情、野蛮、任性,而是偏执地爱一个不爱自己的人。

暗恋是一种自毁,是一种伟大的牺牲。

暗恋,甚至不需要对象,我们不过站在河边,

看着自己的倒影自怜,却以为自己正爱着别人。


(九)


爱情和情歌一样,最高境界是余音袅袅。

最凄美的不是报仇雪恨,而是遗憾。

最好的爱情,必然有遗憾。那遗憾化作余音袅袅,长留心上。

最凄美的爱,不必呼天抢地,只是相顾无言。

失望,有时候,也是一种幸福。

因为有所期待,才会失望。

遗憾,也是一种幸福。因为还有令你遗憾的事情。

追寻爱情,然后发现,爱,从来就是一件千回百转的事。


(十)


最浪漫的爱是得不到的。

最浪漫的情话,是当哪个已经跟你分了手的人打电话来问:”你好吗?”

你稀松平常地回答:”我很好。”

而其实你还爱着他,你一点也不好。

男人伪装坚强,只是害怕被女人发现他软弱。

女人伪装幸福,只是害怕被男人发现她伤心。



(十一)


爱情,有时候,是一件令人沉沦的事情,

所谓理智和决心,不过是可笑的自我安慰的说话。

爱情从来都是一种束缚,追求爱情并不等于追求自由。

自由可贵,我们用这最宝贵的东西换取爱情。

因为爱一个人,明知会失去自由,也甘愿作出承诺。

(十二)


诺言是用来跟一切的变幻抗衡。

变幻原是永恒,我们唯有用永恒的诺言制约世事的变幻。

不能永恒的,便不是诺言。诺言是很贵的,如果你尊重自己的人格。

爱是有安全感,又没有安全感。

爱是一种震撼,也是一种无力感。

爱是诱惑,也惟有爱能给你力量抗拒诱惑。爱是忠诚,可是爱也会令你背叛。

(十三)


一个人负心,或许是因为他的记忆力不好。

他忘记了,所以他能够负心;不是因为他负心,所以他忘记了。

以前种种,他并非完全忘记,但他记忆力太差了,往事已经不再深刻,

很快就被新的记忆取代,只记得新人的欢笑,忘记旧人的笑脸。

爱和怀念是两回事。

男人忘不了旧情人,必然是他在过去的岁月里,曾经伤害她,

那一次的过失,他无法弥补。

当明知不可挽回,唯一补偿的方法就是怀念,同时也用对她的怀念来惩罚自己。

自以为是的深刻不过是自欺欺人的说话。


(十四)


懂爱的女人通常输得很惨。

爱情本来就是残忍的,胜者为王。

感情可以转帐,婚姻可以随时冻结,

激情可以透支,爱情善价而沽。

是的,在这细小的都市里,这就是我们的生活。

今天的长相厮守,只是尽力而为而已。

最安全和最合时宜的方式,还是和自己厮守。


(十五)


一个钱币最美丽的状态,不是静止,

而是当它像陀螺一样转动的时候,没人知道,

即将转出来的那一面,是快乐或痛苦,是爱还是恨。

快乐和痛苦,爱和恨,总是不停纠缠。

所谓缘分,也和发明一样吧,都是源于偶然。

爱情也是一种发明,需要不断改良。

只是,这种发明跟其他发明不一样,它没有专利权,随时会给人抢走。


(十六)


愈害怕失去的人,愈容易失去。

愈想得到,就愈要放手。放手是很难的,但是别无选择。

世上有很多东西是可以挽回的,

比如良知,比如体重。但不可挽回的东西更多,

譬如旧梦,譬如岁月,譬如对一个人的感觉。

放弃一个很爱你的人并不痛苦,放弃一个你很爱的人才是痛苦。


(十七)


食物可以有标签,说明”请在此之前食用”。

女人不是食物,青春是有期限的,忍耐也是有期限的,

请在期限期满之前好好爱她,好好照顾她,因为她是逾时不候的。

万物有时,怀抱有时,爱情也有时序。

爱情有生、老、病、死。爱情总在不知不觉间过期。

有一天,我们把它拿出来,才知道它最鲜活的日子已经永远过去。


(十八)


在最有感觉的时候,她没有停下脚步,

那么,也不必在一起走完那段路之后,

回头去寻找那些散落在地上的感觉,路已经走完。

爱情中最伤感的时刻是后期的冷淡,一个曾经爱过你的人,

忽然离你很远,咫尺之隔,却是天涯。

曾经轰轰烈烈,曾经千回百转,曾经沾沾自喜,曾经柔肠寸断。

到了最后,最悲哀的分手竟然是悄无声息。


(十九)


有相逢就有别离,可是每个人都害怕别离。

大家都知道,最后一次的别离就是死亡。

我们口里说”天下无不散之宴席”,心里却舍不得喝掉手中的酒,

还想再唱一支歌,再唱一支歌。你可不可以不走?


(二十)


失去才知道你最珍贵.

当真的要失去,才知道爱情是那么的珍贵?

为什么在拥有的时候去珍惜,仍然会是失去这样一个结果

也许是因为上天注定,不该开始但是仍然开始了

也许是因为上天注定,要失去为为什么仍然会失去?

太多的疑问,知道了答案又能怎样

如果有种方法可以不要失去,我都愿意 !

使用VFW在windows下编程控制摄像头

测量视频质量

测量视频质量的一个方法是去限定在一个捕获操作期间丢掉的捕获图像帧的数字。当流捕获完成后,质量 = 丢掉的帧 / 所有的帧。如果这个数(百分数)大于wPercentDropForError的值,AVICap将发一个错误信息给错误回调函数。WPercentDropForError是CAPTUREPARMS数据结构体的一个数据成员。

通过WM_CAP_GET_SEQUENCE_SETUP消息(capCaptureGetSetup宏)可以得到当前设定的丢掉帧的限定值。同样对wPercentDropForError进行修改,再把修改后的数据结构体发送给捕获窗体就可以完成对限定值的修改。WM_CAP_GET_SEQUENCE_SETUP消息(capCaptureSetSetup), wPercentDropForErrorm默认值10 (10%)。


用户初始化捕获

通过WM_CAP_GET_SEQUENCE_SETUP消息(capCaptureGetSetup宏)可以得到当前用户初始化捕获的状态值。该值存放在fMakeUserHitOKToCapture中。在开始一个捕获会话前,设置该值为TRUE,可以为用户提供精确的控制。系统为所有的音视频分配好数据缓存区后,AVICap会显示一个对话框。它让用户清除因为软件初始化导致的捕获延迟。如果你的应用程序为视频数据分配的数据缓存区很小,那么这个对话框可能就没的必要了。该值的默认值是FALSE。


和调色板一起工作

最初,如果视频捕获格式需要一个调色板,那么捕获窗口将使用捕获驱动提供的调色板来代替。这个调色板可能由灰度值,或者可选的彩色值组成。使用WM_CAP_PAL_PASTE或者WM_CAP_PAL_OPEN消息(capPalettePaste或capPaletteOpen)可以获得一个现存的调色板去替换默认的调色板。你还可以创建一个自定义的调色板去替换默认的调色板,你要使用WM_CAP_PAL_AUTOCREATE 或者 WM_CAP_PAL_MANUALCREATE消息 ( capPaletteAuto 或 capPaletteManual )。当你替换了调色板后,捕获窗体和驱动程序将使用替换后的调色板,直到你创建或打开其他的调色板为止。


WM_CAP_PAL_AUTOCREATE 或者 WM_CAP_PAL_MANUALCREATE 消息将创建一个基于当前视频输入最优化的调色板。这个自定义的调色板将为视频提供一个最好的颜色逼真度,因为这个调色板的颜色是基于这个视频的。捕获窗口创建一个采样颜色的3维柱状图。它会减小真实颜色和渐近色间的值。

在发送WM_CAP_PAL_AUTOCREATE消息时, 你必须指定AVICap采样的帧数以及调色板的颜色尺寸。在指定帧数时,要保证帧数足够大以保证所有的视频颜色可以被采样收集到。

使用WM_CAP_PAL_MANUALCREATE消息可以对当前帧进行采样。通过该消息,进行几次手动选择帧采样操作,你可以创建自己的调色板,它包含了你想要的颜色信息。


一个调色板可以包含256种颜色。如果你要合并调色板,或者在视频队列中同时在显示其他视频或图像。你可以去使用一个小的颜色集合,这样不同图像或视频的颜色就可以共存了。

使用WM_CAP_PAL_SAVE消息(capPaletteSave),可以保促一个新的调色板。通过WM_CAP_PAL_OPEN消息还可以得到当前的调色板。你可以在调色板处理前保存一个调色板,或者为其他应用程序使用去保存一个调色板。


使用WM_CAP_PAL_PASTE可以把剪贴板中的调色板粘贴到捕获窗口中。捕获窗口通过这个调色板到捕获驱动。其他程序可以拷贝调色板到剪贴板中。你也可以把调色板粘贴到剪贴板中。使用WM_CAP_ENDIT_COPY消息(capEditCopy)。它将拷贝视频缓存区(包括调色板)到剪贴区。



在AVI文件中的嵌入信息块

你可以在一个AVI文件中插入信息块,比如文本或者自定义的数据。通过使用下面的消息:WM_CAP_FILE_SET_INFOCHUNK(capFileSetInfoChunk)。可以使用这个消息还可以清除掉一个AVI文件中的信息块。


用户数据消息

通过使用WM_CAP_GET_USER_DATA和WM_CAP_SET_USER_DATA消息可以关联数据到一个捕获窗体。(capGetUserData 和 capSetUserData宏)。使用…Get…消息可以得到一个LONG数据值,可以通过_Set_消息去设置该值。



3.1.8 AVICap回调函数
你的应用程序可以为一个捕获窗口注册一些回调函数,它们可以告诉你的应用程序一些变化。比如捕获状态发生变化了,或者有错误发生了,音视频缓存区可使用了。下面的消息设置回调函数。





WM_CAP_SET_CALLBACK_CAPCONTROL

CapSetCallbackOnCapControl 宏
在应用程序中指定回调函数用于控制捕获的开始和结束。


WM_CAP_SET_CALLBACK_ERROR

CapSetCallbackOnError宏
在应用程序中指定回调函数,当出错的时候就调用它。


WM_CAP_SET_CALLBACK_FRAME

CapSetCallbackOnFrame宏
在应用程序中指定回调函数,当预览图像帧被捕获了的时候就调用它。


WM_CAP_SET_CALLBACK_STATUS

CapSetCallbackOnStatus宏
在应用程序中指定回调函数,当状态(status)改变的时候就调用它。


WM_CAP_SET_CALLBACK_VIDEOSTREAM

CapSetCallbackOnVideoStream宏
在应用程序中指定回调函数,在流捕获期间,当一个新的视频缓存区可用的时候就调用它。


WM_CAP_SET_CALLBACK_WAVESTREAM

CapSetCallbackOnWaveStream宏
在应用程序中指定回调函数,在流捕获期间,当一个新的音频缓存区可用的时候就调用它。


WM_CAP_SET_CALLBACK_YIELD

CapSetCallbackOnYield宏
在应用程序中指定回调函数,在流捕获期间Yielding(产生?)


精确捕获控制

捕获窗口可以提供捕获回调函数,这个回调函数可以对流捕获的开始和结束时刻进行精确的控制。在捕获驱动程序(capture driver)完成所有缓存区分配和其他捕获准备后,捕获驱动程序就发送第一个消息给回调处理程序,把nState参数设置为:

CONTROLCALLBACK_PREROLL

这个消息告诉应用程序将要开启视频源了。(这个回调函数指定nState为它的第二个参数)回调函数将在开始时刻产生返回值。返回值为TRUE那么将继续捕获。为FALSE就中断捕获。一旦捕获开始,这个回调函数将频繁的调用,把nState设置为:

CONTROLCALLBACK_CAPTURING

将允许应用程序通过返回false去结束捕获。


错 误

捕获窗口使用错误通知消息去告诉你的应用程序,发生了AVICap错误,比如磁盘空间已经用完了,尝试对一个只读文件进行写操作,不能访问硬件,掉帧太多。错误通知内容报价一个消息ID和一个格式化的文本字符(用来显示)。你的应用程序可以通过使用这个消息ID去过滤错误通报,还可以让该错误信息不显示给用户。消息ID为0表示一个新操作正在开始并且这个回调函数会清除掉所有的显示的错误信息。


帧(Frame)

A capture window uses frame callback notification messages to notify your application when a new video frame is available. The capture window enables these callback notifications only if the preview rate is nonzero and streaming capture is not in progress.


状态回调函数

当视频捕获向磁盘写数据,或者在其他较长的操作期间,捕获窗口可以发送消息给状态回调函数通知你正在处理该操作的应用程序。状态信息包括一个消息ID和和一个格式化的文本字符(用来显示)。你的应用程序可以通过使用消息ID去过滤通报,还可以限制该信息是否显示给用户。在捕获操作期间,发给回调函数的第一个消息总是ID_CAP_GEGIN,最后一个总是ID_CAP_END。消息ID为0表示,一个新操作正在进行并且回调函数将清除当前状态。


视频流

在流捕获期间,应用程序可以使用视频流回调函数去处理一个捕获的视频帧。视频窗体只能在每次向磁盘写数据帧前,调用视频流回调函数。


音频流

在流捕获期间,应用程序可以使用音频流回调函数去处理音频缓存区。视频窗体只能在每次向磁盘写数据帧前,调用音频流回调函数。


Yield 回调函数

应用程序在流捕获期间可以使用Yield回调函数。(Yield回调函数一般是由一个消息循环组成,可以调用PeekMessage,TranslateMessage,DispatchMessage)。捕获窗口在每次捕获视频帧时至少调用一次Yield回调函数。但是具体要调用多少次由帧率来决定。


关闭回调函数

你可以暂时或永久关闭所有的回调函数的功能,在发送消息设置回调函数的时候,用NULL替换调回调函数就可以了。

3.2使用视频捕获

3.2.1创建捕获窗体

下面的例子通过使用capCreateCaptureWindow函数来创建一个捕获窗体

hWndC = capCreateCaptureWindow (

(LPSTR) “My Capture Window”, // 如果是Pop-up窗口的窗口名称

WS_CHILD | WS_VISIBLE, // 窗口类型

0, 0, 160, 120, // 窗口位置和尺寸

(HWND) hwndParent,

(int) nID );


3.2.2连接到一个捕获驱动器

下面举例,如何通过捕获窗口的句柄hWndC连接到MS VIDEO驱动程序上,同时还演示了如何断开连接。使用capDriverDisconnect:

fOK = SendMessage (hWndC, WM_CAP_DRIVER_CONNECT, 0, 0L);

// 或者使用宏连接:

// fOK = capDriverConnect(hWndC, 0);

// 关闭连接

capDriverDisconnect (hWndC);

3.2.3列举安装的捕获驱动程序

使用capGetDriverDescription 函数来获得系统已经安装的所有捕获驱动程序的名称和版本。

char szDeviceName[80];

char szDeviceVersion[80];

for (wIndex = 0; wIndex < 10; wIndex++)

{

if (capGetDriverDescription (wIndex, szDeviceName,

sizeof (szDeviceName), szDeviceVersion,

sizeof (szDeviceVersion))

{

// 加入名字到一个已经安装的设备列表中

// 让用户选择一个使用。

}

}

3.2.4获得捕获驱动器的性能参数

WM_CAP_DRIVER_GET_CAPS消息可以返回捕获驱动程序以及其硬件的性能参数。这些信息存放在一个CAPDRIVERCAPS的数据结构中。当你的应用程序的捕获窗口连接到一个新的捕获驱动器后,都会刷新这个CAPDRIVERCAPS数据结构。下面将使用capDriverGetCaps宏来获得捕获设备的性能参数。

CAPDRIVERCAPS CapDrvCaps;

SendMessage (hWndC, WM_CAP_DRIVER_GET_CAPS,

sizeof (CAPDRIVERCAPS), (LONG) (LPVOID) &CapDrvCaps);

// 或者,使用宏来获得驱动器的新能参数

// capDriverGetCaps(hWndC, &CapDrvCaps, sizeof (CAPDRIVERCAPS));

3.2.5获得捕获窗口状态(Status)

下面例子使用SetWindowPos函数区设置捕获窗口的尺寸,这个尺寸的大小是基于输入的视频流大小的。输入视频流的尺寸大小由capGetStatus宏来获得,获得信息放在一个CAPSTATUS的数据结构体中。

CAPSTATUS CapStatus;

capGetStatus(hWndC, &CapStatus, sizeof (CAPSTATUS));

SetWindowPos(hWndC, NULL, 0, 0, CapStatus.uiImageWidth,

CapStatus.uiImageHeight, SWP_NOZORDER | SWP_NOMOVE);



3.2.6显示对话框区设置视频属性

每个捕获驱动器都可以提高3个以上的不同对话框来控制数字视频的特性和捕获处理。下面的例子示范如何显示这些对话框。在显示每个对话框前,该例会调用capDriverGetCaps宏并且检查返回的CAPDRIVERCAPS对象来查看是否可以能够显示特定的对话框。

CAPDRIVERCAPS CapDrvCaps;

capDriverGetCaps(hWndC, &CapDrvCaps, sizeof (CAPDRIVERCAPS));

// 视频源对话框

if (CapDriverCaps.fHasDlgVideoSource)

capDlgVideoSource(hWndC);

// 视频格式对话框

if (CapDriverCaps.fHasDlgVideoFormat)

{

capDlgVideoFormat(hWndC);

// 是否由新的图像尺寸?Are there new image dimensions?

capGetStatus(hWndC, &CapStatus, sizeof (CAPSTATUS));

// 如果有,发送通知给父窗口,告诉它尺寸改变了

}

// 视频显示对话框

if (CapDriverCaps.fHasDlgVideoDisplay)

capDlgVideoDisplay(hWndC);

3.2.7获得和设定视频格式

BITMAPINFO数据结构体可以实现长度可调节地去适应标准压缩的数据格式。因为它的长度可以变,所以在每次获得当前视频格式前,都必须去查询这个结构的长度以及分配的内存大小。该例子使用了capGetVideoFormatSize宏去获得缓存区大小,使用capGetVideoFormat宏区获得当前视频格式。

LPBITMAPINFO lpbi;

DWORD dwSize;

dwSize = capGetVideoFormatSize(hWndC);

lpbi = GlobalAllocPtr (GHND, dwSize);

capGetVideoFormat(hWndC, lpbi, dwSize);

// 访问视频格式,并且释放分配的内存。

应用程序使用capSetVideoFormat宏(WM_CAP_SET_VIDEOFORMAT),把一个BITMAPINFO结构发送给捕获窗口,显示修改。因为视频格式由设备指定的,你的应用程序可以去检查获得的返回值,来知道这个视频格式是不是公开的。

3.2.8预览视频
下面使用capPreviewRate宏来设置预览模式的帧频率为66毫秒/帧,使用capPreview宏在捕获窗口预览图像。

capPreviewRate(hWndC, 66); // 速度,微秒

capPreview(hWndC, TRUE); // 开始预览

capPreview(hWnd, FALSE); // 屏蔽预览

3.2.9允许视频覆盖(Overlay)

下面使用capDriverGetCaps宏去检测这个捕获驱动是否支持覆盖(Overlay)模式,如果支持,就允许视频覆盖模式;

CAPDRIVERCAPS CapDrvCaps;

capDriverGetCaps(hWndC, &CapDrvCaps, sizeof (CAPDRIVERCAPS));

if (CapDrvCaps.fHasOverlay)

capOverlay(hWndC, TRUE);

3.2.10捕获文件命名

下例使用capFileSetCaptureFile宏来指定一个要命名的文件名(mycap.avi),使用capFileAlloc宏去预分配5MB的文件。

char szCaptureFile[] = “MYCAP.AVI”;

capFileSetCaptureFile( hWndC, szCaptureFile);

capFileAlloc( hWndC, (1024L * 1024L * 5));

3.2.11格式化音频捕获

下例使用capSetAudioFormat来设置音频格式为11-KHz PCM 8-bit,立体声。

WAVEFORMATEX wfex;

wfex.wFormatTag = WAVE_FORMAT_PCM;

wfex.nChannels = 2; // 使用立体声

wfex.nSamplesPerSec = 11025;

wfex.nAvgBytesPerSec = 22050;

wfex.nBlockAlign = 2;

wfex.wBitsPerSample = 8;

wfex.cbSize = 0;

capSetAudioFormat(hWndC, &wfex, sizeof(WAVEFORMATEX));

3.2.12改变视频捕获设置

下例使用capCaptureGetSetup和capCaptureSetSetup宏来改变捕获速度,从默认值(15帧/秒)到10帧/秒。

CAPTUREPARMS CaptureParms;

float FramesPerSec = 10.0;

capCaptureGetSetup(hWndC, &CaptureParms, sizeof(CAPTUREPARMS));

CaptureParms.dwRequestMicroSecPerFrame = (DWORD) (1.0e6 /

FramesPerSec);

capCaptureSetSetup(hWndC, &CaptureParms, sizeof (CAPTUREPARMS));

3.2.13捕获数据

下例使用capCaptureSequence宏开始视频捕获,使用capFileSaveAs宏从捕获文件拷贝数据到其他文件NEWFILE.AVI中。

char szNewName[] = “NEWFILE.AVI”;

// Set up the capture operation.

capCaptureSequence(hWndC);

// Capture.

capFileSaveAs(hWndC, szNewName);

3.2.14加入信息块

如果你想添加其他信息(除了音视频),你可以建一个信息块并把它们插入到一个捕获文件中去。信息块可以包含这个方面的内容。比如版权信息,视频源的ID,外部显示的时间信息。下面的例子保存外部时间信息SMPTE()到一个信息块中,并加入使用capFileSetInfoChunk宏加入到捕获文件中。

// This example assumes the application controls

// the video source for preroll and postroll.

CAPINFOCHUNK cic;

// .

// .

// .

cic.fccInfoID = infotypeSMPTE_TIME;

cic.lpData = “00:20:30:12″;

cic.cbData = strlen (cic.lpData) + 1;

capFileSetInfoChunk (hwndC, &cic);

3.2.15在程序中加入回调函数

应用程序可以注册捕获窗口的回调函数,这样就可以把下面的情况通知给应用程序:

l 状态变化了

l 错误发生了

l 视频和音频的缓冲区的数据可以使用了

l 在捕获期间,应用程序将yield

下面的例子将创建一个捕获窗口并在应用的消息循环中,注状态、错误、视频流、帧的回调函数。

case WM_CREATE:

{

char achDeviceName[80] ;

char achDeviceVersion[100] ;

char achBuffer[100] ;

WORD wDriverCount = 0 ;

WORD wIndex ;

WORD wError ;

HMENU hMenu ;

// 使用capCreateCaptureWindow宏创建一个捕获窗体.

ghWndCap = capCreateCaptureWindow((LPSTR)”Capture Window”,

WS_CHILD | WS_VISIBLE, 0, 0, 160, 120, (HWND) hWnd, (int) 0);

// 使用capSetCallbackOnError宏注册错误回调函数

capSetCallbackOnError(ghWndCap, fpErrorCallback);

// 使用capSetCallbackOnStatus宏注册状态回调函数

capSetCallbackOnStatus(ghWndCap, fpStatusCallback);

//使用capSetCallbackOnVideoStream宏注册视频流回调函数

capSetCallbackOnVideoStream(ghWndCap, fpVideoCallback);

//使用capSetCallbackOnFrame宏注册帧回调函数

capSetCallbackOnFrame(ghWndCap, fpFrameCallback);

// 连接到一个捕获驱动器上

break;

}

case WM_CLOSE:

{

//使用capSetCallbackOnFrame宏关闭帧回调函数

// 类似可调用其他存在的回调函数。

capSetCallbackOnFrame(hWndC, NULL);

break;

}

3.2.16创建一个状态回调函数

下面的例子是一个简单的状态回调函数,使用capSetCallbackOnStatus宏来注册这个回调函数。

// StatusCallbackProc: 状态回调函数

// hWnd: 捕获窗体句柄

// nID: 当前状态的状态码

// lpStatusText: 当前状态的文本字符

//

LRESULT PASCAL StatusCallbackProc(HWND hWnd, int nID,

LPSTR lpStatusText)

{

if (!ghWndMain)

return FALSE;

if (nID == 0) { // 清除旧的状态信息

SetWindowText(ghWndMain, (LPSTR) gachAppName);

return (LRESULT) TRUE;

}

// 显示状态ID和状态文本..

wsprintf(gachBuffer, “Status# %d: %s”, nID, lpStatusText);

SetWindowText(ghWndMain, (LPSTR)gachBuffer);

return (LRESULT) TRUE;

}

3.2.17创建一个错误的回调函数

下面例子是一个简单的错误回调函数。通过capSetCallbackOnError宏来注册回调。

// ErrorCallbackProc: 错误回调函数

// hWnd: 捕获窗口句柄

// nErrID: 错误代码

// lpErrorText: 关于错误的文本信息

//

LRESULT PASCAL ErrorCallbackProc(HWND hWnd, int nErrID,

LPSTR lpErrorText)

{

if (!ghWndMain)

return FALSE;

if (nErrID == 0) // Starting a new major function.

return TRUE; // 清除旧的错误

// 显示错误ID和错误文本信息

wsprintf(gachBuffer, “Error# %d”, nErrID);

MessageBox(hWnd, lpErrorText, gachBuffer,

MB_OK | MB_ICONEXCLAMATION);

return (LRESULT) TRUE;

}

3.2.18创建一个帧回调函数

下面是一个简单的帧回调函数。通过capSetCallbackFrame宏来注册回调函数。

// FrameCallbackProc: 帧回调函数

// hWnd: 捕获窗体句柄

// lpVHdr: 指向一个包含帧信息的数据结构体

//

LRESULT PASCAL FrameCallbackProc(HWND hWnd, LPVIDEOHDR lpVHdr)

{

if (!ghWndMain)

return FALSE;

wsprintf(gachBuffer, “Preview frame# %ld “, gdwFrameNum++);

SetWindowText(ghWndMain, (LPSTR)gachBuffer);

return (LRESULT) TRUE ;

}

石头的那种追求。。。

我到底想要什么。。美好的事物大家想要想。。你不去努力。别人就会去努力。。。。同样的道理。。你不去学英语。。别人就会去学。。这样下来你就跟别人有一大截差距。。

给自己一个目标。。给自己一个前进的动力。。。。。

享受生活给自己带来的乐趣。。目标是一个方向标。时刻谨记。体验到达目标后的那种喜悦。。体验奔向目标途中的艰难,困苦。。。。即使达不到既定的目标。。也观赏了沿途的风景。。只赚不赔。嘿嘿。。可有时候为了达到目标。。自己却忘记了欣赏沿途的风景。。失去了生活的乐趣。。忘记了怎样享受生活。。。。。生活很美好。。。石头现在觉得很好。。生活很美好。。大学很美好。。。。

加油。石头。。。语音,视频一个都不能少。。这就是我的目标。正在享受奔向目标途中的艰难。困苦。。嘿嘿。。其乐无穷。。