10/31/2007

视频音频采集传输和播放

采集端
1)媒体服务器:spook<http://www.litech.org/spook/>, 主要工作是编译和安装,并设置spook.conf
2)USB摄像头驱动:spca5xx<http://mxhaard.free.fr/download.html>, 主要是安装驱动
需确认声卡录音和回放功能正常。通过gnomemeeting进行声音的测试,可以矫正音频上面的一些问题。

监控端
1)MPlayer,主要工作是加入 LIVE555 的支持。 VLC,主要工作是编译安装
2)源码下载:
ftp://ccoss:ccoss@192.168.28.1/pub/jiangchanglong/spook-video-audio/ 相关依赖软件包
ftp://ccoss:ccoss@192.168.28.1/pub/jiangchanglong/spook-video-audio/spca5xx-v4l1goodbye.tar.gz
ftp://ccoss:ccoss@192.168.28.1/pub/jiangchanglong/spook-video-audio/spook-20050207.tar.bz2
ftp://ccoss:ccoss@192.168.28.1/pub/jiangchanglong/spook-video-audio/live555-latest.tar.gz
ftp://ccoss:ccoss@192.168.28.1/pub/jiangchanglong/spook-video-audio/vlc-0.8.6c-5.lvn8.src.rpm
ftp://ccoss:ccoss@192.168.28.1/pub/jiangchanglong/spook-video-audio/MPlayer-1.0rc2.tar.bz2
3)最简步骤
在采集端,安装摄像头驱动 spca5xx;tar;make; 复制 spca5xx.ko 到 /lib/modules/2.6.16..../kernel/driver/video/ 执行 depmod -a 连接 USB 摄像头 打开alsamixer,开启MIC的音量控制。 安装spook。tar;configure;make 修改配置文件,可参考 ftp://ccoss:ccoss@192.168.28.1/pub/jiangchanglong/spook-video-audio/spook.conf
启动 ./spook spook.conf 在监控端,安装 MPlayer, ftp://ccoss:ccoss@192.168.28.1/pub/jiangchanglong/spook-video-audio/MPlayer-1.0rc2-1.i386.rpm
播放 rtsp://192.168.28.181:7070/webcam 也可以安装 vlc,编译过程需要很多依赖包。

10/29/2007

_stdcall, _cdecl,_pascal and _fastcall --- calling conventions

1.如果函数func是__cdecl(默认调用方式),调用时情况如下
int main()
{
//参数从右到左压栈
push 4
push 3
push 2
push 1
call func
add esp 0x10 //调用者恢复堆栈指针esp,4个参数的大小是0x10(4x4)
}

2.如果函数func是__stdcall,调用时情况如下
int main()
{
//参数从右到左压栈
push 4
push 3
push 2
push 1
call func
//恢复堆栈指针由被调用者func负责,方法是"ret 0x10"
}

3.如果函数func是__pascal,调用情况如下
int main()
{
//参数从左到右压栈
push 1
push 2
push 3
push 4
call func
//恢复堆栈指针由被调用者func负责,方法是"ret 0x10"
}

3.如果函数func是__fastcall,调用情况如下
int main()
{
//参数先用ecx, edx, eax传递,然后再压栈
//不进栈
//(不知为什么,帮助中写的是从左到右传递的,
//是不是错了,还是BCB6和BCB5的不一样)
push 4
mov ecx 3
mov edx 2
mov eax 1
call func
//恢复堆栈指针由被调用者func负责,方法是"ret 0x04",
//因为只进栈一个参数,其余用寄存器传递,所以用ret 0x04恢复
}

10/27/2007

Linux 中程序运行时存储器映像

每个程序都有一个运行时存储器映像:


一个典型的ELF可执行目标文件信息布局如下:

10/26/2007

在程序内部获得 call back trace

打印出程序运行时的堆栈情况:

#include
#include
#include

/* Obtain a backtrace and print it to stdout.
*/void print_trace(void)
{
void *array[10];
size_t size;
char **strings;
size_t i;
size = backtrace(array, 10);
strings = backtrace_symbols(array, size);
printf("Obtained %zd
stack frames.\n", size);
for (i = 0; i < size; i++)
printf("%s\n", strings[i]);
free(strings);
}

/* A dummy function to make the backtrace more interesting. */
void dummy_function(void)
{
print_trace();
}

int main(void)
{
dummy_function();
return 0;
}

gcc -rdynamic -o t t.c

注:-rdynamic (其实时传给ld的参数),否则可能不会打印出函数名称,而代之以偏移量。

参考:http://www.delorie.com/gnu/docs/glibc/libc_665.html

10/25/2007

调用函数时,寄存器到底发生了那些变化?

linux x86 gcc3.2.3 AT&T格式的汇编

代码如下:


void
fun()
{
int a = 'A';
}

void main()
{
int b;
fun();

return;
}


编译
gcc -g -o t t.c

开始调试
[sanool@sanool ex2]$ gdb t
GNU gdb Red Hat Linux (6.0post-0.20031117.6rh)
Copyright 2003 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i386-redhat-linux-gnu"...(no debugging symbols found)...Using host libthread_db library "/lib/tls/libthread_db.so.1".

(gdb) disas main
Dump of assembler code for function main:
0x08048323 : push %ebp
0x08048324 : mov %esp,%ebp
0x08048326 : sub $0x8,%esp
0x08048329 : and $0xfffffff0,%esp
0x0804832c : mov $0x0,%eax
0x08048331 : sub %eax,%esp
0x08048333 : call 0x8048314
0x08048338 : leave
0x08048339 : ret
0x0804833a : nop
0x0804833b : nop
End of assembler dump.
(gdb) disas fun
Dump of assembler code for function fun:
0x08048314 : push %ebp
0x08048315 : mov %esp,%ebp
0x08048317 : sub $0x4,%esp
0x0804831a : movl $0x41,0xfffffffc(%ebp)
0x08048321 : leave
0x08048322 : ret
End of assembler dump.

解释如下:
**当程序下一步执行 0x08048333 : call 0x8048314
esp = 0xbfffe660 (运行时)
ebp = 0xbfffe668 (运行时)
eip = 0x08048333

**然后执行 call 0x8048314 也就是
push %eip ( 相当于 sub $4 %esp 再 mov %eip %esp )
movl $0x8048314, %eip

则0xbfffe65c 处为 eip = 0x08048338
且esp = 0xbfffe65c
eip = 0x8048314
ebp = 0xbfffe668

**执行0x08048314 : push %ebp后
esp = 0xbfffe658
ebp = 0xbfffe668
0xbfffe658处的值为 ebp = 0xbfffe668

**继续0x08048315 : mov %esp,%ebp
将esp的值赋值给ebp
即 ebp = esp = 0xbfffe658

**开始执行 0x08048321 : leave 前
eip = 0x08048321
ebp = 0xbfffe658
esp = 0xbfffe654

**开始执行 0x08048321 : leave 时
即进行
movl %ebp, %esp ( 即 esp = ebp = 0xbfffe658)
pop %ebp ( 也就是 mov %esp,%ebp 再 add $4,%esp )

此时 ebp = 0xbfffe668 回到了原函数的ebp值,

**再执行 0x08048322 : ret
即 pop %eip
( 也就是 mov %esp,%eip 再 add $4,%esp )
此时 eip = 0x08048338
程序继续执行 main 中的 leave

调用fun函数结束

补充:
i reg //观察寄存器的值 (注意ebp esp eip)

x/20x $esp //查看内存中$esp(如0xbfffef50)后面的数据内容

10/15/2007

大规模并行计算

http://code.google.com/edu 可获得华盛顿大学编写的所有课程资料,以及其他用于帮助学习这一前沿技术的工具和资源。
如果想了解此类项目的意义,请观看系列讲座视频(共五部分,原是谷歌工程部实习生的学习资料),其中介绍了大规模集群计算的一些基本概念。

10/09/2007

cut、tr 等命令格式化字符串

CurreIP=$(wget http://freedns.afraid.org/dynamic/check.php -o /dev/null -O /dev/stdout | grep Detected | cut -d : -f 2 | cut -d '<' -f 1 | tr -d " ")

cat check.php :

Detected IP : 210.73.65.34, 210.73.65.77
HTTP_CLIENT_IP :
HTTP_X_FORWARDED_FOR : 210.73.65.34, 210.73.65.77
REMOTE_ADDR : 72.20.25.132