#1.はじめに
GStreamerはエレメントと呼ばれる処理ブロックを繋げてストリーミング処理をするマルチメディアフレームワークです。
ドキュメントを見ていたらfisheyeというエレメントが気になりました。文字通り魚眼化するエレメントの様ですので、これを使って遊んでみようと思います。
#2.開発環境
筆者の環境はUbuntu 20.04です。下記コマンドで、GStreamer関連ライブラリをごっそり入れます。
sudo apt-get install libgstreamer1.0-0 gstreamer1.0-plugins-base gstreamer1.0-plugins-good \
gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav gstreamer1.0-doc \
gstreamer1.0-tools gstreamer1.0-x gstreamer1.0-alsa gstreamer1.0-gl gstreamer1.0-gtk3 \
gstreamer1.0-qt5 gstreamer1.0-pulseaudio
またGStreamerアプリケーションのコンパイル用にlibtoolをインストールします。
sudo apt install libtool-bin
#3.作成するGstreamerパイプライン
今回のパイプラインで使用するエレメント説明します。
- v4l2src
- webカメラの映像取得するエレメント
- videoscale
- 取得したWebカメラの映像を縮小するエレメント
- capsfilter
- videoscaleエレメントで拡縮するサイズを指定するエレメント
- videoconvert
- ビデオのフォーマット変換を行うエレメント
- fisheye
- 魚眼化補正を行うエレメント
- ximagesink
- X11ウィンドウ上に出力するエレメント
上述のエレメントで必要十分だと思っているのですが、過不足などありましたらコメントを頂けたら幸いです。
#4.コード
#include <gst/gst.h>
#include <glib.h>
#include <stdio.h>
int main (int argc,
char *argv[])
{
GMainLoop *loop;
GstElement *pipeline, *src, *vscale, *filter, *vconv, *fish, *sink;
GstCaps *filtercaps;
/* Initialisation */
gst_init (&argc, &argv);
loop = g_main_loop_new (NULL, FALSE);
/* Create gstreamer elements */
pipeline = gst_element_factory_make("pipeline", "pipeline");
src = gst_element_factory_make("v4l2src", "src");
vscale = gst_element_factory_make("videoscale", "vscale");
filter = gst_element_factory_make("capsfilter", "filter");
vconv = gst_element_factory_make("videoconvert", "vconv");
fish = gst_element_factory_make("fisheye", "fish");
sink = gst_element_factory_make("ximagesink", "sink");
if (!pipeline || !src || !vscale || !filter || !vconv || !fish || !sink) {
g_printerr ("One element could not be created. Exiting.\n");
return -1;
}
/* Set up the pipeline */
/* we set the input web-cam to the source element */
g_object_set (G_OBJECT (src), "device", "/dev/video0", "io-mode", 0, NULL);
filtercaps = gst_caps_new_simple(
"video/x-raw",
"width", G_TYPE_INT, 480,
"height", G_TYPE_INT, 480,
NULL);
g_object_set (G_OBJECT(filter),"caps",filtercaps, NULL);
g_object_set (G_OBJECT(sink),
"sync",FALSE,
NULL);
/* we add all elements into the pipeline */
gst_bin_add_many (GST_BIN (pipeline),
src, vscale, filter, vconv, fish, sink, NULL);
/* we link all elements */
gst_element_link_many (src, vscale, filter, vconv, fish, sink, NULL);
/* Set the pipeline to "playing" state*/
gst_element_set_state (pipeline, GST_STATE_PLAYING);
/* Iterate */
g_print ("Running...\n");
g_main_loop_run (loop);
/* Out of the main loop, clean up nicely */
g_print ("Returned, stopping playback\n");
gst_element_set_state (pipeline, GST_STATE_NULL);
g_print ("Deleting pipeline\n");
gst_object_unref (GST_OBJECT (pipeline));
g_main_loop_unref (loop);
return 0;
}
#5.コンパイルと実行
下記コマンドでコンパイルし、実行ファイルを生成します。
libtool --mode=link gcc `pkg-config --cflags --libs gstreamer-1.0` -o fisheye fisheye.c
生成したファイルを実行します。
./fisheye
次のように魚眼化されます。(PCのディスプレイをwebカメラで撮影したが、魚眼化して表示されている)
近づいてカメラをのぞき込めば、玄関前に居る人みたいになります。
#6.最後に
GStreamerは現在勉強中です。また面白いエレメントがあったら遊んでみます!
ここまで読んでいただいてありがとうございます。