攀翔's profilePromiscuous的2007PhotosBlogListsMore Tools Help

攀翔 张

Occupation
Location
percy_zhang#at#hotmail.com
There are no photo albums.
No list items have been added yet.

Promiscuous的2007

03 February

网关程序消耗大量内存的原因

关于写文件时,free命令显示大量内存消耗的问题 
回应这篇文章回复 


不要随便使用内存泄漏的说法——内存正常消耗和泄漏是完全不同的两回事

不要用free去查看进程使用的内存情况,改用ps或top

free看到的内容中,应该关心的是-/+ buffers/cache那一行
Linux的Kernel会把尽可能多的空闲内存拿去做文件缓存以提高IO效率,
而这部分内存随时可以释放出来供进程使用,并不算是被消耗,更不是泄漏

31 January

low

 
   homesick, 难以派遣.  吃零食没味道, 打游戏没兴趣. 艾.
28 January

自包含和重复包含头文件

 
  cu上的一个关于C的问题, 很巧妙
 
  #include __FILE__   自包含来实现一个函数体实现多个功能/流程相似的函数 避免重复代码

   #ifndef XVID_AUTO_INCLUDE

#include "../portab.h"
#include "qpel.h"

/* Quarterpel FIR definition
************************************************************************
****/

static const int32_t FIR_Tab_8[9][8] = {
    { 14, -3,  2, -1,  0,  0,  0,  0 },
    { 23, 19, -6,  3, -1,  0,  0,  0 },
    { -7, 20, 20, -6,  3, -1,  0,  0 },
    {  3, -6, 20, 20, -6,  3, -1,  0 },
    { -1,  3, -6, 20, 20, -6,  3, -1 },
    {  0, -1,  3, -6, 20, 20, -6,  3 },
    {  0,  0, -1,  3, -6, 20, 20, -7 },
    {  0,  0,  0, -1,  3, -6, 19, 23 },
    {  0,  0,  0,  0, -1,  2, -3, 14 }
};

static const int32_t FIR_Tab_16[17][16] = {
    { 14, -3,  2, -1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 },
    { 23, 19, -6,  3, -1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 },
    { -7, 20, 20, -6,  3, -1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0 },
    {  3, -6, 20, 20, -6,  3, -1,  0,  0,  0,  0,  0,  0,  0,  0,  0 },
    { -1,  3, -6, 20, 20, -6,  3, -1,  0,  0,  0,  0,  0,  0,  0,  0 },
    {  0, -1,  3, -6, 20, 20, -6,  3, -1,  0,  0,  0,  0,  0,  0,  0 },
    {  0,  0, -1,  3, -6, 20, 20, -6,  3, -1,  0,  0,  0,  0,  0,  0 },
    {  0,  0,  0, -1,  3, -6, 20, 20, -6,  3, -1,  0,  0,  0,  0,  0 },
    {  0,  0,  0,  0, -1,  3, -6, 20, 20, -6,  3, -1,  0,  0,  0,  0 },
    {  0,  0,  0,  0,  0, -1,  3, -6, 20, 20, -6,  3, -1,  0,  0,  0 },
    {  0,  0,  0,  0,  0,  0, -1,  3, -6, 20, 20, -6,  3, -1,  0,  0 },
    {  0,  0,  0,  0,  0,  0,  0, -1,  3, -6, 20, 20, -6,  3, -1,  0 },
    {  0,  0,  0,  0,  0,  0,  0,  0, -1,  3, -6, 20, 20, -6,  3, -1 },
    {  0,  0,  0,  0,  0,  0,  0,  0,  0, -1,  3, -6, 20, 20, -6,  3 },
    {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, -1,  3, -6, 20, 20, -7 },
    {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, -1,  3, -6, 19, 23 },
    {  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0, -1,  2, -3, 14 }
};

/* Implementation
************************************************************************
****/

#define XVID_AUTO_INCLUDE

/* 16x? filters */

#define SIZE  16
#define TABLE FIR_Tab_16

#define STORE(d,s)  (d) = (s)
#define FUNC_H      H_Pass_16_C
#define FUNC_V      V_Pass_16_C
#define FUNC_HA     H_Pass_Avrg_16_C
#define FUNC_VA     V_Pass_Avrg_16_C
#define FUNC_HA_UP  H_Pass_Avrg_Up_16_C
#define FUNC_VA_UP  V_Pass_Avrg_Up_16_C

#include __FILE__   /* self-include ourself */

/* note: B-frame always uses Rnd=0... */
#define STORE(d,s)  (d) = ( (s)+(d)+1 ) >> 1
#define FUNC_H      H_Pass_16_Add_C
#define FUNC_V      V_Pass_16_Add_C
#define FUNC_HA     H_Pass_Avrg_16_Add_C
#define FUNC_VA     V_Pass_Avrg_16_Add_C
#define FUNC_HA_UP  H_Pass_Avrg_Up_16_Add_C
#define FUNC_VA_UP  V_Pass_Avrg_Up_16_Add_C

#include __FILE__   /* self-include ourself */

#undef SIZE
#undef TABLE

/* 8x? filters */

#define SIZE  8
#define TABLE FIR_Tab_8

#define STORE(d,s)  (d) = (s)
#define FUNC_H      H_Pass_8_C
#define FUNC_V      V_Pass_8_C
#define FUNC_HA     H_Pass_Avrg_8_C
#define FUNC_VA     V_Pass_Avrg_8_C
#define FUNC_HA_UP  H_Pass_Avrg_Up_8_C
#define FUNC_VA_UP  V_Pass_Avrg_Up_8_C

#include __FILE__   /* self-include ourself */

/* note: B-frame always uses Rnd=0... */
#define STORE(d,s)  (d) = ( (s)+(d)+1 ) >> 1
#define FUNC_H      H_Pass_8_Add_C
#define FUNC_V      V_Pass_8_Add_C
#define FUNC_HA     H_Pass_Avrg_8_Add_C
#define FUNC_VA     V_Pass_Avrg_8_Add_C
#define FUNC_HA_UP  H_Pass_Avrg_Up_8_Add_C
#define FUNC_VA_UP  V_Pass_Avrg_Up_8_Add_C

#include __FILE__   /* self-include ourself */

#undef SIZE
#undef TABLE
#undef XVID_AUTO_INCLUDE

...
... 与话题无关,省略
...

/************************************************************************
*****
* "reference" filters impl. in plain C
************************************************************************
****/

#ifdef XVID_AUTO_INCLUDE

static
void FUNC_H(uint8_t *Dst, const uint8_t *Src, int32_t H, int32_t BpS, int32_t
Rnd)
{
    while(H-->0) {
        int32_t i, k;
        int32_t Sums[SIZE] = { 0 };
        for(i=0; i<=SIZE; ++i)
            for(k=0; k<SIZE; ++k)
                Sums[k] += TABLE[i][k] * Src[i];

        for(i=0; i<SIZE; ++i) {
            int32_t C = ( Sums[i] + 16-Rnd ) >> 5;
            if (C<0) C = 0; else if (C>255) C = 255;
            STORE(Dst[i], C);
        }
        Src += BpS;
        Dst += BpS;
    }
}

static
void FUNC_V(uint8_t *Dst, const uint8_t *Src, int32_t W, int32_t BpS, int32_t
Rnd)
{
    while(W-->0) {
        int32_t i, k;
        int32_t Sums[SIZE] = { 0 };
        const uint8_t *S = Src++;
        uint8_t *D = Dst++;
        for(i=0; i<=SIZE; ++i) {
            for(k=0; k<SIZE; ++k)
                Sums[k] += TABLE[i][k] * S[0];
            S += BpS;
        }

        for(i=0; i<SIZE; ++i) {
            int32_t C = ( Sums[i] + 16-Rnd )>>5;
            if (C<0) C = 0; else if (C>255) C = 255;
            STORE(D[0], C);
            D += BpS;
        }
    }
}

static
void FUNC_HA(uint8_t *Dst, const uint8_t *Src, int32_t H, int32_t BpS, int32_t
Rnd)
{
... 在本话题中的作用与前两个相同,省略
}

static
void FUNC_HA_UP(uint8_t *Dst, const uint8_t *Src, int32_t H, int32_t BpS,
int32_t Rnd)
{
...
}

static
void FUNC_VA(uint8_t *Dst, const uint8_t *Src, int32_t W, int32_t BpS, int32_t
Rnd)
{
...
}

static
void FUNC_VA_UP(uint8_t *Dst, const uint8_t *Src, int32_t W, int32_t BpS,
int32_t Rnd)
{
...
}

#undef STORE
#undef FUNC_H
#undef FUNC_V
#undef FUNC_HA
#undef FUNC_VA
#undef FUNC_HA_UP
#undef FUNC_VA_UP

#endif /* XVID_AUTO_INCLUDE */
 

 重复包含头文件 实现类似模板的功能
[root@commlab2 multi_include]# more test.h
/*test.h*/
#ifndef __MULTI_INCLUDE__
#define __MULTI_INCLUDE__
void FUNC(TYPE* x, TYPE* y)
{
        TYPE tmp;
        tmp = *x;
        *x = *y;
        *y = tmp;
}
#undef TYPE
#undef FUNC
#undef __MULTI_INCLUDE__
#endif
[root@commlab2 multi_include]# more main.c
/* main.c */
int main()
{
        #define TYPE int
        //#define swap_i FUNC
        #define FUNC swap_i
        #include "test.h"
        int a = 3, b = 4;
        swap_i(&a,&b);
        //swap_i(&a,&b);
        printf("%d %d\n",a,b);
        #define TYPE double
        #define FUNC swap_d
        #include "test.h"
        double x=3.4, y = 3.2;
        swap_d(&x,&y);
        printf("%f %f\n",x,y);
}

 
Know who invoke me
 
[root@commlab2 know_who_invoke]# more main.c
#include <iostream>
using namespace std;
void FUNC(){
        printf("this is FUNC\n");
        return;
}
#define FUNC() { FUNC(); cout<<__FILE__<<__FUNCTION__<<endl; }
void INVOKER()
{
        FUNC();
}
int main()
{
        return 1;
}
 

 

 

20 January

RTP Module OK

 
    在sagitta接通信令之后,终于实现了私有电话和SIPPhone的RTP传输,语音流经过 Private = Gateway = Asterisk = sipphone 2道中转, 质量还可以接受。 不容易啊。。。     接下来就是稳定性测试了。。  年前实现落地有望 yep~
 
    时间:11/20/06 ~ 01/17/27 其中扣除了18多天的考试时间,心情亮亮~~
14 January

SIP常见的问题与解答zz

顺路粘过来~ 原来G723是"低带宽的IP通信中最佳的选择" .... 20.8kbps ...
 

1、什么是Outbound proxy(外出代理服务器)?应当设置Outbound proxy 吗?
Outbound proxy通常是在有防火墙/NAT时用,用于处理信号及帮助多媒体数据流通过防火墙。如果用户有Outbound proxy,并且没有使用STUN或者其它的穿过防火墙/NAT的机制,则应当使用Outbound proxy。但是已经使用了STUN或者其它的穿过防火墙/NAT的工具,则不同时使用Outbound proxy。

2、用户ID(User ID)和认证ID(Authentication ID)有什么区别?
用户ID是电话的SIP地址中用户部分,而且通常是作为呼叫者ID的信息,显示在SIP软件或者电话机的LCD上。典型的情况下,用户ID是一个电话号码或者是扩展了的数字,或者是一个用户的名字。而认证ID则是严格地用于认证目的之ID,是电话机联系SIP服务器时验证用户身份用的ID。认证ID可以与用户ID相同,也可以不一样。

3、应当选用哪种语音编码方法?
通常的情况下,所有的编码方法,都能够提供良好的语音。但是低比特速率的编码,对音乐来说质量可能有些差。DTMF(双音多频传输法)音调或者传真信号在音频通道上传输(带宽不够时),有可能在远端不能解码。所以,如果带宽允许,选用G.711编码方法,G.722甚至能够给出更好的音质。
带宽允许的情况下,使用PCMU(G711u)编码。PCMU and PCMA都能够达到CD音质,但是它们消耗的带宽也最多(64kbps)。如果网络带宽比较低,可以选用低比特速率的编码方法,如G.723或 G.729,这两种编码的方法也能达到传统长途电话的音质,但是需要很少的带宽(G723需要5.3/6.3kbps,G729需要8kbps)。
如果带宽足够并且需要更好的语音质量,就使用PCMU 和 PCMA,甚至可以使用宽带的编码方法G722(64kbps),这可以提供有高保真度的音质。

4、"Voice_Frames_Per_TX"是什么意思?它与以太网的流量有什么关系?
为了减少整个 以太网/IP/RTP 的开销(这些开销是由54字节的报文头引起的),多个语音帧可以包在单个以太网帧中发送。不过,这会引起语音延迟。在网络带宽比较紧的时候,增加这个数量,可以提高整个语音质量。

如果RTP数据包每2.5ms发送一个(G.728),则整个以太网/IP/RTP的开销是
0.432*400 = 172.8kbps
这在公共Internet上,将会不太好。但是,如果RTP数据包每10ms发送一个,则总的以太网/IP/RTP的开销是
0.432*100=43.2kbps
如果RTP数据包每20ms发送一个,则总的以太网/IP/RTP的开销是
0.432*50=21.6kbps
推荐对G.723/iLBC编码,每30ms发送一个数据包,所有其它的编码则每20ms发送一个包。所以,对G.723/iLBC编码,Voice_Frames_Per_TX的值设置为1,对G.728设为8,对所有其它的编码设为2。

5、Voice_Frames_Per_TX应当设置为什么值?
这取决于选用什么样的编码方法,及在带宽利用率与丢包影响之间的折衷。这个值越大,则带宽利用率越高,因为更多的语音帧放到一个UDP/RTP数据包中,这样数据报文头的开销减少了。但是丢失了一个数据包,对语音质量的影响比较大。
对PCMU/PCMA,默认值是2,最大值是10
对G.723,默认值是1,最大值是32
对G726-32,默认值是2,最大值是20
对G729,默认值是2,最大值是64
对G728,默认值是4,最大值是64


6、以太网加到RTP数据包上的开销是多少?
对于语音数据,在以太网的IP网上传输,一个RTP数据包包含54字节(或者432比特)的报文头。这54字节包含14字节的以太网头,20字节的IP头,8字节的UDP头,和12字节的RTP头。

7、各种编码方法的帧的速率及比特速率是多少?
G.711 是10ms的帧长度, 64kbps的比特速率
G.722 是10ms的帧长度, 64kbps的比特速率
G.726-32 (也叫 G.721)是10ms的帧长度,32kbps的比特速率
G.728 是2.5ms的帧长度, 16kbps的比特速率
G.729 是10ms的帧长度, 10kbps的比特速率
G.723 是30ms的帧长度, 5.3kbps或者6.4kbps的比特速率
iLBC 是20ms或者30ms的帧长度,15.2kbps 或者 13.3kbps 的比特速率

8、为什么G.723是低带宽的IP通信中最佳的选择?
对G.723,其帧速率是30ms发一个数据包,编码的速率是5.3kbps (20 bytes 每 30ms)或者6.4kbps (24 bytes 每 30ms)。其总的比特速率是
5.3 + 0.432*33.3 = 19.7kbps,
或者 6.4 +0.432*33.3 =20.8kbps。
如此低的比特速率,很适合于在28.8kbps拔号上网的时使用。再与其它的技术配合,如数据链路层压缩、静默抑制,及舒适的噪声产生,总的带宽可能更低。

9、什么是STUN服务,我是否需要使用STUN服务?
STUN 代表UDP数据包简单地穿过NAT(Simple Traversal of UDP over NAT)。这是一个协议,当一个IP电话机在NAT后面时,IP电话机可以使用这个协议检测到NAT的存在,并判断NAT的类型。一个IP电话机如果支持 STUN协议,它就可以发送一系列的STUN查询,到公共的因特网上的STUN服务器,这样就可以得到NAT上映射到话机的公网IP地址和端口。IP电话机就可以智能地修改SIP/SDP消息中的私有IP地址。这样SIP信令和RTP多媒体数据就可以成功地穿过NAT,而不需要修改NAT的任何配置。
STUN代表了对大多数NAT的解决方法,但是不适合于对称的NAT。也就是说,绝大多数的SOHO路由器都是非对称的NAT,在这种情况下,使用STUN是成功的。但是STUN协议不能穿过对称的NAT。如果你的路由器是对称的NAT,则不要使用STUN。

10、如果我的电话机使用了STUN服务,能够正常地工作,我还需要设置外出代理服务器(Outbound proxy)吗?
不需要设置Outbound proxy。