GStreamer概要

GStreamerと呼ばれるものがGNOME 2.2からGNOMEに含まれるようになった。このGStreamerというのはマルチメディア系のデータを扱うアプリケーションを作成する土台となるものである。ラジオをインターネット経由で聞き、音楽をオーディオテープの代わりにmp3やoggのデータに変換し、キャプチャカードで録画した番組をモニタで見る。そのような生活を送るためのアプリケーションがLinux、UNIXでもそろってきてはいるが、Windowsなどに比べればまだまだ弱い。そのような状況をなんとかしようと基礎を固めつつあるのがGStreamerだ。

GStreamerとは何か

GStreamerはGNOME2.2からGNOMEを構成するソフトウェアの一つとして、GNOMEのリリースに含まれるようになったマルチメディアのフレームワークである。GNOMEに含まれてはいるものの、GStreamerはGNOMEとは独立したプロジェクトである。GStreamerそのものは、GNOMEやKDEか、といったことには依存していないシステムだ。X11にすら依存しておらず、また、特定のOSへの依存もない。GNOMEに含まれてはいるものの、GNOMEはまだ全面的にGStreamerを活用しているわけではない。GStreamerのアーキテクチャそのものを受け入れてはいるが、GStreamer自体がまだまだ実用段階にあるわけではないので、GNOMEのアプリケーションがGStreamerを全面的に活用するのは、GNOME2.4よりはまだ後になるものと思われる。

オーディオ、ビデオ機器を考えてみよう。音楽を聴いたり記録するのであれば、マイクやCDプレイヤー、あるいは放送を受信するチューナを「入力」とし、スピーカやテープデッキといった「出力」とする。そしてアンプやイコライザーといった入力と出力の間をとりもつコンポーネント、をそろえることになるだろう。

すべてを同じメーカーでそろえずとも、同じようなコネクタやを持つ機器だったら、異なるメーカーの機器を持ってきてつなぐことができる。レコードプレイヤー、アンプ、スピーカーといった古い構成のコンポを持ってるとしよう。レコードの部分を衛星チューナーと差し替えれば、クオリティなど別にしても、すぐにでもデジタルラジオを楽しむことができる。音声を通すケーブルをつなぐコネクタは昔からそんなに変わるものではない。たとえ、形状や信号が多少異なっていても、変換アダプタを間に挟んだりすればよい。お気に入りのスピーカーを使い続けることは可能だ。

GStreamerは何か、といわれれば、オーディオ、ビデオ機器におけるコネクタの形状の規格、のようなものだ。入力の形態や出力のデバイス、データを処理するコーデックやフィルタの種類を自由に差し替えて、オーディオセットならぬアプリケーションをくみ上げることができるようにするためのフレームワーク、である。

GStreamerはなくとも音楽や動画を楽しんでいる人はUNIX環境であっても多いと思う。アプリケーションによっては「プラグイン」といった形式で、機能を拡張できることが多いし、著名なアプリケーションであればプラグインも充実している。

しかし、それらのアプリケーションが各々が独立して存在であり、アプリケーションに共通な枠組みといったものは存在していない。たとえば、なんらかの動画形式のデコーダを書いたとしよう。デコード処理をプログラミングしても、それを実際のプレイヤーアプリケーションに対応させるには、アプリケーションの種類だけ作業が必要となってしまうのが現状だ。

そういった状況を打破しようというのがGStreamerである。

コマンドラインで試してみる

プログラミングしなくても、GStreamerに付属しているサンプルアプリケーションであるgst-launchを使えばGStreamerに触れることができる。

まずは、MP3 形式の音楽データを再生してみよう。MP3のファイルであるmuisc.mp3というものがあるとして、それをOSSデバイスから出力するには、

  gst-launch filesrc location=music.mp3 ! mad ! osssink

とコマンドラインから打ち込んで実行すればよい。

このコマンドラインはGStreamerの処理単位である「エレメント」の3つ、filesrc、mad、osssink を「パイプ」で接続し、接続したもので「再生」を実行する、という意味である。エクスラメーションマーク「!」がパイプで接続することを意味する。なお、これらのエレメントはプラグインと呼ばれる動的モジュールに含まれており、実行時に動的にリンクされるようになっている。

さて、左から順に説明しよう。filesrcはlocationパラメータ(エレメントのプロパティ)で指定したローカルにあるファイルを読み込んで出力するエレメントである。

次にある madというのは MP3 形式のファイルを入力から受け取ってデコードして出力をする、つまり、MP3形式をraw pcm形式に変換するフィルタとしての動作を行うエレメントである。

最後の osssinkは入力データをOSSサウンドデバイスから出力するエレメントである。

filesrcはローカルのファイルを元にデータを発するエレメントであるが、指定したURLをネットワーク経由で読み込むエレメントもある。たとえば、HTTP上のストリームにアクセスするためのhttpsrcというエレメントもある。

また、出力にOSS(あるいはALSAのOSS互換インターフェイス)ではなく、ALSAを利用する出力エレメントである、alsasink というのもある。

filesrcのかわりにhttpsrc、osssinkのかわりにalsasinkを指定しみよう。

  gst-launch httpsrc location=http://radio.example.com/stream.mp3 ! mad ! alsasink

これにより、http://radio.example.com/stream.mp3によりアクセスできるMP3ストリームを再生し、ALSAデバイスで出力できる。

画像も扱ってみよう。単純な例としてテストパターンを生成する videotestsrcと、Xの画面への出力をおこなうxvideosinkを連結する。ちなみに音声についてもsinesrcという正弦波を出力するテストパターン的な発生エレメントもある。

  gst-launch videotestsrc ! xvideosink

画像の入力はMPEGファイルから行うこともできるし、viode4linuxなどを用いることで、チューナカードからテレビ映像を入力させたりすることもできる。現時点では画像の扱いについてはまだ安定していない。

以上、簡単にいくつか紹介したが、GStreamerで利用できるエレメントはほかにもたくさんある。どのようなものが使えるのか、についてはgst-inspectに引き数を与えずに実行してみてほしい。エレメントを提供するプラグインの名前、エレメントの名前、その説明、が表示されるはずだ。

srcとsink 二種類のpad

各エレメントがほかのエレメントと接続する部分のことをpadという。AV機器におけるコネクタに相当するものだ。そのうち、データが出力されるpadはデータの源であることから、srcと呼ばれる。データが入力されるpadはデータを流しこまれる側であることから、sinkと呼ばれる。

filesrcやsinesrcなどのようにデータの供給源となるようなものはsrcだけが存在し、osssinkやxvidsinkのようにデータを最終的にデバイスへ出力するようなものはsinkのみが存在する。

madのように、入力したデータをデコードするなどの処理を行うタイプのものはsrcとsinkの両方を持つ。

srcやsinkは一つだけでなく、複数存在することもある。たとえばmpegdemuxというエレメントはsinkから入力したMPEGファイルから動画データと音声データを分離し、音声用のsrcと動画用のsrcから別々に出力を行うことができる。逆に、複数のsinkをまとめて一つのsrcから出力するものもある。

srcやsinkはそこから入出力できるデータ形式はどのようなものか、が定義されている。srcからの出力とsinkへの入力を接続する場合、そのデータ形式が合っていないとエラーになる。

逆に、希望するデータ形式を指定すれば、どのようなsrcやsinkがあるのか、を探し出すことも可能である。

二つのbin … pipeとthread

最初のほうでgst-launchを使ってmp3プレイヤーのような動作をさせたが、その例では3つのエレメントを使って「mp3をファイルから再生する」という一つの目的を達成させた。

これは見方を変えれば、「mp3をファイルから再生する」というエレメントを作って、それを動作させた、ということにもなる。このように、パイプでつないで構成されたエレメントのかたまりを、ひとつのエレメントとみなすことができる。

複数のエレメントを固めたものをbinと呼ぶ。pipeというのはbinの一種である。

ではpipe以外にどのようなものがあるかといえば、threadがある。threadはそれ自体が一種の独立した動作単位で、同時に複数のthreadを平行して動かすことができるものである。

さて、複数のsrcまたはsinkを持つエレメントがある、と前述した。たとえば、MPEGデータを入力して、音声と動画などのデータを分離するエレメントである、mpegdemuxというものがある。mpegdemuxであれば音声と動画が別々のsrcから出力させられるが、メディアプレイヤーとして使うのであれば音声と動画は同時にそれぞれのデバイスから出力しなければならない。

このように同時に動かすための処理単位を作るのがthreadである。mp3を出力するthreadと画像データを表示するthreadを作って、それそmpegdemuxの音声srcと動画srcに接続すればメディアプレイヤを作ることができる。

例として、MPEGファイルを再生させてみよう。音声srcからの出力をmp3プレイヤーのthreadに出力させ、動画像srcからの出力をMPEG2デコーダ経由で画面に出力する。(長いので行末に \ を置いて数行に分けた)

gst-launch filesrc location=movie.mpg ! \
  mpegdemux name=demux \
     demux.video_%02d! { queue ! mpeg2dec ! xvideosink } \
     demux.audio_%02d! { queue ! mad ! alsasink }

mpegdemuxにより音声と画像を分離し、動画src(demux.video_%02d)を

{ queue ! mpeg2dec ! xvideosink }
で作成したthreadへ流し、音声src(demux.audio_%02d)を
 { queue ! mad ! alsasink }

のthreadへ流す。{ } というのはthreadを作ることを意味する。video_%02dやaudio_%02dというのは、mpegdemuxが提供する複数のsrcのうち、どのsrcを利用するのか、を指定するものである。

さいごに

実際に細かい定義やCより使用するAPI、プラグインやエレメントの書き方については、GStreamerのドキュメントのページを参照していただきたい。実際のAPIはどうなっているのか、などなど詳細なドキュメントが用意されている。

GStreamerは、GObjectシステムの継承やイントロスペクション、プロパティ、などの機能を活用しているためGObjectのマニュアル解説書も参考にしてほしい。