Raspberry Pi 3 B+ のCentOS7.5にffmpeg4.0をビルド/インストール メモ

# 概要
Raspberry Pi 3 B+ + CentOSでのffmpegをビルドを行った。
Raspberry Pi 2でビルドをした1年半以上前とトラブルが割と変わっていたので、
通しでの備忘録。
(と言うかRaspberry Pi3 + CentOSの情報が少ない)

# 環境
* Raspberry Pi 3 B+
* CentOS 7.5 (1804 armhfp Minimal image for RaspberryPi 2/3)
* /usr/local/src でビルドを行う (PREFIXは使わない)


# 要約
## yum(標準リポジトリ)からinstall
|library|packages|
|:--|:--|
|nasm|nasm|
|bzip2|bzip2 bzip2-libs bzip2-devel|
|libgsm|gsm gsm-devel gsm-tools|
|libogg|libogg libogg-devel libogg-devel-docs|
|libvorbis|libvorbis libvorbis-devel libvorbis-devel-docs vorbis-tools|
|libtheora|libtheora libtheora-devel libtheora-devel-docs|
|speex|speex speex-devel speex-tools|
|libpulse|pulseaudio-libs pulseaudio-libs-devel pulseaudio-libs-glib2|
|~~opus~~|~~opus~~ ~~opus-devel~~ <br />※ 1.0.2では古いのでソースからbuildする|
|~~libvpx~~|~~libvpx~~ ~~libvpx-devel libvpx-utils~~ <br />※ 1.3.0では古いのでソースからbuildする|

## yum(epel)からinstall
|library|packages|
|:--|:--|
|yasm|yasm yasm-devel|
|soxr|soxr soxr-devel|
|lame|lame lame-devel lame-libs lame-mp3|
|openjpeg2|openjpeg2 openjpeg2-devel openjpeg2-tools|

## sourceからbuild
|library|URL|
|:--|:--|
|libfdk_aac|https://sourceforge.net/projects/opencore-amr/files/fdk-aac/fdk-aac-0.1.6.tar.gz|
|xvidcore|https://downloads.xvid.com/downloads/xvidcore-1.3.5.tar.gz|
|libopus|git://github.com/xiph/opus.git|
|libass|https://github.com/libass/libass.git|
|libx264|https://git.videolan.org/git/x264.git|
|libx265|https://bitbucket.org/multicoreware/x265|
|libvpx|https://chromium.googlesource.com/webm/libvpx|
|ffmpeg|git://github.com/ffmpeg/ffmpeg|

# 手順
## 手順①：yum で必要なライブラリをインストール
上述ほか、適宜必用なパッケージ(ライブラリ)をインストールする。

## 手順②：ライブラリをソースからビルドしてインストール
### libfdk_aac
```
# cd /usr/local/src
# wget https://sourceforge.net/projects/opencore-amr/files/fdk-aac/fdk-aac-0.1.6.tar.gz
# tar --no-same-owner -xvf fdk-aac-0.1.6.tar.gz
# cd fdk-aac-0.1.6
# autoreconf -fiv
# ./configure --enable-shared
# make -j2
# make install
# make clean
```
### xvidcore
```
# cd /usr/local/src
# wget https://downloads.xvid.com/downloads/xvidcore-1.3.5.tar.gz
# tar --no-same-owner -xvf xvidcore-1.3.5.tar.gz
# cd xvidcore
# cd build/generic
# autoreconf -fiv
# ./configure
# make -j2
# make install
# make clean
```

### libass
```
# cd /usr/local/src
# git clone https://github.com/libass/libass.git --depth 1
# cd libass
# autoreconf -fiv
# ./configure --enable-shared
# make -j2
# make install
# make clean
```

### opus
* 公式yumリポジトリの1.0.2では古いため、最新ソースからビルドする。

```
# cd /usr/local/src
# git clone git://github.com/xiph/opus.git --depth 1
# cd opus
# ./autogen.sh
# ./configure --enable-shared --enable-pic
# make -j2
# make install
# make clean
```

### x264
```
# cd /usr/local/src
# git clone https://git.videolan.org/git/x264.git --depth 1
# cd x264
# ./configure --enable-static --enable-pic
# make -j2
# make install
# make clean
```

### x265
* 公式yumリポジトリの1.3.0では古いため、ソースからビルドする。
* リポジトリ最新のリビジョンではビルド出来ない。<br />
stable版のリビジョン：12009(2018/03/22 v2.7.x) 以前ではビルドが通る。<br />
(今回は `11991` を利用)
* CGGのバグによりbuildエラーになるため、 `CMakeLists.txt` を修正してCPUアーキテクチャを直指定する<br />
( `cortex-a53` は無いともGCCに怒られるので、 `cortex-a7` を指定)<br />
・Umbrella　RaspberryPi　Pi3でlibx265 リベンジ<br />
http://wbbwbb.blog83.fc2.com/blog-entry-244.html

> ```:error
[  2%] [  2%] Building CXX object common/CMakeFiles/common.dir/arm/asm-primitives.cpp.o
Building CXX object encoder/CMakeFiles/encoder.dir/analysis.cpp.o
*** Error in `/bin/c++': double free or corruption (!prev): 0x00fcf8d8 ***
~~~
~~~
make[2]: *** [encoder/CMakeFiles/encoder.dir/analysis.cpp.o] エラー 134
make[1]: make[2]: *** [encoder/CMakeFiles/encoder.dir/all] エラー 2*** [common/CMakeFiles/common.dir/arm/asm-primitives.cpp.o] エラー 134
make[1]: *** 未完了のジョブを待っています....
make[1]: *** [common/CMakeFiles/common.dir/all] エラー 2
make: *** [all] エラー 2
```

#### ビルド可能なバージョンのリビジョン

|revision|コミット日時|version|ビルド可否|備考|
|:--|:--|:--|:--|:--|
|12416|2018/09/09|v2.8.x|NG|make エラー|
|12346|2018/05/21|v2.8|NG|make エラー|
|11991|2018/02/21|v2.7|OK|※ ./source/CMakeLists.txt の修正あり|
|11729|2017/03/10|v2.3|OK|※ ./source/CMakeLists.txt の修正あり|

#### ビルド可能なstableのリビジョン確認

|revision|コミット日時|version|ビルド可否|備考|
|:--|:--|:--|:--|:--|
|12340|2018/05/02|v2.7.x|NG|make エラー|
|12336|2018/04/30|v2.7.x|NG|make エラー|
|12329|2018/04/12|v2.7.x|NG|make エラー|
|12009|2018/03/22|v2.7.x|OK|※ ./source/CMakeLists.txt の修正あり|
|11993|2018/03/01|v2.7.x|OK|※ ./source/CMakeLists.txt の修正あり|


```
# cd /usr/local/src
# hg clone https://bitbucket.org/multicoreware/x265
# cd x265
# hg update 11991
# vi ./source/CMakeLists.txt
```

``` bash:./source/MakeLists.txt
    if(ARM AND CROSS_COMPILE_ARM)
        set(ARM_ARGS -march=armv6 -mfloat-abi=soft -mfpu=vfp -marm -fPIC)
    elseif(ARM)
        find_package(Neon)
        if(CPU_HAS_NEON)
            # modify(native => cortex-a7, neon => neon-vfpv4)
            # set(ARM_ARGS -mcpu=native -mfloat-abi=hard -mfpu=neon -marm -fPIC)
            set(ARM_ARGS -mcpu=cortex-a7 -mfloat-abi=hard -mfpu=neon-vfpv4 -marm -fPIC)
            add_definitions(-DHAVE_NEON)
        else()
            set(ARM_ARGS -mcpu=native -mfloat-abi=hard -mfpu=vfp -marm)
        endif()
    endif()
```


```
# cd build/linux
# ./make-Makefiles.bash
    ENABLE_PIC    -> ON
    ENABLE_SHARED -> ON
    Press [c] to configure
    Press [g] to generate
# make -j2
# make install
# make clean
```

### libvpx

* 公式リポジトリの1.3.0では古いため、ソースからビルドする。
(ffmpegのビルドには1.4以上が必要)
* ./Configureでエラーになる -> targetに `armv7-linux-gcc` を指定する

> ```:error
 Unable to invoke compiler: gcc  -march=armv7-a -mfloat-abi=softfp -mfpu=neon -DNDEBUG -O3 -fPIC -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0 -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -Wall -Wdeclaration-after-statement -Wdisabled-optimization -Wpointer-arith -Wtype-limits -Wcast-qual -Wvla -Wimplicit-function-declaration -Wuninitialized -Wunused -Wextra -Wundef -Wframe-larger-than=52000
```

```
# cd /usr/local/src
# git clone https://chromium.googlesource.com/webm/libvpx
# cd libvpx
# ./configure --enable-shared --enable-pic --target=armv7-linux-gcc
# make -j2
# make install
# make clean
```

## 手順③：ffmpegをソースからビルドしてインストール
### ffmpeg

* x265使用時はconfigureで `--extra-libs=-lpthread` を指定して `pthread` を無効にする。<br />
・multicoreware / x265 / 課題 / #371 - x265 not found using pkg-config - Bitbucket<br />
https://bitbucket.org/multicoreware/x265/issues/371/x265-not-found-using-pkg-config

> ```:error
gcc -L/home/werner/ffmpeg_build/lib -Wl,--as-needed -Wl,-z,noexecstack -I/home/werner/ffmpeg_build/include -L/home/werner/ffmpeg_build/lib -o /tmp/ffconf.mRzqLK9Z/test /tmp/ffconf.mRzqLK9Z/test.o -lx265 -lstdc++ -lm -lrt -ldl -lnuma
/home/werner/ffmpeg_build/lib/libx265.a(threading.cpp.o): In function `x265::Thread::start()':
threading.cpp:(.text+0x35): undefined reference to `pthread_create'
/home/werner/ffmpeg_build/lib/libx265.a(threading.cpp.o): In function `x265::Thread::stop()':
threading.cpp:(.text+0x63): undefined reference to `pthread_join'
collect2: error: ld returned 1 exit status
ERROR: x265 not found using pkg-config
```

```
# ldconfig
# cd /usr/local/src
# git clone git://github.com/ffmpeg/ffmpeg --depth 1
# cd ffmpeg
# PKG_CONFIG_PATH=/usr/local/lib/pkgconfig \
  ./configure \
  --pkg-config-flags="--static" \
  --enable-static \
  --enable-shared \
  --disable-debug \
  --disable-stripping \
  --enable-nonfree \
  --enable-libfreetype \
  --enable-bzlib \
  --enable-libgsm \
  --enable-libmp3lame \
  --enable-pic \
  --enable-libopenjpeg \
  --enable-libfdk-aac \
  --enable-libopus \
  --enable-libvorbis \
  --enable-libsoxr \
  --enable-libpulse \
  --enable-libspeex \
  --enable-libtheora \
  --enable-libvpx \
  --enable-libass \
  --enable-libx264 \
  --enable-libx265 \
  --enable-libxvid \
  --enable-gpl \
  --extra-libs=-lpthread

# make -j2
# make install
# make distclean
```

# その他
* ffserverがない ⇒ ffmpeg 4.0から削除されたとのこと<br />
・FFmpeg/Changelog at master · FFmpeg/FFmpeg<br />
https://github.com/FFmpeg/FFmpeg/blob/master/Changelog

> ```text:Changelog
version 4.0:
- Bitstream filters for editing metadata in H.264, HEVC and MPEG-2 streams
- Dropped support for OpenJPEG versions 2.0 and below. Using OpenJPEG now
~~~
~~~
- Removed the ffserver program
- Removed the ffmenc and ffmdec muxer and demuxer
```

* ffmpegのビルド・インストールは出来たが動かない ⇒ 共有ライブラリにパスを追加する。

>```:error
ffmpeg: error while loading shared libraries: libavdevice.so.58: cannot open shared object file: No such file or directory
```

```
# touch /etc/ld.so.conf.d/usr-local.conf
# vi /etc/ld.so.conf.d/usr-local.conf
```

``` bash:usr-local.conf
/usr/local/lib
```
```
# ldconfig
```

* pthread無効化にして良いの？ ⇒ 誰か教えてください。。。(むしろそこまでしてx265を有効にする必要ある？)

# 参考(謝辞)

* ffmpegをスタティックビルドする（CentOS6） - Qiita
https://qiita.com/takakiku/items/4f129a8859d99f6be2db

* LinuxでFFmpegをほぼ全自動でビルドする（CentOS、Ubuntu等に対応） | 自分に負けないラボラトリー
https://www.jifu-labo.net/2015/09/ffmpeg_build/

* Umbrella　RaspberryPi　Pi3でlibx265 リベンジ
http://wbbwbb.blog83.fc2.com/blog-entry-244.html

* [FFmpeg] ffmpeg に libx265 をリンクする
https://qiita.com/pb_tmz08/items/29165f4c3ef9bc4285ab

* CentOS7 ffmpegをソースからインストール - わすれないうちにメモしよう
http://d.hatena.ne.jp/kt_hiro/20150101/1420094609

* 3.18.4 ARMオプション | GCC 7 入門リファレンス | サンプルコード [日本語]
https://code-examples.net/ja/docs/gcc~7/arm-options

* Compiling with libvpx support - wiki
http://wiki.webmproject.org/ffmpeg/building-with-libvpx

* multicoreware / x265 / 課題 / #371 - x265 not found using pkg-config - Bitbucket
https://bitbucket.org/multicoreware/x265/issues/371/x265-not-found-using-pkg-config

* LinuxでIntel QSVを使ったH.264ハードウェアエンコード（CentOS7＋ffmpeg） | Kung Noi Blog
http://www.goodnai.com/blog/2015/11/24/linux%E3%81%A7intel-qsv%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%9Fh-264%E3%83%8F%E3%83%BC%E3%83%89%E3%82%A6%E3%82%A7%E3%82%A2%E3%82%A8%E3%83%B3%E3%82%B3%E3%83%BC%E3%83%89%EF%BC%88centos7%EF%BC%8Bffmpeg/

* Amazon Linux 2013.09 に FFmpeg をインストールする - Qiita
https://qiita.com/nifuramu/items/ba86a9940ddf4379765b