欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  网络运营

Linux下编译ffmpeg-4.1,arm32, arm64, x86问题及解决方案

程序员文章站 2022-05-01 19:17:13
目录目标准备工作编译arm版本遇到的问题及解决方案arm32, arm64, 成功编译x86目标编译ffmpeg-4.1版本的 arm32, arm64, x86的动态库。准备工作新建目录,mkdir ffmpeg, cd ffmpeg, 下载ffmpeg4.1的源码,并解压。http://ffmpeg.org/releases/# 下载wgethttp://ffmpeg.org/releases/ffmpeg-4.2.3.tar.bz2 # 解压ta....

目录

目标

准备工作

编译arm版本

遇到的问题及解决方案

arm32, arm64, 成功

编译x86


目标

编译ffmpeg-4.1版本的 arm32, arm64, x86的动态库。

准备工作

新建目录,mkdir ffmpeg, cd ffmpeg, 下载ffmpeg4.1的源码,并解压。http://ffmpeg.org/releases/

# 下载
wget http://ffmpeg.org/releases/ffmpeg-4.2.3.tar.bz2
 
# 解压
tar xvf ffmpeg-4.2.3.tar.bz2

在同一个目录ffmpeg下,下载编译器:版本选择的是14b。https://developer.android.google.cn/ndk/downloads/older_releases

# 下载
wget https://dl.google.com/android/repository/android-ndk-r14b-linux-x86_64.zip
 
# 解压
unzip android-ndk-r21b-linux-x86_64.zip

修改ffmpeg4.1的 configure 文件:

# 将上面的四行注释掉
#SLIBNAME_WITH_MAJOR='$(SLIBNAME).$(LIBMAJOR)'
#LIB_INSTALL_EXTRA_CMD='$$(RANLIB) "$(LIBDIR)/$(LIBNAME)"'
#SLIB_INSTALL_NAME='$(SLIBNAME_WITH_VERSION)'
#SLIB_INSTALL_LINKS='$(SLIBNAME_WITH_MAJOR) $(SLIBNAME)'

# 添加下面的四行
SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)'
LIB_INSTALL_EXTRA_CMD='$$(RANLIB) "$(LIBDIR)/$(LIBNAME)"'
SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)'
SLIB_INSTALL_LINKS='$(SLIBNAME)'

在ffmpeg4.1的根目录下,编写run.sh文件, run64.sh文件。

#run.sh, arm 32
#!/bin/bash
#modify those veriable based on your env
#===========================
NDK=/home/ht-dong/ffmpeg/android-ndk-r14b
#32 or 64
archbit=32

#===========================
echo "build for 32bit"
#32bit
abi='armeabi'
cpu='arm'
arch='arm'
android='androideabi'

SYSROOT=$NDK/platforms/android-24/arch-$arch/
TOOLCHAIN=$NDK/toolchains/$cpu-linux-$android-4.9/prebuilt/linux-x86_64

PREFIX=$(pwd)/android/$cpu
#ADDI_CFLAGS="-marm"

function build_one
{
    ./configure \
    --prefix=$PREFIX \
    --enable-shared \
    --disable-static \
    --disable-doc \
    --disable-ffmpeg \
    --disable-ffplay \
    --disable-ffprobe \
    --disable-avdevice \
    --disable-doc \
    --disable-symver \
    --enable-yasm \
    --cross-prefix=$TOOLCHAIN/bin/$cpu-linux-$android- \
    --target-os=linux \
    --arch=$cpu \
    --enable-cross-compile \
    --sysroot=$SYSROOT \
    --extra-cflags="-Os -fpic -DANDROID" \
    --extra-ldflags="$ADDI_LDFLAGS" \
    $ADDITIONAL_CONFIGURE_FLAG
    make clean
    make
    make install
}

build_one
#run64.sh
#!/bin/bash
#modify those veriable based on your env
#===========================
NDK=/home/ht-dong/ffmpeg/android-ndk-r14b
#32 or 64
archbit=64

#===========================
#64bit
echo "build for 64bit"
abi='arm64-v8a'
cpu='aarch64'
arch='arm64'
android='android'

SYSROOT=$NDK/platforms/android-24/arch-$arch/
TOOLCHAIN=$NDK/toolchains/$cpu-linux-$android-4.9/prebuilt/linux-x86_64

PREFIX=$(pwd)/android/$cpu
#ADDI_CFLAGS="-marm"

function build_one
{
    ./configure \
    --prefix=$PREFIX \
    --enable-shared \
    --disable-static \
    --disable-doc \
    --disable-ffmpeg \
    --disable-ffplay \
    --disable-ffprobe \
    --disable-avdevice \
    --disable-doc \
    --disable-symver \
    --enable-yasm \
    --cross-prefix=$TOOLCHAIN/bin/$cpu-linux-$android- \
    --target-os=linux \
    --arch=$cpu \
    --enable-cross-compile \
    --sysroot=$SYSROOT \
    --extra-cflags="-Os -fpic -DANDROID" \
    --extra-ldflags="$ADDI_LDFLAGS" \
    $ADDITIONAL_CONFIGURE_FLAG
    make clean
    make
    make install
}

build_one

编译arm版本

先编译arm32位的库:

# 为run.sh 文件 授权
chmod 777 run.sh
 
# 运行
./run.sh

遇到的问题及解决方案

错误一:

libavformat/udp.c: In function 'udp_set_multicast_sources':
libavformat/udp.c:290:28: error: request for member 's_addr' in something not a structure or union
         mreqs.imr_multiaddr.s_addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr;
                            ^
libavformat/udp.c:292:32: error: incompatible types when assigning to type '__u32' from type 'struct in_addr'
             mreqs.imr_interface= ((struct sockaddr_in *)local_addr)->sin_addr;
                                ^
libavformat/udp.c:294:32: error: request for member 's_addr' in something not a structure or union
             mreqs.imr_interface.s_addr= INADDR_ANY;
                                ^
libavformat/udp.c:295:29: error: request for member 's_addr' in something not a structure or union
         mreqs.imr_sourceaddr.s_addr = ((struct sockaddr_in *)&sources[i])->sin_addr.s_addr;
                             ^
ffbuild/common.mak:59: recipe for target 'libavformat/udp.o' failed
make: *** [libavformat/udp.o] Error 1

注释掉udp.c中的那几行代码。 以后最好不用ffmpeg的udp, 否则,会有意想不到的惊喜。


解决好错误一之后,重新编译,出现错误二:

libavcodec/aaccoder.c: In function 'search_for_ms':
libavcodec/aaccoder.c:803:25: error: expected identifier or '(' before numeric constant
                     int B0 = 0, B1 = 0;
                         ^
libavcodec/aaccoder.c:865:28: error: lvalue required as left operand of assignment
                         B0 += b1+b2;
                            ^
libavcodec/aaccoder.c:866:25: error: 'B1' undeclared (first use in this function)
                         B1 += b3+b4;

重命名,把B0, 改成了b0。

# 快捷键,全局搜索,一个一个进行更改确认。
:%s/B0/b0/gc

# 解释:
:% 全局。 
s search, 
B0, 关键字, 
b0替换字, 
gc每一行都判断。 
y, 替换。 n不替换,继续下一个。

B1 其实是有初始化声明的,就是803行,但是866是在一个循环中使用。理论上来说,应该是能找到的。所以替换完B0,B1的错误就不再报了。


解决好错误二之后,重新编译,出现错误三:

libavcodec/hevc_mvs.c: In function 'derive_spatial_merge_candidates':
libavcodec/hevc_mvs.c:208:15: error: 'y0000000' undeclared (first use in this function)
             ((y ## v) >> s->ps.sps->log2_min_pu_size))
               ^
......
libavcodec/hevc_mvs.c:207:15: error: 'x0000000' undeclared (first use in this function)
     TAB_MVF(((x ## v) >> s->ps.sps->log2_min_pu_size),                     \
               ^
......
libavcodec/hevc_mvs.c: In function 'ff_hevc_luma_mv_mvp_mode':
libavcodec/hevc_mvs.c:208:15: error: 'y0000000' undeclared (first use in this function)
             ((y ## v) >> s->ps.sps->log2_min_pu_size))
               ^
......
libavcodec/hevc_mvs.c:207:15: error: 'x0000000' undeclared (first use in this function)
     TAB_MVF(((x ## v) >> s->ps.sps->log2_min_pu_size),                     \
               ^
......
ffbuild/common.mak:60: recipe for target 'libavcodec/hevc_mvs.o' failed
make: *** [libavcodec/hevc_mvs.o] Error 1

解决方法:将libavcodec/hevc_mvs.c文件的变量B0改成b0,xB0改成xb0,yB0改成yb0

输入命令:   :%s/B0/b0/gc   ,然后 y 或 n 进行替换或跳过。

20 substitutions on 18 lines(一共替换了这么多)


解决好错误三之后,重新编译,出现错误四:

libavcodec/opus_pvq.c: In function 'quant_band_template':
libavcodec/opus_pvq.c:498:9: error: expected identifier or '(' before numeric constant
     int B0 = blocks;
         ^
libavcodec/opus_pvq.c:559:12: error: lvalue required as left operand of assignment
         B0 = blocks;
            ^
ffbuild/common.mak:60: recipe for target 'libavcodec/opus_pvq.o' failed
make: *** [libavcodec/opus_pvq.o] Error 1

解决方法:将libavcodec/opus_pvq.c文件的变量B0改成b0

输入命令:   :%s/B0/b0/gc   ,然后 y 或 n 进行替换或跳过。

14 substitutions on 14 lines  (修改的个数)


arm32, arm64, 成功

终于通过了,arm32版本的。

Linux下编译ffmpeg-4.1,arm32, arm64, x86问题及解决方案

然后直接执行run64.sh的脚本,直接生成!


编译x86

在ffmpeg4.1的根目录下,直接新建脚本run_x86.sh, 然后执行,

#这个路径,就直接生成在根目录下了,根据自己情况酌情添加。
PREFIX=$(pwd)/ffmpeg_x86

./configure --enable-shared --prefix=$PREFIX

make

sudo make install

报错如下:

INSTALL	libavdevice/libavdevice.a
LD	libavutil/libavutil-56.so
/usr/bin/ld: libavutil/log2_tab.o: Relocations in generic ELF (EM: 183)
/usr/bin/ld: libavutil/log2_tab.o: Relocations in generic ELF (EM: 183)
libavutil/log2_tab.o: error adding symbols: File in wrong format
collect2: error: ld returned 1 exit status
ffbuild/library.mak:102: recipe for target 'libavutil/libavutil-56.so' failed
make: *** [libavutil/libavutil-56.so] Error 1

看来需要一份干净的ffmpeg源码,重新编译。所以,另起一个文件夹,重新解压,源文件并没有任何修改,直接编译生成。

Linux下编译ffmpeg-4.1,arm32, arm64, x86问题及解决方案



内心的戏:arm的两个版本,改了这么多地方,这编译出来的库,会不会有很多坑呀  ̄□ ̄||

参考链接:

https://blog.csdn.net/qq_34732729/article/details/107690316 // 编译ffmpeg3.3版本的,这三个库

https://blog.csdn.net/qq_34902522/article/details/87879145 // 主要记录错误

本文地址:https://blog.csdn.net/qq_34732729/article/details/107761816