libavをCから使う
なぜ?
え?
必要なものがわからない
とりあえず実験用のDockerコンテナを用意しましょう
試したいのは次のもの
ffmpeg
libav
x264
目的は、なんだろう
デコードの流れが分かっていない
WebCodecs自体が、個々のライブラリの違いを吸収してしまっているので
となると、考えるべきはx264なのか
いや、x264はデコーダーは含んでない
やっぱりlibavじゃないか・・・
結論を先に
結論を先に言わない人は嫌われるからね
次の工程です
1. Dev Containerを作る
2.
$ apt install libavcodec-dev
3.
作業工程は次のよーになるでしょーか??
やっぱこれだね
ホストマシンであるWindowsの方は「普通に」ffmpegを使いたい
2. DevContainerのコンテナにffmpegのソースをcloneする
3. ビルドする
ここらへんよくわからない
こういうことするの初めてだから
必要なのか?
普通にffmpegをインストールするだけだと使えないのかな?
そもそもなんでC言語でincludeできるのはなんで?
dllってなんでしたっけ?
ffmpegをダウンロードすると、実行可能ファイルがダウンロードされる気がするんですけど
.hファイルはどこから来るの?
あ、普通は .h ファイルをダウンロードできないから、ソースをダウンロードする必要があるのかな
ライブラリとして使う分には、gccの-Iオプションや-lオプションでffmpeg内のファイルを読み込んでコンパイルすればOK。
スタンドアロンなffmpegを使いたいときはffmpegのファイルのみでビルドを行う。
4. libavcodecをincludeしてコンパイルできることを確認する
作業記録
記録を取っておかないと未来の自分が怒るので
怒らないよ?
環境
Windows11
Docker Desktop
Visual Studio Code
1. DevContainerを作る
1. Docker Desktopを起動する
重いよね
Firefox落ちそう
あ、あかん感じや・・・!
ガックガク
2. VSCodeのDockerタブを開く
そもそもなんでDockerタブがあるんだっけ?
セットアップしたのがかなり前だから忘れた
Docker Desktopを起動する前に開いてた場合は、Docker Desktopの起動を確認したらリロードするボタンを押します
https://scrapbox.io/files/642a6922c33e6d001be8f8d6.png
こうなってますね
3. DevContainerをカレントディレクトリにセットアップする
Dockerタブの「CONTAINERS」パネルの見出し部をホバーしてみてくださいな
https://scrapbox.io/files/642a69752fd2f9001ce939df.png
New Dev Container ボタンを押します
https://scrapbox.io/files/642a7054ceef88001cd8f809.png
今回は既にContainerを作成したいディレクトリを開いています
なので「Open Current Folder in Container」を選びます
https://scrapbox.io/files/642a6a58ba5f8f001b831882.png
下にスクロールしてUbuntuを選びます
特に理由はありません
ありませんよ
バージョンは既定値となっているものを選びました
https://scrapbox.io/files/642a712abe86ef001bfc49c4.png
なんかある
ffmpeg(via apt-get)を選択して、「OK」
Starting Dev Container....
時間がかかります
コンテナが本当に起動したのか分かりにくいんですよね
起動できた
2. ffmpegのclone
これは、もういいのかな?
あ
Dev Container、ヨクワカリマセン
$ cd /
でルートディレクトリに移動
関連しそうなファイルを見つけたい
/usr/share/ffmpeg
よくわからないので実行されたコマンドを読む
ffmpeg(via apt-get)はこれ
・・・?
$ dpkg -L ffmpeg
code: out_1.txt
/.
/usr
/usr/bin
/usr/bin/ffmpeg
/usr/bin/ffplay
/usr/bin/ffprobe
/usr/bin/qt-faststart
/usr/share
/usr/share/doc
/usr/share/doc/ffmpeg
/usr/share/doc/ffmpeg/README.Debian
/usr/share/doc/ffmpeg/RELEASE_NOTES
/usr/share/doc/ffmpeg/TODO.Debian
/usr/share/doc/ffmpeg/copyright
/usr/share/ffmpeg
/usr/share/ffmpeg/ffprobe.xsd
/usr/share/ffmpeg/libvpx-1080p.ffpreset
/usr/share/ffmpeg/libvpx-1080p50_60.ffpreset
/usr/share/ffmpeg/libvpx-360p.ffpreset
/usr/share/ffmpeg/libvpx-720p.ffpreset
/usr/share/ffmpeg/libvpx-720p50_60.ffpreset
/usr/share/lintian
/usr/share/lintian/overrides
/usr/share/lintian/overrides/ffmpeg
/usr/share/man
/usr/share/man/man1
/usr/share/man/man1/ffmpeg-all.1.gz
/usr/share/man/man1/ffmpeg-bitstream-filters.1.gz
/usr/share/man/man1/ffmpeg-codecs.1.gz
/usr/share/man/man1/ffmpeg-devices.1.gz
/usr/share/man/man1/ffmpeg-filters.1.gz
/usr/share/man/man1/ffmpeg-formats.1.gz
/usr/share/man/man1/ffmpeg-protocols.1.gz
/usr/share/man/man1/ffmpeg-resampler.1.gz
/usr/share/man/man1/ffmpeg-scaler.1.gz
/usr/share/man/man1/ffmpeg-utils.1.gz
/usr/share/man/man1/ffmpeg.1.gz
/usr/share/man/man1/ffplay-all.1.gz
/usr/share/man/man1/ffplay.1.gz
/usr/share/man/man1/ffprobe-all.1.gz
/usr/share/man/man1/ffprobe.1.gz
/usr/share/man/man1/qt-faststart.1.gz
/usr/share/doc/ffmpeg/changelog.Debian.gz
なんか、色々入ってますね
/usr/share/man/man1/ffmpeg-all.1.gzを見に行きましょう
なんもなかった
これ、ヘルプじゃない?
普通に/usr/bin/にあった・・・
ディレクトリの役割を忘れちゃったね
4-1. #includeできる?
無理だね
たぶんね
そもそもincludeするファイルがないので・・・・
2-2. ffmpegをclone
やっぱり必要でしたかね
$ ffmpeg
code: ffmpeg-out.txt
ffmpeg version 4.4.2-0ubuntu0.22.04.1 Copyright (c) 2000-2021 the FFmpeg developers
built with gcc 11 (Ubuntu 11.2.0-19ubuntu1)
configuration: --prefix=/usr --extra-version=0ubuntu0.22.04.1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64
/usr/include/x86_64-linux-gnu ってどう使う?
見てきたけど、特にffmpegのファイルはなかった
/usr/lib/x86_64-linux-gnu には libavcodec.so.58, libavfilter.so.7 みたいなファイルが、全てあった
soってなんでしたっけ?
どうやってincludeする?
/usr/include/x86_64-linux-gnuってそもそも何?
libとinclude、bin、何が違う?
lib
include
/usr/includeは、#includeで探索される。
bin
/usr/include/x86_64-linux-gnu/a.out.hって何?
include時にはどう探索が行われ、どのような名前でのincludeが認められるのか?
よくわからないな
候補
Iオプション
Iオプションを使うと、指定されたディレクトリ以下のファイルがまるごと展開されるような見た目の挙動をしたなあ
/usr/include
カレントディレクトリ(#include ""で指定した場合)
ちなみに <hoge/huga/hoge>みたいな感じのincludeはあり得る?
どこ基準のパスなんだろうね
lオプションって何?
多分、/usr/lib/lib〇〇.soとなっているファイルの「〇〇」部分の名前を使ってshared objectをリンクするためのもの、なのか?
リンクってなんでしたっけ
言葉がふわふわしてる
この辺の話はちょうど1ヶ月前に別件で調べたはずなのに、すっかり忘れてる
え、なんで?
なんで忘れてるの?怖い
病気かな
メモ:
一回今までのを
$ sudo apt remove ffmpeg
して、
$ sudo apt install libavcodec-dev
とか
$ sudo apt install libavformat-dev
とかした
すると、
$ dpkg -L libavcodec-dev
で、/usr/include/x86_64-linux-gnu/libavcodec-devと表示されたので、見に行ったらたしかにこのディレクトリに入ってた
さっきはffmpegの類いは入ってなかったはず
普通にffmpegを入れてもinclude用のファイルは入らないってこと?
疑問:dev版のパッケージじゃなかったらどうなるんだ?
dev版だからヘッダーファイルが含まれたのか、それともffmpegではなくlibavcodecだったから含まれたのか。
検証
1.
$ sudo apt remove libavcodec-dev
2. /usr/include/x86_64-linux-gnuで
$ ll
3.
$ sudo apt install libavcodec
4.
$ ll
問題
libavcodecは無い
libavcodec59は無い
なんで?
libavcodec58はある
検証【2】
1.
$ apt install libavcodec58
時間かかったけど完了した
/usr/lib/x86_64-linux-gnu/にlibavcodec.soが入ったことを確認した
/usr/includeは空だった(自分の目が正しければ)
2. コンテナ消去★
寒いよ、黙ってくれや
3.
$ apt install libavcodec-dev
この場合もlibにはsoファイルがある
/usr/includeにx86_64-linux-gnuができてる!
/usr/include/x86_64-linux-gnu/libavcodec/...の各種ファイルもある!
結果
通常の方だと lib だけダウンロードされる
これでもコンパイルの話を抜きにすればリンクはできるので問題ないのか?
dev版だと install にヘッダーファイルがダウンロードされる
これを使えばコーディングが可能だね
オブジェクトファイルを生成したあとは不要かな?
疑問:develって何?
ほんまごめん、これUbuntuのバージョンだ
ffmpegにdevelみたいな版があるのかとおもっちった
よし
今後は、libavのdev版を使う方向で進めていこう
問題は1つ
どのようにincludeするのか
そもそも、コンパイル時に問題があるのか、それともエディタ側だけでエラーが出ているのか、どっちなのか?
VSCodeにincludePathを指定するオプションあったっけ?
お、VS Codeでもincludeできました!
#include <libavcodec/avcodec.h>右クリック -> Go to Definitionでちゃんと/usr/include/x86_64-linux-gnu/libavcodec/avcodec.h に飛べた!
!?!?
gccのリンクで詰まってたんだけど、エラーが出てた
$ gcc -I/usr/include/x86_64-linux-gnu -lavcodec -lavutil main.c
code: error1.txt
/usr/bin/ld: /tmp/ccuUG7Hu.o: in function `main':
main.c:(.text+0xd): undefined reference to `avcodec_version'
collect2: error: ld returned 1 exit status
順番を変えた
$ gcc main.c -I/usr/include/x86_64-linux-gnu -lavcodec -lavutil
すると通った!(わあ)
試したコード
code: 1.c
int main(void) {
unsigned int version;
version = avcodec_version();
printf("%u\n", version);
printf("%u\n", LIBAVCODEC_VERSION_INT);
return 0;
}
だから、version変数の型を unsigned にしたり、
printfの指定子を %u に変えたり、
同値と思われる定数を表示してみたりしたが、変わらず。
24ビット整数を8ビットずつ使って、メジャーバージョン、マイナーバージョン、マイクロバージョンをそれぞれ表現しているらしい。
次のようなコードをブラウザの開発者ツールで書いて確認した。
code: example.js
const n = 3835492;
(n) & 0b1111_1111; // 100
(n >> 8) & 0b1111_1111; // 134
(n >> 16) & 0b1111_1111; // 58
このことから、バージョンは58.134.100だと思われる。
Ubuntuのコンテナ作ってffmpeg入れたら確かにそうだった
$ ffmpeg
code: out_ffmpeg.txt
libavutil 56. 70.100 / 56. 70.100
libavcodec 58.134.100 / 58.134.100
libavformat 58. 76.100 / 58. 76.100
libavdevice 58. 13.100 / 58. 13.100
libavfilter 7.110.100 / 7.110.100
libswscale 5. 9.100 / 5. 9.100
libswresample 3. 9.100 / 3. 9.100
libpostproc 55. 9.100 / 55. 9.100
とりあえず、これで環境構築はOKだね
別のライブラリが必要ならその都度入れればOK
ffmpeg-devみたいの結局なかったんかなあ??