一、发此文的目的
1、对于想通过在chrome浏览器上通过插件的方式跑视频的话,可以解决有无的问题。
2、对于本文提到的问题欢迎有经验的大神给予指导。
二、为什么要做这个事情
由于工作关系,需要在chrome浏览器上实现一个播放视频监控的插件。插件架构选择PNacl,通过对nacl-sdk自带的pp::VideoDecoder进行测试后发现,它非常不稳定,跑rtsp://184.72.239.149:554/vod/mp4:BigBuckBunny_115k.mov,几秒后帧解码就不正常了,图像出不来了,如果跑高分辨率的监控的话,连一个图片也解码不出来,通过对chromium项目的初步研究,pp::VideoDecoder在解码时如果是h.264的话也是ffmpeg参与的解码。折腾了好久,也不知道问题出在哪里,如果有哪位大神踩过这个坑,欢迎沟通讨论。
后面转换思路,抛弃掉nacl-sdk自带的解码功能,采用ffmpeg进行解码,后面取得了成功。下面对过程做一记录,并对可能出现的问题作一个说明。
三、原材料准备
1、CentOS 6.8 X64
2、nacl_sdk linux版(如何获取nacl_sdk不在此讨论)
3、GLIBC要升级到2.15
4、Python2.7(编译插件的时候需要)
5、ffmpeg4.1
四、安装nacl_sdk
只需要设置环境变量即可:
NACL_SDK_ROOT=/home/nacl_sdk/pepper_49
export NACL_SDK_ROOT
PATH=$PATH:/home/nacl_sdk/pepper_49/toolchain/linux_pnacl/bin
五、编译ffmpeg
进入到ffmpeg-4.1目录,执行如下命令
./configure \
--target-os=linux \
--arch=pnacl \
--prefix="$NACL_SDK_ROOT/toolchain/linux_pnacl/le32-nacl/usr" \
--cross-prefix=pnacl- \
--cc=pnacl-clang \
--ld=pnacl-clang++ \
--enable-static
make
make install
编译完成后,在$NACL_SDK_ROOT/toolchain/linux_pnacl/le32-nacl/usr目录下面会有7们le-32架构的静态库,供二次开发使用。
libavcodec.a
libavdevice.a
libavfilter.a
libavformat.a
libavutil.a
libswresample.a
libswscale.a
六、在编译过程中可能遇到的问题
1、libavformat/codec2.c:22:10: fatal error: 'memory.h' file not found
在ffbuild/config.mak文件里面找到CFLAGS,增中头文件依赖-I/home/nacl_sdk/pepper_49/include/pnacl
修改后的样子为:
CFLAGS= -std=c11 -fomit-frame-pointer -pthread -g -Wdeclaration-after-statement -Wall -Wdisabled-optimization -Wpointer-arith -Wredundant-decls -Wwrite-strings -Wtype-limits -Wundef -Wmissing-prototypes -Wno-pointer-to-int-cast -Wstrict-prototypes -Wempty-body -Wno-parentheses -Wno-switch -Wno-format-zero-length -Wno-pointer-sign -Wno-unused-const-variable -O3 -fno-math-errno -fno-signed-zeros -Werror=implicit-function-declaration -Werror=missing-prototypes -Werror=return-type -I/home/nacl_sdk/pepper_49/include/pnacl
2、fftools/cmdutils.c:1072:19: error: variable has incomplete type 'struct rlimit'
找到opt_timelimit函数在
#if HAVE_SETRLIMIT后面增加 && !defined(__pnacl__)
修改后的样子是:
#if HAVE_SETRLIMIT && !defined(__pnacl__)
3、fftools/ffmpeg.c:4800:5: error: implicit declaration of function 'getrusage' is invalid in C99
找到get_benchmark_time_stamps函数在#if HAVE_GETRUSAGE后面增加&& !defined(__pnacl__)
修改后的样子:
#if HAVE_GETRUSAGE && !defined(__pnacl__)
七、需要说明的问题
1、ffmpeg的静态库当中的网络连接功能不能使用,即avformat_open_input是不能使用的。测试过程中一直返回错误,推测可能是由于chrome的沙箱的拦截造成的,网络部分需要通过nacl_sdk的pp::HostResolver、pp::TCPSocket(或者pp::UDPSocket)自己实现才能解决。但是静态库的解码功能是正常可以使用。
2、编译出的静态库只能在linux下进行二次开发使用,在windows当中进行编译会通过,但链接时会出现不明原因错误,导致生成不了pexe。
八、未来需要解决的问题
1、播放过程中有花屏现象(原因不明)效果如下图所示:
经过测试,相同版本的ffmpeg在编译出来的windows的dll库上是不存在此问题的,不知道是不是与pnacl不支持汇编,而ffmpeg有汇编代码有关,欢迎大神们解惑。
2、不支持高清分辨率的视频
经过测试,如果是高清的主码流可以很好的播放,但是如果是主码流1080p的rtsp的话播放会出现花屏和条带现象。
八、致谢
1、在线流媒体测试视频
rtsp://184.72.239.149:554/vod/mp4:BigBuckBunny_115k.mov
2、编译选项启发:
https://github.com/mdhsl/FFmpeg-Pnacl