交叉编译dlna和ushare
现在,Wi-Fi联盟已经开始同DLNA联盟(数字生活网络联盟)合作,将Wi-Fi Direct技术融合到DLNA技术里。一旦该技术稳定成型,应用于无线设备上,如智能手机、平板电脑里,它们就可以变身为多媒体服务器,来分享所收集的多媒体资料。这样在无线设备之间流媒体传递就不再需要无线路由器的连接了。而且,即使在不同的Wi-Fi网络上,你同样可以向你朋友的无线设备上直接共享音乐和视频等多媒体信息.

DLNA(Digital Living Network Alliance)由索尼、英特尔、微软等发起成立、该组织机构成立的目的解决个人PC,消费电器,移动设备在内的无线网络和有线网络的互联互通,使得数字媒体和内容服务的无限制的共享。DLNA是一种在家庭网络中实现数据共享的一种工业标准。下图是DLNA功能组件:

如上图所示, DLNA将其整个应用规定成5个功能组件。从下到上依次为:网络互连,网络协议,媒体传输,设备的发现控制和管理,媒体格式。
1.网络互连。其规定了所接入网络的类型和协议。目前,主要包括:
有线网络:802.3.i/u
无线网络:802.11/a/b/g
2.网络协议。其规定了所使用的网络协议。目前,其规定必须支持IPv4。
3.媒体传输。其规定了所有DLNA设备都必须支持使用HTTP协议进行媒体的传输。(目前也加入rtsp协议)。
4.设备的发现,控制和媒体的管理。这个功能组件是最重要的一个层次。
5.媒体格式。其规定了进行数字媒体和内容的共享和使用的时候的媒体格式。(目前已支持了大部分常用的音视频和图片格式)
uShare 最早实现 DLNA 支持的 UPnP 媒体服务器。关于ushare和dlna的关系我就只找到这句话,比较抽象。按照我的理解就是upnp是负责设备间的识别,dlna依赖于upnp,ushare是基于dlna的媒体服务器。下文提到的libdlna库,它其实只完成对音视频和图像格式的识别与加载功能,并没有实现网络互连、网络传输、设备发现等功能。所以如果需要演示dlna效果的话,需要编译ushare。下面就开始ffmpeg、dlna、upnp和ushare库的交叉编译吧。
在pc机上本地编译时,编译基本没什么问题的,但在交叉编译时却遇到各种问题,因为以前也没有编译比较复杂源码库的经验,所以这次编译只能自己硬着头皮去找问题,解决问题。经过一天的努力,编译通过了。有付出,就有收获!!!在configure出错时,需仔细分析config.log。下面是自己在本地编译时遇到的问题和解决方法。
I. 首先是编译ffmpeg。
ffmpeg是一个完整的,跨平台的解决方案,用来记录,转换和流音频和视频。它包括使用一流的音频/视频编解码器库libavcodec。在这编译时,不对源码库做裁剪,需要裁剪的可通过configure的参数的配置。
./configure –prefix=/home/work/dlna/cross_install–enable-cross-compild –cc=mipsel-linux-gcc –cxx=mipsel-linux-g++ --arch=mips –target-os=linux–host-cc=gcc –disable-static –enable-shared –enable-gpl –enable-pthreads
说明:prefix的路径设定自行决定,arch指定处理器架构(龙芯处理器是mips的),–disable-static –enable-shared只是指定编译动态库、不要静态库,默认的是两个都编译。
然后执行make&& make install
如果在make的过程中出现下面的错误:
INSTALL libswresample/libswresample.so
STRIP install-libswresample-shared
strip: Unable to recognise the format of the inputfile `/home/work/dlna/cross_install/lib/libswresample.so.0.11.100'
解决方法:将Makefile的STRIP=strip 改为STRIP=mipsel-linux-strip。还有另外一个问题,这跟龙芯处理器有关。先看错误信息:
/tmp/ccArHORY.s: Assembler messages:
/tmp/ccArHORY.s:976: Error: opcode not supported onthis processor: mips1 (mips1) `daddu $12,$12,$4'
/tmp/ccArHORY.s:995: Error: opcode not supported onthis processor: mips1 (mips1) `daddu $14,$14,$4'
/tmp/ccArHORY.s:1015: Error: opcode not supported onthis processor: mips1 (mips1) `daddu $4,$4,$10'
/tmp/ccArHORY.s:1031: Error: opcode not supported onthis processor: mips1 (mips1) `daddu $6,$6,$4'
make: *** [libavcodec/ac3dsp.o] 错误 1
错误信息显示是gcc编译链没有daddu这个汇编指令。Ffmpeg是有针对龙芯处理做编译的(#ifdef HAVE_LOONGSON),但daddu指令是2F有而1B是没有的,ffmpeg是针对龙芯2F指令做处理的。解决办法是用c去实现编译不过的汇编,这会影响速度,但没办法啦。具体改动如下:vilibavcodec/mips/mathops.h 将35 36 37行改成38 39行
35 // __asm__ ("dmult.g %1, %2, %3\n\t"
36 // "daddu %0, %0, %1 \n\t"
37 // : "+r"(d),"=&r"(m) : "r"(a), "r"(b));
38 m = (int64_t)a * (int64_t)b;
39 d = m + d;
将4748 49 改成50 51行
47 // __asm__ ("dmult.g %1, %2, %3\n\t"
48 // "dsddu %0, %0, %1 \n\t"
49 // : "+r"(d),"=&r"(m) : "r"(a), "r"(b));
50 m = (int64_t)a * (int64_t)b;
51 d = d – m;
保存退出,重新make && make install
II. 编译dlna源码库
./configure --prefix=/home/work/dlna/cross_install--enable-shared --with-ffmpeg-dir=/home/work/dlna/cross_install--cross-prefix=mipsel-linux- --cross-compile --disable-static
说明:同样是可自由指定prefix的安装目录。--with-ffmpeg-dir一定是ffmpeg安装的路径,也就编译ffmpeg时指定的prefix路径。--cross-prefix=mipsel-linux-指定交叉编译工具为mipsel-linux-,--cross-compile指定为交叉编译,不可少。
在configure过程中可能会遇到下面这个问题
Checking for compiler available...
Checking for libavformat ...
Error, can't find libavformat !
See file "config.log" produced by configurefor more details.
分析:这个问题提示是说没有libavformat动态库,这个库是在ffmpeg编译生成的。下面有三个原因导致了这个错误。1.首先是动态库环境没配置,执行export LD_LIBRARY_PATH=/home/work/dlna/cross_make/lib(路径的配置就是上面的ffmpeg安装的路径)。2.修改configure文件,将640和641行改为check_cflags -I$ffmpegdir/includecheck_ldflags -L$ffmpegdir/lib,因为./configure时,传入的参数是--with-ffmpeg-dir=/home/work/dlna/cross_install,所以需要分别指定include和lib。再修改了上面两处后,直接编译好像没事,但交叉编译时,出现下面错误:
(在config.log文件中)
202 mipsel-linux-gcc-L/home/work/dlna/cross_install/lib -o /tmp/libdlna--25938-/tmp/libdlna--25938-.o -lavformat
/opt/gcc-3.4.6-2f/bin/../lib/gcc/mipsel-linux/3.4.6/../../../../mipsel-linux/bin/ld:warning: libavcodec.so.54, needed by /home/work/dlna/cross_install/l ib/libavformat.so, not found (try using-rpath or -rpath-link)
/opt/gcc-3.4.6-2f/bin/../lib/gcc/mipsel-linux/3.4.6/../../../../mipsel-linux/bin/ld:warning: libavutil.so.51, needed by /home/work/dlna/cross_install/li b/libavformat.so, not found (try using-rpath or -rpath-link)
/home/work/dlna/cross_install/lib/libavformat.so:对‘av_bitstream_filter_filter@LIBAVCODEC_54’未定义的引用
/home/work/dlna/cross_install/lib/libavformat.so:对‘av_strncasecmp@LIBAVUTIL_51’未定义的引用
/home/work/dlna/cross_install/lib/libavformat.so:对‘avpriv_copy_pce_data@LIBAVCODEC_54’未定义的引用
/home/work/dlna/cross_install/lib/libavformat.so:对‘av_aes_init@LIBAVUTIL_51’未定义的引用
/home/work/dlna/cross_install/lib/libavformat.so:对‘av_base64_decode@LIBAVUTIL_51’未定义的引用
2/home/work/dlna/cross_install/lib/libavformat.so:对‘av_grow_packet@LIBAVCODEC_54’未定义的引用
/home/work/dlna/cross_install/lib/libavformat.so:对‘av_get_bits_per_sample@LIBAVCODEC_54’未定义的引用
/home/work/dlna/cross_install/lib/libavformat.so:对‘av_reduce@LIBAVUTIL_51’未定义的引用
/home/work/dlna/cross_install/lib/libavformat.so:对‘av_get_bytes_per_sample@LIBAVUTIL_51’未定义的引用
/home/work/dlna/cross_install/lib/libavformat.so:对‘avcodec_string@LIBAVCODEC_54’未定义的引用
/home/work/dlna/cross_install/lib/libavformat.so:对‘av_freep@LIBAVUTIL_51’未定义的引用
/home/work/dlna/cross_install/lib/libavformat.so:对‘pthread_create’未定义的引用
分析:从上面的错误信息可以得出是缺少链接libavcodec,libavutil,libpthread,那么还是修改configure文件,将check_liblibavformat/avformat.h av_register_all -lavformat || die "Error, can'tfind libavformat !"改成:
check_liblibavformat/avformat.h av_register_all -lavformat -lavutil-lavcodec -lpthread|| die "Error, can't find libavformat !"
上面的问题应该解决了,但make还有另外错误,就是获取版本库失败,为空。因为知道dlna源码库为0.2.4版本,所以直接改VERSION=`$TMPE`为VERSION="0.2.4",算是解决了问题吧。
执行make && make install
III. 编译upnp
./configure --prefix=/home/work/dlna/cross_install--host=mipsel-linux --target=mipsel-linux CC=mipsel-linux-gcc CXX=mipsel-linux-g++
make && make install
这两步应该没什么问题。
IV. 编译ushare
在configure前,修改configure文件。(可先不修改,执行./configure后,如果出现问题再执行此步修改动作)
Vi configure
659 check_cflags -I$libdlnadir/include
660 check_ldflags -L$libdlnadir/lib
662 check_libdlna.h dlna_register_all_media_profiles -ldlna || die "Error, can't findlibdlna (install it or use --disable-dlna) !"改成
check_lib dlna.h dlna_register_all_media_profiles-ldlna -lavformat -lavcodec -lavutil|| die"Error, can't find libdlna (install it or use --disable-dlna) !"
保存退出,执行./configure
./configure --prefix=/home/work/dlna/cross_install--enable-dlna --with-libupnp-dir=/home/work/dlna/cross_install--with-libdlna-dir=/home/work/dlna/cross_install --cross-prefix=mipsel-linux---cross-compile --enable-debug
在configure时,可能会遇到下面的错误:
Checking for libthreadutil ...
Checking for libupnp >= 1.4.2...
Error, libupnp < 1.4.2!
解决方法:在命令行执行exportPKG_CONFIG_PATH=/home/work/dlna/cross_install/lib/pkgconfig/(实际路径视前面编译路径)
然后执行make,执行过程中也可能出现下面的错误:
mipsel-linux-gcc -I.. -MM cds.c cms.c msr.c http.c presentation.cmetadata.c mime.c services.c buffer.c util_iconv.c content.c cfgparser.ctrace.c redblack.c osdep.c ctrl_telnet.c ushare.c 1>.depend
mipsel-linux-gcc cds.o cms.o msr.o http.opresentation.o metadata.o mime.o services.o buffer.o util_iconv.o content.ocfgparser.o trace.o redblack.o osdep.o ctrl_telnet.o ushare.o-L/home/work/dlna/cross_install/lib -lixml -lthreadutil -lpthread -lupnp-L/home/work/dlna/cross_install/lib -ldlna -lavformat -lavcodec -lavutil -oushare
/opt/gcc-3.4.6-2f/bin/../lib/gcc/mipsel-linux/3.4.6/../../../../mipsel-linux/bin/ld:cds.o:普通ELF重定位(M: 3)
/opt/gcc-3.4.6-2f/bin/../lib/gcc/mipsel-linux/3.4.6/../../../../mipsel-linux/bin/ld:cds.o:普通ELF重定位(M: 3)
cds.o: 无法读取符号: 文件格式错误
解决方法:更改config.mak
STRIP=mipsel-linux-strip
INSTALLSTRIP=-s
最后make install
V. 如何应用
启动ushare有两种方式,一种是直接执行./ushare,配置是根据安装目录下的etc/ushare.conf,第二种方式启动./ushare 后面带一系列参数。先看第一种方式的配置文件ushare.conf:
# /etc/ushare.conf
# Configuration file for uShare
# uShare UPnP Friendly Name (default is'uShare').
#设备名,自定义(必填)
USHARE_NAME=
# Interface to listen to (default is eth0).
# Ex : USHARE_IFACE=eth1
#网络接口(必填)
USHARE_IFACE=
# Port to listen to (default is random fromIANA Dynamic Ports range)
# Ex : USHARE_PORT=49200
#端口号,用默认就行
USHARE_PORT=
# Port to listen for Telnet connections
# Ex : USHARE_TELNET_PORT=1337
#端口号,用默认就行
USHARE_TELNET_PORT=
# Directories to be shared (space or CSVlist).
# Ex: USHARE_DIR=/dir1,/dir2
#共享文件夹(至少填一个)
USHARE_DIR=
# Use to override what happens when iconvfails to parse a file name.
# The default uShare behaviour is to notadd the entry in the media list
# This option overrides that behaviour andadds the non-iconv'ed string into
# the media list, with the assumption thatthe renderer will be able to
# handle it. Devices like Noxon 2 have noproblem with strings being passed
# as is. (Umlauts for all!)
#
# Options are TRUE/YES/1 for override andanything else for default behaviour
#可不填
USHARE_OVERRIDE_ICONV_ERR=
# Enable Web interface (yes/no)
#可不填
ENABLE_WEB=
# Enable Telnet control interface (yes/no)
ENABLE_TELNET=yes
# Use XboX 360 compatibility mode (yes/no)
#可不填
ENABLE_XBOX=
# Use DLNA profile (yes/no)
# This is needed for PlayStation3 to work(among other devices)
#需要用dlna,填yes
ENABLE_DLNA=
第二种方式带参数,参数列表如下:
Options:
-n, --name=NAME Set UPnP Friendly Name (default is 'uShare')
-i, --interface=IFACE Use IFACE Network Interface (default is 'eth0')
-f, --cfg=FILE Config file to be used
-p, --port=PORT Forces the HTTP server to run on PORT
-q, --telnet-port=PORT Forces the TELNET server to run on PORT
-c, --content=DIR Share the content of DIR directory (default is './')
-w, --no-web Disable the control web page (enabled
by default)
-t, --no-telnet Disable the TELNET control (enabled by default)
-o, --override-iconv-err If iconv fails parsing name, still add to media contents (hoping the renderer can handle it)
-v, --verbose Set verbose display.
-x, --xbox Use XboX 360 compliant profile
-d, --dlna Use DLNA compliant profile (PlayStation3 needs this)
-D, --daemon Run as a daemon.
-V, --version Display the version of uShare and exit
-h, --help Display this help
主要的参数就有-n –i –c –d,如./ushare –n LOONGSON –i wlan0 –c /home/share –d
好了,ushare跑起来应该没什么问题了,就先介绍到这吧。
浙公网安备 33010602011771号