現状のmomoのビデオ解像度
現状のmomoではビデオ解像度として --resolution
のオプションで{4K,FHD,HD,QVGA,VGA}の5種類の解像度しか指定することができません。
864x480 とか 500x500 の指定をしたいと思ってmomoを修正してみました。
2020.1.21 追記
momoのリリース 2020.1 で任意の解像度を指定できるようになりましたので、この記事の修正は不要になりました。
WebRTC Native Client Momo 2020.1 リリースノート
追加するオプション
解像度の指定方法として--width
と --height
を追加します。
従来との互換性のために、これらの初期値は0になっていて--width
と --height
の両方を指定した時だけこちらの指定が使用され、そうでない場合は--resolution
の指定が使用されます。
また、このオプションは「この解像度をカメラに要求する」だけで、実際にどのような解像度になるかはカメラ次第です。
カメラが指定された解像度をサポートしている場合はそれが採用されますが、そうでない場合はエラー終了したり、近い解像度が選択されたりします。
実際にどのような解像度でカメラから映像を受け取っているかは配信中に別のターミナルから以下のコマンドを実行すると調べることができます。
v4l2-ctl -d /dev/videoX --all
(-d
で使用しているビデオキャプチャデバイスを指定する。)
そのビデオキャプチャデバイスで指定可能な解像度は以下のコマンドで調べることができますので、あらかじめ調べておくのがよいでしょう。
v4l2-ctl -d /dev/videoX --list-formats-ext
ソースコードの変更点
19.08.1をベースにしています。
diff --git a/src/connection_settings.h b/src/connection_settings.h
index 4b2dabb..0145e31 100644
--- a/src/connection_settings.h
+++ b/src/connection_settings.h
@@ -27,6 +27,8 @@ struct ConnectionSettings
int video_bitrate = 0;
int audio_bitrate = 0;
std::string resolution = "VGA";
+ int width = 0;
+ int height = 0;
int framerate = 30;
bool fixed_resolution = false;
std::string priority = "BALANCE";
@@ -45,6 +47,9 @@ struct ConnectionSettings
std::string ayame_signaling_key = "";
int getWidth() {
+ if (width * height != 0) {
+ return width;
+ }
if (resolution == "QVGA") {
return 480;
} else if (resolution == "HD") {
@@ -58,6 +63,9 @@ struct ConnectionSettings
}
int getHeight() {
+ if (width * height != 0) {
+ return height;
+ }
if (resolution == "QVGA") {
return 320;
} else if (resolution == "HD") {
diff --git a/src/util.cpp b/src/util.cpp
index cfd707c..3774518 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -63,6 +63,8 @@ void Util::parseArgs(int argc, char *argv[], bool &is_daemon,
local_nh.param<int>("video_bitrate", cs.video_bitrate, cs.video_bitrate);
local_nh.param<int>("audio_bitrate", cs.audio_bitrate, cs.audio_bitrate);
local_nh.param<std::string>("resolution", cs.resolution, cs.resolution);
+ local_nh.param<int>("width", cs.width, cs.width);
+ local_nh.param<int>("height", cs.height, cs.height);
local_nh.param<int>("framerate", cs.framerate, cs.framerate);
local_nh.param<int>("audio_topic_rate", cs.audio_topic_rate, cs.audio_topic_rate);
local_nh.param<int>("audio_topic_ch", cs.audio_topic_ch, cs.audio_topic_ch);
@@ -116,6 +118,8 @@ void Util::parseArgs(int argc, char *argv[], bool &is_daemon,
#endif
app.add_set("--resolution", cs.resolution, {"QVGA", "VGA", "HD", "FHD", "4K"},
"解像度");
+ app.add_option("--width", cs.width, "width of video")->check(CLI::Range(1, 4096));
+ app.add_option("--height", cs.height, "height of video")->check(CLI::Range(1, 4096));
app.add_option("--framerate", cs.framerate, "フレームレート")->check(CLI::Range(1, 60));
app.add_flag("--fixed-resolution", cs.fixed_resolution, "固定解像度");
app.add_set("--priority", cs.priority, {"BALANCE", "FRAMERATE", "RESOLUTION"},
実際にやってみて
Raspberry Pi カメラモジュール V2
3280×2464 より小さい解像度ならば任意の解像度を指定可能のようです。しかし1920x1080より大きなものは内部の処理が追いつかないようなので現実的ではありません。
ロジクール c270
v4l2-ctl -d /dev/videoX --list-formats-ext
で調べた解像度が選択可能です。
それ以外の場合はより近い解像度が選択されます。
例えば、300x300 を指定すると実際には 352x288 が選択されます。