移植 ffmpeg 到 ARM 平台

简介: 1,yasm: 到 http://www.tortall.net/projects/yasm/wiki/Download 下载yasm0.7.2(x264需要用到的汇编编译器) for x86: .

1,yasm:

http://www.tortall.net/projects/yasm/wiki/Download 下载yasm0.7.2(x264需要用到的汇编编译器)

for x86:

./configure --enable-shared --prefix=/usr/local
make
make install

for arm:
./configure --enable-shared --prefix=/usr/local/ --host=arm-linux
make
make install

2,x264:

ftp://ftp.videolan.org/pub/videolan/x264/snapshots/ 下载x264库

for x86:

./configure --enable-shared --prefix=/usr/local
make
make install

for arm:
./configure --enable-shared --prefix=/usr/local/ --host=arm-linux
到common/cpu.c编译不过,未定义 cpu_set_t。这里改为 返回1.

x264_cpu_num_processors().
cpu_set_t unsinged long.

3,xvid:

http://downloads.xvid.org/downloads/xvidcore-1.1.3.tar.gz  下载xvid
for x86:

cd build/generic
./configure --prefix=/usr/local
make
make install

for arm:
#./configure --prefix=/usr/local/ --host=arm-linux --target=arm-linux
./configure --prefix=/usr/local/ --host=arm-hismall-linux --target=arm-hismall-linux
make
make install

4,ffmpeg:

svn co svn://svn.mplayerhq.hu/ffmpeg/trunk 下载ffmpeg源码

for x86:

./configure --prefix=/usr/local/ --enable-gpl --enable-shared --enable-xvid --enable-x264 --enable-pthreads --disable-ffserver --disable-ffplay --enable-faac --enable-faad

编译不过,I changed the line (about line number 596):

static always_inline long int lrintf(float x)

in /libavcodec/dsputil.h to:

static __inline__ long int lrintf(float x)

make
make install

在x86的linux上执行:

[root@localhost ffmpeg-0.4.9-p20051216]# ffmpeg -i ../test/beijing.mp4 -b 479k -s 320x240 ../test/beijing.h264
ffmpeg version CVS, build 3342336, Copyright (c) 2000-2004 Fabrice Bellard
  configuration:  --prefix=/usr/local/ --enable-gpl --enable-shared --enable-xvid --enable-x264 --enable-pthreads --disable-ffserver --disable-ffplay
  built on Nov 11 2008 08:48:14, gcc: 3.4.6 20060404 (Red Hat 3.4.6-8)
Input #0, mov,mp4,m4a,3gp,3g2, from '../test/beijing.mp4':
  Duration: 00:06:50.2, start: 0.000000, bitrate: 479 kb/s
  Stream #0.0, 23.98 fps: Video: mpeg4, yuv420p, 320x240
  Stream #0.1: Audio: mp4a / 0x6134706D, 16000 Hz, stereo
File '../test/beijing.h264' already exists. Overwrite ? [y/N]
Not overwriting - exiting
[root@localhost ffmpeg-0.4.9-p20051216]# ffmpeg -i ../test/beijing.mp4 -b 479k -s 320x240 ../test/beijing.h264
ffmpeg version CVS, build 3342336, Copyright (c) 2000-2004 Fabrice Bellard
  configuration:  --prefix=/usr/local/ --enable-gpl --enable-shared --enable-xvid --enable-x264 --enable-pthreads --disable-ffserver --disable-ffplay
  built on Nov 11 2008 08:48:14, gcc: 3.4.6 20060404 (Red Hat 3.4.6-8)
Input #0, mov,mp4,m4a,3gp,3g2, from '../test/beijing.mp4':
  Duration: 00:06:50.2, start: 0.000000, bitrate: 479 kb/s
  Stream #0.0, 23.98 fps: Video: mpeg4, yuv420p, 320x240
  Stream #0.1: Audio: mp4a / 0x6134706D, 16000 Hz, stereo
File '../test/beijing.h264' already exists. Overwrite ? [y/N] y
Output #0, h264, to '../test/beijing.h264':
  Stream #0.0,   nan fps: Video: h264, yuv420p, 320x240, q=2-31, 479 kb/s
Stream mapping:
  Stream #0.0 -> #0.0
[h264 @ 0x458428]using SAR=1/1
[h264 @ 0x458428]using cpu capabilities: MMX MMXEXT SSE SSE2
Press [q] to stop encoding
frame= 9835 q=9.0 Lsize=   24683kB time=410.2 bitrate= 492.9kbits/s   
video:24683kB audio:0kB global headers:0kB muxing overhead 0.000000%
[h264 @ 0x458428]slice I:1007  Avg QP:22.31  size:  9162  PSNR Mean Y:43.70 U:48.20 V:47.61 Avg:44.67 Global:43.74
[h264 @ 0x458428]slice P:8828  Avg QP:25.29  size:  1815  PSNR Mean Y:41.23 U:47.00 V:46.21 Avg:42.35 Global:41.02
[h264 @ 0x458428]mb I  I16..4: 23.8%  0.0% 76.2%
[h264 @ 0x458428]mb P  I16..4:  3.6%  0.0%  2.0%  P16..4: 41.9% 17.4%  6.5%  0.0%  0.0%    skip:28.5%
[h264 @ 0x458428]final ratefactor: 21.37
[h264 @ 0x458428]SSIM Mean Y:0.9803090
[h264 @ 0x458428]PSNR Mean Y:41.484 U:47.120 V:46.353 Avg:42.588 Global:41.228 kb/s:492.37
[root@localhost ffmpeg-0.4.9-p20051216]#

共用时3分3秒45

ffmpeg -i ../test/beijing.mp4 -b 479k -s 320x240 -fs 1500 -y ../test/beijing.h264 录制1500kB的文件,用时9秒27

for arm:
./configure --prefix=/usr/local/  --enable-gpl  --cpu=arm --enable-xvid --enable-x264 --enable-pthreads --disable-ffserver --disable-ffplay  --cc=arm-hismall-linux-gcc --enable-shared
编译到最后报错:
arm-hismall-linux-gcc -Wl,--warn-common -rdynamic -g  -o ffmpeg_g ffmpeg.o cmdutils.o -L./libavformat -lavformat -L./libavcodec -lavcodec -L./libavutil -lavutil -lm -lxvidcore -lx264 -ldl -lpthread
./libavcodec/libavcodec.so: undefined reference to `roundf'
./libavcodec/libavcodec.so: undefined reference to `log2'
collect2: ld returned 1 exit status
make: *** [ffmpeg_g] 错误 1

在Makefile中加入-I/home/ellen/compiler/gcc-3.4.3-uClibc-0.9.28/,还是报错。

更换gcc为arm-linux-gcc-3.3.2.tar.bz2,还是报错。

在 libavcodec/Makefile 中加入 -I/home/ellen/compiler/gcc-3.4.3-uClibc-0.9.28/ (roundf和log2都包含在math.h中),还是报错。

在 libavcodec/Makefile 中 定义x264.o 的地方,加入 EXTRALIBS += -lm,还是报错。

用 nm -u libavcodec.so 可以查看so中未定义的函数。

自己写log的函数:
#define M_1_SQRT2 0.70710678118654752440084436210484904
#define POLYNOM1(x, a) ((a)[1]*(x)+(a)[0])
#define POLYNOM2(x, a) (POLYNOM1((x),(a)+1)*(x)+(a)[0])
#define POLYNOM3(x, a) (POLYNOM2((x),(a)+1)*(x)+(a)[0])

double
log(double x)
{
/* Algorithm and coefficients from:
   "Software manual for the elementary functions"
   by W.J. Cody and W. Waite, Prentice-Hall, 1980
*/
static double a[] = {
  -0.64124943423745581147e2,
   0.16383943563021534222e2,
  -0.78956112887491257267e0
};
static double b[] = {
  -0.76949932108494879777e3,
   0.31203222091924532844e3,
  -0.35667977739034646171e2,
   1.0
};

double znum, zden, z, w;
int exponent;

if (x   errno = EDOM;
  return -HUGE_VAL;
}
else if (x == 0) {
  errno = ERANGE;
  return -HUGE_VAL;
}

if (x }
else return x; /* for infinity and Nan */
x = frexp(x, &exponent);
if (x > M_1_SQRT2) {
  znum = (x - 0.5) - 0.5;
  zden = x * 0.5 + 0.5;
}
else {
  znum = x - 0.5;
  zden = znum * 0.5 + 0.5;
  exponent--;
}
z = znum/zden; w = z * z;
x = z + z * w * (POLYNOM2(w,a)/POLYNOM3(w,b));
z = exponent;
x += z * (-2.121944400546905827679e-4);
return x + z * 0.693359375;
}

double
log10(double x)
{
if (x   errno = EDOM;
  return -HUGE_VAL;
}
else if (x == 0) {
  errno = ERANGE;
  return -HUGE_VAL;
}

return log(x) / M_LN10;
}

double log2(double x)
{
return (log10(x) / log10(2) );
}

log2编译通过。

自己写roundf的函数:
double
copysign (double x, double y)
{
  if ((x 0) || (x > 0 && y     return -x;
  return x;
}

float
copysignf (float x, float y)
{
  /* We use the double version.  */
  return copysign (x, y);
}

float modff(float x, float * y)
{
    *y=((int)x);
    return (x-*y);
}

float
roundf(float Arg)
{
    float FracPart, IntPart;

    FracPart = modff(Arg, &IntPart);

    if (fabsf(FracPart) >= 0.5f)
           IntPart += copysignf(1.0, IntPart);

    return IntPart;
}
编译通过。

编译好的ffmpeg放到arm平台上,把libavcodec.so和libavformat.so放到板子上,运行,报错:
/usr/local/lib $ ls -l
-rwxrwxrwx    1 root     root      4984743 Nov 10 15:02 libavcodec.so
-rwxrwxrwx    1 root     root      1466472 Nov 10 15:07 libavformat.so
lrwxrwxrwx    1 root     root           14 Nov 10 15:03 libavformat.so.50 -> libavformat.so
/usr/local/lib $ /ffmpeg
Can't modify /usr/local/lib/libavformat.so.50's text section. Use GCC option -fPIC for shared objects, please.
/usr/local/lib $

在libavformat和libavcodec的makefile中添加 -fPIC,还是不行。

./configure --prefix=/usr/local/  --enable-gpl  --cpu=arm --enable-xvid --enable-x264 --enable-pthreads --disable-ffserver --disable-ffplay  --cc=arm-hismall-linux-gcc  --disable-strip
不用shared,用静态编译,把libavcodec和libavformat都编到ffmpeg中,在板子上运行,需要链接 libx264.so时,还是报错不能 -fPIC,于是想办法把libx264静态编译到ffmepg中。

重新编译x264,不用shared。把libx264.a 和libxvidcore.a 拷贝到libavcodec和libavformat目录下,修改 ffmpeg/Makefile,添加:
LIBSUF += libx264.a libxvidcore.a

放在arm上运行时,还是会报错:

[h264 @ 0x3705fc]no ratecontrol method specified
Error while opening codec for output stream #0.0 - maybe incorrect parameters such as bit_rate, rate, width or height

修改x264/common/common.c的x264_param_default()中:
//param->rc.i_rc_method = X264_RC_NONE;
param->rc.i_rc_method = X264_RC_ABR;
重新编译264,重新编译ffmpeg:
./ffmpeg -i beijing.mp4 -b 479k -s 320x240 -fs 1500 -y beijing.h264
/mnt $ ./ffmpeg -i beijing.mp4 -b 479k -s 320x240 -fs 1500 -y beijing.h264
ffmpeg version CVS, build 3342336, Copyright (c) 2000-2004 Fabrice Bellard
  configuration:  --prefix=/usr/local/ --enable-gpl --cpu=arm --enable-xvid --enable-x264 --enable-pthreads --disable-ffserver --disable-ffplay --cc=arm-hismall-linux-gcc --disable-strip
  built on Nov 11 2008 09:47:01, gcc: 3.4.3 (release) (CodeSourcery ARM Q3cvs 2004)
Input #0, mov,mp4,m4a,3gp,3g2, from 'beijing.mp4':
  Duration: 00:06:50.2, start: 0.000000, bitrate: 479 kb/s
  Stream #0.0, 23.98 fps: Video: mpeg4, yuv420p, 320x240
  Stream #0.1: Audio: mp4a / 0x6134706D, 16000 Hz, stereo
Output #0, h264, to 'beijing.h264':
  Stream #0.0,   nan fps: Video: h264, yuv420p, 320x240, q=2-31, 479 kb/s
Stream mapping:
  Stream #0.0 -> #0.0
[h264 @ 0x3705fc]using SAR=1/1
[h264 @ 0x3705fc]using cpu capabilities: none!
Press [q] to stop encoding
frame=  519 q=25.0 Lsize=    1501kB time=21.6 bitrate= 568.2kbits/s   
video:1501kB audio:0kB global headers:0kB muxing overhead 0.000000%
[h264 @ 0x3705fc]slice I:48    Avg QP:18.17  size: 10418  PSNR Mean Y:48.72 U:52.93 V:51.90 Avg:49.57 Global:45.65
[h264 @ 0x3705fc]slice P:471   Avg QP:22.15  size:  2198  PSNR Mean Y:45.54 U:51.02 V:49.82 Avg:46.54 Global:42.61
[h264 @ 0x3705fc]mb I  I16..4: 24.5%  0.0% 75.5%
[h264 @ 0x3705fc]mb P  I16..4:  8.2%  0.0%  4.8%  P16..4: 42.0% 15.7%  5.8%  0.0%  0.0%    skip:23.5%
[h264 @ 0x3705fc]final ratefactor: 20.83
[h264 @ 0x3705fc]SSIM Mean Y:0.9833328
[h264 @ 0x3705fc]PSNR Mean Y:45.838 U:51.198 V:50.012 Avg:46.823 Global:42.820 kb/s:567.41
/mnt $
共519帧,568.2kbits/s。共用时10分56秒88

相关文章
|
7月前
|
数据采集 监控 安全
精简高效与安全兼备:ARM32与MCU32平台上的信息协议设计新思路
精简高效与安全兼备:ARM32与MCU32平台上的信息协议设计新思路
270 1
|
2月前
|
Linux API 开发工具
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
ijkplayer是由B站研发的移动端播放器,基于FFmpeg 3.4,支持Android和iOS。其源码托管于GitHub,截至2024年9月15日,获得了3.24万星标和0.81万分支,尽管已停止更新6年。本文档介绍了如何在Linux环境下编译ijkplayer的so库,以便在较新的开发环境中使用。首先需安装编译工具并调整/tmp分区大小,接着下载并安装Android SDK和NDK,最后下载ijkplayer源码并编译。详细步骤包括环境准备、工具安装及库编译等。更多FFmpeg开发知识可参考相关书籍。
110 0
FFmpeg开发笔记(五十九)Linux编译ijkplayer的Android平台so库
|
7月前
|
存储 人工智能 达摩院
FunASR 语音大模型在 Arm Neoverse 平台上的优化实践
Arm 架构的服务器通常具备低功耗的特性,能带来更优异的能效比。相比于传统的 x86 架构服务器,Arm 服务器在相同功耗下能够提供更高的性能。这对于大模型推理任务来说尤为重要,因为大模型通常需要大量的计算资源,而能效比高的 Arm 架构服务器可以提供更好的性能和效率。
|
7月前
|
缓存 Linux
ARM平台内存和cache对xenomai实时性的影响
ARM平台内存和cache对xenomai实时性的影响
153 0
ARM平台内存和cache对xenomai实时性的影响
|
7月前
|
JSON Ubuntu Linux
LuaJit交叉编译移植到ARM Linux
LuaJit交叉编译移植到ARM Linux
159 1
|
7月前
|
Linux 计算机视觉
Linux交叉编译opencv并移植ARM端
通过以上步骤,你可以在Linux上交叉编译OpenCV,并将生成的库文件和头文件移植到ARM平台上,从而在ARM上使用OpenCV。 买CN2云服务器,免备案服务器,高防服务器,就选蓝易云。百度搜索:蓝易云
499 0
|
7月前
|
安全 Linux 数据安全/隐私保护
【SPI协议】了解ARM平台上的SPI的基本应用
【SPI协议】了解ARM平台上的SPI的基本应用
655 0
|
7月前
|
安全 Ubuntu Linux
ARM可信固件(TF-A)移植
ARM可信固件(TF-A)移植
284 1
STM32CubeIDE移植ARM DSP库
STM32CubeIDE移植ARM DSP库
|
19天前
|
机器学习/深度学习 弹性计算 人工智能
阿里云服务器架构有啥区别?X86计算、Arm、GPU异构、裸金属和高性能计算对比
阿里云ECS涵盖x86、ARM、GPU/FPGA/ASIC、弹性裸金属及高性能计算等多种架构。x86架构采用Intel/AMD处理器,适用于广泛企业级应用;ARM架构低功耗,适合容器与微服务;GPU/FPGA/ASIC专为AI、图形处理设计;弹性裸金属提供物理机性能;高性能计算则针对大规模并行计算优化。