Table of Contents
1 はじめに
GStreamer は、パイプラインでエレメントを繋いでいく形でデーターを処理する、マルチメディアフレームワークです。この仕組み、Unix のパイプと似ていると思ったことはありませんか?
cat /tmp/a.txt | grep foo echo foo | tee /tmp/a.txt cat /tmp/a.txt /tmp/b.txt >> /tmp/c.txt
Doug McIlroy が述べたように Unix の Philosophy の1つに、"Write programs to handle text streams, because that is a universal interface." 「テキストのストリームを扱うプログラムを書こう。だってそれが共通のインターフェイスなのだから。」というのがあります。 Unix がテキストストリームを共通インターフェイスとしているパイプラインならば、GStreamer は GstBuffer を共通インターフェイスにしたパイプライン構造です。GStreamer は Multimedia Stream を扱うことに特化していますが、テキストもまたメディアデーターの1形態だとすれば テキストファイルも GStreamer でも扱えるはずです。
このシリーズでは、テキスト処理を題材に GStreamer Plugin の作成方法を紹介したいと思います。
第1回目は、おさらいという意味も含め Plugin を作成しなくてもできる cat と cp、dd、tee の紹介です。
2 cat & cp
cat a.txt
gst-launch-1.0 -q filesrc location=a.txt ! fdsink
最初は簡単に、a.txt を cat します。cat は指定されたファイルを標準出力に書き出します。GStreamer でファイルを指定するには filesrc を、標準出力を指定するには fdsink を使います。
cat a.txt | cat
gst-launch-1.0 -q filesrc location=a.txt ! identity ! fdsink
次は cat したデーターを cat に渡してみましょう。cat コマンドは、標準入力から受けたデーターをそのまま標準出力に書き出します。GStreamer では identity というエレメントがアップストリームから受けたデーターをそのままダウンストリームに渡します。identity はそのまま受け渡す以外にも いろいろ使える機能 が入っているので、マニュアルを確認してみると面白いです。
cat a.txt > b.txt; cp a.txt b.txt
gst-launch-1.0 -q filesrc location=a.txt ! filesink location=b.txt
今度は、リダイレクトしてみましょう。これは cp と同じ結果になります。標準出力ではなく、ファイルに書き出す場合は filesink を使います。
cat a.txt >> b.txt
gst-launch-1.0 -q filesrc location=a.txt ! filesink append=true location=b.txt
もちろん、追記も可能です。 filesink の append プロパティを true にします。
cat a.txt b.txt > c.txt
gst-launch-1.0 -q concat name=c ! filesink location=c.txt filesrc location=a.txt ! c. filesrc location=b.txt ! c.
cat コマンドは、複数のファイルを concat (連結) するところから名前が付きました。GStreamer にも concat するエレメントがあります。2つの filesrc で指定された a.txt と b.txt が concat エレメントによって1つになり c.txt に書き出されます。
cat *.txt > all
gst-launch-1.0 -q splitfilesrc location='*.txt' ! filesink location=all
いちいちファイルを指定するのが面倒なとき、よく wildcard 「*」を使いますよね? GStreamer でも可能です。splitfilesrc は「*」に対応しています。shellが「*」を展開しないように、シングルクオート「'」でくくってください。
cat a-01.txt a-02.txt a-03.txt > b.txt
gst-launch-1.0 -q multifilesrc location=a-%02d.txt ! filesink location=b.txt
もしファイルに連番が振られているなら multifilesrc が便利です。「%d」を使ってファイル名の連番部分を指定します。「%d」は printf() と同じ表記です。
cat a.txt > /dev/null
gst-launch-1.0 -q filesrc location=a.txt ! fakesink
出力を捨てたいときも良くありますよね。そんな時は /dev/null の代りに fakesink に捨てましょう。
cat /dev/null > a.txt
gst-launch-1.0 -q fakesrc num-buffers=0 ! filesink location=a.txt
逆にファイルを空っぽにしたいこともあります。そんな時は fakesrc を使うことができます。
3 dd
dd if=a.txt bs=1 count=1
gst-launch-1.0 -q filesrc location=/tmp/a.txt blocksize=1 num-buffers=1 ! fdsink
ddは cat と違いファイルの一部を取り出すときに良く使います。最初の1バイトだけ取り出したい時は blocksize を 1 にして num-buffers で一枚だけ取り出します。
dd if=/dev/zero bs=100 count=2
gst-launch-1.0 -q fakesrc sizetype=fixed sizemax=100 num-buffers=2 ! filesink location=/tmp/a.txt
ゼロ埋めされたファイルを作成するときも、dd は活躍します。200バイトのゼロ埋めされたファイルは、100バイトのバッファー2枚という指定でも作成できます。
4 tee
cat a.txt | tee b.txt
gst-launch-1.0 filesrc location=/tmp/a.txt ! tee name=t t.src_0 ! queue ! fdsink t.src_1 ! filesink location=/tmp/b.txt
標準出力にもファイルにも書き出したいときに tee コマンドはとても便利です。GStreamer の tee エレメントは2ストリーム以上にも対応しているので、もっと多くの場所に同時に書き出すことも可能です。
5 おわりに
このように、テキストファイルも所詮データーなので、GstBuffer に格納すれば GStreamer のパイプラインを流すことが可能です。マルチメディアデーターとテキストデーターが違う点と言えば、処理をする単位が画像や映像のフレームや音のサンプル毎ではなく、「行」毎に処理をするという点です。 grep コマンドが行毎に検索することを考えても Unixコマンドは、行を基本単位として動いています。
GStreamer には「行」という概念がありません。正確には、フレームやサンプルという概念もなく、フレームに分けるパーサーエレメントがあるだけです。つまり行毎に分けるパーサーを作れば、テキストデーターを行毎に処理できるようになります。次回は、テキストデーターを行に分ける Plugin の作成から入ってみようと思います。
No comments:
Post a Comment