Perfil de Matthew记性不好的MatthewBlogListas Herramientas Ayuda
18/09/2007

[FW]A history of video conferencing (VC) technology

from this web link: http://myhome.hanafos.com/~soonjp/vchx.html
"This 'telephone' has too many shortcomings to be seriously considered as a means of communication. The device is inherently of no value to us." -- Western Union internal memo, 1876.

belltelephone[1]
The Bell system Picturephone, 1964

 

  • 1956: AT&T builds the first Picturephone test system
  • 1964: AT&T introduces Picturephone at the World's Fair, New York
  • 1970: AT&T offers Picturephone for $160 per month
  • 1971: Ericsson demonstrates the first trans-atlantic video telephone (LME) call
  • 1973 Dec: ARPAnet packet voice experiments [1]
  • 1976 Mar: Network Voice Protocol (NVP), by Danny Cohen, USC/ISI
  • 1981 Jul: Packet Video Protocol (PVP), by Randy Cole, USC/ISI [2]
  • 1982: CCITT (forerunner of the ITU-T) standard H.120 (2 Mbit/s) video coding, by European COST 211 project
  • 1982: Compression Labs begins selling $250,000 VC system, $1,000 per hour lines
  • 1986: PictureTel's $80,000 VC system, $100 per hour lines
  • 1987: Mitsubishi sells $1,500 still-picture phone
  • 1989: Mitsubishi drops still-picture phone
  • 1990: TWBnet packet audio/video experiments, vt (audio) and pvp (video) from ISI/BBN [3]
  • 1990: CCITT standard H.261 (p x 64) video coding
  • 1990 Dec: CCITT standard H.320 for ISDN conferencing
  • 1991: PictureTel unveils $20,000 black-and-white VC system, $30 per hour lines
  • 1991: IBM and PictureTel demonstrate videophone on PC
  • 1991 Feb: DARTnet voice experiments, Voice Terminal (vt) program from USC/ISI [4]
  • 1991 Jun: DARTnet packet video test between ISI and BBN.
  • 1991 Aug: UCB/LBNL's audio tool vat releases for DARTnet use
  • 1991 Sep: First audio/video conference (H.261 hardware codec) at DARTnet
  • 1991 Dec: dvc (receive-only) program, by Paul Milazzo from BBN, IETF meeting, Santa Fe [5]
  • 1992: AT&T's $1,500 videophone for home market
  • 1992 Mar: World's first MBone audio cast (vat), 23rd IETF, San Diego
  • 1992 Jul: MBone audio/video casts (vat/dvc), 24th IETF, Boston [6]
  • 1992 Jul: INRIA Videoconferencing System (ivs), by Thierry Turletti from INRIA
  • 1992 Sep: CU-SeeMe v0.19 for Macintosh (without audio), by Tim Dorcey from Cornell [7]
  • 1992 Nov: Network Video (nv) v1.0, by Ron Frederick from Xerox PARC, 25th IETF, Washington DC [8]
  • 1992 Dec: Real-time Transport Protocol (RTP) v1, by Henning Schulzrinne
  • 1993 Apr: CU-SeeMe v0.40 for Macintosh (with multipoint conferencing)
  • 1993 May: Network Video (nv) v3.2 (with color video)
  • 1993 Oct: vic initial alpha, by Steven McCanne and Van Jacobson from UCB/LBNL [9]
  • 1993 Nov: VocalChat v1.0, an audio conferencing software for Novell IPX networks [10]
  • 1994 Feb: CU-SeeMe v0.70b1 for Macintosh (with audio) , audio code by Charley Kline's Maven [11]
  • 1994 Apr: CU-SeeMe v0.33b1 for Windows (without audio), by Steve Edgar from Cornell
  • 1995 Feb: VocalTec Internet Phone v1.0 for Windows (without video)
  • 1995 Aug: CU-SeeMe v0.66b1 for Windows (with audio)
  • 1996 Jan: Real-time Transport Protocol (RTP) v2, by IETF avt-wg [12]
  • 1996 Mar: ITU-T standard H.263 (p x 8) video coding for low bit-rate communication
  • 1996 Mar: VocalTec Telephony Gateway
  • 1996 May: ITU-T standard H.324 for POTS conferencing
  • 1996 Jul: ITU-T standard T.120 for data conferencing
  • 1996 Aug: Microsoft NetMeeting v1.0 (without video)
  • 1996 Oct: ITU-T standard H.323 v1, by ITU-T SG 16 [13]
  • 1996 Nov: VocalTec Surf&Call, the first Web to phone plugin
  • 1996 Dec: Microsoft NetMeeting v2.0b2 (with video) [14]
  • 1996 Dec: VocalTec Internet Phone v4.0 for Windows (with video)
  • 1997 Jul: Virtual Room Videoconferencing System (VRVS), Caltech-CERN project
  • 1997 Sep: Resource ReSerVation Protocol (RSVP) v1, by IETF rsvp-wg
  • 1998 Jan: ITU-T standard H.323 v2
  • 1998 Jan: ITU-T standard H.263 v2 (H.263+) video coding
  • 1998 Apr: CU-SeeMe v1.0 for Windows and Macintosh (with color video), from Cornell
  • 1998 May: Cornell's CU-SeeMe development team has completed their work and has gone on to other projects
  • 1998 Oct: ISO/IEC standard MPEG-4 v1, by ISO/IEC JTC1/SC29/WG11 (MPEG)
  • 1999 Feb: Session Initiation Protocol (SIP) makes proposed standard, by IETF mmusic-wg [15]
  • 1999 Apr: Microsoft NetMeeting v3.0b (with gatekeeper)
  • 1999 Aug: ITU-T H.26L Test Model Long-term (TML) project , by ITU-T SG16/Q.6 (VCEG)
  • 1999 Sep: ITU-T standard H.323 v3
  • 1999 Oct: NAT compatible version of iVisit, v2.3b5 for Windows and Mac
  • 1999 Oct: Media Gateway Control Protocol (MGCP) v1, IETF
  • 1999 Dec: Microsoft NetMeeting v3.01 service pack 1 (4.4.3388)
  • 1999 Dec: ISO/IEC standard MPEG-4 v2
  • 2000 May: Columbia SIP user agent sipc v1.30
  • 2000 Oct: Samsung releases the first MPEG-4 streaming 3G (CDMA2000-1x) video cell phone
  • 2000 Nov: ITU-T standard H.323 v4
  • 2000 Nov: MEGACO/H.248 Protocol v1, by IETF megaco-wg and ITU-T SG 16
  • 2000 Dec: Microsoft NetMeeting v3.01 service pack 2 (4.4.3396))
  • 2000 Dec: ISO/IEC Motion JPEG 2000 (JPEG 2000, Part 3) project, by ISO/IEC JTC1/SC29/WG1 (JPEG)
  • 2001 Jun: Windows XP Messenger supports the SIP
  • 2001 Sep: World's first trans-atlantic tele gallbladder surgery (operation Lindbergh)
  • 2001 Oct: NTT DoCoMo sells $570 3G (WCDMA) mobile videophone
  • 2001 Oct: TV reporters use $7,950 portable satellite videophone to broadcast live from Afghanistan
  • 2001 Oct: Microsoft NetMeeting v3.01 (4.4.3400) on XP
  • 2001 Dec: JVT video coding (H.26L and MPEG-4 Part 10) project, by ITU-T SG16/Q.6 (VCEG) and ISO/IEC JTC1/SC29/WG 11 (MPEG)
  • 2002 Jun: World's first 3G video cell phone roaming
  • 2002 Dec: JVT completes the technical work leading to ITU-T H.264
  • 2003 May: ITU-T recommendation H.264 advanced video coding

Sources : Wall Street Journal (27 February 1996), The MBone FAQ, rem-conf listserv, The MBone listserv, CU-SeeMe listserv, RTP: Historical Notes, and few PostScripts (*.ps).

Notes and References

[1] Danny Cohen, "Specifications for the Network Voice Protocol (NVP)", RFC 741, Internet Engineering Task Force, November 1977.
"The major objective of ARPA's Network Secure Communications (NSC) project is to develop and demonstrate the feasibility of secure, high-quality, low-bandwidth, real-time, full-duplex (two-way) digital voice communications over packet-switched computer communications networks. The Network Voice Protocol (NVP), implemented first in December 1973, and has been in use since then for local and transnet real-time voice communication over the ARPANET."

[2] Randy Cole, "PVP - A Packet Video Protocol", Internal Document, USC/ISI, July 1981.
"The Packet Video Protocol (PVP) is a set of extensions to the Network Voice Protocol (NVP-II) and consists mostly of a data protocol for transmission of video data. No specific changes to the NVP-II protocol are necessary for the PVP."

[3] Eve M. Schooler, "A Distributed Architecture for Multimedia Conference Control", ISI research report ISI/RR-91-289, November 1991.
"Voice Terminal (VT) program and Packet Video Program (PVP) were originally implemented on a BBN Butterfly multiprocessor. VT and PVP digitize and packetize data, using the Netowrk Voice Protocol (NVP) for audio and the Packet Video Protocol (PVP) for video. They transmit this data across the network using the experimental Stream Protocol (SP) and the Terrestrial Wideband Network (TWBnet)."

[4] DARTnet : A trans-continental IP network of about a dozen research sites connected by T1 trunks.
November 1988, small group (MIT, BBN, UDel, ISI, SLI, PARC, LBL) led by Bob Braden of USC/ISI proposes testbed net to DARPA. This becomes DARPA Research Testbed Net (DARTnet).
DARTnet has since evolved to CAIRN, which presently connects 27 institutions in the US and Britain.

[5] Tim Dorcey, "CU-SeeMe Desktop VideoConferencing Software", Connexions, Volume 9, No.3, March 1995.
"In fact, it was Paul Milazzo's demonstration of such a tool in 1991 that inspired development of CU-SeeMe."

[6] The video used for the July 1992 Internet Engineering Task Force (IETF) was the Desktop Video Conferencing (DVC) program from BBN, written by Paul Milazzo and Bob Clements.
They have made available a receive-only program, but they retain a proprietary interest in the version that is capable of sending.
This program has since become a product, called PictureWindow.

[7] "When development of CU-SeeMe began in July 1992, the only real-time videoconferencing software for the Internet required expensive hardware which severely limited the number of potential senders and receivers. Working with Richard Cogger in the summer of 1992, Tim Dorcey wrote the original version of CU-SeeMe."
URL: http://cu-seeme.cornell.edu
As the Macintosh did not have IP multicast support, CU-SeeMe took a more traditional approach and developed a multipoint server (Reflector) that CU-SeeMe clients could connect to.

[8] For the November 1992 IETF and several events since then, they have used two other programs.
The first is the Network Video (nv) program from Ron Frederick at Xerox PARC.
Also available from INRIA is the IVS program written by Thierry Turletti.
Van Jacobson, "Old timers might remember that the first, binary-only, release of nv happened 24 hours before the November 1992 IETF where it was first used."

[9] vic (vi/deo c/onfernece) was inspired by nv. Portions of vic (the ordered dither, the nv-format codec, and some of the video capture code) were derived from the nv source code.
An early version of vic was used by the Xunet research community to carry out distributed meetings in Fall 1993.
vic change history at http://www-nrg.ee.lbl.gov/vic/CHANGES.html

[10] In 1991, 5 high school friends established ClassX, a start-up software company, at Raanana, Israel.
2 years later, 4 members of them joined VocalTec and they have developed the VocalChat v1.0-2.5, and the Internet Phone.
Ofer Shem Tov, "VocalChat early version was introduced first time in PCEXPO end of June 1993 in New York. It did half duplex calls over Novell IPX networks. VocalChat v1.0 was released in Comdex Fall, November 1993, in Las Vegas, it was a finished version of the PCEXPO product. First long distance call was done on Bell South Novell network from Atlanta to Miami. VocalChat 2.02 LAN and WAN were released in June 1994 and included voice mail, address book, TCP/IP support and support of VocalTec Compression Card (VCC) for low bandwidth links.
VocalChat GTI (Gateway To the Internet) was released in October 1994. It was focused on the Internet and required the VCC card."

[11] Charley Kline, "I got annoyed at the Fall 1992 IETF when told that the only serious platform for multimedia conferencing was a hefty Unix workstation. I figured a Macintosh has better audio processing ability than a Sun (true!), so set about to write an audio conferencing tool for the Macintosh that would interoperate with the popular vat program for Unix."
URL: http://spiffy.ci.uiuc.edu/~kline/cvk-ido.html

[12] Henning Schulzrinne, "Real-time Transport Protocol (RTP) is the Internet-standard protocol for the transport of real-time data, including audio and video. It can be used for media-on-demand as well as interactive services such as Internet telephony. RTP consists of a data and a control part. The latter is called RTP Control Protocol (RTCP)."
RTP has its roots in the early work done using Network Voice Protocol 2 (NVP-II) with vat, vt and nevot in 1991, which in turn has its roots in the Network Voice Protocol (NVP) experiences in the early 1970s.

[13] H.323 : "Visual telephone systems and equipment for Local Area Networks which provide a non-guaranteed Quality of Service." (original title)
"Packet-based multimedia communications systems." (revised title in H.323 v2 drafts)
4 main H.323 network components; Terminals, Gateways, Gatekeepers, and Multipoint Control Units (MCUs).
H.320 (N-ISDN), H.321 (B-ISDN, ATM), H.322 (GQoS LAN), H.323 (H.320 over LAN), H.324 (SCN), H.324 M (Mobile).

[14] Toby Nixon, "Microsoft NetMeeting version 2.0 and below uses an alternative call setup procedure that is permitted for combined H.323/T.120 terminals. Because NetMeeting was originally a T.120-based product (without H.323 support), it sets up the T.120 (data conference) call first, and then the H.323 (audio and video conference) call."
Current versions of NetMeeting are not compliant with the H.323 standard as they do not attempt to register with a gatekeeper, a required function.

[15] SIP is a simple signaling protocol for Internet conferencing and telephony.
H.323 is an ITU-T standard, while SIP is the IETF approach.

The pioneering video conferencing tools :

  • CU-SeeMe [video]
    from Cornell University
    platform : Apple Macintosh
  • DVC [video]
    from BBN
    platform : Sun SPARC
  • IVS [video & audio]
    from INRIA
    platform : Sun SPARC, HP, SGI and DEC stations
  • NV [video]
    from Xerox PARC
    platform : Sun SPARC, SGI and DEC stations

[Top]

19/06/2007

[Vs.net2003]/GR 编译开关

    做个标志,晚上碰到这个问题,一直不得解,导致程序运行时,调用dynamic_cast总失败,返回NULL。VS2005默认已经打开这个开关,vs.net2003好像是没有打开的。详解如下,摘自MSDN

[quote]

Adds code to check object types at run time.

/GR[-]

Remarks

When /GR is on, the compiler defines the _CPPRTTI preprocessor macro. In Visual C++ 2005, /GR is on by default. /GR- disables run-time type information.

Use /GR if your code uses dynamic_cast Operator or typeid. /GR does, however, cause the .rdata sections of your image to increase in size. If your code does not use dynamic_cast or typeid, using /GR- may produce a smaller image.

For more information on run-time type checking, see Run-Time Type Information in the C++ Language Reference.

To set this compiler option in the Visual Studio development environment
  1. Open the project's Property Pages dialog box. For details, see How to: Open Project Property Pages.

  2. Click the C/C++ folder.

  3. Click the Language property page.

  4. Modify the Enable Run-Time Type Info property.

To set this compiler option programmatically

 

[/quote]

18/06/2007

[VC++ tips]用vs.net 2003打开vs2005的工程

    原先的一个vs2005的工程想转移到vs.net2003上开发,因为vs2005跑在我的笔记本上速度实在不怎么样,特别是打开大工程。一直苦于没办法,今天上网无意得到一个提示,于是在google中搜索了一下,发现果然有方法,而且方法实在是非常简单,只要把工程目录下的以".vcproj"后缀结束的文件用UltraEdit32打开,把里面的"8.00“字段改成"7.10",然后把该目录下的".sln"工程文件删除,再用vs.net2003打开这个".vcproj"文件,vs.net2003会自动重建".sln"文件,选择"Rebuild",一切OK。
   这个方法来自http://www.cppblog.com/hdqqq/archive/2006/12/09/16156.html,感谢这位作者。

13/06/2007

[Life]工作两周年了

     两年前的今天2005年6月13日,第一天踏上工作之路,距离今天已经有整整两年了,感觉真快,特别是这一年来。两年来,感觉自己还是没什么变化,两年前是什么样子,现在还是什么样子,真是“出淤泥而不染”!
     接下来,是时候得更多的考虑生活的问题。不管怎么样,都要好好学习,天天向上。:)

10/06/2007

[Life]绍兴一日游

    去绍兴完全是一个临时的决定,星期五晚上10点多,在QQ上碰到在绍兴的大学同学,聊着聊着突然想到反正明天要去宁波,路过绍兴那就先在绍兴玩一下,晚上再去宁波,况且绍兴还从来没去过呢。然后问了另外一个在杭州的大学同学,刚好他也没事,那就一起过去,结伴而行太好了。第二天早上6点起床,为的是赶上最早的一班火车,结果还是没有买到票,只能冲进去补票。8:30到达绍兴,下车后绍兴给我的感觉非常好,很干净,车站没像杭州这么拥挤。在同学的带领下,我们主要是去了鲁迅故里(包括鲁迅故居、祖居、三味书屋,鲁迅纪念馆),沈园,绍兴博物馆,一直到下午5点多才结束,双腿走的实在不行了,中午的时候去了鲁迅笔下的咸亨酒店吃了午饭,还和“孔乙己”留了张合影。哈!晚上坐8:10的火车去宁波,另外一个同学做8:50的火车回杭州,分道扬镳。

07/06/2007

[转载]和一个美女同事一起电梯里被困了一夜

    已经记不清我第一次在猫扑上看到这篇文章的时候了,大概是是05年下半年吧。当时作者是以连载的方式堪出这篇文章的,我看的时候,作者写了1/3左右,但是在猫扑上已经很火了,跟帖的至少有上万人。后来也时不时地看过,不过作者写的明显没有我们读者看得快,进展很缓慢,也不知道是不是因为事情还没有发生,无法继续还是作者本人太忙,然后就没再关注了。今天无意中在一个blog发现了结局版,看过之后感觉结局还是蛮凄惨的,变得像是小说了,都不知道是真是假。如果哪个男同胞很无聊,可以看看,这是一个男的和三个女的故事。;)

本文从http://www.toplee.com/blog/ 转载过来,原作者署名:赵赶驴 转载请尊重原作者版权。

第一部分:http://www.toplee.com/blog/archives/132.html
第二部分:http://www.toplee.com/blog/archives/139.html
第三部分:http://www.toplee.com/blog/archives/299.html (结局)

02/06/2007

[News]2007年中国软件业务收入前百家企业名单

     昨天上公司主页,一不小心发现我们公司排到了第58位,真是想不到,不管怎么样,希望公司越来越好,越来越强大。

附百强名单:

2007年(第六届)中国软件业务收入前百家企业名单
序号 企 业 名 称 软件收入(万元) 
1 华为技术有限公司 2977800 
2 中兴通讯股份有限公司 1344000 
3 海尔集团公司 810603 
4 神州数码(中国)有限公司 653200 
5 浙大网新科技股份有限公司 459668 
6 熊猫电子集团有限公司 374951 
7 北京北大方正集团公司 337327 
8 同方股份有限公司 315447 
9 上海贝尔阿尔卡特股份有限公司 287484 
10 浪潮集团有限公司 280164 
11 东软集团有限公司 262574 
12 南京联创科技股份有限公司 250326 
13 微软(中国)有限公司 248395 
14 国际商业机器全球服务(中国)有限公司 239942 
15 杭州华为三康技术有限公司 227431 
16 北京甲骨文软件系统有限公司 172905 
17 中国软件与技术服务股份有限公司 164941 
18 山东中创软件工程股份有限公司 158220 
19 海信集团有限公司 141593 
20 中国民航信息网络股份有限公司 139517 
21 上海宝信软件股份有限公司 136521 
22 炬力集成电路设计有限公司 134501 
23 大唐电信科技股份有限公司 123428 
24 福州福大自动化科技有限公司 115112 
25 中国银联股份有限公司 115045 
26 烟台东方电子信息产业集团有限公司 110951 
27 用友软件股份有限公司 106249 
28 深圳市金证科技股份有限公司 97092 
29 杭州恒生电子集团有限公司 87936 
30 国电南瑞科技股份有限公司 85386 
31 盛趣信息技术(上海)有限公司 78607 
32 北京和利时系统工程股份有限公司 77556 
33 南京南瑞集团公司 77170 
34 上海西门子移动通信有限公司 73253 
35 株洲南车时代电气股份有限公司 72632 
36 武汉邮电科学研究院 69176 
37 深圳迈瑞生物医疗电子股份有限公司 68676 
38 南京南瑞继保电气有限公司 68555 
39 中控科技集团有限公司 67925 
40 安德鲁电信器材(中国)有限公司 66873 
41 启明信息股份有限公司 63886 
42 金蝶软件(中国)有限公司 63755 
43 思爱普(北京)软件系统有限公司 63027 
44 福建星网锐捷通讯股份有限公司 60089 
45 无锡华润矽科微电子有限公司 59420 
46 浙江大华技术股份有限公司 59370 
47 江苏南大苏富特软件股份有限公司 58956 
48 北京青鸟信息系统有限公司 57149 
49 信雅达系统工程股份有限公司 56375 
50 北京华胜天成科技股份有限公司 56010 
51 青岛朗讯科技通讯设备有限公司 55972 
52 云南南天电子信息产业股份公司 54323 
53 亿阳信通股份有限公司 53203 
54 大连华信计算机技术有限公司 52712 
55 杭州士兰微电子股份有限公司 50977 
56 太极计算机股份有限公司 50268 
57 大连环宇阳光集团 48136 
58 南望信息产业集团有限公司 47875    <--------------------------------------Here it is. :)
59 上海华讯网络系统有限公司 47659 
60 石化盈科信息技术有限责任公司 47435 
61 日电信息系统(中国)有限公司 46702 
62 福建榕基软件开发有限公司 46583 
63 深圳市同洲电子股份有限公司 45717 
64 上海润星网络科技有限公司 45611 
65 福建富士通信息软件有限公司 45253 
66 长江计算机(集团)公司 45177 
67 北京四方继保自动化股份有限公司 45047 
68 福建新大陆电脑股份有限公司 45000 
69 沈阳昂立信息技术有限公司 44713 
70 亚信科技(中国)有限公司 44688 
71 北京中电华大电子设计有限责任公司 44087 
72 中盈优创资讯科技有限公司 43821 
73 长城计算机软件与系统有限公司 43693 
74 北京握奇数据系统有限公司 43036 
75 中科软件科技股份有限公司 42920 
76 深圳市南凌科技发展有限公司 42805 
77 威海北洋电气集团股份有限公司 40998 
78 新思软件技术(沈阳)有限公司 40332 
79 沈阳先锋计算机工程有限公司 39800 
80 福建南威软件工程发展有限公司 39610 
81 泰豪软件股份有限公司 39184 
82 先锋软件股份有限公司 38763 
83 思创数码科技股份有限公司 38739 
84 北京东华合创数码科技股份有限公司 38285 
85 北京瑞星科技股份有限公司 37131 
86 携程旅游信息技术(上海)有限公司 37001 
87 沈阳新松机器人自动化股份有限公司 36429 
88 深圳市紫金支点技术股份有限公司 36207 
89 珠海金山软件股份有限公司 35953 
90 深圳市大族激光科技股份有限公司 35400 
91 中程科技有限公司 35375 
92 龙旗科技(上海)有限公司 35091 
93 广州数控设备有限公司 34906 
94 花旗软件技术服务(上海)有限公司 34815 
95 浙江浙大网新快威科技有限公司 34760 
96 昆明昆船物流信息产业有限公司 34647 
97 北京联想软件有限公司 33872 
98 广州海格通信产业集团有限公司 32681 
99 杭州新中大软件股份有限公司 32645 
100 江苏金智科技股份有限公司 32400

23/05/2007

[Life]硬盘

 

这是笔记本自带的硬盘,日立的40GN,5400转

这是这个周末刚刚新买的日立80G硬盘,5400转,采用的是垂直技术

 

新盘速度快,安静,发热量小;旧盘就别提了,反正是和新盘相反。不过还是感谢它勤勤恳恳为我工作了一年多,没有出过问题,

现在把它当作移动硬盘来用了。同时希望新盘也能有旧盘的质量。

[C/C++]20 issues of porting C++ code on the 64-bit platform

      这是一篇在CodeProject上的文章,关于把C++代码移植到最新的64位平台上需要注意的20个问题。看过之后,感觉写的非常好,即使不用移植到64位平台,也非常值得推荐阅读,对写跨平台,跨架构的代码有帮助。下面是它的原文地址,因为文章太长了,就没有贴出来。

20 issues of porting C++ code on the 64-bit platform

http://www.codeproject.com/useritems/20ISSUES64BIT.asp

PostScript:发现Windows Live Writter的一个诡异问题,用http://xuyao.spaces.live.com 来建立和Live Writter的关联时,Writer死活不成功,说“你的帐号无法访问该网页。。。“,用http://spaces.live.com/xuyao 就可以了,而msn messager默认打开的是前面的页面,真是搞死人了。

19/05/2007

[Linux]把slackware 11.0升级到最新的2.6.21.1

    因为这几天在学习Linux的编程实战经验,而Linux中的epoll模型是在2.5.44内核版本后才引入的,slackware 因为追求稳定,一直没有采用2.6的内核,而是采用当前最可靠成熟的2.4内核,根据最新的官方更新记录,在接下来的一个版本中默认已经采用2.6内核了,而且版本的发布应该在不远的将来。为了能够调试epoll模式,只能自己手工升级到2.6版本。
    升级过程不是非常顺利,原因在与昨天晚上第一次升级失败了,导致开机失败,说是找不到"/dev/hda3","/dev/hda4",好在升级的过程中,系统对原来的内核自动做过备份,然后自己用Windows下的grub for DOS重新启动到老内核。根据开机提示的错误信息,大概知道有一个叫rc.udev的文件运行失败,找到该文件(/etc/rc.d/rc.udev)发现在该目录下还有一个叫rc.udev.new的文件,这个文件是因为我上次把系统从10.2升级到11.0产生的,因为后来系统运行的一切良好,所以也没有关注这些事情。我试着用这个新的文件替换成老的文件,然后重新启动系统,居然成功了。估计是原来的配置文件中采用的是老的方式来读取设备信息导致的。至于怎么升级内核,在内核目录下的README中讲的非常仔细,不过配置内核还是一件比较麻烦的事情,需要对自己的机器硬件有个了解,而且里面的选项非常多,要有耐心。
    下面是学习poll模型的一个例子:
[code]
/** @file server_poll.c
* \brief a simple case to demonstrate how to use poll model
*
* \author matthew6868
*
* \revised history
* v1.0.0,matthew6868,2007-05-17,created.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <limits.h> /* for OPEN_MAX */
#include <errno.h>

#include <sys/types.h>
#include <poll.h>
#include <netinet/in.h>
#include <sys/socket.h>

#ifndef INFTIM
#define INFTIM (-1) /* infinite poll timeout */
#endif

#ifndef MAXLINE
#define MAXLINE 1500
#endif

#ifndef OPEN_MAX
#define OPEN_MAX 1024
#endif

int main(int argc, char **argv)
{
int i, maxi, listenfd, connfd, sockfd;
int nready;
ssize_t n;
char buf[MAXLINE];
int clilen;
int nreuse = 1;
struct pollfd client[OPEN_MAX];
struct sockaddr_in cliaddr, servaddr;

memset(buf, 0, sizeof(char)*MAXLINE);

listenfd = socket(PF_INET, SOCK_STREAM, 0);

bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(9898);

/* set socket reuse, otherwise it will bind failed sometimes after the program exit. */
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (const void*)&nreuse, sizeof(int));

if ((bind(listenfd, (struct sockaddr*)&servaddr, sizeof(struct sockaddr_in))) == -1){
perror("bind failed\n");
exit(EXIT_FAILURE);
}

if ((listen(listenfd, 10)) == -1){
perror("listen failed\n");
exit(EXIT_FAILURE);
}

client[0].fd = listenfd;
client[0].events = POLLIN;
for (i = 1; i < OPEN_MAX; ++i){
client[i].fd = -1; /* -1 indicates available entry */
}
maxi = 0; /* max index into client[] array */

for (;;){
nready = poll(client, maxi + 1, INFTIM);
printf("nready = %d\n", nready);

if (client[0].revents & POLLIN){ /* new client connection */
clilen = sizeof(cliaddr);
connfd = accept(listenfd, (struct sockaddr*)&cliaddr, &clilen);

for (i = 1; i < OPEN_MAX; ++i){
if (client[i].fd < 0){
client[i].fd = connfd; /* save descriptor */
break;
}
}
if (i == OPEN_MAX){
perror("too many clients");
}

client[i].events = POLLIN;
if (i > maxi)
maxi = i;

printf("receive connection from %s:%d\n", inet_ntoa(cliaddr.sin_addr), ntohs(cliaddr.sin_port));

if (--nready <= 0)
continue; /*no more readable descriptor */
}

for (i = 1; i <= maxi; ++i){ /* check all clients for data */
if ((sockfd = client[i].fd) < 0)
continue;
if (client[i].revents & (POLLIN | POLLERR)){
if ((n = read(sockfd, buf, MAXLINE)) < 0){
if (errno == ECONNRESET){ /* connection reset by client */
close(sockfd);
client[i].fd = -1;
}
else{
perror("read error\n");
}
}
else if (n == 0){
/* connection closed by client */
close(sockfd);
client[i].fd = -1;
}
else{
printf("received data:%s, date length = %d\n", buf, n);
memset(buf, 0, sizeof(buf));
}

if (--nready <= 0)
break; /* no more readable descriptors */
}
}
}

return 0;

[/code]
    下面是学习epoll模型的一个例子:
[code]
/** @file server_epoll.c
* \brief a simple case to demonstrate how to use epoll model
*
* \author matthew6868
*
* \revised histroy
* v1.0.0,matthew6868,2007-05-18,created.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

#include <unistd.h>
#include <sys/types.h>
#include <sys/epoll.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <fcntl.h>

#ifndef MAX_EVENTS
#define MAX_EVENTS 30000
#endif

/* forward declare function proto type */
int handle_packet(int sockfd);
int setnonblocking(int sockfd);

int main(int argc, const char *argv[])
{
int listenfd;
int reuse;
struct sockaddr_in servaddr;
struct sockaddr_in clientaddr;
int socklen;
int epfd; /* epoll instance */
struct epoll_event ev, events[MAX_EVENTS];
int maxevents = MAX_EVENTS;

listenfd = socket(PF_INET, SOCK_STREAM, 0);
if (listenfd <= 0){
perror("socket create failed!\n");
return -1;
}

/* set reuse address flag */
reuse = 1;
setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (const void*)&reuse, sizeof(int));

/* set non-blocking */
setnonblocking(listenfd);

/* initialize the variable to "zero" */
socklen = sizeof(struct sockaddr_in);
memset(&servaddr, 0, socklen);
memset(&clientaddr, 0, socklen);

servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(9890);
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

/* bind the special address and port */
if ((bind(listenfd, (struct sockaddr*)&servaddr, socklen)) == -1){
perror("bind failed\n");
return -2;
}

if ((listen(listenfd, 10)) == -1){
perror("listen failed\n");
return -3;
}

/* create an epoll instance */
epfd = epoll_create(MAX_EVENTS);
ev.events = EPOLLIN | EPOLLET; /* Edge triggered Mode */
ev.data.fd = listenfd;
if (epoll_ctl(epfd, EPOLL_CTL_ADD, listenfd, &ev) < 0){
printf("epoll insert listenfd error:listenfd = %d\n", listenfd);
return -4;
}

do{
int n = 0;
int nfds = epoll_wait(epfd, events, maxevents, -1);
if (nfds < 0){
printf("epoll_wait error, errno = %d,\t detail:%s\n", errno, strerror(errno));
return - 4;
}

for (n = 0; n < nfds; ++n){
if (events[n].data.fd == listenfd){
int client = accept(listenfd, (struct sockaddr*)&clientaddr, &socklen);
if (client < 0){
perror("accpet error\n");
continue;
}

printf("accpet new connection from:%s:%d\n", inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port));

setnonblocking(client);
ev.events = EPOLLIN | EPOLLET;
ev.data.fd= client;
if (epoll_ctl(epfd, EPOLL_CTL_ADD, client, &ev) < 0){
printf("epoll set insertion error:fd = %d\n", client);
return -4;
}
}
else{
handle_packet(events[n].data.fd);
}
}
}while (1);

/* release the epoll instance */
close(epfd);

return 0;
}

int handle_packet(int sockfd)
{
char buf[1500] = {0};
int len = 0;

printf("active socket file descriptor: %d\n", sockfd);
len = recv(sockfd, buf, sizeof(buf), 0);
if (len <= 0){
perror("socket recv failed or closed\n");
close(sockfd);
return -1;
}
printf("receive date:%s, length = %d\n", buf, len);

return 0;
}

int setnonblocking(int sockfd)
{
int flags;

if ((flags = fcntl(sockfd, F_GETFL, 0)) < 0){
perror("F_GETFL failed\n");
return -1;
}
flags |= O_NONBLOCK;
if ((flags = fcntl(sockfd, F_SETFL, 0 )) < 0){
perror("F_SETFL failed\n");
return -2;
}

return 0;
}
[/code]

17/05/2007

[Algorithm]计算一个数中“1”的位数的个数的算法

    今天通过www.chinaunix.net上发现的计算一个数中“1”的位数的个数的算法。转贴在BLOG上学习,
对于后面的parallel_bitcount和mit_bitcount实现还不懂,有空研究。
Fast Bit Counting Routines
counting 1 bits C implementations
/* ==========================================================================
   Bit Counting routines

   Author: Gurmeet Singh Manku    (manku@cs.stanford.edu)
   Date:   27 Aug 2002
   ========================================================================== */


#include <stdlib.h>
#include <stdio.h>
#include <limits.h>

/* Iterated bitcount iterates over each bit. The while condition sometimes helps
   terminates the loop earlier */
int iterated_bitcount (unsigned int n)
{
    int count=0;    
    while (n)
    {
        count += n & 0x1u ;    
        n >>= 1 ;
    }
    return count ;
}


/* Sparse Ones runs proportional to the number of ones in n.
   The line   n &= (n-1)   simply sets the last 1 bit in n to zero. */
int sparse_ones_bitcount (unsigned int n)
{
    int count=0 ;
    while (n)
    {
        count++ ;
        n &= (n - 1) ;     
    }
    return count ;
}


/* Dense Ones runs proportional to the number of zeros in n.
   It first toggles all bits in n, then diminishes count repeatedly */
int dense_ones_bitcount (unsigned int n)
{
    int count = 8 * sizeof(int) ;   
    n ^= (unsigned int) -1 ;
    while (n)
    {
        count-- ;
        n &= (n - 1) ;    
    }
    return count ;
}


/* Precomputed bitcount uses a precomputed array that stores the number of ones
   in each char. */
static int bits_in_char [256] ;

void compute_bits_in_char (void)
{
    unsigned int i ;    
    for (i = 0; i < 256; i++)
        bits_in_char [i] = iterated_bitcount (i) ;
    return ;
}

int precomputed_bitcount (unsigned int n)
{
    // works only for 32-bit ints
    
    return bits_in_char [n         & 0xffu]
        +  bits_in_char [(n >>  8) & 0xffu]
        +  bits_in_char [(n >> 16) & 0xffu]
        +  bits_in_char [(n >> 24) & 0xffu] ;
}


/* Here is another version of precomputed bitcount that uses a precomputed array
   that stores the number of ones in each short. */

static char bits_in_16bits [0x1u << 16] ;

void compute_bits_in_16bits (void)
{
    unsigned int i ;    
    for (i = 0; i < (0x1u<<16); i++)
        bits_in_16bits [i] = iterated_bitcount (i) ;
    return ;
}

int precomputed16_bitcount (unsigned int n)
{
    // works only for 32-bit int
    
    return bits_in_16bits [n         & 0xffffu]
        +  bits_in_16bits [(n >> 16) & 0xffffu] ;
}


/* Parallel   Count   carries   out    bit   counting   in   a   parallel
   fashion.   Consider   n   after    the   first   line   has   finished
   executing. Imagine splitting n into  pairs of bits. Each pair contains
   the <em>number of ones</em> in those two bit positions in the original
   n.  After the second line has finished executing, each nibble contains
   the  <em>number of  ones</em>  in  those four  bits  positions in  the
   original n. Continuing  this for five iterations, the  64 bits contain
   the  number  of ones  among  these  sixty-four  bit positions  in  the
   original n. That is what we wanted to compute. */

#define TWO(c) (0x1u << (c))
#define MASK(c) (((unsigned int)(-1)) / (TWO(TWO(c)) + 1u))
#define COUNT(x,c) ((x) & MASK(c)) + (((x) >> (TWO(c))) & MASK(c))

int parallel_bitcount (unsigned int n)
{
    n = COUNT(n, 0) ;
    n = COUNT(n, 1) ;
    n = COUNT(n, 2) ;
    n = COUNT(n, 3) ;
    n = COUNT(n, 4) ;
    /* n = COUNT(n, 5) ;    for 64-bit integers */
    return n ;
}


/* Nifty  Parallel Count works  the same  way as  Parallel Count  for the
   first three iterations. At the end  of the third line (just before the
   return), each byte of n contains the number of ones in those eight bit
   positions in  the original n. A  little thought then  explains why the
   remainder modulo 255 works. */

#define MASK_01010101 (((unsigned int)(-1))/3)
#define MASK_00110011 (((unsigned int)(-1))/5)
#define MASK_00001111 (((unsigned int)(-1))/17)

int nifty_bitcount (unsigned int n)
{
    n = (n & MASK_01010101) + ((n >> 1) & MASK_01010101) ;
    n = (n & MASK_00110011) + ((n >> 2) & MASK_00110011) ;
    n = (n & MASK_00001111) + ((n >> 4) & MASK_00001111) ;        
    return n % 255 ;
}

/* MIT Bitcount

   Consider a 3 bit number as being
        4a+2b+c
   if we shift it right 1 bit, we have
        2a+b
  subtracting this from the original gives
        2a+b+c
  if we shift the original 2 bits right we get
        a
  and so with another subtraction we have
        a+b+c
  which is the number of bits in the original number.

  Suitable masking  allows the sums of  the octal digits  in a 32 bit  number to
  appear in  each octal digit.  This  isn't much help  unless we can get  all of
  them summed together.   This can be done by modulo  arithmetic (sum the digits
  in a number by  molulo the base of the number minus  one) the old "casting out
  nines" trick  they taught  in school before  calculators were  invented.  Now,
  using mod 7 wont help us, because our number will very likely have more than 7
  bits set.   So add  the octal digits  together to  get base64 digits,  and use
  modulo 63.   (Those of you  with 64  bit machines need  to add 3  octal digits
  together to get base512 digits, and use mod 511.)
 
  This is HACKMEM 169, as used in X11 sources.
  Source: MIT AI Lab memo, late 1970's.
*/

int mit_bitcount(unsigned int n)
{
    /* works for 32-bit numbers only */
    register unsigned int tmp;
    
    tmp = n - ((n >> 1) & 033333333333) - ((n >> 2) & 011111111111);
    return ((tmp + (tmp >> 3)) & 030707070707) % 63;
}

void verify_bitcounts (unsigned int x)
{
    int iterated_ones, sparse_ones, dense_ones ;
    int precomputed_ones, precomputed16_ones ;
    int parallel_ones, nifty_ones ;
    int mit_ones ;
    
    iterated_ones      = iterated_bitcount      (x) ;
    sparse_ones        = sparse_ones_bitcount   (x) ;
    dense_ones         = dense_ones_bitcount    (x) ;
    precomputed_ones   = precomputed_bitcount   (x) ;
    precomputed16_ones = precomputed16_bitcount (x) ;
    parallel_ones      = parallel_bitcount      (x) ;
    nifty_ones         = nifty_bitcount         (x) ;
    mit_ones           = mit_bitcount           (x) ;

    if (iterated_ones != sparse_ones)
    {
        printf ("ERROR: sparse_bitcount (0x%x) not okay!\n", x) ;
        exit (0) ;
    }
    
    if (iterated_ones != dense_ones)
    {
        printf ("ERROR: dense_bitcount (0x%x) not okay!\n", x) ;
        exit (0) ;
    }

    if (iterated_ones != precomputed_ones)
    {
        printf ("ERROR: precomputed_bitcount (0x%x) not okay!\n", x) ;
        exit (0) ;
    }
        
    if (iterated_ones != precomputed16_ones)
    {
        printf ("ERROR: precomputed16_bitcount (0x%x) not okay!\n", x) ;
        exit (0) ;
    }
    
    if (iterated_ones != parallel_ones)
    {
        printf ("ERROR: parallel_bitcount (0x%x) not okay!\n", x) ;
        exit (0) ;
    }

    if (iterated_ones != nifty_ones)
    {
        printf ("ERROR: nifty_bitcount (0x%x) not okay!\n", x) ;
        exit (0) ;
    }

    if (mit_ones != nifty_ones)
    {
        printf ("ERROR: mit_bitcount (0x%x) not okay!\n", x) ;
        exit (0) ;
    }
    
    return ;
}


int main (void)
{
    int i ;
    
    compute_bits_in_char () ;
    compute_bits_in_16bits () ;

    verify_bitcounts (UINT_MAX) ;
    verify_bitcounts (0) ;
    
    for (i = 0 ; i < 100000 ; i++)
        verify_bitcounts (lrand48 ()) ;
    
    printf ("All bitcounts seem okay!\n") ;
    
    return 0 ;
}
14/05/2007

[VoIP]RGB与YUV 摘自《DirectShow实务精选》p51-p55 作者:陆其明

计算机彩色显示器显示色彩的原理与彩色电视机一样,都是采用R(Red)、G(Green)、B(Blue)相加混色的原理:通过发射出三种不同强度的电子束,使屏幕内侧覆盖的红、绿、蓝磷光材料发光而产生色彩。这种色彩的表示方法称为RGB色彩空间表示(它也是多媒体计算机技术中用得最多的一种色彩空间表示方法)。
根据三基色原理,任意一种色光F都可以用不同分量的R、G、B三色相加混合而成。
F = r [ R ] + g [ G ] + b [ B ]
其中,r、g、b分别为三基色参与混合的系数。当三基色分量都为0(最弱)时混合为黑色光;而当三基色分量都为k(最强)时混合为白色光。调整r、g、b三个系数的值,可以混合出介于黑色光和白色光之间的各种各样的色光。
那么YUV又从何而来呢?在现代彩色电视系统中,通常采用三管彩色摄像机或彩色CCD摄像机进行摄像,然后把摄得的彩色图像信号经分色、分别放大校正后得到RGB,再经过矩阵变换电路得到亮度信号Y和两个色差信号R-Y(即U)、B-Y(即V),最后发送端将亮度和色差三个信号分别进行编码,用同一信道发送出去。这种色彩的表示方法就是所谓的YUV色彩空间表示。
采用YUV色彩空间的重要性是它的亮度信号Y和色度信号U、V是分离的。如果只有Y信号分量而没有U、V分量,那么这样表示的图像就是黑白灰度图像。彩色电视采用YUV空间正是为了用亮度信号Y解决彩色电视机与黑白电视机的兼容问题,使黑白电视机也能接收彩色电视信号。
YUV与RGB相互转换的公式如下(RGB取值范围均为0-255):
Y = 0.299R + 0.587G + 0.114B
U = -0.147R - 0.289G + 0.436B
V = 0.615R - 0.515G - 0.100B
R = Y + 1.14V
G = Y - 0.39U - 0.58V
B = Y + 2.03U
在DirectShow中,常见的RGB格式有RGB1、RGB4、RGB8、RGB565、RGB555、RGB24、RGB32、ARGB32等;常见的YUV格式有YUY2、YUYV、YVYU、UYVY、AYUV、Y41P、Y411、Y211、IF09、IYUV、YV12、YVU9、YUV411、YUV420等。作为视频媒体类型的辅助说明类型(Subtype),它们对应的GUID见表2.3。
表2.3 常见的RGB和YUV格式
GUID    格式描述
MEDIASUBTYPE_RGB1    2色,每个像素用1位表示,需要调色板
MEDIASUBTYPE_RGB4    16色,每个像素用4位表示,需要调色板
MEDIASUBTYPE_RGB8    256色,每个像素用8位表示,需要调色板
MEDIASUBTYPE_RGB565    每个像素用16位表示,RGB分量分别使用5位、6位、5位
MEDIASUBTYPE_RGB555    每个像素用16位表示,RGB分量都使用5位(剩下的1位不用)
MEDIASUBTYPE_RGB24    每个像素用24位表示,RGB分量各使用8位
MEDIASUBTYPE_RGB32    每个像素用32位表示,RGB分量各使用8位(剩下的8位不用)
MEDIASUBTYPE_ARGB32    每个像素用32位表示,RGB分量各使用8位(剩下的8位用于表示Alpha通道值)
MEDIASUBTYPE_YUY2    YUY2格式,以4:2:2方式打包
MEDIASUBTYPE_YUYV    YUYV格式(实际格式与YUY2相同)
MEDIASUBTYPE_YVYU    YVYU格式,以4:2:2方式打包
MEDIASUBTYPE_UYVY    UYVY格式,以4:2:2方式打包
MEDIASUBTYPE_AYUV    带Alpha通道的4:4:4 YUV格式
MEDIASUBTYPE_Y41P    Y41P格式,以4:1:1方式打包
MEDIASUBTYPE_Y411    Y411格式(实际格式与Y41P相同)
MEDIASUBTYPE_Y211    Y211格式
MEDIASUBTYPE_IF09    IF09格式
MEDIASUBTYPE_IYUV    IYUV格式
MEDIASUBTYPE_YV12    YV12格式
MEDIASUBTYPE_YVU9    YVU9格式
下面分别介绍各种RGB格式。
¨ RGB1、RGB4、RGB8都是调色板类型的RGB格式,在描述这些媒体类型的格式细节时,通常会在BITMAPINFOHEADER数据结构后面跟着一个调色板(定义一系列颜色)。它们的图像数据并不是真正的颜色值,而是当前像素颜色值在调色板中的索引。以RGB1(2色位图)为例,比如它的调色板中定义的两种颜色值依次为0x000000(黑色)和0xFFFFFF(白色),那么图像数据001101010111…(每个像素用1位表示)表示对应各像素的颜色为:黑黑白白黑白黑白黑白白白…。
¨ RGB565使用16位表示一个像素,这16位中的5位用于R,6位用于G,5位用于B。程序中通常使用一个字(WORD,一个字等于两个字节)来操作一个像素。当读出一个像素后,这个字的各个位意义如下:
高字节 低字节
R R R R R G G G     G G G B B B B B
可以组合使用屏蔽字和移位操作来得到RGB各分量的值:
#define RGB565_MASK_RED    0xF800
#define RGB565_MASK_GREEN  0x07E0
#define RGB565_MASK_BLUE   0x001F
R = (wPixel & RGB565_MASK_RED) >> 11;   // 取值范围0-31
G = (wPixel & RGB565_MASK_GREEN) >> 5;  // 取值范围0-63
B =  wPixel & RGB565_MASK_BLUE;         // 取值范围0-31
¨ RGB555是另一种16位的RGB格式,RGB分量都用5位表示(剩下的1位不用)。使用一个字读出一个像素后,这个字的各个位意义如下:
高字节 低字节
X R R R R G G       G G G B B B B B       (X表示不用,可以忽略)
可以组合使用屏蔽字和移位操作来得到RGB各分量的值:
#define RGB555_MASK_RED    0x7C00
#define RGB555_MASK_GREEN  0x03E0
#define RGB555_MASK_BLUE   0x001F
R = (wPixel & RGB555_MASK_RED) >> 10;   // 取值范围0-31
G = (wPixel & RGB555_MASK_GREEN) >> 5;  // 取值范围0-31
B =  wPixel & RGB555_MASK_BLUE;         // 取值范围0-31
¨ RGB24使用24位来表示一个像素,RGB分量都用8位表示,取值范围为0-255。注意在内存中RGB各分量的排列顺序为:BGR BGR BGR…。通常可以使用RGBTRIPLE数据结构来操作一个像素,它的定义为:
typedef struct tagRGBTRIPLE {
  BYTE rgbtBlue;    // 蓝色分量
  BYTE rgbtGreen;   // 绿色分量
  BYTE rgbtRed;     // 红色分量
} RGBTRIPLE;
¨ RGB32使用32位来表示一个像素,RGB分量各用去8位,剩下的8位用作Alpha通道或者不用。(ARGB32就是带Alpha通道的RGB32。)注意在内存中RGB各分量的排列顺序为:BGRA BGRA BGRA…。通常可以使用RGBQUAD数据结构来操作一个像素,它的定义为:
typedef struct tagRGBQUAD {
  BYTE    rgbBlue;      // 蓝色分量
  BYTE    rgbGreen;     // 绿色分量
  BYTE    rgbRed;       // 红色分量
  BYTE    rgbReserved;  // 保留字节(用作Alpha通道或忽略)
} RGBQUAD;
下面介绍各种YUV格式。YUV格式通常有两大类:打包(packed)格式和平面(planar)格式。前者将YUV分量存放在同一个数组中,通常是几个相邻的像素组成一个宏像素(macro-pixel);而后者使用三个数组分开存放YUV三个分量,就像是一个三维平面一样。表2.3中的YUY2到Y211都是打包格式,而IF09到YVU9都是平面格式。(注意:在介绍各种具体格式时,YUV各分量都会带有下标,如Y0、U0、V0表示第一个像素的YUV分量,Y1、U1、V1表示第二个像素的YUV分量,以此类推。)
¨ YUY2(和YUYV)格式为每个像素保留Y分量,而UV分量在水平方向上每两个像素采样一次。一个宏像素为4个字节,实际表示2个像素。(4:2:2的意思为一个宏像素中有4个Y分量、2个U分量和2个V分量。)图像数据中YUV分量排列顺序如下:
Y0 U0 Y1 V0    Y2 U2 Y3 V2 …
¨ YVYU格式跟YUY2类似,只是图像数据中YUV分量的排列顺序有所不同:
Y0 V0 Y1 U0    Y2 V2 Y3 U2 …
¨ UYVY格式跟YUY2类似,只是图像数据中YUV分量的排列顺序有所不同:
U0 Y0 V0 Y1    U2 Y2 V2 Y3 …
¨ AYUV格式带有一个Alpha通道,并且为每个像素都提取YUV分量,图像数据格式如下:
A0 Y0 U0 V0    A1 Y1 U1 V1 …
¨ Y41P(和Y411)格式为每个像素保留Y分量,而UV分量在水平方向上每4个像素采样一次。一个宏像素为12个字节,实际表示8个像素。图像数据中YUV分量排列顺序如下:
U0 Y0 V0 Y1    U4 Y2 V4 Y3    Y4 Y5 Y6 Y8 …
¨ Y211格式在水平方向上Y分量每2个像素采样一次,而UV分量每4个像素采样一次。一个宏像素为4个字节,实际表示4个像素。图像数据中YUV分量排列顺序如下:
Y0 U0 Y2 V0    Y4 U4 Y6 V4 …
¨ YVU9格式为每个像素都提取Y分量,而在UV分量的提取时,首先将图像分成若干个4 x 4的宏块,然后每个宏块提取一个U分量和一个V分量。图像数据存储时,首先是整幅图像的Y分量数组,然后就跟着U分量数组,以及V分量数组。IF09格式与YVU9类似。
¨ IYUV格式为每个像素都提取Y分量,而在UV分量的提取时,首先将图像分成若干个2 x 2的宏块,然后每个宏块提取一个U分量和一个V分量。YV12格式与IYUV类似。
¨ YUV411、YUV420格式多见于DV数据中,前者用于NTSC制,后者用于PAL制。YUV411为每个像素都提取Y分量,而UV分量在水平方向上每4个像素采样一次。YUV420并非V分量采样为0,而是跟YUV411相比,在水平方向上提高一倍色差采样频率,在垂直方向上以U/V间隔的方式减小一半色差采样,如图2.12所示。

图2.12 YUV411和YUV420的采样格式
06/05/2007

[SQLite]奇怪的一个命名问题

晚上从http://www.codeproject.com/database/CppSQLite.asp上看了一片关于SQLite的文章,因为现在要写一个东西,需要用到数据库。然后把晚上下载的一个例子插入到我的工程文件中,结果让我碰到一件极其郁闷的事情,一开始我就把数据库命名为"aux.db",然后试着去创建它,结果老是会堵在sqlite3_open这个函数中,仔细对比网上的例子,实在是找不到有什么差别。除了数据库的名称,人家命名为"test.db",好在发现了这个问题,于是我更改了数据库的名字也为"test.db",居然成功了,接着我又把改为除"aux.db"的其它名称,都没问题。真是见鬼了,第一次用就碰到这个问题,也不知道是BUG呢还是因为"aux"是什么关键字,也没空去查。浪费我将近2个小时。。。。。。
25/04/2007

[VoIP]P2Pnat Media

[source]http://www.pacphone.com/p2pnat.html

What is P2Pnat Media?
How is P2Pnat MEDIA different to ICE?
How is P2Pnat media simple while ICE is complex?
Does P2Pnat Media proxy media as little as ICE does?
Why can this be done in H.323 and not SIP?
Is P2Pnat compatible with legacy H.323 equipment?
Does P2Pnat require additional services?
Where can I get more information on P2Pnat?
How does P2Pnat Media actually work?

What is P2Pnat Media?

P2Pnat Media or point to point through NAT media is a revolutionary method of NAT traversal in which the local NAT topography of the devices are taken into consideration when the servers decide how two devices are to flow media directly between each other.

How is P2Pnat Media different to ICE?

P2Pnat Media is different to ICE in that there is no blind end device trial and error guesses (candidates) which can add long delays in establishment of direct media connectivity. P2Pnat Media utilises network intelligence, rather than dumb device probing, to efficiently collect information on the devices's NAT status. It then uses that information when placing the call to determine how the devices are going to send the media directly and then instruct the devices on how to configure themselves to acheive direct connectivity.

How is P2Pnat media simple while ICE is complex?

P2Pnat Media has a different set of objectives. The purpose is to establish direct media quickly and efficiently between devices not just purely to find the best direct pathway. With P2Pnat Media, the Gatekeeper collects a defined set of information on the endpoints in advance and quickly compares this information and formulates how NATs are to be traversed during call setup process, removing the complexity and delay from the endpoint and hence improves media establishment timing.

To it's credit, ICE, now in draft 14, almost 4 years in development and 100 pages long, does try almost all known methods to guess how to send media directly, it supports some of the most obscure network configurations, however in the end it is at the expense of degregation in performance. It may take several seconds to work through the various candidates to find a workable candidate while the call parties wait for the media to be established..

P2Pnat media takes a more pragmatic approach and intelligently determines, with the information collected, general known methods (perhaps not the ICE optimum) that will just work, it takes a 3 step approach, 1.Can we quickly calculate a known direct method, if not 2. Can we proxy the media somewhere (either locally or remote gatekeeper, only need 1) if not 3. tell the caller that the call cannot be routed.

Does P2Pnat Media proxy media as little as ICE does?

No It has slightly higher proxying requirements than ICE. With ICE you can typically reduce the call proxying requirement to about 8% (with a centralised proxy), with P2Pnat Media it may be slightly higher at about the 10% mark however the load can be share across the gatekeepers involved (reducing proxy load to 5%). It is true to say there is a trade off with slightly higher proxying requirements for more efficient media establishment however as this proxying load can be shared, it makes P2Pnat Media overall a more efficient system.

Why can this be done in H.323 and not SIP?

In H.323 call routing is intelligent in that, prior to sending the call setup (equiv. to SIP INVITE), a request, is first sent to the local server (gatekeeper) to request a destination to send the call setup to, the gatekeeper then sends requests to other gatekeepers enquiring on behalf of the endpoint. When a destination is located, the endpoint is informed on where to send the setup message. P2Pnat Media extends this mechanism to include the abilty to exchange and process NAT traversal information.

SIP does not have this pre-call setup (INVITE) targeting facility to be able to facilitate the collection, calculation and configuration for NAT. Calls start at the INVITE which the server passes on in the hope that a server will respond.

Is P2Pnat compatible with legacy H.323 equipment?

Yes, P2Pnat Media utilises the H.460 GEF (or Generic Extensibility Framework) which is supported in all H.323v4 (standardised in 2000) or higher endpoints when means that even if a Gatekeeper may not support the feature it can still pass the fields onto other gatekeepers that do. This allows only the local gatekeepers (ones directly connected to the endpoints) need to support the feature and all other H.323 equipment just passes it on.

P2Pnat media also supports calling legacy H.323 devices by providing default inputs into the NAT Traversal calculations and allowing NAT/FW endpoints to directly connect to legacy devices without requiring proxying. .

Does P2Pnat Media require additional services?

Yes P2Pnat media requires some form of NAT friendly call signalling service such as H.460.17/18 or GnuGk Nat and as a last resort proxying facilities of H.460.19 or GnuGk. It also requires the NAT testing facilities of STUN (RFC3489) to determine the characteristics of the NAT. The gatekeeper allocates the STUN server to use and instructs the endpoint when to test and if it is to be used to traverse the NAT for a call..

Where can I get more information on P2Pnat Media?

You can view the following relevent documents:
White Paper on H.460.17/18/19 (which P2Pnat Media is Built upon)
GnuGk NAT Traversal Method (alternative to H.460.17/18/19)
Presentation of P2Pnat Media at ITU Rapporteur meeting in Shenzen China March 2007 (ppt)
Proposed H.460 Standard draft documents for P2Pnat Media (zip)

So how does P2Pnat Media actually work?

The gatekeeper collects network topography information from the endpoint upon registration.

Information collected:
1. Whether the device itself is detected as being behind a NAT/FW.
2. The detected type of NAT/FW it is detected behind.
3. If not behind NAT/FW whether the device can provide assistance to other devices behind NAT/FW.

When placing a call the gatekeeper hosting each devices registration must also supply it's own information on how it may assist in NAT traversal.

Gatekeeper information collected
1. Whether the gatekeeper can provide NAT assistance. ie Proxy media.
2. Whether the gatekeeper must proxy media. ie. The device is behind NAT/FW and server must proxy media to reach the device.

The above NAT information on both devices is collected by the caller’s gatekeeper and compared. Using a logical progression of steps the most appropriate method to connect the media is calculated. The proposed method is transmitted to the devices and the devices configure themselves as per those instructions for the particular call.

Call Flow diagrams (highly technical click to enlarge)

sample1

sample2

sample3

11/04/2007

[openh323]比较重要的更新

    今天上午,收到了openh323的CVS更新邮件:
   * $Log$
+  * Revision 2.45  2007/04/10 05:15:54  rjongbloed
+  * Fixed issue with use of static C string variables in DLL environment,
+  *   must use functional interface for correct initialisation.
+  *
   因为静态变量的问题,害得我上次耽误了好几天,最后还是放弃了最新CVS上的版本,改用Opal 2.3.1版本。虽然上次最后我也找到这个原因,不过现在作者他们自己修正了,更好,对我来说是个重大的更新,可以考虑重新转移到CVS版本的开发。

[YaPhone]Subject: SourceForge.net Project Approved

Your project registration for SourceForge.net has been approved. 


Project Information:

Project Descriptive Name: YaPhone
Project Unix Name: yaphone
CVS Server: cvs.sourceforge.net
Shell Server: shell.sourceforge.net
Web Server: yaphone.sourceforge.net


Project Administration:

The Project Admin page for your project may be accessed at
https://sourceforge.net/project/admin/?group_id=193642
after logging-in.


Service Availability for New Projects:

The DNS for your project web site may take up to 24 hours to become
active. Until DNS is active for your project, attempts to access
your project web site will result in 404 errors. Once DNS is active,
you will see an empty directory index when accessing your project
web site, until you have placed content in your project web space
(remember: project web space is provided solely for use in storing
project-related information; see the Web section of the Project Admin
page for additional details).

Your access to the project shell and CVS servers (including your
new CVS repository, which has already been initialized and is ready
for your first import) are typically available within four hours
from the time when your project was approved. If after 6 hours
your shell/CVS accounts still do not work, please submit a Support
Request (on the "alexandria" project, see below), so as that we may
look in to the problem.


Site Documentation and Support:

SourceForge.net maintains a large amount of documentation about
the SourceForge.net site and services offered to hosted projects.
This documentation may be accessed using the "Site Docs" link in the
left navbar, or directly at: https://sourceforge.net/docman/?group_id=1

Should you need to contact the SourceForge.net team, we may be reached
by submitting a Support Request at:
https://sourceforge.net/tracker/?func=add&group_id=1&atid=200001


Reminder: Acceptable Use and Project Licensing:

By using the SourceForge.net site, you agree to be bound by the terms
and conditions of the SourceForge.net Terms of Use Agreement.

SourceForge.net provides hosting solely for Open Source software
development projects; if your project is not being released under an
Open Source license, or is not developing software, please contact
the SourceForge.net team immediately for assistance. Questions
regarding acceptable use of the SourceForge.net site and resources
should be directed to the SourceForge.net team by submitting a
Support Request (see above).


Donation System:

SourceForge.net provides a donation system that allows users and
projects to accept donations on an opt-in basis.

You may opt-in your user account to receive donations at:
https://sourceforge.net/my/donate_manage.php

You may opt-in this project to receive donations at:
https://sourceforge.net/project/admin/donations.php?group_id=193642

Documentation on the donation system may be found at:
https://sourceforge.net/docman/display_doc.php?docid=20244&group_id=1


Getting Started:

A significant amount of project service information may be found
on the Project Admin pages for your project, as seen at:
https://sourceforge.net/project/admin/?group_id=193642

The Project Admin page for your project is the best place to start.
Please ensure that you have established a suitable Public Description
for your project, and have categorized your project within the Trove;
both of these operations may be performed using the "Public Info"
section of your Project Admin pages.


Enjoy the system, and please tell others about SourceForge.net. Let us know
if there is anything we can do to help you (we can always be reached
by submitting a Support Request on the "alexandria" project (see above)).

-- the SourceForge.net crew

09/04/2007

[Mark]The Open Source Definition

Introduction
Open source doesn't just mean access to the source code. The distribution terms of open-source software must comply with the following criteria:


1. Free Redistribution
The license shall not restrict any party from selling or giving away the software as a component of an aggregate software distribution containing programs from several different sources. The license shall not require a royalty or other fee for such sale.

2. Source Code
The program must include source code, and must allow distribution in source code as well as compiled form. Where some form of a product is not distributed with source code, there must be a well-publicized means of obtaining the source code for no more than a reasonable reproduction cost preferably, downloading via the Internet without charge. The source code must be the preferred form in which a programmer would modify the program. Deliberately obfuscated source code is not allowed. Intermediate forms such as the output of a preprocessor or translator are not allowed.

3. Derived Works
The license must allow modifications and derived works, and must allow them to be distributed under the same terms as the license of the original software.

4. Integrity of The Author's Source Code
The license may restrict source-code from being distributed in modified form only if the license allows the distribution of "patch files" with the source code for the purpose of modifying the program at build time. The license must explicitly permit distribution of software built from modified source code. The license may require derived works to carry a different name or version number from the original software.

5. No Discrimination Against Persons or Groups
The license must not discriminate against any person or group of persons.

6. No Discrimination Against Fields of Endeavor
The license must not restrict anyone from making use of the program in a specific field of endeavor. For example, it may not restrict the program from being used in a business, or from being used for genetic research.

7. Distribution of License
The rights attached to the program must apply to all to whom the program is redistributed without the need for execution of an additional license by those parties.

8. License Must Not Be Specific to a Product
The rights attached to the program must not depend on the program's being part of a particular software distribution. If the program is extracted from that distribution and used or distributed within the terms of the program's license, all parties to whom the program is redistributed should have the same rights as those that are granted in conjunction with the original software distribution.

9. License Must Not Restrict Other Software
The license must not place restrictions on other software that is distributed along with the licensed software. For example, the license must not insist that all other programs distributed on the same medium must be open-source software.

*10. License Must Be Technology-Neutral
No provision of the license may be predicated on any individual technology or style of interface.


sourceforge.net上载的,做个标记。
07/04/2007

[VS2005]解决“由于应用程序的配置不正确,应用程序未能启动,重新安装应用程序可能会纠正这个问题”

   今天在准备发布用VS2005写的那个程序时,拷贝到我同事机器上,双击突然出现了“由于应用程序的配置不正确,应用程序未能启动,重新安装应用程序可能会纠正这个问题“,这个问题很让我意外,以前只出现过缺少DLL的情况,而这次出现这个问题,让我一时没办法。想想,无非是两个原因引起的,要么是他没有安装VS2005的原因,要么是我的程序里依赖了其它的一些库。于是百度一下,发现好多相关主题。我是按照这个帖子解决的:

在VS2005下用C++写的程序,在一台未安装VS2005的系统上,
用命令行方式运行,提示:
“系统无法执行指定的程序”
直接双击运行,提示:
“由于应用程序的配置不正确,应用程序未能启动,重新安装应用程序可能会纠正这个问题”

以前用VC6和VS2003的话, 如果缺少库文件,是会提示缺少“**.dll”,但是用VS2005却没有这样的提示。

自己实验了一下,感觉以下几种解决办法是可行的:
方法一:
在类似C:\Program Files\Microsoft Visual Studio 8\VC\redi
st\Debug_NonRedist\x86\Microsoft.VC80.DebugCRT 下找到了下列文件:

msvcm80d.dll
msvcp80d.dll
msvcr80d.dll
Microsoft.VC80.DebugCRT.manifest

把这几个文件拷贝到目标机器上,与运行程序同一文件夹或放到system32下,就可以正确运行了。

其他release版、MFC程序什么的都是拷redist下相应文件夹下的文件就可以了,文件夹后都有标识!

方法二:
修改编译选项,将/MD或/MDd 改为 /MT或/MTd,这样就实现了对VC运行时库的静态链接,在运行时就不再需要VC的dll了。

方法三:

工程-》属性-》配置属性-》常规-》MFC的使用,选择“在静态库中使用mfc”
这样生成的exe文件应该就可以在其他机器上跑了。

方法四:

你的vc8安装盘上找到再分发包vcredist_xxx.exe和你的程序捆绑安装

转载http://blog.csdn.net/universefighter/archive/2006/10/23/1347521.aspx

05/04/2007

[C/C++]Linkage:external linkage, internal linkage and no linkage

 这几天在利用OpenH323写一个终端程序时,被一个问题困扰了好几天。当我想访问编译好后dll里的一个静态成员变量时,老实提示非法,Debug跟踪进去后,发现dll里面是好好的,一返回到我的函数里,地址就变得无效(bad pointer),而这段代码是参考Ekiga的。查了书,发现书上说静态变量采用"internal linkage"方式,当时也没有注意。今天调试的时候,仔细想想,应该是dll惹得祸,而之所以会这样,就是不同的Linkage导致的。后来发现在Bjarne Stroustrup的“The C++ Programming Language,Special Edition"的第198-200页有描述。
网上也找到相信的详细描述

"The C Book"

4.4. Linkage


04/04/2007

原来代码可以这么写

今天在google groups 的comp.lang.c++邮件列表里看到这么一段代码,真是有意思,我是第一次看到这种代码。

#include <iostream>

int main()
{
  int arr[3] = {1, 2, 3};

  for (int i = 0; i < 3; ++i)
    std::cout << i[arr] << " ";

  std::cout << std::endl;
 
  for (int j = 0; j < 3; ++j)
      std::cout << arr[j] << " ";

  std::cout << std::endl;

  return 0;
}

据说是利用了加法的交换性和传递性(commutativity and transitivity of addition)。

推导过程:
[quote]
.......

Using the transitivity of addition (meaning that A+B == B+A) we can
get some pretty ugly, but valid, syntax when indexing into arrays:

So arr[N] == *(arr + N) then we apply the transitivity rule on the
left hand giving *(N + arr) and then go back to the array-form gives
N[arr].

So given array arr then 2[arr] will give the third element in arr. And
then we replace the N with a variable and we get something like this:

int main()
{
  int arr[3] = {1, 2, 3};
  for (int i = 0; i < 3; ++i)
    std::cout << i[arr];
  return 0;
}
[/quote]

原文:
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/599be6c63ddaba57?hl=en