Firefly AIO-3399Pro C开发板交叉编译OpenCV 3.4.10及FFmpeg、x264等依赖库,实现视频播放等功能

文章目录

  • 前言
  • 一、开发部署环境
  • 二、安装前的相关包下载及环境准备
    • 1. Qt交叉编译环境搭建
    • 2.安装环境所需依赖包
    • 3. 交叉编译OpenCV所需x264、FFmpeg等依赖库
      • 3.1 nasm编译
      • 3.2 x264编译
      • 3.3 ZLIB编译
      • 3.4 libjpeg 编译
      • 3.5 libpng 编译
      • 3.6 libtiff编译
      • 3.7 FFmpeg编译
      • 3.8 libxvidcore编译
      • 3.9 将各软件的依赖库复制到交叉编译工具链文件路径下
      • 3.10 配置动态链接库
  • 三、交叉编译OpenCV 3.4.10
  • 四、测试OpenCV是否可以交叉编译
  • 总结


前言

实验室所用的Firefly AIO-3399Pro C开发板需要用到OpenCV和FFmpeg来实现视频播放,而OpenCV源码默认编译时,有些选项默认未打开,导致OpenCV无法配合FFmpeg正常使用,故在PC端的Ubuntu系统中交叉编译OpenCV 3.4.10版本和各个软件依赖库,配合Qt在PC端交叉编译,并移植到开发板上实现视频播放等功能。


提示:以下是本篇文章正文内容,因开发环境和文件路径的不同,下面案例仅供参考,需要按照自己的实际情况进行修改方可交叉编译成功。

一、开发部署环境

开发环境 软件版本
PC系统版本 Ubuntu 18.04LTS
开发板型号 Firefly AIO-3399 ProC开发板 (3+16GB)
开发板操作系统 Ubuntu 18.04LTS
开发板固件版本 AIO-RK3399PROC-UBUNTU18.04-GPT-20200525-1016.img
交叉编译工具链 gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu
OpenCV版本 3.4.10
Python版本 Python 3.7.10
Qt版本 5.12.2
Qt Creator版本 4.8.2
电脑远程软件 Xshell 6&Xftpd 6
依赖库软件 软件版本
nasm 2.14.02
zlib 1.12.11
x264 20191217-2245-stable
libjpeg jpegsrc.v9d
libpng 1.6.34
libtiff 4.0.9
ffmpeg 4.2.4
libxvidcore 1.3.7

二、安装前的相关包下载及环境准备

1. Qt交叉编译环境搭建

参考《Firefly AIO-3399ProC开发板与PC端部署Qt5.12.2交叉编译环境》
文章部署Qt交叉编译环境。并部署好gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu交叉编译工具链。

2.安装环境所需依赖包

  • 安装编译所需依赖包
 user@admin-machine:~$ sudo apt-get update
 user@admin-machine:~$ sudo apt-get install build-essential
 user@admin-machine:~$ sudo apt install software-properties-common
 user@admin-machine:~$ sudo apt-get install cmake git pkg-config
 
  • 安装Python3.7
user@admin-machine:~$ sudo apt update #检查可更新文件
user@admin-machine:~$ sudo apt install software-properties-common  #安装可添加源的工具
user@admin-machine:~$ sudo add-apt-repository ppa:deadsnakes/ppa #添加源,否则会无法找到python3.7-dev软件包
user@admin-machine:~$ sudo apt install python3.7-dev -y #安装python3.7
  • 配置Python3.7环境
#查看路径python,python3.7路径
user@admin-machine:~$ which python python3.7
/usr/bin/python
/usr/bin/python3.7
user@admin-machine:~$ sudo rm /usr/bin/python
user@admin-machine:~$ sudo rm /usr/bin/python3
#创建python3.7软连接到python&Python3
user@admin-machine:~$ sudo ln -s /usr/bin/python3.7 /usr/bin/python
user@admin-machine:~$ sudo ln -s /usr/bin/python3.7 /usr/bin/python3

#测试Python版本
user@admin-machine:~$ python
Python 3.7.10 (default, Feb 20 2021, 21:17:23) 
[GCC 7.5.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 
user@admin-machine:~$ python3
Python 3.7.10 (default, Feb 20 2021, 21:17:23) 
[GCC 7.5.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 

3. 交叉编译OpenCV所需x264、FFmpeg等依赖库

OpenCV的依赖库关系如下图所示:
Firefly AIO-3399Pro C开发板交叉编译OpenCV 3.4.10及FFmpeg、x264等依赖库,实现视频播放等功能_第1张图片必须交叉编译的依赖库有zlib、libjpeg、libpng等否则源码编译OpenCV时,会报缺少依赖库的错误,导致编译中断。
以下编译均在PC端的Ubuntu 18.04 LTS系统中编译,所用的交叉编译工具链为gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu

3.1 nasm编译

Netwide Assembler (简称 NASM)是一款基于x86架构的汇编与反汇编软件。它可以用来编写16位(8086、80286等)、32位(IA-32)和64位(x86_64)的程序。 NASM被认为是Linux平台上最受欢迎的汇编工具之一。

  • 解压nasm-2.14.02.tar.bz2,打开终端后进入文件夹中,执行:
user@admin-machine:~/compile/nasm-2.14.02$ ./configure --host=arm-linux --prefix=/home/user/compile/nasm-2.14.02/_libs --enable-shared  CC=aarch64-linux-gnu-gcc --disable-asm
  • 若无报错,编辑文件夹下的Makefile文件,将CC、AR、RANLIB、STRIP改为交叉编译工具的命令后保存。
user@admin-machine:~/compile/nasm-2.14.02$ sudo vim Makefile

#
# Auto-configuring Makefile for the Netwide Assembler.
#
# The Netwide Assembler is copyright (C) 1996 Simon Tatham and
# Julian Hall. All rights reserved. The software is
# redistributable under the license given in the file "LICENSE"
# distributed in the NASM archive.



top_srcdir	= .
srcdir		= .
objdir		= .

prefix		= /home/user/complier/opencv_lib
exec_prefix	= ${prefix}
bindir		= ${exec_prefix}/bin
mandir		= ${datarootdir}/man
datarootdir	= ${prefix}/share

CC		= aarch64-linux-gnu-gcc
CFLAGS		= -g -O3 -fwrapv -U__STRICT_ANSI__ -fno-common -Werror=attributes -fvisibility=hidden -W -Wall -pedantic -Wc90-c99-compat -Wno-long-long -Wno-shift-negative-value -Werror=implicit -Werror=missing-braces -Werror=return-type -Werror=trigraphs -Werror=pointer-arith -Werror=missing-prototypes -Werror=missing-declarations -Werror=comment -Werror=vla
CPPFLAGS	= 
BUILD_CFLAGS	= $(CPPFLAGS) $(CFLAGS) -DHAVE_CONFIG_H
INTERNAL_CFLAGS = -I$(srcdir) -I$(objdir) \
		  -I$(srcdir)/include -I$(objdir)/include \
		  -I$(srcdir)/x86 -I$(objdir)/x86 \
		  -I$(srcdir)/asm -I$(objdir)/asm \
		  -I$(srcdir)/disasm -I$(objdir)/disasm \
		  -I$(srcdir)/output -I$(objdir)/output
ALL_CFLAGS	= $(BUILD_CFLAGS) $(INTERNAL_CFLAGS)
LDFLAGS		=  -fvisibility=hidden
LIBS		= 

AR		= aarch64-linux-gnu-ar
RANLIB		= aarch64-linux-gnu-gcc-ranlib
STRIP		= aarch64-linux-gnu-strip

PERL		= perl
PERLFLAGS	= -I$(srcdir)/perllib -I$(srcdir)
RUNPERL         = $(PERL) $(PERLFLAGS)

INSTALL		= /usr/bin/install -c
INSTALL_PROGRAM	= ${INSTALL}
INSTALL_DATA	= ${INSTALL} -m 644

NROFF		= nroff
ASCIIDOC	= false
XMLTO		= false

MAKENSIS	= makensis

MKDIR		= mkdir -p
RM_F		= rm -f
RM_RF		= rm -rf
LN_S		= ln -s
FIND		= find

ESC 后输入:wq后保存并退出,执行make和make install即可。

user@admin-machine:~/compile/nasm-2.14.02$ make

user@admin-machine:~/compile/nasm-2.14.02$ make install

  • 安装完成后文件夹下的_libs中生成的文件结构如下:
user@admin-machine:~/compile/nasm-2.14.02/_libs$ tree
.
├── bin
│   ├── nasm
│   └── ndisasm
└── share
    └── man
        └── man1
            ├── nasm.1
            └── ndisasm.1

4 directories, 4 files

3.2 x264编译

H.264是ITU(International Telecommunication Union,国际通信联盟)和MPEG(Motion Picture Experts Group,运动图像专家组)联合制定的视频编码标准。而x264是一个开源的H.264/MPEG-4 AVC视频编码函数库,是最好的有损视频编码器之一。

  • 解压x264-snapshot-20191217-2245-stable.tar.bz2,打开终端后进入文件夹中,执行:
#x264编译
user@admin-machine:~/compile/x264-20191217$ ./configure --enable-shared --enable-static --disable-asm --prefix=$PWD/_libs --host=arm-linux --cross-prefix=aarch64-linux-gnu-
  • 若无报错,make & make install即可。
user@admin-machine:~/compile/x264-20191217$ make

user@admin-machine:~/compile/x264-20191217$ make install

  • 安装完成后文件夹下的_libs中生成的文件结构如下:
user@admin-machine:~/compile/x264-20191217/_libs$ tree
.
├── bin
│   └── x264
├── include
│   ├── x264_config.h
│   └── x264.h
└── lib
    ├── libx264.a
    ├── libx264.so -> libx264.so.157
    ├── libx264.so.157
    └── pkgconfig
        └── x264.pc

3.3 ZLIB编译

zlib是提供数据压缩用的函式库,由Jean-loup Gailly与Mark Adler所开发。

  • 解压zlib-1.2.11.tar.gz,打开终端后进入文件夹中,执行:
#zlib compile
user@admin-machine:~/compile/zlib-1.2.11$ ./configure --prefix=./lib --enable-shared 

  • 若无报错,编辑文件夹下的Makefile文件,将CC、AR、RANLIB改为交叉编译工具的命令后保存。
user@admin-machine:~/compile/zlib-1.2.11$ sudo vim Makefile
CC=aarch64-linux-gnu-gcc

CFLAGS=-O3 -D_LARGEFILE64_SOURCE=1 -DHAVE_HIDDEN
#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
#CFLAGS=-g -DZLIB_DEBUG
#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
#           -Wstrict-prototypes -Wmissing-prototypes

SFLAGS=-O3 -fPIC -D_LARGEFILE64_SOURCE=1 -DHAVE_HIDDEN
LDFLAGS=
TEST_LDFLAGS=-L. libz.a
LDSHARED=aarch64-linux-gnu-gcc -shared -Wl,-soname,libz.so.1,--version-script,zlib.map
CPP=aarch64-linux-gnu-gcc -E

STATICLIB=libz.a
SHAREDLIB=libz.so
SHAREDLIBV=libz.so.1.2.11
SHAREDLIBM=libz.so.1
LIBS=$(STATICLIB) $(SHAREDLIBV)

AR=aarch64-linux-gnu-gcc-ar
ARFLAGS=rc
RANLIB=aarch64-linux-gnu-gcc-ranlib
LDCONFIG=ldconfig
LDSHAREDLIBC=-lc
TAR=tar
SHELL=/bin/sh
EXE=

ESC 后输入:wq后保存并退出。

  • make & make install
user@admin-machine:~/compile/zlib-1.2.11$ make

user@admin-machine:~/compile/zlib-1.2.11$ make install

  • 安装完成后文件夹下的_libs中生成的文件结构如下:
user@admin-machine:~/compile/zlib-1.2.11/_lib$ tree
.
├── include
│   ├── zconf.h
│   └── zlib.h
├── lib
│   ├── libz.a
│   ├── libz.so -> libz.so.1.2.11
│   ├── libz.so.1 -> libz.so.1.2.11
│   ├── libz.so.1.2.11
│   └── pkgconfig
│       └── zlib.pc
└── share
    └── man
        └── man3
            └── zlib.3

6 directories, 8 files

3.4 libjpeg 编译

LibJPEG 是一个广泛使用的 JPEG 图像压缩库,用于读取和写入 JPEG图像文件,采用 C 语言开发。

  • 解压jpegsrc.v9d.tar.gz,打开终端后进入文件夹中,执行:
user@admin-machine:~/compile/libjpeg$ CC=aarch64-linux-gnu-gcc ./configure --host=arm-linux --prefix=$PWD/_libs --enable-shared --enable-static
  • 若无报错,make & make install即可。
user@admin-machine:~/compile/libjpeg$ make

user@admin-machine:~/compile/libjpeg$ make install

  • 安装完成后文件夹下的_libs中生成的文件结构如下:
user@admin-machine:~/compile/libjpeg/_libs$ tree
.
├── bin
│   ├── cjpeg
│   ├── djpeg
│   ├── jpegtran
│   ├── rdjpgcom
│   └── wrjpgcom
├── include
│   ├── jconfig.h
│   ├── jerror.h
│   ├── jmorecfg.h
│   └── jpeglib.h
├── lib
│   ├── libjpeg.a
│   ├── libjpeg.la
│   ├── libjpeg.so -> libjpeg.so.9.4.0
│   ├── libjpeg.so.9 -> libjpeg.so.9.4.0
│   ├── libjpeg.so.9.4.0
│   └── pkgconfig
│       └── libjpeg.pc
└── share
    └── man
        └── man1
            ├── cjpeg.1
            ├── djpeg.1
            ├── jpegtran.1
            ├── rdjpgcom.1
            └── wrjpgcom.1

7 directories, 20 files

3.5 libpng 编译

libpng是官方的PNG参考库。它支持几乎所有PNG功能。libpng可作为ANSIC(C89)源代码提供,并且依赖于zlib 1.0.4 或更高版本。

  • 解压libpng-1.6.34.tar.gz,打开终端后进入文件夹中,执行:
user@admin-machine:~/compile/libpng-1.6.34$ cd ./scripts
user@admin-machine:~/compile/libpng-1.6.34/scripts$ sudo cp ./makefile.linux ../makefile
user@admin-machine:~/compile/libpng-1.6.34/scripts$ cd ..
user@admin-machine:~/compile/libpng-1.6.34$ sudo vim makefile

  • 将makefile文件对应位置的gcc,ac ar ranlib修改为交叉编译工具链命令,并指定安装路径prefilx和ZIBLIC和ZIBLNC的文件路径。修改为如下内容:

# makefile for libpng.a and libpng16.so on Linux ELF with gcc
# Copyright (C) 1998, 1999, 2002, 2006, 2008, 2010-2014 Greg Roelofs and
# Glenn Randers-Pehrson
# Copyright (C) 1996, 1997 Andreas Dilger
#
# This code is released under the libpng license.
# For conditions of distribution and use, see the disclaimer
# and license in png.h

# Library name:
LIBNAME = libpng16
PNGMAJ = 16
RELEASE = 34

# Shared library names:
LIBSO=$(LIBNAME).so
LIBSOMAJ=$(LIBNAME).so.$(PNGMAJ)
LIBSOREL=$(LIBSOMAJ).$(RELEASE)
OLDSO=libpng.so

# Utilities:
AR_RC=aarch64-linux-gnu-gcc-ar rc
CC=aarch64-linux-gnu-gcc
MKDIR_P=mkdir -p
LN_SF=ln -sf
RANLIB=aarch64-linux-gnu-ranlib
CP=cp
RM_F=/bin/rm -f

# where "make install" puts libpng16.a, libpng16.so*,
# libpng16/png.h, libpng16/pngconf.h, and libpng16/pnglibconf.h
# Prefix must be a full pathname.
prefix=/home/user/compile/libpng-1.6.34/_libs
exec_prefix=$(prefix)

# Where the zlib library and include files are located.
#ZLIBLIB=/usr/local/lib
#ZLIBINC=/usr/local/include
ZLIBLIB=/home/user/compile/zlib-1.2.11/_libs/lib
ZLIBINC=/home/user/compile/zlib-1.2.11/_libs/include

ESC 后输入:wq后保存并退出。

  • 修改pngpriv.h文件,将
if (defined(__ARM_NEON__) || defined(__ARM_NEON)) && \

注释掉,即改为:

/*#  if (defined(__ARM_NEON__) || defined(__ARM_NEON)) && \*/

然后添加一行

#   if defined(PNG_ARM_NEON) && (defined(__ARM_NEON__) || defined(__ARM_NEON)) && \

后保存修改。若不修改,后续make会出现以下错误:

libpng.a(pngrutil.o):在函数‘png_read_filter_row’中:
pngrutil.c:(.text+0x951c):对‘png_init_filter_functions_neon’未定义的引用
collect2: 错误: ld 返回 1
makefile:133: recipe for target 'pngtest-static' failed
make: *** [pngtest-static] Error 1
make: *** 正在等待未完成的任务....
  • make & make install
user@admin-machine:~/compile/libpng-1.6.34$ make -j4
user@admin-machine:~/compile/libpng-1.6.34$ make install
cp png.h pngconf.h pnglibconf.h /home/user/compile/libpng-1.6.34/lib/include/libpng16
chmod 644 /home/user/compile/libpng-1.6.34/_libs/include/libpng16/png.h /home/user/compile/libpng-1.6.34/_libs/include/libpng16/pngconf.h /home/user/compile/libpng-1.6.34/_libs/include/libpng16/pnglibconf.h
(cd /home/user/compile/libpng-1.6.34/_libs/include; ln -sf libpng16 libpng; ln -sf libpng16/* .)
cp libpng.a /home/user/compile/libpng-1.6.34/_libs/lib/libpng16.a
chmod 644 /home/user/compile/libpng-1.6.34/_libs/lib/libpng16.a
(cd /home/user/compile/libpng-1.6.34/_libs/lib; ln -sf libpng16.a libpng.a)
cp libpng16.so.16 /home/user/compile/libpng-1.6.34/_libs/lib/libpng16.so.16.34
chmod 755 /home/user/compile/libpng-1.6.34/_libs/lib/libpng16.so.16.34
(cd /home/user/compile/libpng-1.6.34/_libs/lib; \
ln -sf libpng16.so.16.34 libpng16.so; \
ln -sf libpng16.so libpng.so)
cp libpng.pc /home/user/compile/libpng-1.6.34/_libs/lib/pkgconfig/libpng16.pc
chmod 644 /home/user/compile/libpng-1.6.34/_libs/lib/pkgconfig/libpng16.pc
(cd /home/user/compile/libpng-1.6.34/_libs/lib/pkgconfig; ln -sf libpng16.pc libpng.pc)
cp libpng.3 /home/user/compile/libpng-1.6.34/_libs/man/man3
cp libpngpf.3 /home/user/compile/libpng-1.6.34/_libs/man/man3
cp png.5 /home/user/compile/libpng-1.6.34/_libs/man/man5
cp libpng-config /home/user/compile/libpng-1.6.34/_libs/bin/libpng16-config
chmod 755 /home/user/compile/libpng-1.6.34/_libs/bin/libpng16-config
(cd /home/user/compile/libpng-1.6.34/_libs/bin; ln -sf libpng16-config libpng-config)
  • 安装完成后文件夹下的_libs中生成的文件结构如下:
user@admin-machine:~/compile/libpng-1.6.34/_libs$ tree
.
├── bin
│   ├── libpng16-config
│   └── libpng-config -> libpng16-config
├── include
│   ├── libpng -> libpng16
│   ├── libpng16
│   │   ├── pngconf.h
│   │   ├── png.h
│   │   └── pnglibconf.h
│   ├── pngconf.h -> libpng16/pngconf.h
│   ├── png.h -> libpng16/png.h
│   └── pnglibconf.h -> libpng16/pnglibconf.h
├── lib
│   ├── libpng16.a
│   ├── libpng16.so -> libpng16.so.16.34
│   ├── libpng16.so.16.34
│   ├── libpng.a -> libpng16.a
│   ├── libpng.so -> libpng16.so
│   └── pkgconfig
│       ├── libpng16.pc
│       └── libpng.pc -> libpng16.pc
└── man
    ├── man3
    │   ├── libpng.3
    │   └── libpngpf.3
    └── man5
        └── png.5

9 directories, 18 files

3.6 libtiff编译

该软件支持标签图像文件格式(TIFF),这是一种用于存储图像数据的广泛使用的格式。发行版中包括一个libtiff库,用于读写TIFF;一小部分工具集,用于在UNIX系统上进行TIFF映像的简单操作;以及库和工具上的文档。还包括由他人提供的一小部分与TIFF相关的UNIX软件。

  • 解压tiff-4.0.9.tar.gz,打开终端后进入文件夹中,执行:
user@admin-machine:~/compile/tiff-4.0.9$ ./configure CC=aarch64-linux-gnu-gcc CXX=aarch64-linux-gnu-g++ --host=arm-linux --prefix=$PWD/_libs --enable-shared --enable-static
  • 若无报错,make & make install即可。
user@admin-machine:~/compile/tiff-4.0.9$ make

user@admin-machine:~/compile/tiff-4.0.9$ make install

3.7 FFmpeg编译

FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。采用LGPL或GPL许可证。它提供了录制、转换以及流化音视频的完整解决方案。它包含了非常先进的音频/视频编解码库libavcodec,为了保证高可移植性和编解码质量,libavcodec里很多code都是从头开发的。

  • 解压ffmpeg-4.2.4.tar.xz,打开终端后进入文件夹中,执行:
user@admin-machine:~/compile/ffmpeg-4.2.4$ ./configure --enable-shared --enable-static --prefix=$PWD/_libs --cross-prefix=aarch64-linux-gnu- --arch=arm64 --target-os=linux --enable-gpl --enable-ffmpeg --enable-libx264 --extra-cflags=-I/home/user/compile/x264-20191217/_libs/include --extra-ldflags=-L/home/user/compile/x264-20191217/_libs/lib
  • 若无报错,make & make install即可。
user@admin-machine:~/compile/ffmpeg-4.2.4$ make

user@admin-machine:~/compile/ffmpeg-4.2.4$ make install

  • 安装完成后文件夹下的_libs中生成的文件结构如下:
user@admin-machine:~/compile/ffmpeg-4.2.4/_libs$ tree
.
├── bin
│   ├── ffmpeg
│   └── ffprobe
├── include
│   ├── libavcodec
│   │   ├── ac3_parser.h
│   │   ├── adts_parser.h
│   │   ├── avcodec.h
│   │   ├── avdct.h
│   │   ├── avfft.h
│   │   ├── d3d11va.h
│   │   ├── dirac.h
│   │   ├── dv_profile.h
│   │   ├── dxva2.h
│   │   ├── jni.h
│   │   ├── mediacodec.h
│   │   ├── qsv.h
│   │   ├── vaapi.h
│   │   ├── vdpau.h
│   │   ├── version.h
│   │   ├── videotoolbox.h
│   │   ├── vorbis_parser.h
│   │   └── xvmc.h
│   ├── libavdevice
│   │   ├── avdevice.h
│   │   └── version.h
│   ├── libavfilter
│   │   ├── avfilter.h
│   │   ├── buffersink.h
│   │   ├── buffersrc.h
│   │   └── version.h
│   ├── libavformat
│   │   ├── avformat.h
│   │   ├── avio.h
│   │   └── version.h
│   ├── libavutil
│   │   ├── adler32.h
│   │   ├── aes_ctr.h
│   │   ├── aes.h
│   │   ├── attributes.h
│   │   ├── audio_fifo.h
│   │   ├── avassert.h
│   │   ├── avconfig.h
│   │   ├── avstring.h
│   │   ├── avutil.h
│   │   ├── base64.h
│   │   ├── blowfish.h
│   │   ├── bprint.h
│   │   ├── bswap.h
│   │   ├── buffer.h
│   │   ├── camellia.h
│   │   ├── cast5.h
│   │   ├── channel_layout.h
│   │   ├── common.h
│   │   ├── cpu.h
│   │   ├── crc.h
│   │   ├── des.h
│   │   ├── dict.h
│   │   ├── display.h
│   │   ├── downmix_info.h
│   │   ├── encryption_info.h
│   │   ├── error.h
│   │   ├── eval.h
│   │   ├── ffversion.h
│   │   ├── fifo.h
│   │   ├── file.h
│   │   ├── frame.h
│   │   ├── hash.h
│   │   ├── hdr_dynamic_metadata.h
│   │   ├── hmac.h
│   │   ├── hwcontext_cuda.h
│   │   ├── hwcontext_d3d11va.h
│   │   ├── hwcontext_drm.h
│   │   ├── hwcontext_dxva2.h
│   │   ├── hwcontext.h
│   │   ├── hwcontext_mediacodec.h
│   │   ├── hwcontext_qsv.h
│   │   ├── hwcontext_vaapi.h
│   │   ├── hwcontext_vdpau.h
│   │   ├── hwcontext_videotoolbox.h
│   │   ├── imgutils.h
│   │   ├── intfloat.h
│   │   ├── intreadwrite.h
│   │   ├── lfg.h
│   │   ├── log.h
│   │   ├── lzo.h
│   │   ├── macros.h
│   │   ├── mastering_display_metadata.h
│   │   ├── mathematics.h
│   │   ├── md5.h
│   │   ├── mem.h
│   │   ├── motion_vector.h
│   │   ├── murmur3.h
│   │   ├── opt.h
│   │   ├── parseutils.h
│   │   ├── pixdesc.h
│   │   ├── pixelutils.h
│   │   ├── pixfmt.h
│   │   ├── random_seed.h
│   │   ├── rational.h
│   │   ├── rc4.h
│   │   ├── replaygain.h
│   │   ├── ripemd.h
│   │   ├── samplefmt.h
│   │   ├── sha512.h
│   │   ├── sha.h
│   │   ├── spherical.h
│   │   ├── stereo3d.h
│   │   ├── tea.h
│   │   ├── threadmessage.h
│   │   ├── timecode.h
│   │   ├── time.h
│   │   ├── timestamp.h
│   │   ├── tree.h
│   │   ├── twofish.h
│   │   ├── tx.h
│   │   ├── version.h
│   │   └── xtea.h
│   ├── libpostproc
│   │   ├── postprocess.h
│   │   └── version.h
│   ├── libswresample
│   │   ├── swresample.h
│   │   └── version.h
│   └── libswscale
│       ├── swscale.h
│       └── version.h
├── lib
│   ├── libavcodec.a
│   ├── libavcodec.so -> libavcodec.so.58.54.100
│   ├── libavcodec.so.58 -> libavcodec.so.58.54.100
│   ├── libavcodec.so.58.54.100
│   ├── libavdevice.a
│   ├── libavdevice.so -> libavdevice.so.58.8.100
│   ├── libavdevice.so.58 -> libavdevice.so.58.8.100
│   ├── libavdevice.so.58.8.100
│   ├── libavfilter.a
│   ├── libavfilter.so -> libavfilter.so.7.57.100
│   ├── libavfilter.so.7 -> libavfilter.so.7.57.100
│   ├── libavfilter.so.7.57.100
│   ├── libavformat.a
│   ├── libavformat.so -> libavformat.so.58.29.100
│   ├── libavformat.so.58 -> libavformat.so.58.29.100
│   ├── libavformat.so.58.29.100
│   ├── libavutil.a
│   ├── libavutil.so -> libavutil.so.56.31.100
│   ├── libavutil.so.56 -> libavutil.so.56.31.100
│   ├── libavutil.so.56.31.100
│   ├── libpostproc.a
│   ├── libpostproc.so -> libpostproc.so.55.5.100
│   ├── libpostproc.so.55 -> libpostproc.so.55.5.100
│   ├── libpostproc.so.55.5.100
│   ├── libswresample.a
│   ├── libswresample.so -> libswresample.so.3.5.100
│   ├── libswresample.so.3 -> libswresample.so.3.5.100
│   ├── libswresample.so.3.5.100
│   ├── libswscale.a
│   ├── libswscale.so -> libswscale.so.5.5.100
│   ├── libswscale.so.5 -> libswscale.so.5.5.100
│   ├── libswscale.so.5.5.100
│   └── pkgconfig
│       ├── libavcodec.pc
│       ├── libavdevice.pc
│       ├── libavfilter.pc
│       ├── libavformat.pc
│       ├── libavutil.pc
│       ├── libpostproc.pc
│       ├── libswresample.pc
│       └── libswscale.pc
└── share
    ├── ffmpeg
    │   ├── examples
    │   │   ├── avio_dir_cmd.c
    │   │   ├── avio_reading.c
    │   │   ├── decode_audio.c
    │   │   ├── decode_video.c
    │   │   ├── demuxing_decoding.c
    │   │   ├── encode_audio.c
    │   │   ├── encode_video.c
    │   │   ├── extract_mvs.c
    │   │   ├── filter_audio.c
    │   │   ├── filtering_audio.c
    │   │   ├── filtering_video.c
    │   │   ├── http_multiclient.c
    │   │   ├── hw_decode.c
    │   │   ├── Makefile
    │   │   ├── metadata.c
    │   │   ├── muxing.c
    │   │   ├── qsvdec.c
    │   │   ├── README
    │   │   ├── remuxing.c
    │   │   ├── resampling_audio.c
    │   │   ├── scaling_video.c
    │   │   ├── transcode_aac.c
    │   │   ├── transcoding.c
    │   │   ├── vaapi_encode.c
    │   │   └── vaapi_transcode.c
    │   ├── ffprobe.xsd
    │   ├── libvpx-1080p50_60.ffpreset
    │   ├── libvpx-1080p.ffpreset
    │   ├── libvpx-360p.ffpreset
    │   ├── libvpx-720p50_60.ffpreset
    │   └── libvpx-720p.ffpreset
    └── man
        ├── man1
        │   ├── ffmpeg.1
        │   ├── ffmpeg-all.1
        │   ├── ffmpeg-bitstream-filters.1
        │   ├── ffmpeg-codecs.1
        │   ├── ffmpeg-devices.1
        │   ├── ffmpeg-filters.1
        │   ├── ffmpeg-formats.1
        │   ├── ffmpeg-protocols.1
        │   ├── ffmpeg-resampler.1
        │   ├── ffmpeg-scaler.1
        │   ├── ffmpeg-utils.1
        │   ├── ffprobe.1
        │   └── ffprobe-all.1
        └── man3
            ├── libavcodec.3
            ├── libavdevice.3
            ├── libavfilter.3
            ├── libavformat.3
            ├── libavutil.3
            ├── libswresample.3
            └── libswscale.3

18 directories, 208 files

3.8 libxvidcore编译

Xvid(以前称为XviD)是一种开源MPEG-4视频编解码器,实现了对MPEG-4简单配置文件,高级简单配置文件和高级视频编码标准。它是用C语言编写的,具有针对质量和速度的汇编程序优化(包括i386的MMX,SSE和3Dnow代码以及PowerPC的AltiVec),并且特别针对存储和归档目的进行了脱机,多遍压缩的优化。

  • 解压 xvidcore-1.3.7.tar.gz,打开终端后进入文件夹中,执行:
user@admin-machine:$ cd /home/user/compile/xvidcore-1.3.7/xvidcore/build/generic/
./configure --prefix=$PWD/_libs --disable-assembly
  • 修改该文件夹下的platform.inc中的CC为交叉编译工具链
user@admin-machine:~/compile/xvidcore-1.3.7/xvidcore/build/generic$ sudo vim platform.inc

# Compiler
# ============================================================================

CC=aarch64-linux-gnu-gcc
SPECIFIC_CFLAGS=-fPIC -DHAVE_PTHREAD
ALTIVEC_CFLAGS=
CFLAGS=-Wall -O2 -fstrength-reduce -finline-functions -ffast-math -fomit-frame-pointer
LDFLAGS=

# =============================================================

ESC 后输入:wq后保存并退出。

  • make & make install编译安装
user@admin-machine:~/compile/xvidcore-1.3.7/xvidcore/build/generic$ make 

user@admin-machine:~/compile/xvidcore-1.3.7/xvidcore/build/generic$ make install

  • 安装完成后文件夹下的_libs中生成的文件结构如下:
user@admin-machine:~/compile/xvidcore-1.3.7/_libs$ tree
.
├── include
│   └── xvid.h
└── lib
    ├── libxvidcore.a
    ├── libxvidcore.so -> libxvidcore.so.4.3
    ├── libxvidcore.so.4 -> libxvidcore.so.4.3
    └── libxvidcore.so.4.3

2 directories, 5 files

3.9 将各软件的依赖库复制到交叉编译工具链文件路径下

  • 将3.1-3.7节中各软件包生成的依赖库文件复制到交叉编译工具链文件路径下,以x264为例:
user@admin-machine:~/compile/x264-20191217/_libs$ sudo cp -r ./lib/ /opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/
user@admin-machine:~/compile/x264-20191217/_libs$ sudo cp -r ./incude/ /opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/

FFmpeg、libjpeg等的复制操作与之类似。

  • 复制完成后,进/opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/lib文件夹,检查链接库是否均为ARM架构的文件。
user@admin-machine:/opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/lib$ file *
gcc:                      directory
libavcodec.a:             current ar archive
libavcodec.so:            symbolic link to libavcodec.so.58.54.100
libavcodec.so.58:         symbolic link to libavcodec.so.58.54.100
libavcodec.so.58.54.100:  ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[sha1]=f717d7feed92ef79256df1b7ebe1d60509f00e65, stripped
libavdevice.a:            current ar archive
libavdevice.so:           symbolic link to libavdevice.so.58.8.100
libavdevice.so.58:        symbolic link to libavdevice.so.58.8.100
libavdevice.so.58.8.100:  ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[sha1]=ce6f80cfd6ddb657727e36f1bfddbbfbcba8f241, stripped
libavfilter.a:            current ar archive
libavfilter.so:           symbolic link to libavfilter.so.7.57.100
libavfilter.so.7:         symbolic link to libavfilter.so.7.57.100
libavfilter.so.7.57.100:  ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[sha1]=fa9e52d6b6bb1260ac0f9978e85cfd7000c12c1c, stripped
libavformat.a:            current ar archive
libavformat.so:           symbolic link to libavformat.so.58.29.100
libavformat.so.58:        symbolic link to libavformat.so.58.29.100
libavformat.so.58.29.100: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[sha1]=c9616380bf06e4d09e1c3fbd363f829e3351be57, stripped
libavutil.a:              current ar archive
libavutil.so:             symbolic link to libavutil.so.56.31.100
libavutil.so.56:          symbolic link to libavutil.so.56.31.100
libavutil.so.56.31.100:   ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[sha1]=5e648f1c3850f44a78d7ba92123fccc592fc0eeb, stripped
libcc1.so:                symbolic link to libcc1.so.0.0.0
libcc1.so.0:              symbolic link to libcc1.so.0.0.0
libcc1.so.0.0.0:          ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=9fe3b1d6c8946e1966c95dfd0d287263abc3435a, stripped
libgmp.a:                 current ar archive
libgmpxx.a:               current ar archive
libjpeg.a:                current ar archive
libjpeg.la:               libtool library file, ASCII text
libjpeg.so:               symbolic link to libjpeg.so.9.4.0
libjpeg.so.9:             symbolic link to libjpeg.so.9.4.0
libjpeg.so.9.4.0:         ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[sha1]=d990d2ecbea5c1ff78e8eb802e77d5df6439d743, with debug_info, not stripped
libmpc.a:                 current ar archive
libmpfr.a:                current ar archive
libpng16.a:               current ar archive
libpng16.so:              symbolic link to libpng16.so.16.34
libpng16.so.16.34:        ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[sha1]=5536d208849ab426956ed9ec73965d20040322b0, with debug_info, not stripped
libpng.a:                 symbolic link to libpng16.a
libpng.so:                symbolic link to libpng16.so
libpostproc.a:            current ar archive
libpostproc.so:           symbolic link to libpostproc.so.55.5.100
libpostproc.so.55:        symbolic link to libpostproc.so.55.5.100
libpostproc.so.55.5.100:  ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[sha1]=4798fc2642fe09eaef5b2b03c1769dbd5f34281e, stripped
libswresample.a:          current ar archive
libswresample.so:         symbolic link to libswresample.so.3.5.100
libswresample.so.3:       symbolic link to libswresample.so.3.5.100
libswresample.so.3.5.100: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[sha1]=fead8371cacca4ac37e4e88884f672f159035805, stripped
libswscale.a:             current ar archive
libswscale.so:            symbolic link to libswscale.so.5.5.100
libswscale.so.5:          symbolic link to libswscale.so.5.5.100
libswscale.so.5.5.100:    ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[sha1]=8b7f0116299e8347d6df0fa5bca28ccc581470bd, stripped
libtiff.a:                current ar archive
libtiff.la:               libtool library file, ASCII text
libtiff.so:               symbolic link to libtiff.so.5.3.0
libtiff.so.5:             symbolic link to libtiff.so.5.3.0
libtiff.so.5.3.0:         ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[sha1]=7fc15db14e04b778b9784ba383819227ce34e59f, with debug_info, not stripped
libtiffxx.a:              current ar archive
libtiffxx.la:             libtool library file, ASCII text
libtiffxx.so:             symbolic link to libtiffxx.so.5.3.0
libtiffxx.so.5:           symbolic link to libtiffxx.so.5.3.0
libtiffxx.so.5.3.0:       ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[sha1]=7f88a2d639f1a17f7e6a15317da3a2ffc27f708c, with debug_info, not stripped
libx264.a:                current ar archive
libx264.so:               symbolic link to libx264.so.157
libx264.so.157:           ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[sha1]=278766e50b44ea00b9f18d30c3292765338a6990, with debug_info, not stripped
libxvidcore.a:            current ar archive
libxvidcore.so:           symbolic link to libxvidcore.so.4.3
libxvidcore.so.4:         symbolic link to libxvidcore.so.4.3
libxvidcore.so.4.3:       ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[sha1]=0cb5f71001f2dc8f322a46941fdb1d7ecfec4f47, with debug_info, not stripped
libz.a:                   current ar archive
libz.so:                  symbolic link to libz.so.1.2.11
libz.so.1:                symbolic link to libz.so.1.2.11
libz.so.1.2.11:           ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[sha1]=5d86358d79f0a958135e5bb6f086b25817ed2ebb, with debug_info, not stripped
pkgconfig:                directory

3.10 配置动态链接库

3.8节步骤完成后,/opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/lib/pkgconfig/路径下的文件结构如下:

── pkgconfig
    ├── libavcodec.pc
    ├── libavdevice.pc
    ├── libavfilter.pc
    ├── libavformat.pc
    ├── libavutil.pc
    ├── libjpeg.pc
    ├── libpng16.pc
    ├── libpng.pc -> libpng16.pc
    ├── libpostproc.pc
    ├── libswresample.pc
    ├── libswscale.pc
    ├── libtiff.pc
    ├── x264.pc
    └── zlib.pc

  • 需修改文件中perfix等路径,并配置动态链接库,以zlib.pc为例:
user@admin-machine:/opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/lib/pkgconfig$ sudo vim zlib.pc
prefix=/opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu
exec_prefix=${prefix}
libdir=${prefix}/lib
sharedlibdir=${libdir}
includedir=${prefix}/include

Name: zlib
Description: zlib compression library
Version: 1.2.11

Requires:
Libs: -L${libdir} -L${sharedlibdir} -lz
Cflags: -I${includedir}

ESC 后输入:wq后保存并退出,按此步骤将所有.pc文件中的路径均修改为对应路径。

  • 运行sudo vim /etc/bash.bashrc 在最后一行添加如下
PKG_CONFIG_PATH=/opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/lib/pkgconfig:$PKG_CONFIG_PATH
 export PKG_CONFIG_PATH

ESC 后输入:wq后保存并退出,随后运行source ~/.bashrc激活生效。

  • 添加动态库加载路径。以zlib为例:
user@admin-machine:~$ sudo vim /etc/ld.so.conf.d/zlib.conf
/opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/lib

ESC 后输入:wq后保存并退出,随后运行sudo ldconfig激活生效。
按此方法添加libavcodec、x264、libjpeg等的动态库加载路径后,重启PC使其生效。

  • 验证各依赖包动态链接库是否生效,若出现以下路径,则表明动态链接库生效。
user@admin-machine:~$ pkg-config --libs --cflags zlib
-I/opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/include -L/opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/lib -lz
user@admin-machine:~$ pkg-config --libs --cflags x264
-I/opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/include -L/opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/lib -lx264
user@admin-machine:~$ pkg-config --libs --cflags libavcodec
-I/opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/include -L/opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/lib -lavcodec
user@admin-machine:~$ pkg-config --libs --cflags libjpeg
-I/opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/include -L/opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/lib -ljpeg
...

至此,OpenCV交叉编译所需的依赖库及编译环境配置完成。

三、交叉编译OpenCV 3.4.10

  • 解压opencv-3.4.10.zip,进文件夹中执行以下操作:
user@admin-machine:~/opencv/opencv-3.4.10$ sudo mkdir release
user@admin-machine:~/opencv/opencv-3.4.10$ cd ./release
user@admin-machine:~/opencv/opencv-3.4.10/release$ sudo mkdir install
  • 新建toolchain.cmake文件,配置交叉编译工具链,并设置OPENCV_ENABLE_PKG_CONFIG ON(OpenCV 3.4默认关闭此项,若不配置,cmake时会导致无法找到FFmpeg的链接库路径)和FFMPEG的文件路径。未编译FFmpeg的程序在开发板上执行时会报下图错误:
@admin-machine:~/opencv/opencv-3.4.10/release$ sudo vim toolchain.cmake

###########user defined#############
set( CMAKE_SYSTEM_NAME Linux )
set( CMAKE_SYSTEM_PROCESSOR arm )
set( CMAKE_C_COMPILER aarch64-linux-gnu-gcc )
set( CMAKE_CXX_COMPILER aarch64-linux-gnu-g++ )
set( OPENCV_ENABLE_PKG_CONFIG ON)
set( FFMPEG_INCLUDE_DIR "/opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/include")
set( FFMPEG_LIB_DIR "/opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/lib")
###########user defined#############
set( CMAKE_FIND_ROOT_PATH "/opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu" )
set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER )
set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
######################################
  • 执行cmake,由于项目使用Qt作为GUI设计软件,不使用GTK,故配置WITH_GTK=OFF(PC端不可安装libgtk2.0-dev,会因为软件包支持系统架构不同,导致OpenCV交叉编译时报错)
cmake -D CMAKE_TOOLCHAIN_FILE=toolchain.cmake -D BUILD_opencv_python3=yes -D BUILD_opencv_python2=no -D PYTHON3_EXECUTABLE=/usr/bin/python3.7m -D PYTHON3_INCLUDE_DIR=/usr/include/python3.7m -D PYTHON3_LIBRARY=/usr/lib/x86_64-linux-gnu/libpython3.7m.so -D PYTHON3_PACKAGES_PATH=/usr/lib/python3/dist-packages -D PYTHON_DEFAULT_EXECUTABLE=/usr/bin/python3.7m -D CMAKE_BUILD_TYPE=RELEASE -D CMAKE_INSTALL_PREFIX=/home/user/opencv/opencv-3.4.10/release/install -D BUILD_ZLIB=ON -D BUILD_JPEG=ON -D BUILD_PNG=ON -D BUILD_TIFF=ON -D ENABLE_CXX11=ON -D WITH_FFMPEG=ON -D WITH_OPENCL=ON -D WITH_GTK=OFF -D WITH_OPENGL=ON -D WITH_OPENMP=ON -D WITH_PNG=ON ..

打印以下内容:

-- General configuration for OpenCV 3.4.10 =====================================
--   Version control:               unknown
-- 
--   Platform:
--     Timestamp:                   2021-04-22T13:25:33Z
--     Host:                        Linux 5.4.0-66-generic x86_64
--     Target:                      Linux arm
--     CMake:                       3.10.2
--     CMake generator:             Unix Makefiles
--     CMake build tool:            /usr/bin/make
--     Configuration:               RELEASE
-- 
--   CPU/HW features:
--     Baseline:                    NEON FP16
--       requested:                 DETECT
--       disabled:                  VFPV3 NEON
-- 
--   C/C++:
--     Built as dynamic libs?:      YES
--     C++11:                       YES
--     C++ Compiler:                /opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-g++  (ver 7.5.0)
--     C++ flags (Release):         -fsigned-char -W -Wall -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wundef -Winit-self -Wpointer-arith -Wshadow -Wsign-promo -Wuninitialized -Winit-self -Wsuggest-override -Wno-delete-non-virtual-dtor -Wno-comment -Wimplicit-fallthrough=3 -Wno-strict-overflow -fdiagnostics-show-option -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections  -fvisibility=hidden -fvisibility-inlines-hidden -fopenmp -O3 -DNDEBUG  -DNDEBUG
--     C++ flags (Debug):           -fsigned-char -W -Wall -Werror=return-type -Werror=non-virtual-dtor -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wundef -Winit-self -Wpointer-arith -Wshadow -Wsign-promo -Wuninitialized -Winit-self -Wsuggest-override -Wno-delete-non-virtual-dtor -Wno-comment -Wimplicit-fallthrough=3 -Wno-strict-overflow -fdiagnostics-show-option -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections  -fvisibility=hidden -fvisibility-inlines-hidden -fopenmp -g  -O0 -DDEBUG -D_DEBUG
--     C Compiler:                  /opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu-gcc
--     C flags (Release):           -fsigned-char -W -Wall -Werror=return-type -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wundef -Winit-self -Wpointer-arith -Wshadow -Wuninitialized -Winit-self -Wno-comment -Wimplicit-fallthrough=3 -Wno-strict-overflow -fdiagnostics-show-option -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections  -fvisibility=hidden -fopenmp -O3 -DNDEBUG  -DNDEBUG
--     C flags (Debug):             -fsigned-char -W -Wall -Werror=return-type -Werror=address -Werror=sequence-point -Wformat -Werror=format-security -Wmissing-declarations -Wmissing-prototypes -Wstrict-prototypes -Wundef -Winit-self -Wpointer-arith -Wshadow -Wuninitialized -Winit-self -Wno-comment -Wimplicit-fallthrough=3 -Wno-strict-overflow -fdiagnostics-show-option -pthread -fomit-frame-pointer -ffunction-sections -fdata-sections  -fvisibility=hidden -fopenmp -g  -O0 -DDEBUG -D_DEBUG
--     Linker flags (Release):      -Wl,--gc-sections -Wl,--as-needed  
--     Linker flags (Debug):        -Wl,--gc-sections -Wl,--as-needed  
--     ccache:                      NO
--     Precompiled headers:         NO
--     Extra dependencies:          dl m pthread rt
--     3rdparty dependencies:
-- 
--   OpenCV modules:
--     To be built:                 calib3d core dnn features2d flann highgui imgcodecs imgproc ml objdetect photo shape stitching superres ts video videoio videostab
--     Disabled:                    world
--     Disabled by dependency:      -
--     Unavailable:                 cudaarithm cudabgsegm cudacodec cudafeatures2d cudafilters cudaimgproc cudalegacy cudaobjdetect cudaoptflow cudastereo cudawarping cudev java js python2 python3 viz
--     Applications:                tests perf_tests apps
--     Documentation:               NO
--     Non-free algorithms:         NO
-- 
--   GUI: 
--     OpenGL support:              NO
-- 
--   Media I/O: 
--     ZLib:                        build (ver 1.2.11)
--     JPEG:                        build-libjpeg-turbo (ver 2.0.4-62)
--     WEBP:                        build (ver encoder: 0x020f)
--     PNG:                         build (ver 1.6.37)
--     TIFF:                        build (ver 42 - 4.0.10)
--     JPEG 2000:                   build (ver 1.900.1)
--     HDR:                         YES
--     SUNRASTER:                   YES
--     PXM:                         YES
-- 
--   Video I/O:
--     DC1394:                      NO
--     FFMPEG:                      YES
--       avcodec:                   YES (ver 58.54.100)
--       avformat:                  YES (ver 58.29.100)
--       avutil:                    YES (ver 56.31.100)
--       swscale:                   YES (ver 5.5.100)
--       avresample:                NO
--     GStreamer:                   NO
--     libv4l/libv4l2:              NO
--     v4l/v4l2:                    linux/videodev2.h
-- 
--   Parallel framework:            OpenMP
-- 
--   Trace:                         YES (with Intel ITT)
-- 
--   Other third-party libraries:
--     Lapack:                      NO
--     Custom HAL:                  YES (carotene (ver 0.0.1))
--     Protobuf:                    build (3.5.1)
-- 
--   OpenCL:                        YES (no extra features)
--     Include path:                /home/user/opencv/opencv-3.4.10/3rdparty/include/opencl/1.2
--     Link libraries:              Dynamic load
-- 
--   Python 3:
--     Interpreter:                 /usr/bin/python3.7m (ver 3.7.10)
--     Libraries:                   NO
--     numpy:                       NO (Python3 wrappers can not be generated)
--     install path:                -
-- 
--   Python (for build):            /usr/bin/python3.7m
-- 
--   Install to:                    /home/user/opencv/opencv-3.4.10/build/install
-- -----------------------------------------------------------------
-- 
-- Configuring done
-- Generating done
-- Build files have been written to: /home/user/opencv/opencv-3.4.10/build
  • 修改生成的CMakeCache.txt文件,配置CMAKE_CXX_FLAGS:STRING= 和CMAKE_C_FLAGS:STRING= 的路径,否则会报以下错误:
[ 62%] Building CXX object modules/dnn/CMakeFiles/opencv_dnn.dir/src/layers/eltwise_layer.cpp.o
/opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/bin/../lib/gcc/aarch64-linux-gnu/7.5.0/../../../../aarch64-linux-gnu/bin/ld: warning: libavcodec.so.58, needed by ../../lib/libopencv_videoio.so.3.4.10, not found (try using -rpath or -rpath-link)
/opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/bin/../lib/gcc/aarch64-linux-gnu/7.5.0/../../../../aarch64-linux-gnu/bin/ld: warning: libavformat.so.58, needed by ../../lib/libopencv_videoio.so.3.4.10, not found (try using -rpath or -rpath-link)
/opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/bin/../lib/gcc/aarch64-linux-gnu/7.5.0/../../../../aarch64-linux-gnu/bin/ld: warning: libavutil.so.56, needed by ../../lib/libopencv_videoio.so.3.4.10, not found (try using -rpath or -rpath-link)
/opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/bin/../lib/gcc/aarch64-linux-gnu/7.5.0/../../../../aarch64-linux-gnu/bin/ld: warning: libswscale.so.5, needed by ../../lib/libopencv_videoio.so.3.4.10, not found (try using -rpath or -rpath-link)
../../lib/libopencv_videoio.so.3.4.10:对‘av_init_packet@LIBAVCODEC_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘avformat_get_riff_video_tags@LIBAVFORMAT_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘avformat_get_mov_video_tags@LIBAVFORMAT_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘avcodec_find_decoder@LIBAVCODEC_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘avcodec_find_decoder_by_name@LIBAVCODEC_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_frame_alloc@LIBAVUTIL_56’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘avcodec_get_name@LIBAVCODEC_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_malloc@LIBAVUTIL_56’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘avio_open@LIBAVFORMAT_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘avformat_alloc_context@LIBAVFORMAT_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_sub_q@LIBAVUTIL_56’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘avformat_network_init@LIBAVFORMAT_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘avcodec_flush_buffers@LIBAVCODEC_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘avcodec_find_encoder@LIBAVCODEC_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘sws_getContext@LIBSWSCALE_5’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_write_frame@LIBAVFORMAT_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘avformat_close_input@LIBAVFORMAT_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_seek_frame@LIBAVFORMAT_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘sws_freeContext@LIBSWSCALE_5’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_dict_set@LIBAVUTIL_56’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘sws_scale@LIBSWSCALE_5’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_packet_unref@LIBAVCODEC_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_dict_parse_string@LIBAVUTIL_56’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_frame_get_buffer@LIBAVUTIL_56’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_freep@LIBAVUTIL_56’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘avformat_find_stream_info@LIBAVFORMAT_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_read_frame@LIBAVFORMAT_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘avformat_free_context@LIBAVFORMAT_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_register_all@LIBAVFORMAT_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_free@LIBAVUTIL_56’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_guess_sample_aspect_ratio@LIBAVFORMAT_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘avcodec_encode_video2@LIBAVCODEC_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘avformat_new_stream@LIBAVFORMAT_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_frame_unref@LIBAVUTIL_56’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_write_trailer@LIBAVFORMAT_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_bsf_get_by_name@LIBAVCODEC_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_dict_get@LIBAVUTIL_56’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_bsf_free@LIBAVCODEC_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘avformat_open_input@LIBAVFORMAT_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_lockmgr_register@LIBAVCODEC_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_bsf_send_packet@LIBAVCODEC_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_bsf_alloc@LIBAVCODEC_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_log_set_level@LIBAVUTIL_56’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_rescale_q@LIBAVUTIL_56’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_image_get_buffer_size@LIBAVUTIL_56’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘avcodec_open2@LIBAVCODEC_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_guess_format@LIBAVFORMAT_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_image_fill_arrays@LIBAVUTIL_56’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_bsf_receive_packet@LIBAVCODEC_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘sws_getCachedContext@LIBSWSCALE_5’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_codec_get_tag@LIBAVFORMAT_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_log_set_callback@LIBAVUTIL_56’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_opt_set@LIBAVUTIL_56’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘avcodec_decode_video2@LIBAVCODEC_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_codec_get_id@LIBAVFORMAT_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘avformat_write_header@LIBAVFORMAT_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘avcodec_parameters_copy@LIBAVCODEC_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘avcodec_pix_fmt_to_codec_tag@LIBAVCODEC_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_mallocz@LIBAVUTIL_56’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_find_input_format@LIBAVFORMAT_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_guess_codec@LIBAVFORMAT_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_dict_free@LIBAVUTIL_56’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘avio_close@LIBAVFORMAT_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_frame_free@LIBAVUTIL_56’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘av_bsf_init@LIBAVCODEC_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘avcodec_close@LIBAVCODEC_58’未定义的引用
../../lib/libopencv_videoio.so.3.4.10:对‘avcodec_get_context_defaults3@LIBAVCODEC_58’未定义的引用
collect2: 错误: ld 返回 1
apps/visualisation/CMakeFiles/opencv_visualisation.dir/build.make:99: recipe for target 'bin/opencv_visualisation' failed

#大约在278行和302行左右

user@admin-machine:~/opencv/opencv-3.4.10/release$ sudo vim CMkeCacche.txt

...
//Flags used by the compiler during all build types.
CMAKE_CXX_FLAGS:STRING=-Wl,-rpath-link=/opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/lib
...
//Flags used by the compiler during all build types.
CMAKE_C_FLAGS:STRING=-Wl,-rpath-link=/opt/gcc-linaro-7.5.0-x86_64_aarch64-linux-gnu/lib
...

ESC 后输入:wq后保存并退出。执行make & make install 即可。

user@admin-machine:~/opencv/opencv-3.4.10/release$ make -j6
user@admin-machine:~/opencv/opencv-3.4.10/release$ make install

耐心等待几十分钟。Firefly AIO-3399Pro C开发板交叉编译OpenCV 3.4.10及FFmpeg、x264等依赖库,实现视频播放等功能_第2张图片

  • 若无报错,再配置OpenCV的动态链接库路径。配置方法和上文3.8节类似,修改lib/pkgconfig下的opencv.pc,新建openc.conf文件,然后测试opencv的动态链接库是否生效,如下所示:
user@admin-machine:~$ pkg-config --libs --cflags opencv
-I/home/user/opencv/opencv-3.4.10/release/install/include/opencv -I/home/user/opencv/opencv-3.4.10/release/install/include -L/home/user/opencv/opencv-3.4.10/release/install/lib -lopencv_dnn -lopencv_highgui -lopencv_ml -lopencv_objdetect -lopencv_shape -lopencv_stitching -lopencv_superres -lopencv_videostab -lopencv_calib3d -lopencv_videoio -lopencv_imgcodecs -lopencv_features2d -lopencv_video -lopencv_photo -lopencv_imgproc -lopencv_flann -lopencv_core

四、测试OpenCV是否可以交叉编译

user@admin-machine:$ cd /home/user/opencv/opencv-3.4.10/samples/cpp/example_cmake
#改CMakeLists.txt,指定OpenCVConfig.cmake opencv-config.cmake的安装路径,否则编译会报错
user@admin-machine:~/opencv/opencv-3.4.10/samples/cpp/example_cmake$sudo vim CMakeLists.txt
# cmake needs this line
cmake_minimum_required(VERSION 2.8)

# Define project name
project(opencv_example_project)

# Find OpenCV, you may need to set OpenCV_DIR variable
# to the absolute path to the directory containing OpenCVConfig.cmake file
# via the command line or GUI
#新增以下行,指定OpenCV__DIR的路径
set(OpenCV_DIR /home/user/opencv/opencv-3.4.10/release/install/share/OpenCV)
find_package(OpenCV REQUIRED)

# If the package has been found, several variables will
# be set, you can find the full list with descriptions
# in the OpenCVConfig.cmake file.
# Print some message showing some of them
message(STATUS "OpenCV library status:")
message(STATUS "    version: ${OpenCV_VERSION}")
message(STATUS "    libraries: ${OpenCV_LIBS}")
message(STATUS "    include path: ${OpenCV_INCLUDE_DIRS}")

if(CMAKE_VERSION VERSION_LESS "2.8.11")
  # Add OpenCV headers location to your include paths
  include_directories(${OpenCV_INCLUDE_DIRS})
endif()

# Declare the executable target built from your sources
add_executable(opencv_example example.cpp)

# Link your application with OpenCV libraries
target_link_libraries(opencv_example PRIVATE ${OpenCV_LIBS})
user@admin-machine:~/opencv/opencv-3.4.10/samples/cpp/example_cmake$ aarch64-linux-gnu-g++ example.cpp -o example -lpthread -lrt `pkg-config --libs --cflags opencv` -Wl,-rpath-link=/home/user/opencv/opencv-3.4.10/release/install/lib
user@admin-machine:~/opencv/opencv-3.4.10/samples/cpp/example_cmake$ file *
CMakeLists.txt: ASCII text
example:        ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, for GNU/Linux 3.7.0, BuildID[sha1]=3e5ea3912e81c33c10592ce628b1250a65f6e457, with debug_info, not stripped
example.cpp:    C++ source, ASCII text
Makefile:       makefile script, ASCII text

  • 将生成的example可执行文件复制到开发板的任意路径,执行sudo chmod +x example,配置可执行权限,./example运行后如下图所示:
    Firefly AIO-3399Pro C开发板交叉编译OpenCV 3.4.10及FFmpeg、x264等依赖库,实现视频播放等功能_第3张图片
    Firefly AIO-3399Pro C开发板交叉编译OpenCV 3.4.10及FFmpeg、x264等依赖库,实现视频播放等功能_第4张图片
  • Qt中编写一段程序,交叉编译后复制到开发板上,测试USB摄像头的视频播放和播放本地mp4视频,如下列图所示:
    Firefly AIO-3399Pro C开发板交叉编译OpenCV 3.4.10及FFmpeg、x264等依赖库,实现视频播放等功能_第5张图片
    Firefly AIO-3399Pro C开发板交叉编译OpenCV 3.4.10及FFmpeg、x264等依赖库,实现视频播放等功能_第6张图片
    Qt中的项目pro文件配置的动态链接库路径图:
    Firefly AIO-3399Pro C开发板交叉编译OpenCV 3.4.10及FFmpeg、x264等依赖库,实现视频播放等功能_第7张图片

总结

交叉编译OpenCV过程十分繁琐,需要一步步按照依赖关系处理,由于OpenCV的Python接口依赖numpy,暂时还没找到交叉编译numpy支持OpenCV的Python接口的方法,后续再进行进一步测试。

本文主要参考的文章:
《Ubuntu16.04交叉编译openCV》
《Ubuntu 14.04 LTS下使用arm-linux-gcc交叉编译OpenCV 2.4.9》
《arm-himix200-linux交叉编译opencv4.1》
《虚拟机交叉编译openCV详细步骤及bug解决详解》
《Toybrick TB-RK3399ProD《在Ubuntu18.04下基于RK3399交叉编译工具交叉编译libx264和ffmpeg》》
《交叉编译libpng报错:configure: error: zlib not installed》
《常用库之五:libtiff的交叉编译》
《Firefly AIO-3399ProC开发板与PC端部署Qt5.12.2交叉编译环境》
等。

你可能感兴趣的:(笔记,linux,arm,ubuntu,opencv,视频处理)