LoginSignup
16
8

More than 1 year has passed since last update.

OpenCVのvideoioモジュールでソースビルドのFFmpegを使う

Last updated at Posted at 2022-12-10

この記事はOpenCV Advent Calendar 2022の11日目の記事です。

1. はじめに

OpenCVのvideoioモジュールはいくつかのbackendを用意しています。このbackendの一つにFFmpegがあります。https://docs.opencv.org/4.6.0/d0/da7/videoio_overview.htmlの「The FFmpeg library」にも

OpenCV can use the FFmpeg library (http://ffmpeg.org/) as backend to record, convert and stream audio and video.

とあります。また、

FFmpeg is licensed under the GNU Lesser General Public License (LGPL) version 2.1 or later. See OPENCV_SOURCE_CODE/3rdparty/ffmpeg/readme.txt and http://ffmpeg.org/legal.html for details and licensing information

という説明もあり、OpenCVを自作ソフトウェア、プロダクトに組み込むケースなどでこの点を気にする人が居るかもしれません。それ以外にも

など、OpenCVのvideoioモジュールで使用するFFmpegをカスタムしたい状況があるかもしれません。この記事ではOpenCVのvideoioモジュールでソースビルドのFFmpegを使う方法を紹介します。

2. OpenCV公式ドキュメントを読む

前述の説明で

See OPENCV_SOURCE_CODE/3rdparty/ffmpeg/readme.txt

とあったのでhttps://github.com/opencv/opencv/blob/4.6.0/3rdparty/ffmpeg/readme.txtを読んでみましょう。ここではプラットフォーム別に掻い摘んで読んでいきます。

2.1 Linux and other Unix flavors

On Linux and other Unix flavors OpenCV uses default or user-built ffmpeg/libav libraries.
If user builds ffmpeg/libav from source and wants OpenCV to stay BSD library, not GPL/LGPL,
he/she should use --enabled-shared configure flag and make sure that no GPL components are
enabled (some notable examples are x264 (H264 encoder) and libac3 (Dolby AC3 audio codec)).
See https://www.ffmpeg.org/legal.html for details.

  • Linux and other Unix flavorsだとシステムにインストールされているFFmpeg、libavライブラリを使用する
  • ソースからビルドしたFFmpeg、libavライブラリを使用する場合、FFmpegのビルド設定で非GPL/非LGPLにすることができる

If you want to play very safe and do not want to use FFMPEG at all, regardless of whether it's installed on
your system or not, configure and build OpenCV using CMake with WITH_FFMPEG=OFF flag. OpenCV will then use
AVFoundation (OSX), GStreamer (Linux) or other available backends supported by opencv_videoio module.

  • OpenCVのvideoioモジュールでFFmpegを使用したくない場合、WITH_FFMPEG=OFFを指定してビルドし、他のサポートされたbackendを使用するようにすることができる

という旨が書かれています。

2.2 Windows

On Windows OpenCV uses pre-built ffmpeg binaries, built with proper flags (without GPL components) and
wrapped with simple, stable OpenCV-compatible API.
The binaries are opencv_videoio_ffmpeg.dll (version for 32-bit Windows) and
opencv_videoio_ffmpeg_64.dll (version for 64-bit Windows).

  • Windows版のOpenCVはpre-builtのFFmpegバイナリを使用する
    • 32-bit Windows:opencv_videoio_ffmpeg.dll
    • 64-bit Windows:opencv_videoio_ffmpeg_64.dll
  • 「without GPL components」のビルド設定でビルドされている

という記載があります。pre-builtのバイナリ、ソースはopencv_3rdpartyで管理されています。

The pre-built opencv_videoio_ffmpeg*.dll is:

  • LGPL library, not BSD libraries.
  • Loaded at runtime by opencv_videoio module.
    If it succeeds, ffmpeg can be used to decode/encode videos;
    otherwise, other API is used.
  • pre-builtのopencv_videoio_ffmpeg*.dllのライセンスはLGPL
  • opencv_videoioモジュールはAPI実行時のこのDLLをロードし、ロードが成功したらFFmpegを使用する

という記載があります。ライブラリをビルドするためのスクリプトであるhttps://github.com/opencv/opencv_3rdparty/blob/ffmpeg/4.x_20220912/ffmpeg/make_mingw.shを読むと、配布されているライブラリのFFMPEGビルドオプションで--enable-gplが指定されていません。https://www.ffmpeg.org/legal.htmlに以下の記載があります。

  • FFmpeg is licensed under the GNU Lesser General Public License (LGPL) version 2.1 or later.
  • Compile FFmpeg without "--enable-gpl" and without "--enable-nonfree".

上記のことから、pre-builtのopencv_videoio_ffmpeg*.dllはLGPLバイナリとして頒布するために--enable-gpl--enable-nonfree、いずれも指定せずにビルドされていることがわかります。

3. OpenCV videoioモジュールにソースビルドしたFFmpegを組み込む

それではOpenCV videoioモジュールにソースビルドしたFFmpegを組み込む方法を紹介します。以降はUbuntu 22.04上で行った手順となります。

3.1 FFmpegインストール

https://mikoto2000.blogspot.com/2021/10/ubuntu-1804-h264-ffmpeg.htmlを参考にしてFFmpegをインストールします。Ubuntuへの公式のインストール手順はhttps://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntuにあります。

3.1.1 依存パッケージのインストール

今回ビルドするFFmpegに必要な依存パッケージをインストールします。ビルド設定によってインストールに必要なパッケージは変わるので留意ください。

sudo apt-get -y install \
  autoconf \
  automake \
  build-essential \
  cmake \
  git-core \
  libass-dev \
  libfreetype6-dev \
  libgnutls28-dev \
  libmp3lame-dev \
  libsdl2-dev \
  libtool \
  libunistring-dev \
  libva-dev \
  libvdpau-dev \
  libvorbis-dev \
  libx264-dev \
  libxcb-shm0-dev \
  libxcb-xfixes0-dev \
  libxcb1-dev \
  libaom-dev \
  meson \
  nasm \
  ninja-build \
  pkg-config \
  texinfo \
  wget \
  yasm \
  zlib1g-dev

3.1.2 FFmpegのインストール

以下のコマンドを実行して、FFmpeg n5.0.2をインストールします。

git clone https://github.com/FFmpeg/FFmpeg.git
cd FFmpeg
git checkout n5.0.2

./configure \
  --enable-shared \
  --enable-gpl \
  --enable-libx264 \
  --enable-libaom \
  --enable-nonfree

make -j8
sudo make install
sudo ldconfig

FFmpegインストール先はデフォルトの/usr/localにしています。また、ここではGPLとなることは気にせず、さらにH.264、AV1を使えるようにしたオプションにしています(実際に使うときのオプションは用途に応じて各自でカスタムしてください)。

3.1.3 FFmpeg動作確認

FFmpegの各コンポーネントバージョンを確認します。

$ ffmpeg -version
ffmpeg version n5.0.2 Copyright (c) 2000-2022 the FFmpeg developers
built with gcc 11 (Ubuntu 11.3.0-1ubuntu1~22.04)
configuration: --enable-shared --enable-gpl --enable-libx264 --enable-libaom --enable-nonfree
libavutil      57. 17.100 / 57. 17.100
libavcodec     59. 18.100 / 59. 18.100
libavformat    59. 16.100 / 59. 16.100
libavdevice    59.  4.100 / 59.  4.100
libavfilter     8. 24.100 /  8. 24.100
libswscale      6.  4.100 /  6.  4.100
libswresample   4.  3.100 /  4.  3.100
libpostproc    56.  3.100 / 56.  3.100

また、

$ ffmpeg -codecs

でH.264、AV1が含まれていることを確認しました。

3.2 OpenCVビルド

以下のコマンドを実行してOpenCVをビルドします。ここでは-D OPENCV_FFMPEG_USE_FIND_PACKAGE=ONとしています(「3.4 OPENCV_FFMPEG_USE_FIND_PACKAGE」参照)。

git clone https://github.com/opencv/opencv.git
cd opencv
git checkout 4.6.0
mkdir build
cd build
cmake -D CMAKE_BUILD_TYPE=Release -D WITH_FFMPEG=ON -D OPENCV_FFMPEG_USE_FIND_PACKAGE=ON -D BUILD_TESTS=OFF -D BUILD_PERF_TESTS=OFF -D BUILD_opencv_calib3d=OFF -D BUILD_opencv_dnn=OFF -D BUILD_opencv_features2d=OFF -D BUILD_opencv_flann=OFF -D BUILD_opencv_gapi=OFF -D BUILD_opencv_ml=OFF -D BUILD_opencv_objdetect=OFF -D BUILD_opencv_photo=OFF -D BUILD_opencv_stitching=OFF -D BUILD_opencv_video=OFF ..
make -j8
sudo make install
sudo ldconfig

OpenCVインストール後、libopencv_videoio.soが今回ソースビルドしたFFmpegをリンクしているのか確認します。

$ ldd /usr/local/lib/libopencv_videoio.so  
	linux-vdso.so.1 (0x00007ffce2995000)
	libopencv_imgcodecs.so.406 => /usr/local/lib/libopencv_imgcodecs.so.406 (0x00007efe0dcf3000)
	libopencv_imgproc.so.406 => /usr/local/lib/libopencv_imgproc.so.406 (0x00007efe0c168000)
	libopencv_core.so.406 => /usr/local/lib/libopencv_core.so.406 (0x00007efe0b16f000)
	libavcodec.so.59 => /usr/local/lib/libavcodec.so.59 (0x00007efe09e2d000)
	libavformat.so.59 => /usr/local/lib/libavformat.so.59 (0x00007efe09bc8000)
	libavutil.so.57 => /usr/local/lib/libavutil.so.57 (0x00007efe09a1a000)
	libswscale.so.6 => /usr/local/lib/libswscale.so.6 (0x00007efe09985000)
	libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007efe09753000)
	<中略>

/usr/local/lib以下にある今回ソースビルドしたFFmpeg(libavcodec、libavformatなど)をリンクしていることがわかります。

3.3 動作確認

以下のスクリプトを実行して動画ファイルのキャプチャができることを確認しました。
(テストデータはhttps://github.com/opencv/opencv/blob/4.6.0/samples/data/vtest.aviを使用)

import cv2

def main():
    capture = cv2.VideoCapture("vtest.avi")
    if not capture.isOpened():
        raise IOError("can't open capture!")

    while True:
        result, image = capture.read()
        if result is False:
            cv2.waitKey(0)
            break

        cv2.imshow("image", image)
        key = cv2.waitKey(10)
        if key == ord('q'):
            break

    cv2.destroyAllWindows()


if __name__ == '__main__':
    main()

また、OpenCVのAV1テストデータhttps://github.com/opencv/opencv_extra/blob/4.6.0/testdata/highgui/video/sample_322x242_15frames.yuv420p.libaom-av1.mp4も再生できることを確認しました。

3.4 OPENCV_FFMPEG_USE_FIND_PACKAGEとは

「3.2 OpenCVビルド」でも少し出てきましたが、OPENCV_FFMPEG_USE_FIND_PACKAGEは、CMakeのfind_packageを使ってFFmpegを探索するCMakeオプションです。https://github.com/opencv/opencv/pull/11636で追加されています。

4. Appendix:FFmpegインストールパスのカスタム

4.1 FFmpegのインストール

「3.1.2 FFmpegのインストール」ではFFmpegのインストールパスをデフォルトの/usr/localとしていましたが、./configure--prefix=でFFmpegのインストールパスをカスタムすることができます。
https://github.com/FFmpeg/FFmpeg/blob/n5.0.2/configure#L83

以降、FFmpegのインストールパスを$HOME/dev/ffmpegにしたものとして説明します。

4.2 パス設定

FFmpegのインストール後、以下のパスを設定します。PKG_CONFIG_PATHの設定はOpenCVビルド時に必要になります。

export PATH="$HOME/dev/ffmpeg/bin:$PATH"
export LD_LIBRARY_PATH="$HOME/dev/ffmpeg/lib:$LD_LIBRARY_PATH"
export PKG_CONFIG_PATH="$HOME/dev/ffmpeg/lib/pkgconfig:$PKG_CONFIG_PATH"

4.3 OpenCVビルド

「3.2 OpenCVビルド」の手順と同様です。OpenCVインストール後、lddコマンドで依存関係を確認します。/home/opencv/dev/ffmpeg/lib以下にあるライブラリをリンクしていることがわかります。

$ ldd /usr/local/lib/libopencv_videoio.so  
	linux-vdso.so.1 (0x00007fff7d959000)
	libopencv_imgcodecs.so.406 => /usr/local/lib/libopencv_imgcodecs.so.406 (0x00007f83e490a000)
	libopencv_imgproc.so.406 => /usr/local/lib/libopencv_imgproc.so.406 (0x00007f83e2d7f000)
	libopencv_core.so.406 => /usr/local/lib/libopencv_core.so.406 (0x00007f83e1d86000)
	libavcodec.so.59 => /home/opencv/dev/ffmpeg/lib/libavcodec.so.59 (0x00007f83e0a44000)
	libavformat.so.59 => /home/opencv/dev/ffmpeg/lib/libavformat.so.59 (0x00007f83e07dd000)
	libavutil.so.57 => /home/opencv/dev/ffmpeg/lib/libavutil.so.57 (0x00007f83e0631000)
	libswscale.so.6 => /home/opencv/dev/ffmpeg/lib/libswscale.so.6 (0x00007f83e059c000)
	libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f83e036a000)
	<中略>

5. 動作確認環境

  • Ubuntu 22.04
  • OpenCV 4.6.0
  • FFmpeg n5.0.2

6. おわりに

この記事ではソースビルドしたFFmpegをOpenCVのvideoioモジュールで使用する方法を紹介しました。明日のOpenCV Advent Calendar 2022fukushima1981さんの「facebookのキャリブレーションパターン検出器の精度はOpenCV実装よりも高い」です。

参考URL

16
8
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
8