当前位置: > 华清远见教育集团 > 嵌入式学习 > 讲师博文 > mjpg-streamer网络视频服务器移植
mjpg-streamer网络视频服务器移植
时间:2017-11-14作者:华清远见

MJPG简介:

MJPG是MJPEG的缩写,但是MJPEG还可以表示文件格式扩展名.全名为 "Motion Joint Photographic Experts Group",是一种视频编码格式,Motion JPEG技术常用与闭合电路的电视摄像机的模拟视频信号“翻译”成视频流,并存储在硬盘上。

典型的应用如数字视频记录器等。MJPEG不像MPEG,不使用帧间编码,因此用一个非线性编辑器就很容易编辑。

MJPEG的压缩算法与MPEG一脉相承,功能很强大,能发送高质图片,生成完全动画视频等。

但相应地,MJPEG对带宽的要求也很高,相当于T-1,MJPEG信息是存储在数字媒体中的庞然大物,需要大量的存储空间以满足如今多数用户的需求。

因此从另一个角度说,在某些条件下,MJPEG也许是效率低的编码/解码器之一。

MJPEG 是 24-bit 的 "true-color" 影像标准,MJPEG 的工作是将 RGB 格式的影像转换成 YCrCB 格式,目的是为了减少档案大小,一般约可减少 1/3 ~ 1/2 左右。

MJPEG与MJPG的区别:

1、mjpeg是视频,就是由系列jpg图片组成的视频。

2、MJPG是MJPEG的缩写,但是MJPEG还可以表示文件格式扩展名.

一、环境

主机环境:ubuntu 12.04.4 LTS

        目标机:Cortex-A9

        主机工具链:gcc-4.6.4

        交叉工具链:arm-none-linux-gnueabi-

        摄像头:ZC301

 

二、移植过程

1、配置内核是内核支持芯片为ZC301的摄像头

        Make menuconfig

                Device Drivers ---> 

                        <*> Multimedia support --->

                                <*> Video For linux 

                                [*] Enable Video For Linux API 1 (DEPRECATED) (NEW)

                                [*] Video capture adapters (NEW) --->

                                        [*] V4L USB devices (NEW) ---> 

                                                <*> USB Video Class (UVC) 

                                                [*] UVC input events device support (NEW)

                                        <*> USB ZC0301[P] webcam support (DEPRECATED)

2、重新编译内核

make uImage

通过上面两个步骤就可以驱动我们的摄像头了。但是这个驱动是基于V4l2的。以前基于V4L的一些上层应用就不能用了,或需要做大量的修改!

这里我们要实现网络视频的功能,以前都是用servfox这个网络视频服务器,但是这个服务器就是基于V4L的,

我们如果想用的话就得对servfox的源码进行修改。这里我们选用另外一种方案mjpg-streamer。

 

 

(2)mjpg-stream的移植

        1)mjpg-stream源码包通过下面这个网址下载

https://sourceforge.net/projects/mjpg-streamer/ 打开稍等一下,在Browse All Files上会出现源码的下载

2)解压源码

tar xvf mjpg-streamer-r63.tar.gz

3)修改源码

cd mjpg-streamer-r63

修改顶层makefile及plugins目录中的各级makefile将所有

修改

CC = gcc

CC = arm-cortex_a8-linux-gnueabi

4)*/修改plugins/input_uvc/Makfile

   在第 16 行添加编译时需要的 jpeg 头文件的路径

CFLAGS += -I /home/david/Exynos4412/test/mjpg-streamer/jpeg /include

在第 24 行添加编译时需要的 jpeg 库的路径

修改

$(CC) $(CFLAGS) -ljpeg -o $@ input_uvc.c v4l2uvc.lo jpeg_utils.lo dynctrl.lo

$(CC) $(CFLAGS) -ljpeg -L /home/david/Exynos4412/test/mjpg-streamer/jpeg /lib -o $@

input_uvc.c v4l2uvc.lo jpeg_utils.lo dynctrl.lo

5)修改 plugins/input_uvc/v4l2uvc.c

这个目录是支持 uvc 摄像头的,而我们的 FS4412 的摄像头使用的 samsung 的 FIMC

架构,所有在应用程序编程时有点细微差别,这里需要针对这些差别做一些改动:

修改 static int init_v4l2(struct vdIn *vd)函数

/*

* set format int

*/

前添加如下代码

int input = 0;

ret = ioctl(vd->fd, VIDIOC_S_INPUT, &input);

if (ret < 0) {

perror(“Unable to set input”);

goto fatal;

}

/ *

* set framerate

*/

前添加

vd->fmt.type = 0x80;

ret = ioctl(vd->fd, VIDIOC_S_FMT, &vd->fmt);

if (ret < 0) {

perror(“Unable to set format”);

goto fatal;

}

注释如下代码

/*

* set framerate

*/

struct v4l2_streamparm *setfps;

setfps = (struct v4l2_streamparm *) calloc(1, sizeof(struct v4l2_streamparm));

memset(setfps, 0, sizeof(struct v4l2_streamparm));

setfps->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

setfps->parm.capture.timeperframe.numerator = 1;

setfps->parm.capture.timeperframe.denominator = vd->fps;

ret = ioctl(vd->fd, VIDIOC_S_PARM, setfps);

修改

vd->buf.length, PROT_READ, MAP_SHARED, vd->fd,

vd->buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, vd->fd,

修改 int uvcGrab(struct vdIn *vd)函数

修改

ret = ioctl(vd->fd, VODIOC_DQBUF, &vd->buf);

if (ret < 0) {

perror(“Unable to dequeue buffer”);

goto err;

}

retry:

ret = ioctl(vd->fd, VODIOC_DQBUF, &vd->buf);

if (ret < 0) {

usleep(10000);

goto retry;

}

修改

memcpy(vd->framebuffer, vd->mem[vd->buf.index], (size_t) vd->bytesused);

memcpy(vd->framebuffer, vd->mem[vd->buf.index], (size_t) vd->framesizeIn);

修改 static int video_enable(struct vdIn *vd)函数

vd->isstreaming = 1;

前添加

sleep(1);

c) 编译 mjpg-streamer

make clean

make

6)错误

       plugins/input_uvc all

       make[1]: Entering directory `/home/swchen/code/tools/mjpeg/mjpg-streamer/plugins/input_uvc'

       arm-linux-gcc -O1 -DLINUX -D_GNU_SOURCE -Wall -shared -fPIC -I /home/swchen/code/tools/libjpeg/jpeg-install/include -o input_uvc.so input_uvc.c v4l2uvc.lo jpeg_utils.lo dynctrl.lo -ljpeg -L /home/swchen/code/tools/libjpeg/jpeg-install/lib

 /home/swchen/enviroment/4.1.2/bin/../lib/gcc/arm-angstrom-linux-gnueabi/4.1.2/../../../../arm-angstrom-linux-gnueabi/bin/ld: v4l2uvc.lo: Relocations in generic ELF (EM: 3)

 /home/swchen/enviroment/4.1.2/bin/../lib/gcc/arm-angstrom-linux-gnueabi/4.1.2/../../../../arm-angstrom-linux-gnueabi/bin/ld: v4l2uvc.lo: Relocations in generic ELF (EM: 3)

 v4l2uvc.lo: could not read symbols: File in wrong format

 collect2: ld returned 1 exit status

     make[1]: *** [input_uvc.so] Error 1

     make[1]: Leaving directory `/home/swchen/code/tools/mjpeg/mjpg-streamer/plugins/input_uvc'

     make: *** [input_uvc.so] Error 2

说的是错误的格式。 但是自己很确定自己在编译libjpeg的使用时交叉编译的,这么说的话libjpeg就不会有问题的。

是在mjpg-streamer这边出了问题,由于问题一的缘故,自己使用了make 和 make CC=arm-linux-gcc 重复了很多次。

所以有部分的生成的文件 是x86下的。 所以才导致了这个问题。

这个只要清空一下就好,make clean -w ,再重新编译,这个问题跳过了。


发表评论
前台专线:010-82525158 企业培训洽谈专线:010-82525379 院校合作洽谈专线:010-82525379 Copyright © 2004-2018 北京华清远见科技发展有限公司 版权所有 ,京ICP备16055225号,京公海网安备11010802025203号