2012年4月

mjpg-streamer 安装

mjpg-streamer 源码


[root@fire ~]# svn co https://mjpg-streamer.svn.sourceforge.net/svnroot/mjpg-streamer mjpg-streamer

[root@fire mjpg-streamer]# ls -l
总用量 24
drwxr-xr-x. 3 root root 4096 4月 29 11:31 doc
drwxr-xr-x. 4 root root 4096 4月 29 11:31 mjpeg-client
drwxr-xr-x. 6 root root 4096 4月 29 11:31 mjpg-streamer
drwxr-xr-x. 6 root root 4096 4月 29 11:31 mjpg-streamer-experimental
drwxr-xr-x. 3 root root 4096 4月 29 11:31 udp_client
drwxr-xr-x. 3 root root 4096 4月 29 17:07 uvc-streamer

编译:


[root@fire mjpg-streamer/mjpg-streamer-experimental]# make

[root@fire mjpg-streamer/uvc-streamer]# make (这里会编译下面的所有组件)

这里可能会出现错误,显示linux/videodev.h找不到,这是因为内核版本太高的原因,videodev.h这个接口不支持了。具体解决方案google下就可以了。我后来是换了ubuntu 10.10然后就能顺利配置了。

[root@fire mjpg-streamer/mjpg-streamer-experimental]# ./start.sh

如果启动后显示

Unable to set format: Invalid argument
Init v4L2 failed !! exit fatal
i: init_VideoIn failed

查看http://www.firefoxbug.com/?p=942

查看视频流


本机查看输入 http://localhost:8080/

其它电脑查看输入:  http://本机ip:8080/

mjpg-streamer:Init v4L2 failed

系统:ubuntu 10.10

启动: ./start.sh

错误内容:

root@fire:~/mjpg-streamer/mjpg-streamer-experimental# ./start.sh
MJPG Streamer Version: svn rev: 3:160
 i: Using V4L2 device.: /dev/video0
 i: Desired Resolution: 640 x 480
 i: Frames Per Second.: -1
 i: Format............: JPEG
Unable to set format: 1196444237 res: 640x480
 Init v4L2 failed !! exit fatal
 i: init_VideoIn failed

错误原因:
市面上大部分摄像头都是支持YUV的,而不是JPEG的。mjpg-stream支持JPEG和YUV两种格式。

[fire@fire mjpg-streamer]$ cd mjpg-streamer-experimental/plugins/input_uvc/
[fire@fire input_uvc]$ vim input_uvc.c

int input_init(input_parameter *param, int id)
{
    char *dev = "/dev/video0", *s;
    int width = 640, height = 480, fps = -1, format = V4L2_PIX_FMT_MJPEG, i;

    /* initialize the mutes variable */
    if(pthread_mutex_init(&cams[id].controls_mutex, NULL) != 0) {
        IPRINT("could not initialize mutex variable\n");
        exit(EXIT_FAILURE);
    }
.......................

format = V4L2_PIX_FMT_YUYV
以上就设置了默认的图像格式,重新把模块编译,之后就成功了!

source exec fork 区别

#1.sh
#!/bin/bash

A=B
echo "PID for 1.sh before exec/source/fork ; $$"
export A
echo "1.sh : \$A is $A"
case $1 in 
	exec)
		echo "using exec..."
		exec ./2.sh
		;;
	source)
		echo "using source..."
		. ./2.sh
		;;
	*)
		echo "using fork by default..."
		./2.sh
		;;	
esac 

echo "PID for 1.sh after exec/source/fork : $$"
echo "1.sh : \$A is $A"
#2.sh
#!/bin/bash

echo "PID for 2.sh : $$ "
echo "2.sh get \$A=$A from 1.sh"
A=C
export A
echo "2.sh : \$A is $A"

source测试


[root@fire Shell]# ./1.sh source
PID for 1.sh before exec/source/fork ; 8952
1.sh : $A is B
using source...
PID for 2.sh : 8952 
2.sh get $A=B from 1.sh
2.sh : $A is C
PID for 1.sh after exec/source/fork : 8952
1.sh : $A is C

对于参数 source,表示执行2脚本格式是:source 2.sh,由输出可以看出,source的执行就是在本shell中执行,共用原shell的环境变量

fork测试


[root@fire Shell]# ./1.sh 
PID for 1.sh before exec/source/fork ; 9019
1.sh : $A is B
using fork by default...
PID for 2.sh : 9020 
2.sh get $A=B from 1.sh
2.sh : $A is C
PID for 1.sh after exec/source/fork : 9019
1.sh : $A is B

对于普通的./xxx.sh,shell新建了一个子shell(sub-shell),sub-shell继承了父shell的环境变量,仅仅是copy版本而已,子shell里面无论怎么修改变量,在子shell退出之后,子shell的所有资源和变量都被回收。所以是不会影响父shell的。在子shell执行的时候,父shell会处于挂起状态,等待子shell结束返回。

exec测试


PID for 1.sh before exec/source/fork ; 9095
1.sh : $A is B
using exec...
PID for 2.sh : 9095 
2.sh get $A=B from 1.sh
2.sh : $A is C

对于exec也会让行程在同一个shell上执行,只是exec的调用会把原来的shell执行的行程结束了,重新开始另一个行程。

linux下GTK+配置

上面是linux下GTK+配置所需要的库,关于各个库的功能,查看http://www.gtk.org/overview.php,至于库的下载在http://www.gtk.org/download/linux.php

linux下GTK+的一键安装和配置:(fedora16和centos下配置成功)


必要组件:

# yum install gtk2 gtk2-devel gtk2-devel-docs

可选组件:

# yum install gnome-devel gnome-devel-docs

安装好之后,写个程序测试下
[cc lang="c"]
#include

int main(int argc, char *argv[])
{
GtkWidget *windows;
gtk_init(&argc,&argv);

windows = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_widget_show(windows);

gtk_main();

return 0;
}
[/cc]

GTK+程序的编译链接执行


$ gcc -o simple simple.c `pkg-config --libs --cflags gtk+-2.0`
$ ./simple
若出现对话框代表成功!

fedora16音频视频全解码

1)音频rhythmbox(mp3等常见格式):

# rpm -ivh http://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-stable.noarch.rpm

# rpm -ivh http://download1.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-stable.noarch.rpm

# yum install gstreamer-ffmpeg gstreamer-plugins-ugly gstreamer-plugins-bad

 

2)totem: mp4,rm,rmvb,flv 等常见格式

# wget http://www1.mplayerhq.hu/MPlayer/releases/codecs/all-20110131.tar.bz2

# tar jxf all-20110131.tar.bz2

# mv all-20110131 /usr/lib/codecs

 

如果是32位系统你已经可以享受各种音频和视频,64位系统请加 第3步

 

3)# wget http://www1.mplayerhq.hu/MPlayer/releases/codecs/essential-amd64-20071007.tar.bz2

# tar jxf essential-amd64-20071007.tar.bz2

# mv essential-amd64-20071007 /usr/lib64/codecs

 

至此音视频解码完毕! enjoy ~

centos下ddd的安装

  1. 从这里下载http://rpmfind.net/linux/rpm2html/search.php?query=ddd合适的包
  2. 这里得到的是*.src.rpm,解压出来里面的源码包,进入到目录下
  3. #./configure && make 可能会出现错误,错误的内容大概是是说EOF没有声明,文件是strclass.C
  4. find . -name strclass.C 找到文件的路径,然后vim编辑,在头部加入#define EOF -1
  5. 重新编译#make
  6. #make install

在fedora16上面的yum下就OK了,我在centos上yum search下,发现有ddd的包,但是需要依赖环境,无法下载,目前搞不明白。所以就去编译下了源码。

 

undefined reference to `pthread_create'

pthread_create()


头文件


#include<pthread.h>

函数声明


int pthread_create(pthread_t*restrict tidp,const pthread_attr_t *restrict_attr,void*(*start_rtn)(void*),void *restrict arg);

返回值


若成功则返回0,否则返回出错编号

 问题出现:


在链接 pthread_create 的时候出现:undefined reference to `pthread_create'

 问题原因:


thread 库不是 Linux 系统默认的库,连接时需要使用静态库 libpthread.a,所以在使用pthread_create()创        建线程,以及调用 pthread_atfork()函数建立fork处理程序时,需要链接该库。

 问题解决:


在链接的时候加-lpthread

# gcc -g test.c -o test  -lpthread

linux下添加libpcap模块

  1. 先从 http://www.linuxfromscratch.org/blfs/view/svn/basicnet/libpcap.html 下载libpcap-1.1.1.tar.gz
  2. # tar -xvf libpcap-1.1.1.tar.gz 解压
  3. cd libpcap-1.1.1/ 进入到路径下
  4. ./configure && make
  5. 这时候可能会提示:configure : error : Your operating system's lex is insufficient to compile .XXXXXXXXX 这时候只需要安装下flex #yum install flex
  6. 接着就是 # make install
  7. 这时候又可能会提示yacc -d grammar.y

    make: yacc:命令未找到

    make: *** [grammar.c] 错误 127。  # yum install byacc.i686即可
  8. 最后重新# make install 就会成功,然后去/usr/include/下查看,会出现pcap/和.h文件
  9. 接下来就可以使用库了,只要在gcc 最后加 -lpcap 即可# gcc test.c -o test -lpcap

     

    另外可以把libpcap编译生成的 .o 文件都拷贝到自己的一个目录下面,然后gcc -L XXX/*.o 来实现源代码的链接!

linux下默认删除文件到回收站(bash实现)

fedora下总是会把文件不小心删除了,所以下面的脚本把实现:文件删除默认移动到自己的回收站里面。

功能:

  1. 脚本实现删除文件或者目录到~/waste/(自己定义)。
  2. 脚本附带文件名或者目录名,则默认代表”删除”,移动到回收站。
  3. 参数 -l 代表列出回收站内容,后面不带参数则列出所有内容,可以指定文件或者目录。
  4. -d 代表清空回收站,后面不带参数为清空回收站,也可以指定删除文件或者目录。
  5. 脚本执行权限为root。

- 阅读剩余部分 -

字节序

今晚网络编程的时候又碰到了字节序的问题,这次可能要在嵌入式上开发,所以得小心点。

对于0X12345678来存储

大端模式:比较符合直观(地址从左到右增加,数据高位到地位写过去就行)


地址 : 00 01 02 03

数据 : 12 34 56 78

小段模式:比较符合逻辑(低地址存低位,高字节存高位)


地址 : 00 01 02 03

数据:78 56 34 12

拿个IP地址传输来说:


IP : 106.187.89.255

0X : 6a : bb : 59 :e1

在小端模式CPU(X86的都是)下:


地址:00 01 02 03

数据:e1:59:bb:6a

转化成网络字节序,填充到IP头里面:


地址:00 01 02 03

数据:6a:bb:59:e1

传输过程:    0~7 bit, 8 ~ 15 bit,16 ~ 23 bit, 24 ~ 31 bit

传输中数据:   6a      ,    bb        ,       59       ,       e1

接收方


接收过程也是先来先服务(数据链路层也存在传输误码率的控制,这里不考虑丢包,重传之类的了)

那么接收方(假设也是小端)得到数据要是不通过字节序转化(此时还是网络字节序):

地址:00 01 02 03

数据:6a:bb:59:e1

这个时候IP就是就是e1.59.bb.6a,点分十进制就是225.89.187.106。

所以可以用inet_ntoa()进行字节序和字符串转换。

目录树的拷贝--shell

之前写过一篇类似的目录树的完整拷贝的文章http://www.firefoxbug.com/?p=602。今早逛论坛的时候看了一个帖子,说的是:如何带文件路径拷贝?下面的回复开始的时候看不懂,后来去实践了下。下面是用法:

#tar用-来代替目标文件(这里是标准输出),-c代表创建一个打包文件,-f代表是文件,-x代表解压,-p保留文件原有属性和所有权
tar -cpf - sourdir/file | tar -xpf - -C desdir/
# tar -cpf - /home/firefox/Picture/disk2.png | tar -xpf - -C MyProgram/

(cd sourdir/ && tar -cpf - .) | (cd desdir/ && tar -xpf p -C .)
(cd /home/MyProgram/ && tar -cpf - .) | (cd /home/des/ && tar -xpf - -C .)

原本 tar 命令的用法是http://www.firefoxbug.com/?p=504,这里就是把目标文件都用“-”来代替了,"-"在这里分别表示指定目标文件作为stdout指定stdout作为目标文件 。

Makefile使用

make能作为工程管理器,把不同的源文件进行编译链接到一个工程。make每次读取的都是Makefile,它也就是普通的文本文件,只是它有它自己的语法。make主要通过时间戳的原理来进行管理工程。比如main.c的文件总是会main.o的文件更旧,因为main.o是依赖于main.c而产生的。一旦出现main.c的文件比main.o时间还新,那说明main.c肯定是被更新了,这个时候make就会把该文件重新编译。

- 阅读剩余部分 -