Introduction

OpenH264 を使いたくて FFMPEG をカスタムビルドしたが、どうやっても OpenCV が FFMPEG を検出してくれない問題にぶつかった。
FFMPEG に OpenH264 をリンクさせるのは自分も 開発メモ その316 FFMPEG で libopenh264 を Windows で使う その2 とかで実施していたが、FFMPEG を単独で利用したケースで、ライブラリとして他と組み合わせたことがなかった。

What’s problem?

問題点の原因は、OpenCV に OpenH264 の情報を伝えていなかったことにあった。
結論は OPENCV_EXTRA_EXE_LINKER_FLAGS にあるが、なぜそうなったか、詳細を理解しないと意味がないので書き記しておく。
検証環境は下記。

  • Ubuntu
    • 22.04
  • CMake
    • 4.0.3
  • gcx
    • 11.4.0
  • OpenCV
    • 4.13.0
  • FFMPEG
    • n8.1
  • OpenH264
    • 2.6.0

1. 普通にビルドした FFMPEG をリンク

まず、普通に FFMPEG をビルドする。この時点では OpenH264 は有効にしない。
イメージは下記。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ /path/to/ffmpeg/configure \
--enable-optimizations \
--disable-debug \
--enable-shared \
--disable-static \
--disable-logging \
--fatal-warnings \
--enable-pic \
--disable-doc \
--disable-htmlpages \
--disable-manpages \
--disable-podpages \
--disable-txtpages \
--disable-gpl \
--prefix=/path/to/install/ffmpeg
$ make -j $nproc && make install

次に OpenCV をビルドする。
当然、システムに ffmpeglibavcodec-dev がインストールされていないものとする。
WITH_FFMPEG=ON を追加し、それ以外は極力無効にしてミニマムな状態にした。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
$ cmake -D CMAKE_INSTALL_PREFIX=/path/to/install/opencv \
-D CMAKE_BUILD_TYPE=Release \
-D BUILD_SHARED_LIBS=OFF \
-D BUILD_LIST=core,imgproc \
-D BUILD_opencv_apps=OFF \
-D BUILD_opencv_world=OFF \
-D BUILD_opencv_java=OFF \
-D BUILD_opencv_python=OFF \
-D BUILD_opencv_python2=OFF \
-D BUILD_opencv_python3=OFF \
-D BUILD_DOCS=OFF \
-D BUILD_EXAMPLES=OFF \
-D BUILD_PERF_TESTS=OFF \
-D BUILD_TESTS=OFF \
-D WITH_JASPER=OFF \
-D WITH_IMGCODEC_HDR=OFF \
-D WITH_IMGCODEC_PFM=OFF \
-D WITH_IMGCODEC_PXM=OFF \
-D WITH_IMGCODEC_SUNRASTER=OFF \
-D WITH_OPENEXR=OFF \
-D WITH_OPENJPEG=OFF \
-D WITH_TIFF=OFF \
-D WITH_WEBP=OFF \
-D WITH_DSHOW=OFF \
-D WITH_FFMPEG=ON \
-D WITH_GSTREAMER=OFF \
-D WITH_MSMF=OFF \
-D WITH_OBSENSOR=OFF \
-D WITH_VA=OFF \
-D WITH_ITT=OFF \
-D WITH_EIGEN=OFF \
-D WITH_IPP=OFF \
-D WITH_PROTOBUF=OFF \
-D WITH_OPENCL=OFF \
-D WITH_FLATBUFFERS=OFF \
path/to/source/opencv

上記でコンソールを見ると途中で

1
2
3
4
-- Checking for modules 'libavcodec;libavformat;libavutil;libswscale'
-- No package 'libavcodec' found
-- No package 'libavformat' found
-- FFMPEG is disabled. Required libraries: libavcodec;libavformat;libavutil;libswscale. Missing libraries: libavcodec;libavformat;libavutil;libswscale

のように表示され FFMPEG が使えないことが示される。

1
2
3
4
5
6
7
8
9
--   Video I/O:
-- FFMPEG: NO
-- avcodec: NO
-- avformat: NO
-- avutil: NO
-- swscale: NO
-- avdevice: NO
-- v4l/v4l2: YES (linux/videodev2.h)
-- Orbbec: NO

この時点では FFMPEG の情報を指定していないので予定通り。
次に FFMPEG の情報を指定してみる。
FFMPEG は CMake に対応していないので、PkgConfig を使う必要がある。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
$ export PKG_CONFIG_PATH=${PKG_CONFIG_PATH}:/path/to/ffmpeg/lib/pkgconfig
$ cmake -D CMAKE_INSTALL_PREFIX=/path/to/install/opencv \
-D CMAKE_BUILD_TYPE=Release \
-D BUILD_SHARED_LIBS=OFF \
-D BUILD_LIST=core,imgproc \
-D BUILD_opencv_apps=OFF \
-D BUILD_opencv_world=OFF \
-D BUILD_opencv_java=OFF \
-D BUILD_opencv_python=OFF \
-D BUILD_opencv_python2=OFF \
-D BUILD_opencv_python3=OFF \
-D BUILD_DOCS=OFF \
-D BUILD_EXAMPLES=OFF \
-D BUILD_PERF_TESTS=OFF \
-D BUILD_TESTS=OFF \
-D WITH_JASPER=OFF \
-D WITH_IMGCODEC_HDR=OFF \
-D WITH_IMGCODEC_PFM=OFF \
-D WITH_IMGCODEC_PXM=OFF \
-D WITH_IMGCODEC_SUNRASTER=OFF \
-D WITH_OPENEXR=OFF \
-D WITH_OPENJPEG=OFF \
-D WITH_TIFF=OFF \
-D WITH_WEBP=OFF \
-D WITH_DSHOW=OFF \
-D WITH_FFMPEG=ON \
-D WITH_GSTREAMER=OFF \
-D WITH_MSMF=OFF \
-D WITH_OBSENSOR=OFF \
-D WITH_VA=OFF \
-D WITH_ITT=OFF \
-D WITH_EIGEN=OFF \
-D WITH_IPP=OFF \
-D WITH_PROTOBUF=OFF \
-D WITH_OPENCL=OFF \
-D WITH_FLATBUFFERS=OFF \
path/to/source/opencv

これにより先ほどの出力が

1
2
3
4
5
6
7
-- Checking for modules 'libavcodec;libavformat;libavutil;libswscale'
-- Found libavcodec, version 62.28.100
-- Found libavformat, version 62.12.100
-- Found libavutil, version 60.26.100
-- Found libswscale, version 9.5.100
-- Checking for module 'libavdevice'
-- Found libavdevice, version 62.3.100

1
2
3
4
5
6
7
8
9
--   Video I/O:
-- FFMPEG: YES
-- avcodec: YES (62.28.100)
-- avformat: YES (62.12.100)
-- avutil: YES (60.26.100)
-- swscale: YES (9.5.100)
-- avdevice: YES (62.3.100)
-- v4l/v4l2: YES (linux/videodev2.h)
-- Orbbec: NO

となる。

ここまでが 前提

2. OpenH264 を有効にした FFMPEG をリンク

次に OpenH264 を有効化して FFMPEG をビルドする。
イメージは下記。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ PKG_CONFIG_PATH="/path/to/libopenh264/lib/pkgconfig:/usr/local/lib/pkgconfig" \
/path/to/ffmpeg/configure \
--enable-optimizations \
--disable-debug \
--enable-shared \
--disable-static \
--disable-logging \
--fatal-warnings \
--enable-pic \
--disable-doc \
--disable-htmlpages \
--disable-manpages \
--disable-podpages \
--disable-txtpages \
--disable-gpl \
--enable-libopenh264 \
--prefix=/path/to/install/ffmpeg
$ make -j $nproc && make install

同様に OpenCV をビルドする。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
$ export PKG_CONFIG_PATH=${PKG_CONFIG_PATH}:/path/to/ffmpeg/lib/pkgconfig
$ cmake -D CMAKE_INSTALL_PREFIX=/path/to/install/opencv \
-D CMAKE_BUILD_TYPE=Release \
-D BUILD_SHARED_LIBS=OFF \
-D BUILD_LIST=core,imgproc \
-D BUILD_opencv_apps=OFF \
-D BUILD_opencv_world=OFF \
-D BUILD_opencv_java=OFF \
-D BUILD_opencv_python=OFF \
-D BUILD_opencv_python2=OFF \
-D BUILD_opencv_python3=OFF \
-D BUILD_DOCS=OFF \
-D BUILD_EXAMPLES=OFF \
-D BUILD_PERF_TESTS=OFF \
-D BUILD_TESTS=OFF \
-D WITH_JASPER=OFF \
-D WITH_IMGCODEC_HDR=OFF \
-D WITH_IMGCODEC_PFM=OFF \
-D WITH_IMGCODEC_PXM=OFF \
-D WITH_IMGCODEC_SUNRASTER=OFF \
-D WITH_OPENEXR=OFF \
-D WITH_OPENJPEG=OFF \
-D WITH_TIFF=OFF \
-D WITH_WEBP=OFF \
-D WITH_DSHOW=OFF \
-D WITH_FFMPEG=ON \
-D WITH_GSTREAMER=OFF \
-D WITH_MSMF=OFF \
-D WITH_OBSENSOR=OFF \
-D WITH_VA=OFF \
-D WITH_ITT=OFF \
-D WITH_EIGEN=OFF \
-D WITH_IPP=OFF \
-D WITH_PROTOBUF=OFF \
-D WITH_OPENCL=OFF \
-D WITH_FLATBUFFERS=OFF \
path/to/source/opencv

ここで先ほどと違った挙動を見せる

1
2
3
4
5
6
7
8
-- Checking for modules 'libavcodec;libavformat;libavutil;libswscale'
-- Found libavcodec, version 62.28.100
-- Found libavformat, version 62.12.100
-- Found libavutil, version 60.26.100
-- Found libswscale, version 9.5.100
-- Checking for module 'libavdevice'
-- Found libavdevice, version 62.3.100
-- WARNING: Can't build ffmpeg test code

警告が見える。

1
2
3
4
5
6
7
8
9
--   Video I/O:
-- FFMPEG: NO
-- avcodec: YES (62.28.100)
-- avformat: YES (62.12.100)
-- avutil: YES (60.26.100)
-- swscale: YES (9.5.100)
-- avdevice: YES (62.3.100)
-- v4l/v4l2: YES (linux/videodev2.h)
-- Orbbec: NO

libavcodec 等のコンポーネントは有効なのに FFMPEG 自体が無効になっている…

3. PKGCONFIG に OpenH264 を足す

単純に環境変数ないしはシェル変数 PKGCONFIG に OpenH264 の PkgConfig までのパスを追加すれば治るでしょう?、と思った。
違いは OpenH264 の有無だけだし。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
$ export PKG_CONFIG_PATH=${PKG_CONFIG_PATH}:/path/to/ffmpeg/lib/pkgconfig:/path/to/libopenh264/lib/pkgconfig
$ cmake -D CMAKE_INSTALL_PREFIX=/path/to/install/opencv \
-D CMAKE_BUILD_TYPE=Release \
-D BUILD_SHARED_LIBS=OFF \
-D BUILD_LIST=core,imgproc \
-D BUILD_opencv_apps=OFF \
-D BUILD_opencv_world=OFF \
-D BUILD_opencv_java=OFF \
-D BUILD_opencv_python=OFF \
-D BUILD_opencv_python2=OFF \
-D BUILD_opencv_python3=OFF \
-D BUILD_DOCS=OFF \
-D BUILD_EXAMPLES=OFF \
-D BUILD_PERF_TESTS=OFF \
-D BUILD_TESTS=OFF \
-D WITH_JASPER=OFF \
-D WITH_IMGCODEC_HDR=OFF \
-D WITH_IMGCODEC_PFM=OFF \
-D WITH_IMGCODEC_PXM=OFF \
-D WITH_IMGCODEC_SUNRASTER=OFF \
-D WITH_OPENEXR=OFF \
-D WITH_OPENJPEG=OFF \
-D WITH_TIFF=OFF \
-D WITH_WEBP=OFF \
-D WITH_DSHOW=OFF \
-D WITH_FFMPEG=ON \
-D WITH_GSTREAMER=OFF \
-D WITH_MSMF=OFF \
-D WITH_OBSENSOR=OFF \
-D WITH_VA=OFF \
-D WITH_ITT=OFF \
-D WITH_EIGEN=OFF \
-D WITH_IPP=OFF \
-D WITH_PROTOBUF=OFF \
-D WITH_OPENCL=OFF \
-D WITH_FLATBUFFERS=OFF \
path/to/source/opencv

が、何一つ変わらない。
なんで?

4. Can’t build ffmpeg test code、って何?

どう考えてもこのエラーが怪しい。
OpenCV のソースを見ると該当するのはここ。
opencv/modules/videoio/cmake/detect_ffmpeg.cmake#L89

1
2
3
4
5
6
7
8
9
10
11
12
13
14
if(HAVE_FFMPEG AND NOT HAVE_FFMPEG_WRAPPER AND NOT OPENCV_FFMPEG_SKIP_BUILD_CHECK)
try_compile(__VALID_FFMPEG
"${OpenCV_BINARY_DIR}"
"${OpenCV_SOURCE_DIR}/cmake/checks/ffmpeg_test.cpp"
CMAKE_FLAGS "-DINCLUDE_DIRECTORIES:STRING=${FFMPEG_INCLUDE_DIRS}"
"-DLINK_LIBRARIES:STRING=${FFMPEG_LIBRARIES}"
OUTPUT_VARIABLE TRY_OUT
)
if(NOT __VALID_FFMPEG)
# message(FATAL_ERROR "FFMPEG: test check build log:\n${TRY_OUT}")
message(STATUS "WARNING: Can't build ffmpeg test code")
set(HAVE_FFMPEG FALSE)
endif()
endif()

どうも、try_compile で失敗しているというのは読める。
CMake の公式 try_compile を見ると、読んで字のごとく、「実行可能または静的ライブラリをソースからビルドしてみる」、とある。
${OpenCV_SOURCE_DIR}/cmake/checks/ffmpeg_test.cpp を見ても、まぁ、すごい簡単なソースがあって、単純に FFMPEG を使ってビルドできるかどうかを事前確認している模様。

で、これが失敗しているから cmake の設定でエラーになっているのだが、肝心の理由が出力されていない。
それもそのはずで、上の公式にこのような一文がある。

CMake automatically generates, for each try_compile operation, a unique directory under ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeScratch with an unspecified name. These directories are cleaned automatically unless –debug-trycompile is passed to cmake. Such directories from previous runs are also unconditionally cleaned at the beginning of any cmake execution.

CMakeは、各try_compile操作に対して、${CMAKE_BINARY_DIR}/CMakeFiles/CMakeScratch 配下に、名前が未指定の一意なディレクトリを自動的に生成します。これらのディレクトリは、cmakeに–debug-trycompileが指定されない限り、自動的に削除されます。また、以前の実行で生成されたこのようなディレクトリも、cmakeの実行開始時に無条件に削除されます。

勝手に消えるけど、cmake に --debug-trycompile を付与すれば消えないと読める。
そして、 ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeScratch に何か出力される、と。
実際、 ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeScratch には何も存在しないことは確認できた。

なので、さっきの CMake のコマンドを

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
$ export PKG_CONFIG_PATH=${PKG_CONFIG_PATH}:/path/to/ffmpeg/lib/pkgconfig:/path/to/libopenh264/lib/pkgconfig
$ cmake -D CMAKE_INSTALL_PREFIX=/path/to/install/opencv \
-D CMAKE_BUILD_TYPE=Release \
-D BUILD_SHARED_LIBS=OFF \
-D BUILD_LIST=core,imgproc \
-D BUILD_opencv_apps=OFF \
-D BUILD_opencv_world=OFF \
-D BUILD_opencv_java=OFF \
-D BUILD_opencv_python=OFF \
-D BUILD_opencv_python2=OFF \
-D BUILD_opencv_python3=OFF \
-D BUILD_DOCS=OFF \
-D BUILD_EXAMPLES=OFF \
-D BUILD_PERF_TESTS=OFF \
-D BUILD_TESTS=OFF \
-D WITH_JASPER=OFF \
-D WITH_IMGCODEC_HDR=OFF \
-D WITH_IMGCODEC_PFM=OFF \
-D WITH_IMGCODEC_PXM=OFF \
-D WITH_IMGCODEC_SUNRASTER=OFF \
-D WITH_OPENEXR=OFF \
-D WITH_OPENJPEG=OFF \
-D WITH_TIFF=OFF \
-D WITH_WEBP=OFF \
-D WITH_DSHOW=OFF \
-D WITH_FFMPEG=ON \
-D WITH_GSTREAMER=OFF \
-D WITH_MSMF=OFF \
-D WITH_OBSENSOR=OFF \
-D WITH_VA=OFF \
-D WITH_ITT=OFF \
-D WITH_EIGEN=OFF \
-D WITH_IPP=OFF \
-D WITH_PROTOBUF=OFF \
-D WITH_OPENCL=OFF \
-D WITH_FLATBUFFERS=OFF \
--debug-trycompile \
path/to/source/opencv

--debug-trycompile を付与してみた。

すると再び出力が変化した。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
--   No package 'gtk+-2.0' found
CMake Debug Log at modules/videoio/cmake/detect_ffmpeg.cmake:80 (try_compile):
Executing try_compile (__VALID_FFMPEG) in:

/data/work/oss/Demo/Multimedia/FFmpeg/01_OpenCV/build/linux/opencv/4.13.0/static/Release/CMakeFiles/CMakeTmp
Call Stack (most recent call first):
modules/videoio/cmake/init.cmake:7 (include)
modules/videoio/cmake/init.cmake:11 (add_backend)
cmake/OpenCVModule.cmake:298 (include)
cmake/OpenCVModule.cmake:361 (_add_modules_1)
cmake/OpenCVModule.cmake:408 (ocv_glob_modules)
CMakeLists.txt:1097 (ocv_register_modules)


-- WARNING: Can't build ffmpeg test code

…あれ ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeScratch じゃないの?…思ったら公式の説明には続きがあり

In this version, try_compile will use /CMakeFiles/CMakeTmp for its operation, and all such files will be cleaned automatically.

とある。
In this version が何時からなのかは不明だが、少なくとも 3.0 にはこの記述がある。

CMakeFiles/CMakeTmp を見ると、CMakeError.log みたいなのはないが、一つずつ眺めていると、Makefile があることに気づいた。
中を見ると、ffmpeg_test.cpp の記述があり、これが問題のテストプロジェクトだとわかった。
なので、手動で make を実行する。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ cd ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeTmp
$ make
...
/usr/bin/ld: warning: libopenh264.so.8, needed by /data/work/oss/Demo/Multimedia/FFmpeg/install/linux/ffmpeg/n8.1/dynamic/Release/lib/libavcodec.so, not found (try using -rpath or -rpath-link)
/usr/bin/ld: /data/work/oss/Demo/Multimedia/FFmpeg/install/linux/ffmpeg/n8.1/dynamic/Release/lib/libavcodec.so: undefined reference to `WelsDestroyDecoder'
/usr/bin/ld: /data/work/oss/Demo/Multimedia/FFmpeg/install/linux/ffmpeg/n8.1/dynamic/Release/lib/libavcodec.so: undefined reference to `WelsDestroySVCEncoder'
/usr/bin/ld: /data/work/oss/Demo/Multimedia/FFmpeg/install/linux/ffmpeg/n8.1/dynamic/Release/lib/libavcodec.so: undefined reference to `WelsCreateDecoder'
/usr/bin/ld: /data/work/oss/Demo/Multimedia/FFmpeg/install/linux/ffmpeg/n8.1/dynamic/Release/lib/libavcodec.so: undefined reference to `WelsCreateSVCEncoder'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/cmTC_6624f.dir/build.make:107: cmTC_6624f] Error 1
make[2]: Leaving directory '/data/work/oss/Demo/Multimedia/FFmpeg/01_OpenCV/build/linux/opencv/4.13.0/static/Release/CMakeFiles/CMakeTmp'
make[1]: *** [CMakeFiles/Makefile2:90: CMakeFiles/cmTC_6624f.dir/all] Error 2
make[1]: Leaving directory '/data/work/oss/Demo/Multimedia/FFmpeg/01_OpenCV/build/linux/opencv/4.13.0/static/Release/CMakeFiles/CMakeTmp'
make: *** [Makefile:94: all] Error 2

原因がわかった。
libopenh264.so.8 が必要だが、それがリンカーにわたっていない、と。

5. リンカーに外から指示

そもそも PkgConfig で OpenH264 を指定しているのに、なんでリンカーは解釈してくれないの?、と思う。
libavcodec は解決できているし。

それでいろいろググっていたら build script for opencv using a custom ffmpeg installation という gist を見つける。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/bin/bash

# Note: You need to replace the path accordingly

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/insert/path/here/ffmpeg-4.4.1-5/lib
export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/insert/path/here/ffmpeg-4.4.1-5/lib/pkgconfig
export PKG_CONFIG_LIBDIR=$PKG_CONFIG_LIBDIR:/insert/path/here/ffmpeg-4.4.1-5/lib

cmake \
-D BUILD_EXAMPLES=ON \
-D BUILD_TESTS=OFF \
-D OPENCV_EXTRA_EXE_LINKER_FLAGS="-Wl,-rpath,/insert/path/here/ffmpeg-4.4.1-5/lib" \
-D CMAKE_BUILD_TYPE=RELEASE \
-D CMAKE_INSTALL_PREFIX=$HOME/Applications/opencv \
/insert/path/here/opencv-python/opencv

OPENCV_EXTRA_EXE_LINKER_FLAGS なる見慣れないオプションがあり、リンカーに指示を与えていた。
素直に上をまねて OpenH264 のライブラリディレクトリを指定してみる。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
$ export PKG_CONFIG_PATH=${PKG_CONFIG_PATH}:/path/to/ffmpeg/lib/pkgconfig:/path/to/libopenh264/lib/pkgconfig
$ cmake -D CMAKE_INSTALL_PREFIX=/path/to/install/opencv \
-D CMAKE_BUILD_TYPE=Release \
-D BUILD_SHARED_LIBS=OFF \
-D BUILD_LIST=core,imgproc \
-D BUILD_opencv_apps=OFF \
-D BUILD_opencv_world=OFF \
-D BUILD_opencv_java=OFF \
-D BUILD_opencv_python=OFF \
-D BUILD_opencv_python2=OFF \
-D BUILD_opencv_python3=OFF \
-D BUILD_DOCS=OFF \
-D BUILD_EXAMPLES=OFF \
-D BUILD_PERF_TESTS=OFF \
-D BUILD_TESTS=OFF \
-D WITH_JASPER=OFF \
-D WITH_IMGCODEC_HDR=OFF \
-D WITH_IMGCODEC_PFM=OFF \
-D WITH_IMGCODEC_PXM=OFF \
-D WITH_IMGCODEC_SUNRASTER=OFF \
-D WITH_OPENEXR=OFF \
-D WITH_OPENJPEG=OFF \
-D WITH_TIFF=OFF \
-D WITH_WEBP=OFF \
-D WITH_DSHOW=OFF \
-D WITH_FFMPEG=ON \
-D WITH_GSTREAMER=OFF \
-D WITH_MSMF=OFF \
-D WITH_OBSENSOR=OFF \
-D WITH_VA=OFF \
-D WITH_ITT=OFF \
-D WITH_EIGEN=OFF \
-D WITH_IPP=OFF \
-D WITH_PROTOBUF=OFF \
-D WITH_OPENCL=OFF \
-D WITH_FLATBUFFERS=OFF \
-D OPENCV_EXTRA_EXE_LINKER_FLAGS="-Wl,-rpath,/path/to/ffmpeg/lib -Wl,-rpath,/path/to/libopenh264/lib" \
path/to/source/opencv

これで無事に警告が消えて、FFMPEG が有効になった。
ちなみに、PKG_CONFIG_PATH から OpenH264 のパスは外しても問題はなかったし、OPENCV_EXTRA_EXE_LINKER_FLAGS も OpenH264 だけでよかった。
最終的には下記。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
$ export PKG_CONFIG_PATH=${PKG_CONFIG_PATH}:/path/to/ffmpeg/lib/pkgconfig
$ cmake -D CMAKE_INSTALL_PREFIX=/path/to/install/opencv \
-D CMAKE_BUILD_TYPE=Release \
-D BUILD_SHARED_LIBS=OFF \
-D BUILD_LIST=core,imgproc \
-D BUILD_opencv_apps=OFF \
-D BUILD_opencv_world=OFF \
-D BUILD_opencv_java=OFF \
-D BUILD_opencv_python=OFF \
-D BUILD_opencv_python2=OFF \
-D BUILD_opencv_python3=OFF \
-D BUILD_DOCS=OFF \
-D BUILD_EXAMPLES=OFF \
-D BUILD_PERF_TESTS=OFF \
-D BUILD_TESTS=OFF \
-D WITH_JASPER=OFF \
-D WITH_IMGCODEC_HDR=OFF \
-D WITH_IMGCODEC_PFM=OFF \
-D WITH_IMGCODEC_PXM=OFF \
-D WITH_IMGCODEC_SUNRASTER=OFF \
-D WITH_OPENEXR=OFF \
-D WITH_OPENJPEG=OFF \
-D WITH_TIFF=OFF \
-D WITH_WEBP=OFF \
-D WITH_DSHOW=OFF \
-D WITH_FFMPEG=ON \
-D WITH_GSTREAMER=OFF \
-D WITH_MSMF=OFF \
-D WITH_OBSENSOR=OFF \
-D WITH_VA=OFF \
-D WITH_ITT=OFF \
-D WITH_EIGEN=OFF \
-D WITH_IPP=OFF \
-D WITH_PROTOBUF=OFF \
-D WITH_OPENCL=OFF \
-D WITH_FLATBUFFERS=OFF \
-D OPENCV_EXTRA_EXE_LINKER_FLAGS="-Wl,-rpath,/path/to/libopenh264/lib" \
path/to/source/opencv

6. まとめ

OPENCV_EXTRA_EXE_LINKER_FLAGS なる初見のオプションで解決するなど、OpenCV はまだまだ闇が深い。
ちなみに、このオプション、検索すると、少なくとも Configure and Build OpenCV to Custom FFMPEG Install という 2012 年という古い記事で見つかった。
今日も先人に感謝。