| Perfil de Matthew记性不好的MatthewBlogListas | Ayuda |
|
18/09/2007 [FW]A history of video conferencing (VC) technologyfrom 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.
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. [2] Randy Cole, "PVP - A Packet Video Protocol", Internal Document, USC/ISI, July 1981. [3] Eve M. Schooler, "A Distributed Architecture for Multimedia Conference Control", ISI research report ISI/RR-91-289, November 1991. [4] DARTnet : A trans-continental IP network of about a dozen research sites connected by T1 trunks. [5] Tim Dorcey, "CU-SeeMe Desktop VideoConferencing Software", Connexions, Volume 9, No.3, March 1995. [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. [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." [8] For the November 1992 IETF and several events since then, they have used two other programs. [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. [10] In 1991, 5 high school friends established ClassX, a start-up software company, at Raanana, Israel. [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." [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)." [13] H.323 : "Visual telephone systems and equipment for Local Area Networks which provide a non-guaranteed Quality of Service." (original title) [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." [15] SIP is a simple signaling protocol for Internet conferencing and telephony. The pioneering video conferencing tools :
19/06/2007 [Vs.net2003]/GR 编译开关做个标志,晚上碰到这个问题,一直不得解,导致程序运行时,调用dynamic_cast总失败,返回NULL。VS2005默认已经打开这个开关,vs.net2003好像是没有打开的。详解如下,摘自MSDN [quote] Adds code to check object types at run time. /GR[-] RemarksWhen /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
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。 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 02/06/2007 [News]2007年中国软件业务收入前百家企业名单昨天上公司主页,一不小心发现我们公司排到了第58位,真是想不到,不管怎么样,希望公司越来越好,越来越强大。 附百强名单: 2007年(第六届)中国软件业务收入前百家企业名单 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版本。 #include <sys/types.h> #ifndef INFTIM #ifndef MAXLINE #ifndef OPEN_MAX int main(int argc, char **argv) memset(buf, 0, sizeof(char)*MAXLINE); listenfd = socket(PF_INET, SOCK_STREAM, 0); bzero(&servaddr, sizeof(servaddr)); /* set socket reuse, otherwise it will bind failed sometimes after the program exit. */ if ((bind(listenfd, (struct sockaddr*)&servaddr, sizeof(struct sockaddr_in))) == -1){ if ((listen(listenfd, 10)) == -1){ client[0].fd = listenfd; for (;;){ if (client[0].revents & POLLIN){ /* new client connection */ for (i = 1; i < OPEN_MAX; ++i){ client[i].events = POLLIN; printf("receive connection from %s:%d\n", inet_ntoa(cliaddr.sin_addr), ntohs(cliaddr.sin_port)); if (--nready <= 0) for (i = 1; i <= maxi; ++i){ /* check all clients for data */ if (--nready <= 0) return 0; #include <unistd.h> #ifndef MAX_EVENTS /* forward declare function proto type */ int main(int argc, const char *argv[]) listenfd = socket(PF_INET, SOCK_STREAM, 0); /* set reuse address flag */ /* set non-blocking */ /* initialize the variable to "zero" */ servaddr.sin_family = AF_INET; /* bind the special address and port */ if ((listen(listenfd, 10)) == -1){ /* create an epoll instance */ do{ for (n = 0; n < nfds; ++n){ printf("accpet new connection from:%s:%d\n", inet_ntoa(clientaddr.sin_addr), ntohs(clientaddr.sin_port)); setnonblocking(client); /* release the epoll instance */ return 0; int handle_packet(int sockfd) printf("active socket file descriptor: %d\n", sockfd); return 0; int setnonblocking(int sockfd) if ((flags = fcntl(sockfd, F_GETFL, 0)) < 0){ return 0; 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? 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: So how does P2Pnat Media actually work? The gatekeeper collects network topography information from the endpoint upon registration. Information collected: 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 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) 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 ApprovedYour project registration for SourceForge.net has been approved. 09/04/2007 [Mark]The Open Source DefinitionIntroduction 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的系统上, 自己实验了一下,感觉以下几种解决办法是可行的: msvcm80d.dll 把这几个文件拷贝到目标机器上,与运行程序同一文件夹或放到system32下,就可以正确运行了。 其他release版、MFC程序什么的都是拷redist下相应文件夹下的文件就可以了,文件夹后都有标识! 方法二: 方法三: 工程-》属性-》配置属性-》常规-》MFC的使用,选择“在静态库中使用mfc” 方法四: 你的vc8安装盘上找到再分发包vcredist_xxx.exe和你的程序捆绑安装 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. Linkage04/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 So arr[N] == *(arr + N) then we apply the transitivity rule on the So given array arr then 2[arr] will give the third element in arr. And int main() |
|
|