文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>2410摄像头问题专贴(zt)

2410摄像头问题专贴(zt)

时间:2006-05-29  来源:rwen2012

- 华恒技术支持论坛 (http://www.hhcn.com/cgi-bin/leoboard.cgi)
-- (http://www.hhcn.com/cgi-bin/forums.cgi?forum=1)
--- 2410摄像头问题专贴 (http://www.hhcn.com/cgi-bin/forums.cgi?forum=1&topic=247)

-- 作者: daily3
-- 发布时间: 2006/03/24 11:05am

一个建议:可以分类讨论问题,设置成专贴,方便查找。我就开个摄像头问题的帖子吧。
近日有不少网友问me 2410上摄像头驱动加载,那我就将我的方法贴出来。嘿嘿。若有不对之处请大家多多指正哦。
  驱动加载步骤:(模块加载方式)
1.修改/driver/usb/ov511.c中ov51x_set_default_params函数,改ov511->frame[i].format = VIDEO_PALETTE_RGB24;
为ov511->frame[i].format = VIDEO_PALETTE_RGB565;当然了这是为了在LCD上显示才这样做的(LCD是16位显示的)。
2.在arm linux的kernel目录下make menuconfig,首先<*>选择Multimedia device->下的Video for linux,然后在usb support->目录下<*>选择support for usb和<M>选择usb camera ov511 support,保存退出。
3.Make dep;make zImage;make modules然后就在/driver/usb下生成ov511.o,同时生成的zImage自动放在/tftpboot下了。
4.然后用新内核启动板子后insmod ov511.o就可以成功加载啦。

静态加载的方式还没试。嘿嘿。

-- 作者: daily3
-- 发布时间: 2006/03/24 11:08am


模块加载中的一些问题的总结,现将我遇到的贴出来。以后慢慢加喽。
1.insmod和modprobe间的一个区别试后者不会在当前目录中查找模块,它只在/lib/modules下的缺省目录下查找,这是因为该程序只是一个系统实用例程,不是一个交互工具。可以通过在/etc/modules.conf中指定自己的目录,来把它们加到缺省目录集中。
2.如果插入模块ov511.o时,出现以下信息:
Ov511.o:unresolved symbol video********之类的,说明还有其它模块videodev.o没有加啊。
3.出现错误:ov511.o:couldn’t find the kernel version this modules was compiled for。这是试图插入一个不是可装入模块的目标文件。因为在内核配置阶段,是把ov511模块静态加到内核中的,虽然看起来和可装入模块的文件名ov511.o完全一样,但是不能用insmod命令加入。

-- 作者: hn
-- 发布时间: 2006/03/24 11:29am

静态编译到内核里面就是按我们文档直接操作就是了。
编出来的驱动就打到最后生成的zImage里面了,下载到板子的SDRAM中go 30008000跑起来后插入摄像头进行测试即可。
但这样显然不如动态MODULES加载的方式方便嘛,每次都要下载整个的内核。

-- 作者: daily3
-- 发布时间: 2006/03/24 11:51am

那天加载spac5xx摄像头的驱动成功了,但是还没有找到程序来测试。知道的吱一声啦。要么自己写一个算了。多谢sunjiangbo大虾的指点。

-- 作者: daily3
-- 发布时间: 2006/03/25 02:32pm

根据hhq0216网友的实验结果,如果出现Ov511.o:unresolved symbol video********,那就<M>选中video for linux,用新生成的内核启动系统,再insmod videodev.o,insmod ov511.o就可以啦。

-- 作者: sunjiangbo
-- 发布时间: 2006/03/27 07:42pm

spac5xx摄像头驱动的测试实际上很简单,呵呵,cat /dev/video0 > pic.jpg
然后把板子上的文件ftp到pc机中,随便用看图软件看看就知道了。还有,那个网站上实际上提供了基于以太网的测试程序,自己移植一下,很简单

-- 作者: daily3
-- 发布时间: 2006/03/27 09:24pm

哦,谢谢sunjiangbo

-- 作者: daily3
-- 发布时间: 2006/03/28 03:52pm

呵呵,搞定。下载了一个servfox移植到arm上做为采集端,在pc上运行spcaview做为接受端,就可以看到图像了。。^_^不过只看到几秒钟,就出现段错误而退出。

-- 作者: daily3
-- 发布时间: 2006/03/28 04:27pm

特意装了一个Fedora4,把那个驱动包spca5xx下载,make;make install就可以直接安装了,然后通过gnomemeeting就可以看到采集的图像,三分钟搞定。可是在rh9下安装那个驱动包,make出现许多错误,至今还未解决。只能用liteEdition的patch在2410的内核中补丁成功。

-- 作者: daily3
-- 发布时间: 2006/03/30 11:40am

^_^,今天实现了接多个ov511摄像头。方法如下:买一个usb hub(我的是四口的)接到开发板的usb host上,理论上应该可以接四个摄像头,可是我只有两个,嘿嘿,所以只接两个。cat /proc/devices可以知道video capture device的major是81,再ls –l /dev看到video0的次设备号是0。两个摄像头当然要两个设备号啦,所以mknod /dev/video1 c 81 1,如果接4个,就mknod /dev/video2 c 81 2,mknod /dev//video3 c 81 3。依次类推。
  在应用程序中,一个open(dev/video0),一个open(/dev/video1)就可以测试了,我用cam2fb通过测试。两个不能同时运行,否则出现usb schedule overrun。

-- 作者: hn
-- 发布时间: 2006/03/30 11:54am

嗯,接HUB但实际还是就一个USB HOST口,肯定不能同时打开两个USB 摄像头嘛。

-- 作者: daily3
-- 发布时间: 2006/03/31 11:31am

先说明一下,我的中芯微的摄像头的驱动,应用程序都是从http://mxhaard.free.fr/下的。待会就不说明了。
针对embeded环境,有专门的patch,我用的是usb-2.4.31LE06.patch。
(1)把它放到/HHARM9-EDU/kernel/driver/usb下,解压,打补丁。就会在此目录下看到spca5xx文件夹了。可能会有一些错误,我的错误是在Makefile和config.in文件中,根据它的提示,进行相应的修改即可。Patch时会将修改方法写到Makefile.rej和config.in.rej文件中,把这两个文件里的内容加到Makefile和config.in中就行了。
(2)编译内核,进入/HHARM9-EDU/kernel,make menuconfig。我采用和上面介绍的ov511驱动的方法一样,动态加载。(M)选中SPCA5XX这一项。
(3)make dep;make zImage;make modules。就会在/HHARM9-EDU/kernel/driver/usb/spca5xx中生成spca5xx.o,spcadecoder.o,spca_core.o啦。这就是我们要的驱动。
(4)用新内核启动,insmod这三个.o文件,摄像头就加载成功啦。
应用程序servfox和spcaview的使用方法:
(1)Spcaview既可以做采集端,也可以做接收端。不过移植有点复杂^_^。所以采用servfox做为采集端,移植到arm上。修改servfox里的Makefile文件,很简单,只用将gcc改成/opt/host/armv41/bin/armv41-unknown-linux-gcc即可。Make一下,就可以在板上运行啦。
(2)Spcaview直接make即可生成可执行文件spcaview。
(3)现在就可以工作啦。在开发板上servfox –d /dev/video0 –s 640x480 –w 192.168.2.122:7070
在PC上,spcaview –w 192.168.2.120:7070就可以看到摄像头采集来的图片啦。Servfox和spcaview还有很多选项,可以通过spcaview –h 和servfox –h查阅。
^_^。有时间把spcaview和servfox的源码好好研究一下。改成从无线方式发送。

-- 作者: hn
-- 发布时间: 2006/03/31 11:37am

采集后PC显示可有多少个fps?

-- 作者: daily3
-- 发布时间: 2006/03/31 12:02pm

不知道,还没测。正在弄两个摄像头轮流采集的程序。还没搞定:(。
搞定了再测

-- 作者: sunjiangbo
-- 发布时间: 2006/03/31 02:15pm

640x480大概有15
320x240大概有25

-- 作者: wpq
-- 发布时间: 2006/03/31 02:20pm

ARM 2410上?这么高?

-- 作者: daily3
-- 发布时间: 2006/03/31 06:56pm

^_^。实现了用程序控制两个摄像头轮流采集啦。说说我的思路,写三个程序。两个用于发送端,一个用于接收端接收显示图像。发送端的两个程序一个是主程序,不停的循环,用于生成子进程来execl图像采集发送程序,采集到一定帧数就退出。每次生成的子进程,传递不同的设备名,也就是/dev/video0或/dev/video1。也就是父子进程通讯啦。

-- 作者: HHARMLIKER
-- 发布时间: 2006/04/04 03:17pm

我这里有

-- 作者: daily3
-- 发布时间: 2006/04/04 05:25pm

你有啥啊?

-- 作者: hn
-- 发布时间: 2006/04/04 05:27pm

yun4 x 1000000000000000000000000000000000000000000000000000000000000000

-- 作者: daily3
-- 发布时间: 2006/04/05 03:19pm

嗯。可以实现在一个usb hub上接一个摄像头,一个u盘,然后一边采集一边压缩成jpeg图像保存到u盘里啦

-- 作者: 奥尔特云
-- 发布时间: 2006/04/06 11:49am

你的jpeg算法是自己做的么?,你能发个源程序给我么?
我的邮箱是 [email protected]

-- 作者: hn
-- 发布时间: 2006/04/06 11:58am

应该是网上下载的吧?
JPEG压缩算法的软件网上很多的。

-- 作者: daily3
-- 发布时间: 2006/04/06 12:12pm

就是网上的,最简单的就是下个jpeg库,里面有压缩解压的实例程序

-- 作者: HHARMLIKER
-- 发布时间: 2006/04/07 09:55am

那是由于redhat的内核版本问题,2.4.20不支持spca5xx的驱动

-- 作者: HHARMLIKER
-- 发布时间: 2006/04/07 10:20am

我以模块的形式编译了spca5xx驱动,我把新编译的zImage 下载到ram运行后,lsmod spca5xx.o, insmod spca5xx.o怎么都没有那个模块呢?我看了编译的过程,明明已经用交叉编译器编译过了,而且在目录kernel/drivers/usb/spca5xx下也有spca5xx.o的啊?

-- 作者: hn
-- 发布时间: 2006/04/07 10:27am

MODULE形式的驱动是独立的.o,没有放到zImage里面的,所以你下载到RAM中当然没有啦。
你必须把这几个.o复制到PC的/目录下,然后NFS mount上测试。
当然啦,你也可以复制到ramdisk里面,下载后测试。

-- 作者: daily3
-- 发布时间: 2006/04/07 05:48pm

实现了一边采集图像一边实时通过局域网传输一边本地保存。结果是通过网络接收的图像大小和保存的是一样的。现在有个问题不知为什么?从摄像头采集到一帧图像怎么会既通过网络传输走了又能本地保存????我在程序中采集到一帧图像没有把它复制一份啊??谁知道啊?
无线的方式下能发送出去,但是保存的图像大小都是0。。:(不知为什么

-- 作者: sil80
-- 发布时间: 2006/04/12 11:49am

超级女生真是厉害

-- 作者: daily3
-- 发布时间: 2006/04/12 04:54pm

嗯。想实现
1.用minigui来接收从摄像头采集到的图片,然后在加上字显示出来。
2.通过boa来看视频播放,就不需要把视频通过网络传输到指定的地址了。
有兴趣的,大家一起弄啊。。嘿嘿

-- 作者: hn
-- 发布时间: 2006/04/12 05:00pm

嗯,8错,搞个开源项目,daily3牵头。

-- 作者: 电动车
-- 发布时间: 2006/04/12 09:02pm

好久没来了!感兴趣!!!呵呵 ,加油!!

-- 作者: daily3
-- 发布时间: 2006/04/13 10:30am

问sunjiangbo大虾:您的spca5xx摄像头采集和接收是用的spcaview和servfox吗?我想在window下接收这个图像能实现吗?就是把spcaview改成windows下的。可是windows支持v4l吗?好像不支持啊。yun。。。怎么改啊。。
老板认为ov511的摄像头不美观,非要换物美价廉的中芯微。。还要改成无线发送。yun啊。:(


-- 作者: daily3
-- 发布时间: 2006/04/15 04:00pm

嗯。这两天把servfox和spcaview中的音频部分去掉,代码少了很多。哈哈。
总共找了8个中芯微的摄像头,发现这两个程序支持zc301P/0x303b和zc301P/0x301b,不支持zc305B/0x305b的。
zc301P/0x303b和zc301P/0x301b这两种摄像头一个是80元左右,一个是100元左右
zc305B/0x305b的摄像头卖45元。
晕,看来便宜的东西果真功能有限啊。
不过ov511的摄像头还真是难买啊,从网上订购一个90,加上邮费手续费,共要130。更晕。。看来还是要支持国产的东东啊

-- 作者: daily3
-- 发布时间: 2006/04/15 04:09pm

有网友问:运行./servfox时出现Error Opening V4L interface.
我测试一下,是没有加载驱动啊。
虽然内核中(M)选中了驱动,但是启动后要手工加进去。insmod一下啦。

-- 作者: daily3
-- 发布时间: 2006/04/15 04:12pm

还有啦,不能在这个版内发贴的xdjm,请到技术园地的置顶的摄像头贴里提问和建议啦,不要通过QQ和email找我,我平常很少在线的。要是被老板看见,我就挂了。。。。@&@敬请原谅。。嘿嘿

-- 作者: sunjiangbo
-- 发布时间: 2006/04/18 06:16pm

我是直接用IE播放视频的

-- 作者: daily3
-- 发布时间: 2006/04/20 02:10pm

类似网络摄像机?

-- 作者: sunjiangbo
-- 发布时间: 2006/04/20 08:02pm

恩,是的

-- 作者: daily3
-- 发布时间: 2006/04/22 10:39am

现在从中芯微的摄像头采集到的图像质量好,size最小为320x240,导致一张jpeg图像有8-10几k,无法在无线网络中传输啊。
于是想到图像分割。把一张分成每个为1k的包在发送出去,在接收方重新组合。晕啊。读jpeg图像时读出的数据就和原始数据不一样,每次大约在1024倍数的位置,连续有4位出错,其它地方完全一样。
导致无法合成一张图片。
晕。。。。。。是不是jpeg编码里加了保护机制啊??????

-- 作者: daily3
-- 发布时间: 2006/04/22 10:47am

哪位大虾懂jpeg编码的啊。。。。
我总觉得图像分割仅仅是读图像里的16进制的数据,分别存储在几个文件中。再把这几个文件组合成jpeg图像,好像没有这么简单。
不得其解。
忘各位大虾指点。。。。。

-- 作者: HHARMLIKER
-- 发布时间: 2006/04/22 08:09pm

开头的几个字节是文件头的吧,这样组合肯定不行的

-- 作者: sunjiangbo
-- 发布时间: 2006/04/23 04:16pm

jpeg 里没有保护机制啊?估计是你传输中有错误

-- 作者: daily3
-- 发布时间: 2006/04/23 06:39pm

嗯。已经搞定了。。。仅仅又开了一个缓冲区就可以了。。。也不知道为什么。。。哈哈

-- 作者: sunjiangbo
-- 发布时间: 2006/04/23 08:24pm

哈哈,是不是你以前的那个缓冲区跟别的缓冲有冲突啊,被覆盖了,我以前也碰到过

-- 作者: daily3
-- 发布时间: 2006/04/23 08:57pm

应该没有吧?我是专门写了一个小程序来测试的。。就是很奇怪。。开了那个缓冲区,但是根本没用。要是把那个缓冲区去掉图像就是花的。
呵呵。。。

-- 作者: st0302
-- 发布时间: 2006/04/25 12:41pm

[quote][b]下面引用由[u]daily3[/u]在 [i]2006/04/22 10:39am[/i] 发表的内容:[/b]
现在从中芯微的摄像头采集到的图像质量好,size最小为320x240,导致一张jpeg图像有8-10几k,无法在无线网络中传输啊。
于是想到图像分割。把一张分成每个为1k的包在发送出去,在接收方重新组合。晕啊。读jpeg图 ...
[/quote]
你用的什么无线网络,十来K也要分割图像??
还有想问下,如果用STUDY的板子一边采集图像数据一边通过GPRS发出去,调试时应该怎么扩展串口,因为只有一个串口可以用?

-- 作者: hn
-- 发布时间: 2006/04/25 01:48pm

她用CDMA1X传输,比你的GPRS还快些。

-- 作者: daily3
-- 发布时间: 2006/04/25 09:30pm

嗯。。不知道是不是联通的网络变差了的缘故,我们去年暑假测试的时候,每张图片是1点几k,通过cdma传送仅有几帧图像会丢失。同样的东西,现在传图像稍微复杂一点就丢失了。。晕。。所以只能分割图像了
理论上cdma1x上行是80kbps,也就是每秒能传送8k的数据。实际上大约也就3-4k的样子。
唉,期待3G的出现。

-- 作者: hn
-- 发布时间: 2006/04/26 10:36am

晕,这个
spcaview –w 192.168.2.120:7070
要在X下运行,而且频繁退出,晕死。还是比较垃圾。

另外,只要HHARM2410内核选中V4L即可,然后下载
http://mxhaard.free.fr/download.html
最新的驱动
spca5xx-20060402.tar.gz
这个可独立编译,无需放到linux内核里面,编译生成一个spca5xx.o即可,不要三个.o做驱动了。

-- 作者: daily3
-- 发布时间: 2006/04/26 11:38am

可以不用在spcaview下运行的啊,我的没有退出啊,晕哦。只是发送完后,spcaview这边不能自动退出,只能切换到其它控制台下杀死这个的进程

-- 作者: daily3
-- 发布时间: 2006/04/27 06:44pm

^_^。庆祝一下,我通过无线把分割后的图片发送出去,在接收端能组合成一张清晰的图片啦

-- 作者: hn
-- 发布时间: 2006/04/28 11:43am

NB

-- 作者: daily3
-- 发布时间: 2006/05/10 10:37am

从http://mxhaard.free.fr/spcaserv.html上copy下来的:呵呵

What is spcaserv/servfox ?
Spcaserv or Servfox are streaming servers to used in conjonction of the spca5xx spca5xx-LE module
Spacserv is the more generic one and work on x86 embedded machine.Spcaserv support the whole set of spca5xx webcams and provide a jpeg compressor, no external library are need to compile the package. The parallel port is used as Input Output lines and can be set by the client side to command servo, motors, relays, Pir detector and so on.
Servfox is set for the embedded Foxboard and can be used on the Arm9 board to:) Only the subset of webcams used in the spca5xx-LE package can run . The Foxboard or the Arm9 provided usefull set of I/O lines and can be used for i2c chips like the SD20 or SI2C20 from the pic familly to command 20 servos motors,Real times clock, AD DA convertor, motors, Ultrasound, Pir, IR detectors.
What is protocol between Client and Server?
When a Client connect it send a short message to the server asking for a frame.
Then the Client go to sleep waiting for a frame header.
The server is waiting and read the short message
If the short message is OK it send a frame header over TCP to the client
Following by a whole compressed frame
When the Client get the header it will ask for the corresponding frame
receive the frame and go back to the short message sleeping.
This is a closed loop protocol, with bidirectional exchange. Client can then command the remote server for the video stream parameters but also read or write the remote GPIO pins.
The server side is multithread so many client can connect to the server in real times. The server have a ring buffer of fresh frames in memory and can then provide video streaming without buffering :)
It should be simple to add a custom lock in the closed loop protocol to provide better security.
The client/server protocol allow the client to sleep until an hardware event comes trought the GPIO lines.
How can i run spcaserv servfox ?
There are a README file in the package to know all parameters setting.
spcaserv -h or servfox -h give you usefull informations to :)

servfox -d /dev/video0 -s 320x240 -w 7070
run servfox on the first video node available with 320x240 framesize and listen to port 7070
spcaserv -d /dev/video0 -f yuv -s 352x288 -w 7070
run spcaserv on the first video node with a frame size of 352x288, palette yuv420p, listen on port 7070

to get the server working in background the & operator can be used :)

-- 作者: daily3
-- 发布时间: 2006/05/10 10:40am

从http://mxhaard.free.fr/spcaview.html上copy下来的:呵呵
What is spcaview ?
Spcaview package include a set of tools, for the spca5xx, spca5xx-LE kernel modules. Spcaview is a video grabber software, but can also act as a video player or a client streaming viewer for the spcaserv serfox streaming server.To view all possible setting spcaview -h can help :)
to run spcaview as a client viewer run the following command:
spcaview -w 192.168.0.90:7070
where:192.168.0.90 is the server IP address
7070 is the port to use for the connection

when the client is connected the following keyboard key are active :
key b -> brightness up
key n -> brightness down
key w -> contrast up
key x -> contrast down
key s take a picture in your current directory
don't touch key l that will put the server to sleep :) and i have not set a
method to wake up at the moment.
key q disconnect and quit.

-- 作者: daily3
-- 发布时间: 2006/05/10 10:45am

从http://mxhaard.free.fr/spca5le.html上copy下来的:呵呵
What is spca5xx-Light-Edition ?
The goal of spca5xx-Light-Edition (spca5xx-LE for short) is to provide USB webcams support for small embedded devices. This support can be used for "Vision Machine" like robotics projects telepresence detection and so on ..Spca5xx-LE should be used with a TCP UDP /IP server that forward the video MJPEG stream over IP
You can used spcaserv or servfox for that :) You can also used the spcav4l.c spcav4l.h code to setup your own server according the GPL licence.
The spca5xx-LE design is very different from the spca5xx full package. The memory in use are the most smaller as possible ? The spcadecoder is reduce and only raw jpeg webcam are used.All ioctl are compliant to the v4l spec with a MJPEG extension. V4l2 support are planned soon with others features that cannot be set on the Full packages

-- 作者: daily3
-- 发布时间: 2006/05/10 11:03am

从http://mxhaard.free.fr/sview.html上copy下来的:呵呵
SpcaView & SpcaTools Howto
Michel Xhaard

01 March 2004

Contents
Contents
1 Overview:
1.1 Camera Type
1.2 Probing the Camera
1.3 What the driver do ?
2 Spcaview Grabber
2.1 Why a new grabber in Linux World ?
2.2 What Spcaview Grabber can do ?
2.3 Picture Grabbing
2.4 Can i record video Stream ?
3 Spcaview Player
3.1 Why a new player in Linux world?
3.2 What Spcaview Player can do ?
4 How Spcaview can be installed ?
5 Spcatools
5.1 Spcatools extract
5.2 Spcatools Edit
5.3 Spcatools Picture
5.4 Spcatools more ?
About this document ...

1 Overview:
This set of tools are provide to test WebCam under Linux. Especially camera based on Sunplus chips, but that should work with some others cameras too.You need knowledge of Linux to use these tools and we don't provide any GUI interface for a large public area. These tools are design to: test, improve, perform our Kernel module in a lot of situations and provide usefull API for developer . As others projects in the Linux World we don't have any help, documentation from SunPlus compagny. All that great work use Reverse Engeneering to provide interoperabilities of our WebCam device. At this times, we support up to 40 Webcams from a lot of compagnies: (Aiptek, Mustek, Intel, Grandtec, Maxell, Genius, Dlink, Kodak, Creative, Logitech, Benq, ViewQuest.. ) and only one driver can deal with all, strange Linux World :)

Our kernel module spca50x or spca5xx is developed outside the kernel tree. that way provide a more reactive stuff according our support product life, we are more free, to develop here part of code like specific decompressor .

Why spca50x ,spca5xx ? spca50x was originally developed by Joel Crip on the Omnivision OV511 code.it is the official branch .spca5xx is an experimental stuff, i have begin in january 2003, i don't need to start another project with the same objective, so when that stuff is know to be stable, it will be integrate in the spca50x CVS tree. I did not have any responsabilities if that stuff, become or not in a release, ask the maintener Miah Gregory for that. At the moment spca50x is know to be very ``static'' and spca5xx very ``reactive'' .

Also if your distro clearelly patch the kernel and become uncompatible with the others Linux stuff.we cannot offer support . The best way get a vanilla kernel from http://www.kernel.org it should work with our module.


1.1 Camera Type
Our webcams are all USB and can be managed in three familly of chips who stream nativelly in :

Jpeg Yuv Bayer
Spca500 Spca501 Spca561a
Spca504a Spca505  
Spca504b Spca506  
Spca533a Spca508  


Yuv and Bayer can be encoded with specific compressor from Sunplus. As we don't know that proprietary stuff ,we cannot provide any support of the compressed mode, we use instead uncompressed stream.

Jpeg is more atractive that we know how the stream is encoded . A peace of code from the bootsplash project as be rewrite to support our raw jpeg stream ( Michael Shroeder (Suse), Till Adam, Michel Xhaard).


1.2 Probing the Camera
At the USB probe function ,Webcam device is registered and the struct provide :


spca50x->bridge the know chip
spca50x->desc camera modele identifier
spca50x->cameratype what stream we are in use
Some Webcam have a know sensor we can access trought i2c bus the struct register in

spca50x-sensor the know sensor chip
Spca50x->sensor = SENSOR_INTERNAL mean we don't care about sensor (unknow or didn't have any know command)
Each Webcam is now registered and should work with the driver.


1.3 What the driver do ?

1.3.1 V4L layer
The first step provide a V4L layer to the userspace software .That mean Ioctl will be implemented to provide different kind of choice : Palette ,Capture Size, Picture setting.

All that chips didn't have the same capabilities:

Palette setting we courrently support for all cameras :


VIDEO_PALETTE_RGB565 16 Bits Video palette
VIDEO_PALETTE_RGB24 24 Bits Video palette
VIDEO_PALETTE_RGB32 32 Bits Video palette ( Not really a good idea )
VIDEO_PALETTE_YUV420P Planar yuv 4.2.0 palette (Best performance according Bandwith)
VIDEO_PALETTE_RAWJPEG 8 Bits raw stream ( Not really a good idea some webcam are not jpeg and can be use in raw mode )

1.3.2 Capture Size:
All camera didn't support nativelly the whole set of picture size setting .Because Kernel space is not a good place to provide upscaling we have only developed a peace of code to provide intermediate resolution. These intermediate setting are get by crop the first available hardware mode also we only decode the surface need by the application software.VIDIOCGCAP Ioctl will get the capabilities of your cam .

Maximum expected size:

``Vga'' size 640x480 is provide by :


Spca500 Spca501 Spca504a Spca504b
``Sif'' size 352x288 is provide by:

Spca505 Spca506 Spca508 Spca561
Spca533 is weird and can do 464x480 that need to upscale on 640x480
Default Maxsize is set to 352x288

Minimum expected Size:

``QCif'' size 160x120 is provide by:


Spca501 Spca505 Spca506 Spca508 Spca561
``QSif'' size 176x144 is provide by:

Spca504a Spca504b Spca533 (Jpeg decoding need Height and Width modulo size of MacroBlock 16x16)

1.3.3 Pictures setting:
Unfortunatelly all Webcams didn't have an easy way to perform adjustement of Contrast, Brightness, Colors but exept some model we have implented those features via VIDIOCSPICT and VIDIOCGPICT Ioctl.


1.3.4 Asking Data from the Drivers
The driver implement VIDIOCMCAPTURE and VIDIOCSYNC to provide a good way for asking a frame and wait until that frame will be ready.At the moment our driver use four frames in the framebuffer get trought VIDIOCGMBUF Ioctl .

Read and Mmap method can be use to get video data from kernel space to usersland.


1.3.5 Usb Isochronous
As soon as the open function will be ask, driver allocate the whole memory ressource need by the grabbing stuff and install the callback function of the Interrupt Handler then the Urb is submitted to the usb host controller .If all are right with the initialize of the camera the isochronous stream become and, for each iso packet the driver will consume the data until a video frame start is found. A start of frame is a least the end of preceding frame, a new buffer for grabbing is asked and a tasklet will be schedule to perform the video decoding. If something goes wrong in the iso stuff the tasklet will not be schedule and the wrong frame will be recycled for a new one .

All that stuff are in interrupt context and need more attention to prevent Kernel ``crash''.

at the end of the process close function will stop the iso stream and remove all the grabbing memory in use.


1.3.6 Video Decoding
When the tasklet was schedule a whole frame is grabbing and is present in the frame temporary buffer.Also all the camera setting are set in the frame struct . the outpicture function first test what camera familly are responsive of that stream then the good decoding function are ask .Because proprietary stuff are always strange we have to deal with a lot pixels arrangement for exemple yuv become yuyv yyuv yuvy .

Tasklet work in safe times and so didn't corrupt the iso interrupt handler stuff.

A gamma set of tables are available to correct some sensor setting That need to experiment and choice the good setting for your cam if necessary. Spcatools is design to help you for that work.


1.3.7 Miscaneallus function
A set of usefull functions are implemented to get right parameters for:

frame size, picture setting , The setting of those parameters will find the good parameters for the usb stuff: pipe size Alternate setting according to frame size


2 Spcaview Grabber

2.1 Why a new grabber in Linux World ?
Our spca50x spca5xx have specific feature that was not supported with others userspace apps .for example rawjpeg stream .We need a grabber to test our module in that way also able to ask our set of palette size and so on. Tha's not really a good idea to merge bugs or unsupported feature from: xawtv, gnomemeeting and the pwlib, gqcam, vic, camstream and so on and our module. a lot of confusing will be result that way and we don't want to spend times with that. At least, if our module works fine with spcaview it should work with the others apps. Spcaview was developed with that objective so it cannot do what gnomemeeting gstreamer mplayer xawtv ...do :)


2.2 What Spcaview Grabber can do ?
Grab of course, in all supported palettes and sizes of our module no more no less. The resulting video stream are decoded and appears in a SDL window ( That mean you need the great libsdl to compile, but now all serious distro will offer libsdl from Loki just don't forget to install devel package too).

When the stream are displayed you can change the picture setting by pressing some key:


'n' brightness up
'b' brightness down
'v' color up
'c' color down
'x' contrast up
'w' contrast down

2.3 Picture Grabbing
Of course you can ask for a picture when grabbing spcaview will build a picture name according the frame number and freeze the picture .jpg for jpeg grabbing and pnm for all the others palettes.That mean if you have ask for an yuv420p palette that the stream is converted to a RGB24 before writing in the picture file. To get a picture only press key 's' from your keyboard.


2.4 Can i record video Stream ?
Sure ,when streaming it is also possible to record the resulting video in an avi file .We use the great ``avilib'' from Rainer Johanni all the necessary file are include in our package so you have nothing to install .


2.4.1 What are the suported codec ?
Some Fourcc are always supported in most Linux or Mac OSX, Windoze ,Player The raw jpeg camera can use ``MJPG'' the others have ``I420'' for yuv420p palette .

because we can also record RGB non standard Fourcc are in use :


RGB2 for 16bits stream
RGB3 for 24 bits stream
RGB4 for 32bits stream
asking spcaview to record an avi will automatiquely set the right fourcc code :
spcaview -f yuv -o myavifile.avi start record an avi with I420

spcaview -f r16 -o myavifile.avi start record an avi with RBG2

spcaview -f r24 -o myavifile.avi start record an avi with RBG3

spcaview -f r32 -o myavifile.avi start record an avi with RBG4

And the MJPG ?

If your cam are jpeg compatible

spcaview -o myavifile.avi start the record with MJPG


2.4.2 Is There A Way to Record Raw Data ?
Sure RawData can be ask to the driver with

spcaview -v -o myrawdata.avi

That mean the grabber screen will be black but the data are writting directly to the drive and so can be process in a second times with SpcaTools .The fourcc was RAWD of course


2.4.3 Record avi from RGB or YUV give large file what can we do ?
Spcaview have a smart compressor that can compress in real times .

Differential Pixels Static Huffmann Encoding is GPL and are writting by Alexander Sikamov (Russian) and me (French)

You can expect 50% less in size without any loss in data . The fourcc was DPSH of course .

spcaview -z -o myavifile.avi record compressed DPSH yuv stream in an avi


2.4.4 Is there a way to add sound with video picture ?
Why not ? Sndlib from Bill Schottstaedt provide a great interface for that and is include in the package too so

spcaview -a 1 -o myavifile.avi will record an avi in MJPG with sound from the microphone .

spcaview -a 2 -f yuv -o myavifile.avi will record an avi file in I420 with sound from the mixer.

Some camera have an Usb Microphone device that will be a good idea if someone can experiment that :)


3 Spcaview Player

3.1 Why a new player in Linux world?
As designed in Spcaview grabbing some video encoding are specific . So we provide a great tools to read the avi get by spcaview grabber .All the Fourcc code from spcaview grabber are supported exept RAWD that need spcatools to be decoded.


3.2 What Spcaview Player can do ?
Play the video stream of course. All the setting are get trought the avi header so we have nothing todo exept looking the SDL output of your screen and listen the sound trought your loudspeaker .

just use:

spcaview -i myavifile.avi

tha's all


3.2.1 Is there a way to play frame by frame ?
Yes press


down key will stop the stream
up key restart the stream
right key go one frame forward
left go one frame backward

3.2.2 I want a picture ?
Press the down key to stop the stream select the right one with left and right then press s

a Picture name is build from the avi name and the frame number .The Picture will be record according your palette Rawjpeg give jpg picture all the others give pnm 24 Bits


4 How Spcaview can be installed ?
Spcaview is an unique package for grabbing or playing, only the command line argument select the right mode.

http://mxhaard.free.fr/download.html

Spcaview come with all library exept libsdl and libjpeg you have to install first.

just type

make

make install

tha's all :)

what spcaview can't do ?

The Cafe of course .


5 Spcatools
Spcatools perform frame analisys from the raw data get with spcaview grabber .That way we can in userspace decode the frame extract from the avi file .As in kernel spcace spcadecoder (the same) perform the decoding according parameters send by the user on command line. That tools is not for a large public audience you need knowledge of what you are doing before use .

you will first specify what is the camera type with -f parameter that also specify the incoming stream


-f yuyv
-f yyuv
-f yuvy
-f gbrg
-f jpeg
also output palette are need with -p parameters

-p r16 for RGB16 bits
-p r24 for RGB24 bits
-p r32 for RGB32 bits
-p yuv for yuv420p
The incoming avi rawdata file are set with -i parameter
incoming width and height are get from the avi file header. at least you can specify an outcoming size with -s parameters.You only need that the output size is smaller that input size and for jpeg camera modulo 16

for exemple a spca561 based camera have gbrg bayer stream the raw data are get in 352x288 in the file raw561.avi we want an yuv420p output with 176x144 .Let go

spcatools -i raw561.avi -f gbrg -p yuv -s 176x144


5.1 Spcatools extract
Some time we need to perform a raw frame analisys so we have to extract the frame from the avi file.

spcatools -i raw561.avi -f gbrg -p yuv -e

will extract all frame from the avi file the file name is build with avifile name number of frame and the stream type extension.


5.2 Spcatools Edit
Well now what can we do with those frames ? After extracting a picture editor are open.some keys are used to perform picture setting .


Right goes next frame
Left goes last frame
f Filter RGB to BGR
s Take a Picture in pnm
Space bar enter in Edit mode
q Exit Spcatools

5.2.1 Edit Mode Commands
That mode allow to change parameters of the Colors setting . Each Color channel can move with an Offset [+128..-128] and Gain [1/2 .. 2] The resulting change is applied trought a gamma corrector curve [0.4545.. 2.2]

All the setting are set with the keyboard :


F1 Adjust gamma +
F2 Adjust gamma -
f Filter RGB to BGR
r Enter Red Channel Change
g Enter Green Channel Change
b Enter Blue Cannel Change
UP Increase Offset for Channel
DOWN Decrease Offset for Channel
RIGHT Up Gain Value for Channel
LEFT Down Gain Value for Channel
s Take a picture in pnm
l or Space Lock the change and go back Edit frame

5.3 Spcatools Picture
Is there a way to save a picture with that setting ?

Sure press key s will get a picture name according avifile name and frame number and save the file in pnm format.


5.4 Spcatools more ?
That tools are new and we can add some stream or frame process in a small C function.

an exemple is given for a Labteck Camera we need to detect iso packet and remove header part at the beginning and the end of the each iso packet .

static processFilter(unsigned char *inbuff, unsigned char *outbuff,int size)

{ char val;

int i,p,k,lastp;

int frameseq = 0x80;

for (i = 0, p=1 ,lastp=0,k=0;i < size; i ++){

if (inbuff[p] == 0xFF && inbuff[p+1]== 0xFF){

printf ("found Packet End at 0x%04X size 0x%04X isoseq: 0x%03X frameseq: 0x%03X \n",p,p-lastp,inbuff[p-1],frameseq++);

lastp=p;

p += 2; /* advance 2 Bytes so skip the header of 2 iso desc Frame 0xFF 0xFF Nbyte*/

k -= 8; /* rewind 8 bytes remove end marquer */

}

outbuff[k++] = inbuff[p++];

}

}

-- 作者: HHARMLIKER
-- 发布时间: 2006/05/11 11:15am

请问超女:如果把图片分割,一次发送1K字节,用以太网发送速度可以跟上吗?你是怎么在接受端组合得到的JPG图象的?

-- 作者: daily3
-- 发布时间: 2006/05/11 11:27am

呵呵,用以太网就不用分割了。。。多大的图片传的都很流畅。
把接收到的数据写到一个文件即可

-- 作者: benjaminwan
-- 发布时间: 2006/05/19 02:09am

既然这是专贴,那就贴在这里了,希望有人看到吧
--------------------------------------------------------------------------
前阶段我所说的ov511(网眼3000)在我自己写的程序以240x320方式下截图花屏,是因为ov511不支持此分辨率,已经在pc上用其他视频程序证实。现在我的程序可以良好的工作在240x240模式以RGB565方式输出图像,并且直接显示在液晶屏上。屏幕下方一段240x80的空间用来显示一些信息(说白了就是显示些字),因为摄像头模块只是我所要做的一部分。

最近刚新买了一个中星微芯片zc0301p的摄像头,碰到了一些问题,如下:
PC平台:装了3系统,SUSE Linux 9.3(2.6核),Red Hat Linux 9(2.4.20-8),Windows XP
嵌入式平台:华恒HHARM9-EDU-R2

1.首先在嵌入式平台试了spca5xx-LE驱动,可以驱动。移植的Servfox可以工作,spcaview可以接收到图像,但会掉帧。但这还不是首要问题。

2.用spca5xx-LE驱动时,我自己写的程序无法使用,运行到设置图像格式(RGB565或RGB24)时出错,说不支持此参数。原因在于:(摘自驱动程序主页http://mxhaard.free.fr/spca5le.html)
The spca5xx-LE design is very different from the spca5xx full package(LE版的驱动和完全版的差很多)。
The memory in use are the most smaller as possible(LE版的驱动会尽量减少内存的使用)
The spcadecoder is reduce and only raw jpeg webcam are used.(驱动模块只支持输出原始jpeg格式,my god!)

3.明显LE的驱动不符合我的要求。我所要做的是:我已经有了自己的摄像头应用程序,只想在驱动方面多支持一些市面上常用摄像头。(如果只能支持现在已经基本灭绝的几款摄像头,那还有什么意义,不过实在不行也没办法就是了)

4.那么只能移植完整版的驱动到实验箱了。问题来了,按照spca5xx完整版的INSTALL安装指南,在SuSE 9.3上轻松编译安装(也就只是make;make install而已)。用我自己写的程序测试可以驱动并成功截图,但分辨率不支持240x240(shit!难道我还得改实验箱上弄好的程序),只支持640x480和320x240,并且240x320也不支持。难道要把输出的320x240图像,旋转90度,再显示在lcd上,那可真够麻烦的。

5.试着做了一下:安装指南里并没有讲如何移植,难道只要在编译的时候指定gcc为armv4l-unknown-gcc就可以?(试过,失败)或者像LE版驱动一样,复制到usb驱动文件夹,建个spca5xx文件夹,修改makefile和config.in?(试过,仍然不行,make modules可以生成驱动模块,但insmod时出错,说找不到支持的核心版本),谁能给出一个详细的移植过程(要的是完整版的spca5xx驱动)

6.在Red Hat9上编译失败(解决办法在后面,但是我并没有去试,因为我的SuSE已经可以用了),原因在于:
这里引用一个大牛的说法(原文连接http://blog.wulei.net/2006/04/10/62.html#more-62):"RedHat 的内核是非标准内核,他将 remap_page_range从4个参数擅自更改为5个参数。然而这5个参数的remmap_page_range是内核2.5.0中使用的 ,2.6中也已经弃用了。换句话说,就是RedHat linux己制造了不兼容!!!感觉这种手段和xxx何其相似!!!在此严重鄙视一下Redhat.也就是如果你选择了redhat的产品,要么掏钱去请求其服务,要么自己解决问题。而隔绝了和其他linux社区的帮助。于是我决定抛弃其提供的内核,升级到标准内核。于是,开始疯狂的下载内核,编译内核,试图通过这种方式来解决这个不兼容的问题。我尝试 redhat自己的2.4.21的更高版本2.4.21-40.EL, 但是编译spca之后发现出现的错误更加多, 说明现在redhat自己的内核已经离标准愈来愈远了。太息之余,我想试试标准的内核能否工作。我于是在kernel.org下载并编译了2.4.32和2.4.31,这两个内核都可以完全正确的编译spca5xx 驱动。但是严重的是,我的其他软件变的非常不稳定,而且系统自带的mysql和我的XFree86完全启动不了。这再次印证了RedHat的非标准作风。证实了其试图将用户帮定在其平台的野心。我决心以后一定皈依到debian门下。但是我目前还得想办法解决。"

请继续看:"通过阅读我有了一个重要的发现在05年初期的开发版中,很多人都说只要将RH9_REMMAP宏定义打开就可以了。于是我决定试试这个时候的版本。于是下载了spca5xx20050111版本,结果出乎我意料,真的可以运行了!!!但是,效果非常差。没有我实验的在2.6内核下的那么好。但是我终于有了一个可用的版本。现在有好的开始了。我终于能找到门路了。我只要从这个版本开始跟踪开发,就能知道到底是什么导致了在我们的系统上不能成功。于是我陆续下载了20050319和20050419,结果发现前者是可以运行的,后者开始出错。好了,我现在十分满意,通过对这两个版本的比较,我就能搞清楚问题所在了。"

原因真相大白:"于是我通过emacs的ediff对比阅读了这两个版本的spca5xx.c文件。原来不光是remap_page_range这一个函数的问题,而是围绕这个问题的一些程序的架构。估计是从20050419以后由于大部分人都从redhat 9转到了Fedra结果着个问题就不重要了,因此该驱动在redhat下的分支已经没有人维护了,才导致了代码的不兼容。"

解决方法:此大牛提供了一个patch,放在最后吧,需要注意的是他的系统是redhat企业版,内核:2.4.21-4.EL i686,不过spca5xx在sourceforge也提供了它的解决方法,如下:
Q:I'm using Redhat 9, and the driver won't compile!(我用Redhat9,但驱动无法成功编译)
A:This problem is caused by the fact that Redhat has tweaked the default kernel included in Redhat 9(redhat公司修改了默认的内核), to solve this problem get different kernel(想要解决这个问题,要么下载新的内核(源代码)), or do this:(要么只能……自己看吧)
Download the CVS version of the driver, and add #define RH9_REMAP 1 to the top of spca50x.c. then compile and install.
原文连接http://spca50x.sourceforge.net/spca50x.php?page=faq#5

=========================================================================
总结如下:
1.我需要完整版的spca5xx驱动详细的移植过程(如果你有耐心看到这里,就一定有耐心再写一篇文章出来,大侠们,快点跳出来吧)
2.spca5xx-LE驱动只支持输出jpeg格式图像
3.许多2.6核的linux系统编译spca5xx完整版会很顺利(有些甚至直接就支持)
4.Red hat 9编译完整版spca5xx时,版本号在20050319之前的可能不会出错(但效果很差),而之后的会出错。
出错有解决办法(并且这些方法没有经过我自己的验证,所以不保证能用):第一种方法:去www.kernel.org下载官方的核心源代码编译。第二种方法:spca5xx开发站点提供的做法Download the CVS version of the driver, and add #define RH9_REMAP 1 to the top of spca50x.c. then compile and install.  第三种方法:把下面的内容(源自http://blog.wulei.net/2006/04/10/62.html#more-62)存成spca5xx20060402.patch,然后将该文件放在解压后的spca5xx20060402/目录下,执行patch -p1 < spca5xx20060402.patch
========================================================================
diff -rc spca5xx-20060402/drivers/usb/spca5xx.c spca5xx-20060402-wu/drivers/usb/spca5xx.c
*** spca5xx-20060402/drivers/usb/spca5xx.c2006-04-03 03:33:50.000000000 +0800
--- spca5xx-20060402-wu/drivers/usb/spca5xx.c2006-04-10 18:05:48.000000000 +0800
***************
*** 81,86 ****
--- 81,91 ----
#endif

//#define RH9_REMAP 1
+ #if defined(RHEL3)
+ #ifndef  RH9_REMAP
+ #define RH9_REMAP 1
+ #endif
+ #endif

#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
#include "spcaCompat.h"
***************
*** 1174,1180 ****
{
void *mem;
unsigned long adr;
! #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 23)
unsigned long page;
#endif
size = PAGE_ALIGN(size);
--- 1179,1185 ----
{
void *mem;
unsigned long adr;
! #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,23) && !defined(RHEL3)
unsigned long page;
#endif
size = PAGE_ALIGN(size);
***************
*** 1188,1194 ****
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 68)
SetPageReserved(vmalloc_to_page((void *) adr));
#else
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 23)
mem_map_reserve(vmalloc_to_page((void *) adr));
#else
page = kvirt_to_pa(adr);
— 1193,1199 —-
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 68)
SetPageReserved(vmalloc_to_page((void *) adr));
#else
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,23) || defined(RHEL3)
mem_map_reserve(vmalloc_to_page((void *) adr));
#else
page = kvirt_to_pa(adr);
***************
*** 1205,1211 ****
static void rvfree(void *mem, unsigned long size)
{
unsigned long adr;
! #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 23)
unsigned long page;
#endif
if (!mem)
--- 1210,1216 ----
static void rvfree(void *mem, unsigned long size)
{
unsigned long adr;
! #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,23) && !defined(RHEL3)
unsigned long page;
#endif
if (!mem)
***************
*** 1216,1222 ****
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 68)
ClearPageReserved(vmalloc_to_page((void *) adr));
#else
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 23)
mem_map_unreserve(vmalloc_to_page((void *) adr));
#else
page = kvirt_to_pa(adr);
— 1221,1227 —-
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 5, 68)
ClearPageReserved(vmalloc_to_page((void *) adr));
#else
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,23) || defined(RHEL3)
mem_map_unreserve(vmalloc_to_page((void *) adr));
#else
page = kvirt_to_pa(adr);
***************
*** 3869,3875 ****
spin_unlock_irqrestore(&spca50x->v4l_lock, flags);
}

! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
static int spca5xx_open(struct inode *inode, struct file *file)
{
struct video_device *vdev = video_devdata(file);
— 3874,3880 —-
spin_unlock_irqrestore(&spca50x->v4l_lock, flags);
}

! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) || defined(RHEL3)
static int spca5xx_open(struct inode *inode, struct file *file)
{
struct video_device *vdev = video_devdata(file);
***************
*** 3912,3918 ****
spca5xx_setFrameDecoder(spca50x);

spca50x->user++;
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
file->private_data = vdev;
#endif
err = spca50x_init_isoc(spca50x);
— 3917,3923 —-
spca5xx_setFrameDecoder(spca50x);

spca50x->user++;
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) || defined(RHEL3)
file->private_data = vdev;
#endif
err = spca50x_init_isoc(spca50x);
***************
*** 3922,3928 ****
spca5xx_kill_isoc(spca50x);
up(&spca50x->lock);
spca5xx_dealloc(spca50x);
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
file->private_data = NULL;
#endif
goto out2;
— 3927,3933 —-
spca5xx_kill_isoc(spca50x);
up(&spca50x->lock);
spca5xx_dealloc(spca50x);
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) || defined(RHEL3)
file->private_data = NULL;
#endif
goto out2;
***************
*** 3978,3984 ****
}
}

! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
static int spca5xx_close(struct inode *inode, struct file *file)
{

— 3983,3989 —-
}
}

! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) ||defined(RHEL3)
static int spca5xx_close(struct inode *inode, struct file *file)
{

***************
*** 4017,4023 ****
MOD_DEC_USE_COUNT;
#endif

! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
file->private_data = NULL;
return 0;
#endif
— 4022,4028 —-
MOD_DEC_USE_COUNT;
#endif

! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) || defined(RHEL3)
file->private_data = NULL;
return 0;
#endif
***************
*** 4037,4043 ****
return 0;
}

! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
static int
spca5xx_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
void *arg)
— 4042,4048 —-
return 0;
}

! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) || defined(RHEL3)
static int
spca5xx_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
void *arg)
***************
*** 4058,4064 ****
switch (cmd) {
case VIDIOCGCAP:
{
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
struct video_capability *b = arg;
#else
struct video_capability j;
— 4063,4069 —-
switch (cmd) {
case VIDIOCGCAP:
{
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) || defined(RHEL3)
struct video_capability *b = arg;
#else
struct video_capability j;
***************
*** 4076,4082 ****

b->minwidth = spca50x->minwidth;
b->minheight = spca50x->minheight;
! #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,22)
if (copy_to_user(arg, b, sizeof(struct video_capability)))
return -EFAULT;
#endif
--- 4081,4087 ----

b->minwidth = spca50x->minwidth;
b->minheight = spca50x->minheight;
! #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,22) && !defined(RHEL3)
if (copy_to_user(arg, b, sizeof(struct video_capability)))
return -EFAULT;
#endif
***************
*** 4085,4091 ****
}
case VIDIOCGCHAN:
{
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
struct video_channel *v = arg;
#else
struct video_channel k;
— 4090,4096 —-
}
case VIDIOCGCHAN:
{
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) || defined(RHEL3)
struct video_channel *v = arg;
#else
struct video_channel k;
***************
*** 4148,4154 ****
v->flags = 0;
v->tuners = 0;
v->type = VIDEO_TYPE_CAMERA;
! #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,22)
if (copy_to_user(arg, v, sizeof(struct video_channel)))
return -EFAULT;
#endif
--- 4153,4159 ----
v->flags = 0;
v->tuners = 0;
v->type = VIDEO_TYPE_CAMERA;
! #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,22) && !defined(RHEL3)
if (copy_to_user(arg, v, sizeof(struct video_channel)))
return -EFAULT;
#endif
***************
*** 4163,4169 ****
of video_channel is an int channel number
and we just ignore the rest
*/
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
struct video_channel *v = arg;
#else
struct video_channel k;
— 4168,4174 —-
of video_channel is an int channel number
and we just ignore the rest
*/
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) || defined(RHEL3)
struct video_channel *v = arg;
#else
struct video_channel k;
***************
*** 4184,4190 ****
}
case VIDIOCGPICT:
{
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
struct video_picture *p = arg;
#else
struct video_picture p1;
— 4189,4195 —-
}
case VIDIOCGPICT:
{
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) ||defined(RHEL3)
struct video_picture *p = arg;
#else
struct video_picture p1;
***************
*** 4327,4333 ****
}
}

! #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,22)
if (copy_to_user(arg, p, sizeof(struct video_picture)))
return -EFAULT;
#endif
--- 4332,4338 ----
}
}

! #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,22) && !defined(RHEL3)
if (copy_to_user(arg, p, sizeof(struct video_picture)))
return -EFAULT;
#endif
***************
*** 4337,4343 ****
case VIDIOCSPICT:
{
int i;
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
struct video_picture *p = arg;
#else
struct video_picture p1;
— 4342,4348 —-
case VIDIOCSPICT:
{
int i;
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) ||defined(RHEL3)
struct video_picture *p = arg;
#else
struct video_picture p1;
***************
*** 4555,4561 ****
}
case VIDIOCSCAPTURE:
{
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
struct video_capture *vc = arg;
#else
struct video_capture vc1;
— 4560,4566 —-
}
case VIDIOCSCAPTURE:
{
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) ||defined(RHEL3)
struct video_capture *vc = arg;
#else
struct video_capture vc1;
***************
*** 4574,4580 ****
case VIDIOCSWIN:
{
int result;
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
struct video_window *vw = arg;
#else
struct video_window vw1;
— 4579,4585 —-
case VIDIOCSWIN:
{
int result;
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) || defined(RHEL3)
struct video_window *vw = arg;
#else
struct video_window vw1;
***************
*** 4632,4638 ****
}
case VIDIOCGWIN:
{
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
struct video_window *vw = arg;
#else
struct video_window vw1;
— 4637,4643 —-
}
case VIDIOCGWIN:
{
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) || defined(RHEL3)
struct video_window *vw = arg;
#else
struct video_window vw1;
***************
*** 4647,4653 ****
vw->flags = 0;

PDEBUG(4, “VIDIOCGWIN: %dx%d”, vw->width, vw->height);
! #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,22)
if (copy_to_user(arg, vw, sizeof(struct video_capture)))
return -EFAULT;
#endif
--- 4652,4658 ----
vw->flags = 0;

PDEBUG(4, “VIDIOCGWIN: %dx%d”, vw->width, vw->height);
! #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,22) && !defined(RHEL3)
if (copy_to_user(arg, vw, sizeof(struct video_capture)))
return -EFAULT;
#endif
***************
*** 4656,4662 ****
}
case VIDIOCGMBUF:
{
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
struct video_mbuf *vm = arg;
#else
struct video_mbuf vm1;
— 4661,4667 —-
}
case VIDIOCGMBUF:
{
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) ||defined(RHEL3)
struct video_mbuf *vm = arg;
#else
struct video_mbuf vm1;
***************
*** 4671,4677 ****
for (i = 0; i < SPCA50X_NUMFRAMES; i++) {
vm->offsets[i] = MAX_DATA_SIZE * i;
}
! #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,22)
if (copy_to_user(arg, vm, sizeof(struct video_mbuf)))
return -EFAULT;
#endif
--- 4676,4682 ----
for (i = 0; i < SPCA50X_NUMFRAMES; i++) {
vm->offsets[i] = MAX_DATA_SIZE * i;
}
! #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,22) && !defined(RHEL3)
if (copy_to_user(arg, vm, sizeof(struct video_mbuf)))
return -EFAULT;
#endif
***************
*** 4681,4687 ****
case VIDIOCMCAPTURE:
{
int ret, depth;
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
struct video_mmap *vm = arg;
#else
struct video_mmap vm1;
— 4686,4692 —-
case VIDIOCMCAPTURE:
{
int ret, depth;
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) || defined(RHEL3)
struct video_mmap *vm = arg;
#else
struct video_mmap vm1;
***************
*** 4816,4822 ****
case VIDIOCSYNC:
{
int ret;
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
unsigned int frame = *((unsigned int *) arg);
#else
unsigned int frame;
— 4821,4827 —-
case VIDIOCSYNC:
{
int ret;
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) ||defined(RHEL3)
unsigned int frame = *((unsigned int *) arg);
#else
unsigned int frame;
***************
*** 4875,4881 ****
}
case VIDIOCGFBUF:
{
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
struct video_buffer *vb = arg;
#else
struct video_buffer vb1;
— 4880,4886 —-
}
case VIDIOCGFBUF:
{
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) || defined(RHEL3)
struct video_buffer *vb = arg;
#else
struct video_buffer vb1;
***************
*** 4883,4889 ****
#endif
memset(vb, 0, sizeof(struct video_buffer));
vb->base = NULL;/* frame buffer not supported, not used */
! #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,22)
if (copy_to_user(arg, vb, sizeof(struct video_buffer)))
return -EFAULT;
#endif
--- 4888,4894 ----
#endif
memset(vb, 0, sizeof(struct video_buffer));
vb->base = NULL;/* frame buffer not supported, not used */
! #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,22) && !defined(RHEL3)
if (copy_to_user(arg, vb, sizeof(struct video_buffer)))
return -EFAULT;
#endif
***************
*** 4892,4898 ****
}
case SPCAGVIDIOPARAM:
{
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
struct video_param *vp = arg;
#else
struct video_param vp1;
— 4897,4903 —-
}
case SPCAGVIDIOPARAM:
{
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) || defined(RHEL3)
struct video_param *vp = arg;
#else
struct video_param vp1;
***************
*** 4901,4907 ****
vp->autobright = (__u8) spca50x->autoexpo;
vp->quality = (__u8) spca50x->qindex;
vp->time_interval = (__u16) spca50x->dtimes;
! #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,22)
if (copy_to_user(arg, vp, sizeof(struct video_param)))
return -EFAULT;
#endif
--- 4906,4912 ----
vp->autobright = (__u8) spca50x->autoexpo;
vp->quality = (__u8) spca50x->qindex;
vp->time_interval = (__u16) spca50x->dtimes;
! #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,22) && !defined(RHEL3)
if (copy_to_user(arg, vp, sizeof(struct video_param)))
return -EFAULT;
#endif
***************
*** 4910,4916 ****

case SPCASVIDIOPARAM:
{
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
struct video_param *vp = arg;
#else
struct video_param vp1;
— 4915,4921 —-

case SPCASVIDIOPARAM:
{
! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) || defined(RHEL3)
struct video_param *vp = arg;
#else
struct video_param vp1;
***************
*** 4957,4963 ****
return 0;
}

! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
static int
spca5xx_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg)
— 4962,4968 —-
return 0;
}

! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) ||defined(RHEL3)
static int
spca5xx_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg)
***************
*** 4974,4987 ****
#endif
rc = video_usercopy(inode, file, cmd, arg, spca5xx_do_ioctl);
#if 0
! /* see 7 lines up */ */
up(&spca50x->lock);
#endif
return rc;
}
#endif

! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
static ssize_t
spca5xx_read(struct file *file, char *buf, size_t cnt, loff_t * ppos)
{
— 4979,4992 —-
#endif
rc = video_usercopy(inode, file, cmd, arg, spca5xx_do_ioctl);
#if 0
! /* see 7 lines up */
up(&spca50x->lock);
#endif
return rc;
}
#endif

! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)||defined(RHEL3)
static ssize_t
spca5xx_read(struct file *file, char *buf, size_t cnt, loff_t * ppos)
{
***************
*** 5089,5095 ****
}

! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22)
static int spca5xx_mmap(struct file *file, struct vm_area_struct *vma)
{

— 5094,5100 —-
}

! #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,22) || defined(RHEL3)
static int spca5xx_mmap(struct file *file, struct vm_area_struct *vma)
{

***************
*** 5144,5150 ****
return 0;
}

! #if LINUX_VERSION_CODE >= KERNEL_VERSION (2,4,22)
static struct file_operations spca5xx_fops = {
.owner = THIS_MODULE,
.open = spca5xx_open,
— 5149,5155 —-
return 0;
}

! #if LINUX_VERSION_CODE >= KERNEL_VERSION (2,4,22) || defined(RHEL3)
static struct file_operations spca5xx_fops = {
.owner = THIS_MODULE,
.open = spca5xx_open,
***************
*** 8458,8464 ****

}

! #if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22)
static struct usb_driver spca5xx_driver = {
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)
.owner = THIS_MODULE,
--- 8463,8469 ----

}

! #if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,22) || defined(RHEL3)
static struct usb_driver spca5xx_driver = {
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)
.owner = THIS_MODULE,
***************
*** 8470,8476 ****
};
#else
static struct usb_driver spca5xx_driver = {
! #if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,20)
THIS_MODULE,
#endif
“spca5xx”,
— 8475,8481 —-
};
#else
static struct usb_driver spca5xx_driver = {
! #if LINUX_VERSION_CODE > KERNEL_VERSION(2,4,23)||defined(RHEL3)
THIS_MODULE,
#endif
“spca5xx”,
Only in spca5xx-20060402-wu/drivers/usb: spca5xx.c~
diff -rc spca5xx-20060402/Makefile spca5xx-20060402-wu/Makefile
*** spca5xx-20060402/Makefile2006-04-03 04:27:03.000000000 +0800
— spca5xx-20060402-wu/Makefile2006-04-10 18:14:27.000000000 +0800
***************
*** 32,37 ****
— 32,38 —-
# Setup defines
DEFINES   += -DCONFIG_USB_SPCA5XX_MODULE=1 -DMODULE -D__KERNEL__
DEFINES   += -DVID_HARDWARE_SPCA5XX=0xFF -DSPCA5XX_VERSION=”$(VERSION)”
+ DEFINES   += -DRHEL3

ifneq ($(shell uname -r | cut -d. -f1,2), 2.4)

Only in spca5xx-20060402-wu: Makefile~

-- 作者: hn
-- 发布时间: 2006/05/19 08:35am

hao!

-- 作者: daily3
-- 发布时间: 2006/05/19 11:58am

嗯。。呵呵,在fedora编译什么错误都没有的。

-- 作者: 奥尔特云
-- 发布时间: 2006/05/21 05:58pm

我现在搞了一个在2410上用v4l抓图用再用bmp方式发送到pc机显示需要连续的不断显示不断的抓图,但while抓图抓了30帧的时候就出现发送错误了。有人能解答我么?

-- 作者: daily3
-- 发布时间: 2006/05/21 09:57pm

什么发送错误,提示是什么?socket是有发送接收缓冲区的,可能发送速度过快就导致出错

-- 作者: 奥尔特云
-- 发布时间: 2006/05/22 03:05pm

应该是网络发送出错了,但不知怎样能得到发送错误后的错误代码,在vc下我可以用getlasterror()函数但在linux下我就不知怎样了.我用tcp发送一次发完一帧160*120*3=57600 用vc来接收时用重载的onreceive来接收,onreceive事件一次是不能收完的,我就用了多次接收,边接收边重组bmp图片直到收下 了57600字节才显示图片,我发现每次接收,接到的字节数是不一样的,但在最后可以接到57600字节大小.开始的几帧还是正确的但到了一定帧数就总会出错.发送也出错,返回发送字节为-1
 

-- 作者: daily3
-- 发布时间: 2006/05/22 07:48pm

perror啦

-- 作者: 奥尔特云
-- 发布时间: 2006/05/22 09:25pm

具体怎样用阿,好像只是打印你想的字符串而已,像printf一样

-- 作者: benjaminwan
-- 发布时间: 2006/05/22 09:32pm

具体就像这样
lcdfd = open("/dev/fb/0", O_RDWR);
if (vd->lcdfd < 0)
{
perror("/dev/fb/0");
return -1;
}

if ((lcdfb = (char*)mmap(0, FB_WIDTH*FB_HEIGHT*2,PROT_READ | PROT_WRITE, MAP_SHARED, vd->lcdfd, 0)) < 0)
{
perror("mmap()");
return -1;
}

-- 作者: 奥尔特云
-- 发布时间: 2006/05/22 09:47pm

我用了在出现发送错误时,出错为:Connection reset by peer   不知什么意思

-- 作者: benjaminwan
-- 发布时间: 2006/05/22 10:16pm

连接重置?

-- 作者: 奥尔特云
-- 发布时间: 2006/05/23 09:42am

while(1)
 {
   sin_size=sizeof(struct sockaddr_in);
   if((new_fd2=accept(sockfd,(struct sockaddr *)&their_addr,&sin_size))==-1)
   {
     printf("accept2 error\n");                                
     continue;
   }else
   {
     break;
   }
 }
  close(sockfd);

while (max_try) {
dev = open (device, O_RDWR);
 

     if (dev == -1) {
if (!--max_try) {
fprintf (stderr, "Can't open device %s\n", device);
return (1);
}
sleep (1);        
} else { break; }
}


if (ioctl (dev, VIDIOCGMBUF, &vid_buf) == -1) {
    printf("vidiocgmbuf error \n");
    return (1);
        }

map = mmap (0, vid_buf.size, PROT_READ|PROT_WRITE,MAP_SHARED,dev,0);
if ((unsigned char *)-1 == (unsigned char *)map) {
perror ("mmap()");
return (NULL);
}
 

vid_mmap.format = palette;
vid_mmap.width = width;
vid_mmap.height = height;
 vid_mmap.frame = frame;
if (ioctl (dev, VIDIOCMCAPTURE, &vid_mmap) == -1) {
perror ("VIDIOCMCAPTURE");
fprintf (stderr, "args: width=%d height=%d palette=%d\n",
vid_mmap.width, vid_mmap.height, vid_mmap.format);
munmap (map, vid_buf.size);
return (NULL);
}
 
 while(1)
{

 if(ioctl (dev, VIDIOCSYNC, &vid_mmap.frame) == -1) {
perror ("VIDIOCSYNC");
munmap (map, vid_buf.size);
   close(dev);
   if(sockfd)
   close(sockfd);
   if(new_fd2)
   close(new_fd2);
return (NULL);
}
 

 memset(buf,0,57600);

 memcpy(buf,map+vid_buf.offsets[frame],57600);
 
 

if((sended=send(new_fd2,buf,57600,0))==-1)
{
 perror("perr");
 printf("send bmp data error\n");
 
 close(new_fd2);
 exit(0);
}

printf("sended=%d\n",sended);


frame=(frame+1)%2;
 vid_mmap.frame = frame;


if (ioctl (dev, VIDIOCMCAPTURE, &vid_mmap) == -1) {
perror ("VIDIOCMCAPTURE");
fprintf (stderr, "args: width=%d height=%d palette=%d\n",
vid_mmap.width, vid_mmap.height, vid_mmap.format);
munmap (map, vid_buf.size);
   if(dev)

   close(dev);
    if(sockfd)
   close(sockfd);
   if(new_fd2)
   close(new_fd2);
return (NULL);  
}

是啊,在pc机上就出现10053的错误

-- 作者: daily3
-- 发布时间: 2006/05/23 11:39am

while(1)
{
  sin_size=sizeof(struct sockaddr_in);
  if((new_fd2=accept(sockfd,(struct sockaddr *)&their_addr,&sin_size))==-1)
  {
    printf("accept2 error\n");                                
    continue;
  }else
  {
    break;
  }
}
 close(sockfd);

创建了连接套接字,干吗要把监听套接字关掉啊。。把 close(sockfd);去掉试试

-- 作者: 奥尔特云
-- 发布时间: 2006/05/23 04:36pm

没什么影响的,我试过了,accept后就会将连接套接字给了new_fd2,监听套接字sockfd,只要我不再次连接就没用了,我在windows下试过这样传输了,用capSetCallbackOnFrame(this->m_hWndCapture,FrameCallBack)来取得帧数据,发送接收是不会出错的。但在linux和windows就会出错,我试过延时一下发送好像好点,但不久还是会出错的,每次出错前帧显示都会先有错乱就出现10053的错误,linux下就会10054,我不用2410板在我的redhat9。0下情况一样。

-- 作者: 奥尔特云
-- 发布时间: 2006/05/23 05:26pm

开来我要加上标识头来接收数据了

-- 作者: hn
-- 发布时间: 2006/05/23 07:24pm

嗯,这些传输型的代码必须自己定义一个简单的协议的。最常见的就是加一个头,就像我在下面的那个串口传输的帖子里面描述的那样。
不过这都必须是阻塞型的接收方式才能用,异步方式就不好了,在大量数据情况下容易丢包。

-- 作者: benjaminwan
-- 发布时间: 2006/05/24 00:01am

[这个贴子最后由benjaminwan在 2006/05/24 11:17am 第 4 次编辑]

从你的代码可以看出来:
1.使用的是TCP协议,嵌入式设备为服务端,pc为客户端
2.
while(1)
{
   sin_size=sizeof(struct sockaddr_in);
   if((new_fd2=accept(sockfd,(struct sockaddr *)&their_addr,&sin_size))==-1)
   {//如果连接错误,打印出错信息,继续循环
       printf("accept2 error\n");                                
       continue;
   }else//如果new_fd2不等于-1(连接上的时候),break跳出循环
   {
       break;
   }
}
close(sockfd);
如果这个while循环没有上一级while循环的话,一旦有客户端连接上了,while循环就不再起作用,也就是再有连接,就无法响应(我有没有理解错?)。
也就是说pc客户端不能connect 两次 或 两次以上。
或者pc客户端在接收时不能调用的closesocket(),调用之后连接中断就再也连不上了。

3.第一次VIDIOCMCAPTURE后进入while(1)循环,也就是说截取第一帧之后才进入循环
4.VIDIOCSYNC判断第一帧截取结束后,清空buf,把数据复制到buf,然后发送数据,
然后用另一个frame进行VIDIOCMCAPTURE,之后就是循环了。
====================================================
传送视频流这方面有专门的超好用的RTP协议可以用
http://www.jollen.org/linux/video_streaming/
你可以看看这篇文章的第四篇有详细介绍
RTP 通讯协议
RTP 全名为 Real-Time Protocol,RTP 是在 UDP 封包之前多加 10 bytes 的文件头,里面记载有时间、序号、压缩型态等信息。RTP 是目前大多数 Video Streaming 软件所使用的通讯协议。
RTP 可用来针对各种不同的多媒体格式做 Streaming 的工作,因为我们将影像分解成数个 RTP 封包再传送出去,因此会遇到许多网络技术常会遇到的问题。例如,因为封包送达的时间不一,造成播放时会画面不流畅的现像,因此,在播发时就必须使用一个缓冲区(playout buffer)来暂时存放并处理网络上接受到的封包。
由网络上接收的影像封包因为彼此之间到达的时间间隔不同 (Synchronous Data Packets),所以必须利用缓冲区将这些封包做缓冲,让彼此之间的时间间隔一样 (Isochronous Data Packets)。
=========================================================================
如果是我,我会这样写:(以下只是假设的例子)
程序初始化(网络,摄像头初始化等)
mmap()摄像头内存映射//我试过1个frame采集和2个frame采集,觉得速度差不多,所以我只用一个frame
//一个frame的好处是,程序比较简单,不用计算偏移地址,不用munmap()
bing()绑定
listen()函数开始监听
while(1)
{
   new_fd2=accept(sockfd,,(struct sockaddr *)&their_addr,&sin_size);
   if(new_fd2 < 0)
   {
       perror("accept error");
       exit (-1);
   }
   while(1)//有连接才开始获取帧图像
   {
       if(ioctl (dev, VIDIOCMCAPTURE, &vid_mmap) < 0) //开始截取一帧
       {
           perror ("VIDIOCMCAPTURE");
           break;//出错就跳出第二个while重新等待连接
       }
       if(ioctl(dev, VIDIOCSYNC, &vid_mmap.frame)<0)//如果等待不成功
       {
           perror("VIDIOCSYNC");
           break;//出错就跳出第二个while重新等待连接
       }
       else//如果截取一帧成功
       {
           memset(buf,0,57600);
           memcpy(buf,map,57600);//我只用一个frame所以不用计算偏移地址
           if((sended=send(new_fd2,buf,57600,0))<0)
           {
                perror("Send error");
                break;//发送出错可能是连接中断,也要跳出第二个while重新等待连接
           }
         }//end of else
     }//end of 第二个while
}//end of 第一个while
==============================================================
pc客户端大概是这样:
int recvlen;
初始化等
connect();//连接
while((recvlen=recv(sockfd,buf,57600,0))>0)//有接收到数据才显示
{
   printf("%d data read\n",readlen);
   显示图像;
}
closesocket(sockfd);
=============================================================
以上仅是我个人的想法,仅供参考
以上代码没有经过验证,仅供参考

-- 作者: hn
-- 发布时间: 2006/05/24 06:20am

好啊!

-- 作者: daily3
-- 发布时间: 2006/05/24 09:16am

to   benjaminwan:呵呵,你用的rtp库是c还是C++的啊。。哪里有c版本的rtp库啊?  

-- 作者: benjaminwan
-- 发布时间: 2006/05/24 04:04pm

to daily3:
1.抱歉,虽然仔细看过video streaming那篇文章,但没有实际动手做过,所以……

2.JRTPLIB is an object-oriented RTP library written in C++.
只有C++写的库

3. Platforms
Currently, the library is known to work on the following platforms:
GNU/Linux
MS-Windows
Solaris
The library will probably work on other unix-like environments too.
可以用在Linux、Windows上

4.那文章里所写的,是用JRTPLIB v2.x
现在的版本是3.5.2,有些函数不一样了

5.可能是由于linux上的jpeg库是用c语言写的,而jrtp库却是用c++写的,虽然g++可以编译c程序,但要同时链接这2种库是个令人头痛的问题。(我尝试过同时编译连接2种库,但失败了,而分开却可以成功)

6.所以我宁愿自己用TCP来实现它
(servfox也是用TCP…………)
===============================================================
有稍微试了一下:
1.以前写的main.c,用来截取一帧图像并存成jpeg和ppm,把main.c改成main.cc
用g++编译,和jpeg相关的函数有错,把jpeg相关的函数注释掉,编译通过。

2.把载下来的jrtplib编译make;make install一下

3.把jrtplib-3.5.2\src这个文件夹复制->和main.cc放在一起

4.在main.c里加
#include "rtpsession.h"
#include "rtppacket.h"
#include "rtpudpv4transmitter.h"
#include "rtpipv4address.h"
#include "rtpsessionparams.h"
#include "rtperrors.h"
//main()里面添加
RTPSession sess;
RTPUDPv4TransmissionParams transparams;
RTPSessionParams sessparams;
sess.Create(sessparams,&transparams);

5.编译
g++ -I ./src/ -c -o main.o main.cc
g++ -O2 -o main main.o -ljrtp

使用-ljrtp之前,你必须确保第2步有成功地把库装上去
==========================================================
总结:如果你不用jpeg库或你用C++来写程序的话,可以考虑用rtp。
但是要我选,我还是会选TCP/IP。

-- 作者: daily3
-- 发布时间: 2006/05/24 04:54pm

非常感谢

-- 作者: ariesp
-- 发布时间: 2006/05/24 10:47pm

insmod spcadecoder.o时,出现错误:spcadecoder.o:couldn’t find the kernel version this modules was compiled for。
我完全按照:在arm linux的kernel目录下make menuconfig,首先<*>选择Multimedia device->下的Video for linux,然后在usb support->目录下<*>选择support for usb和<M>选择SPCA5XX support,保存退出。
帮忙啊

-- 作者: benjaminwan
-- 发布时间: 2006/05/25 00:19am

to ariesp:如果你insmod spca5xx.o成功的话就不需要再insmod其他模块了。
你移植的是spca5xx-LE还是spca5xx完整版的驱动?

-- 作者: daily3
-- 发布时间: 2006/05/25 09:20am

to  benjaminwan  :你有没有做过无线cdma传输啊
有没有做过cdma下socket传输的啊?

cdma无线上网的时候是不是网络拥塞比较严重啊。你们是用什么无线上网的啊?
我们的传视频图片的程序在无线情况下有时能很快的正常收发,有时延时非常严重,有时还收不到。
在有线下就很正常。

cdma的上行速率是8kbytes啊。我们把图片分割了,每次只传1k啊。。

难道网络的实际速度连1k都没吗?

-- 作者: benjaminwan
-- 发布时间: 2006/05/25 10:01pm

[这个贴子最后由benjaminwan在 2006/05/25 11:58pm 第 2 次编辑]

to  daily3:
没有用过CDMA,只用过实验箱上的GPRS模块,插上动感地带的手机号码卡,pppd拨号。
拨上了之后除了慢、贵、不稳定和网络不好时会掉线以外,用tcp/ip协议传输消息、文件,与普通的以太网没区别。
感觉GPRS网用UDP协议发短一些的消息,还行,但有时还是会丢。
发文件或图像一定得用TCP协议,虽然慢了一点,但毕竟TCP有出错重传的机制。

网上的说法是:实际速度CDMA在150K左右,而GPRS在45K左右,CDMA是GPRS速度的三倍多。

但实验箱上GPRS模块实际就是一个接在串口的调制解调器,GPRS模块与串口通讯的速度为115200bps
8比特/秒bps(bits per second)= 1字节/秒Bps(bytes per second)
1024 Bps = 1 KBps
115200bps/8/1024=14KB/s,虽然网上说的理论上的GPRS访问速度很高,但受限于串口的速度,实际速度都在10KB/s以下。

分辨率240*240,quality为50的jpeg图片大小约4KB,以1KB为单位发送的话

TCP发送的过程:
A发送端:我要传了(等接收端回应要延迟)
B接收端:传吧
A发送端:传1KB的数据(传送也要延迟)
A发送端:收到了么?(确认还要延迟)
B接收端:我收到了

发1帧图像4KB就要4次这样的过程,还没算上出错重传。再加上,10KB/s说的只是下行速度,不知道上行速度怎么样。
如此小的分辨率和如此低的图像质量,发送1帧图像要1秒吧?
大点的分辨率高点的质量,那就是:惨、惨、惨、惨不忍睹!

除非课题要求一定要用GPRS,不然我发图像和文件肯定选择用以太网。
===================================================================
综上所述:CDMA没用过,但再怎么说都比GPRS好点吧。

-- 作者: daily3
-- 发布时间: 2006/05/26 09:25am

不过无线网络中用tcp速度实在是慢啊。我们就想到发送确认帧的方式
UDP+确认帧发送过程:
client:发送第i帧(等待server收到确认)
server:收到第i帧,向client发送确认帧(我已经收到第i帧啦)
client:收到server发的确认第i帧,向server再发确认帧(我已经收到你发的确认帧啦)
server:再次收到确认帧,再向client发送确认。

yun4,来来回回折腾几次,干脆就三次握手吧。结果老是确认帧收不到。yun
如果不加确认帧用不能保证顺序。唉。
现在不是有很多做cdma视频传输的嘛。他们是用什么协议的呢?

-- 作者: benjaminwan
-- 发布时间: 2006/05/26 01:38pm

to daily3 :
…………
自己设计一个协议确实令人头痛……
如果你不在乎收到的数据正确与否,client只要一直发就行了。(就算收到的数据只有1字节出错,那图像就废了)

但是如果想要server收到错误数据后,client重新传,那就比较麻烦了。

就比如传送数据时,加上CRC32校验码

假设用udp一次发送整个1帧图像
client:发送1帧+这一帧的CRC32校验码
server:收到1帧,用校验码验证数据有没有出错(没错就发确认,出错就要求重新传)
client:收到确认就继续发,收到出错就重新传,没收到怎么办?重新发一次

1.server收到的图像出错,收到的CRC校验码没错,无可厚非,重发一次。
2.server收到的图像没错,但收到的CRC校验码错了,重发一次吧,这种情况就亏了。
3.server什么数据都没收到,server就不会回应,那client就得设个延时了,超过此延时没回应,就再把数据发一遍。
延时为多久才好?重发数据多少次才放弃这一帧继续发下一帧?

越想越头痛,UDP协议设计出来目的就是丢出去就不管了。

udp协议要是用在不丢数据的网络,就算它网速慢,应该比tcp好用。
===========================================================
没有实际做过这个东西,以上只是凭空想象而已。
不知道别人怎么做,或者还有我所不知道的某协议可以用?或者别人是:掉帧就掉帧,不管了!

-- 作者: kylfox
-- 发布时间: 2006/05/26 02:56pm

我按照daily3 所说的方法重新编译了内核,然后用新内核启动板子后insmod ov511.o会提示no this file or directory
请问是什么原因啊?

-- 作者: daily3
-- 发布时间: 2006/05/26 03:06pm

ov511.o你放在哪啦

-- 作者: kylfox
-- 发布时间: 2006/05/26 03:14pm

我再板子上找了半天都没找到ov511.o

-- 作者: daily3
-- 发布时间: 2006/05/26 07:30pm

mount到机子上,从机子上加啊。。或者直接放到ramdisk里

-- 作者: kylfox
-- 发布时间: 2006/05/26 09:50pm

把宿主机mount到板子上时mount 192.168.2.222:/ /mnt
提示no such file or directory

-- 作者: daily3
-- 发布时间: 2006/05/27 09:04am

晕。那就是你的宿主机上的根目录没有这个ov511.o嘛

-- 作者: daily3
-- 发布时间: 2006/05/27 09:16am

to   benjaminwan :我们要做的是确保图像一定要传送到,所以必须要确认啊。
经过实验,发现,把每次发送的字节改小,现在是512k,发送的速度变慢,usleep(125000)。能实现大约4秒正确无误的传1K,不会丢帧。
不过这个速度实在是太慢了:(
其实发现以前丢帧的情况确实比较少,大部分都是延时很严重。有时是一个包都收不到,有时一下子又收到许多个包。怀疑是当时网路拥塞,无法传,待网络通畅时,一下子就全发了

-- 作者: benjaminwan
-- 发布时间: 2006/05/27 11:33am

to daily3:
看来现在的无线网络仍然不够完善。要怪只能怪该死的移动和联通。

© 中文版权所有: 华恒科技  版本: LB5000MX 2.00
相关阅读 更多 +
排行榜 更多 +
无敌流浪汉3手机版下载

无敌流浪汉3手机版下载

飞行射击 下载
龙珠巅峰对决手游下载

龙珠巅峰对决手游下载

飞行射击 下载
杀戮尖塔mod手机版下载

杀戮尖塔mod手机版下载

棋牌卡牌 下载