玩式草子─ソフトウェアとたわむれる日々

第20回Linuxとマルチメディア環境その2]

前回作業用のBGMが欲しくてMPlayerをビルドした話を紹介しました。その際見たように、MPlayerは外部のソフトウェアが無くても主要なCODECには自前で対応しており、単独でMP3ファイルやYouTubeの動画ファイルなどを再生することができました。

その後、MPlayerのビルド時に不足を指摘されたソフトウェアを用意しつつ、MPlayer以外のマルチメディアプレイヤーをあれこれビルドしてみたところ、使っているだけでは気づかないそれぞれのマルチメディアプレイヤーの設計方針の違いに気づかされることになりました。

通常、マルチメディアプレイヤーの評価というと、対応しているCODECの多寡や機能の豊富さが中心になりがちですが、設計方針の違いという視点から眺めるとまた別の特徴が見えてくることでしょう。

Plamo Linux上のマルチメディアプレイヤー

最近では多数のマルチメディアプレイヤーがオープンソースソフトウェア(OSS)として公開されていますが、Plamo Linuxでパッケージとして含めているマルチメディアプレイヤーはMPlayerxineVLCtotemといったところです。ChangeLogファイルを調べてみると、MPlayerが2004年、xineが2005年、totemが2006年、VLCが2007年にそれぞれパッケージを登録していました。

以下に各メディアプレイヤーの特徴を簡単に紹介しましょう。

MPlayer

MPlayerは元々ハンガリーで開発が始まったメディアプレイヤーです。前回も紹介したように、MPlayerはLinuxのみならず、WindowsやMacOSでも動作するマルチプラットフォームなソフトウェアを目指して、CUIとして起動する本体部分とそれを操作するためのGUI部分が分離され、開発の中心はCUIとして起動する本体部分になっています。

前回、ほとんど外部ソフトウェアが無い状態でもMPlayerはビルドでき、MP3形式の音声ファイルやMPEG4形式の動画ファイルが再生できることを紹介しました。このような特徴を実現するために、MPlayerではOSSとして公開されている必要な機能のソースコードを積極的に自身の中に取り込む設計になっています。

以下はMPlayerのソースコードを展開した直下のディレクトリです。

 $ ls
 AUTHORS             cfg-mencoder.h     drivers/          libmenu/      mencoder.h  osdep/            snapshot_version
 Changelog           cfg-mplayer-def.h  edl.c             libmpcodecs/  metadata.h  parser-cfg.c      stream/
 Copyright           cfg-mplayer.h      edl.h             libmpdemux/   mixer.c     parser-cfg.h      sub/
 DOCS/               codec-cfg.c        etc/              libmpeg2/     mixer.h     parser-mecmd.c    subopt-helper.c
 LICENSE             codec-cfg.h        ffmpeg/           libvo/        mp3lib/     parser-mecmd.h    subopt-helper.h
 ...
 av_opts.c           configure*         libao2/           m_property.h  mpbswap.h   playtreeparser.c  xvid_vbr.h
 av_opts.h           cpudetect.c        libass/           m_struct.c    mpcommon.c  playtreeparser.h
 bstr.c              cpudetect.h        libdvdcss/        m_struct.h    mpcommon.h  pnm_loader.c
 bstr.h              cpuinfo.c          libdvdnav/        mangle.h      mplayer.c   pnm_loader.h
 cfg-common.h        debian/            libdvdread4/      mencoder.c    mplayer.h   rpm/

ここにあるファイルのうち、たとえばlibdvdcssディレクトリには後述するVLCの開発元であるVideoLanプロジェクトが開発しているlibdvdcssパッケージのソースコードが含まれており、その旨はファイルの先頭部分のコメントにも明示されています。

 $ head libdvdcss/libdvdcss.c

 /* libdvdcss.c: DVD reading library.
  *
  * Authors: Stephane Borel <stef@via.ecp.fr>
  *          Sam Hocevar <sam@zoy.org>
  *          Hakan Hjort <d95hjort@dtek.chalmers.se>
  *
  * Copyright (C) 1998-2008 VideoLAN
  * $Id: libdvdcss.c 31883 2010-08-01 13:52:17Z reimar $
  *
  * This library is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.

また、ffmpegディレクトリにはffmpegプロジェクトが開発しているコードが、READMEやCREDITS、ライセンス文書なども含めて、ほぼそのまま収められています。

 $ ls ffmpeg/
 COPYING.GPLv2     Changelog    Makefile                common.mak  ffplay.c    libavcodec/   libavutil/    tools/
 COPYING.GPLv3     Doxyfile     README                  config.mak  ffpresets/  libavcore/    libpostproc/  version.sh*
 COPYING.LGPLv2.1  INSTALL      cmdutils.c              configure*  ffprobe.c   libavdevice/  libswscale/
 COPYING.LGPLv3    LICENSE      cmdutils.h              doc/        ffserver.c  libavfilter/  subdir.mak
 CREDITS           MAINTAINERS  cmdutils_common_opts.h  ffmpeg.c    ffserver.h  libavformat/  tests/

もちろん、改造や再配布が自由なOSSでは他のプロジェクトのソースコードを再利用することは問題にはなりませんが、後述するようにMPlayerの開発者たちは明確な意図を持ってこのような構成にしているようです。

xine

xineもMPlayer同様、2000年ごろから開発が始まった古参のメディアプレイヤーです。MPlayerが元々ハンガリーを中心に開発が始まったのに対し、xineはドイツで行われたLinuxイベントをきっかけに、当時のLinux上でのDVDの扱いが大変だったことを改良するためのプロジェクトとして始まり、後にはDVDに限らず、さまざまなマルチメディアデータを再生できるメディアプレイヤーに発展していきました。

図1 xineの画面
図1 xineの画面

xineの特徴は、実際にマルチメディアデータを処理するバックエンド部xine-libとユーザインターフェース部xine-uiが分離され、それぞれが独立したソフトウェアとして開発されていることです。開発の軸足はバックエンド部のxine-libに置かれ、"lib"という名称どおり、さまざまなマルチメディアデータを処理する機能をライブラリとして提供しています。

xine-libのソースコードには、それぞれのCODECを処理する機能がライブラリ化されて収録されています。xine-libでも動画CODECの多くをffmpegを使って処理しますが、MPlayerとは異なり、ffmpegもライブラリ(libffmpeg)化された形で収められています。

 $ ls src/
 Makefile.am  demuxers/  libdts/     libmpeg2/     libspucc/    libspuhdmv/   libxinevdec/  xine-utils/
 Makefile.in  dxr3/      libfaad/    libmpeg2new/  libspucmml/  libsputext/   post/
 audio_out/   input/     libffmpeg/  libmusepack/  libspudec/   libw32dll/    video_out/
 combined/    liba52/    libmad/     libreal/      libspudvb/   libxineadec/  xine-engine/

これらのディレクトリに含まれるソースコードは、MPlayer同様、他のOSSプロジェクトが開発したコードを流用しています。

なお、MPlayerが内蔵しているffmpegのコードはffmpegの最新版に近いようですが、xine-libが内蔵しているffmpegのコードはかなり古いバージョンのままになっていて、xine-libでは外部のffmpegライブラリを使うことを推奨しています。

VLCメディアプレイヤー

VLCメディアプレイヤーは、もともとフランスのエコール・サントラル・パリ校で、校内のネットワーク上にビデオストリーミング・サービスを提供するVideoLanプロジェクトのクライアントVideoLan Client)として開発されたソフトウェアです。後にはVideoLanプロジェクトとは独立したマルチメディアプレイヤーとして成長していきますが、もともとの由来がクライアント用ソフトウェアだったこともあって、GUIなユーザインターフェースも重視した作りになっています。

図2 vlcの画面
図2 vlcの画面

一方、ソースコード的に見ると、VLCはMPlayerやxineとは異なり、各種CODECを処理する機能は外部ソフトウェアを積極的に利用するように設計されていて、VLC自身にはそれらのライブラリを利用するためのコードしか存在しません。

たとえば、MPlayerやxineではffmpegのコードを自身に含んでいましたが、VLCではmodules/codec/avcodec/avcodec.cというコードで、ffmpegが提供する外部のlibavcodecライブラリを使うような設計になっています。

 $ less modules/codec/avcodec/avcodec.c

 *****************************************************************************
  * avcodec.c: video and audio decoder and encoder using libavcodec
  *****************************************************************************
  * Copyright (C) 1999-2008 the VideoLAN team
  * $Id: 7313a9b503291939af63bb02bd9eb16b2560841b $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *          Gildas Bazin <gbazin@videolan.org>
  *
  * This program is free software; you can redistribute it and/or modify
 ...

libavcodecライブラリはバージョンによって機能の違いがあるため、このコードにはlibavcodecのバージョンをチェックしてあまりに古いバージョンならばエラー終了するような部分もありました。

 if LIBAVCODEC_VERSION_INT < AV_VERSION_INT( 51, 48, 0 )
 #   error You must update libavcodec to a version >= 51.48.0
 #elif LIBAVCODEC_VERSION_INT < AV_VERSION_INT( 52, 25, 0 )
 #   warning You should update libavcodec to get subtitle support
 #endif

VLCのmodules/codecディレクトリには以下のようなファイルがありますが、これらはそれぞれ外部のライブラリを利用するためのコードになっていて、実際のマルチメディアデータの処理は外部のライブラリに委ねています。

 $ ls modules/codec/
 Makefile.am  aes3.c    cvdsub.c  fake.c        libmpeg2.c    quicktime.c     speex.c     twolame.c
 Makefile.in  araw.c    dirac.c   flac.c        lpcm.c        rawvideo.c      spudec/     vorbis.c
 Modules.am   avcodec/  dmo/      fluidsynth.c  mash.cpp      realvideo.c     subtitles/  wmafixed/
 a52.c        cc.c      dts.c     invmem.c      mpeg_audio.c  schroedinger.c  svcdsub.c   x264.c
 a52.h        cc.h      dvbsub.c  kate.c        omxil/        sdl_image.c     telx.c      zvbi.c
 adpcm.c      cdg.c     faad.c    libass.c      png.c         shine/          theora.c

このような設計にした結果、VLCでは外部ライブラリへの依存性が高くなり、それらの存在しない環境ではビルドできません。

 $ ./configure
 checking build system type... x86_64-unknown-linux-gnu
 checking host system type... x86_64-unknown-linux-gnu
 ...
 checking for mad.h... no
 configure: error: Could not find libmad on your system: you may get it from http://www.underbit.com/products/mad/.\
 Alternatively you can use --disable-mad to disable the mad plugin.

この例ではMPEG形式のオーディオファイルを処理するlibmadが無い、というエラーでconfigureスクリプトが終了しています。表示にあるように--disable-madを指定すればlibmad無しでもビルドできそうですが、MPEG形式のオーディオファイルを処理できないとDVDの再生等に不具合が出そうです。

Totem/GStreamer

Plamoで採用しているもう1つのマルチメディアプレイヤーはTotemですが、以前にも紹介したように、Totemはマルチメディアプレイヤーではあるものの、自身ではマルチメディアデータを処理する機能は持たず、GStreamerが提供するマルチメディアフレームワークを利用しているので、今回は実際のマルチメディア処理機能を提供しているGStreamerを見てみます。

GStreamerはGNOMEプロジェクトが採用しているマルチメディアフレームワークで、さまざまな種類のマルチメディアデータを処理する機能をプラグイン可能なライブラリ群として提供し、適切なライブラリを組み合わせて必要な処理を実行するような設計になっています。

マルチメディアデータの処理機能をライブラリとして提供するという目的は先に紹介したxine-libと共通しますが、主要な処理機能は自ら提供するxine-libとは異なり、GStreamerでは外部のライブラリをプラグインとして利用するためのラッパー機能を提供して、実際のデータ処理は外部のライブラリに委ねています。

「実際の処理は外部のライブラリに委ねる」と言うと、ライブラリの呼び出しルーチンだけを用意すればいいように聞こえるかも知れませんが、開発者が世界中に散らばり、仕様やそれぞれの設計方針、コーディングスタイル、リリース頻度などが千差万別なOSSの場合、必要なライブラリを統一的に扱えるようにするのは並大抵のことではありません。

そのため、GStreamerでは、全体の基盤となる部分gstreamer⁠、各種プラグインが共通に使う部分gst-plugins-base⁠、メンテナンスが行き届いているプラグインの部分gst-plugins-good⁠、そこまではきちんとメンテナンスできていない部分gst-plugins-bad⁠、メンテナンスはできているものの、ライセンス条件や特許がらみの問題がありうる部分gst-plugins-ugly⁠、ffmpegをプラグインとして取り込んだ部分gst-plugins-ffmpeg等にソースコードを分割し、それぞれに異なるペースで開発を進めています。

このうち、機能が最も豊富なgst-plugins-badのconfigureスクリプトを動かすと、以下のような結果となりました。

 ./configure
 checking for a BSD-compatible install... /usr/bin/install -c
 checking whether build environment is sane... yes
 ...
 configure: *** checking feature: alsa plug-ins ***
 configure: *** for plug-ins: gstalsa ***
 checking for ALSA... yes
 configure: *** These plugins will be built: gstalsa
 
 configure: *** checking feature: ASS/SSA renderer ***
 configure: *** for plug-ins: assrender ***
 checking for ASSRENDER... no
 no
 configure: *** These plugins will not be built: assrender
  ...
 configure: *** Plug-ins with dependencies that will be built:
         apexsink
         bz2
         cog
         dvb
         exif
 ...
 configure: *** Plug-ins with dependencies that will NOT be built:
         acm
         amrwbenc
         assrender
         cdaudio
 ...

GStreamerの場合、各機能をプラグインライブラリとして提供するため、たとえばDVDの再生に必須の外部ソフトウェアが欠けていたとしても、VLCのようにエラー終了しないようになっていますが、その反面、ビルドはできても必要な機能が正しく組み込まれているかはわからないので、configureのログ等をチェックすることが必要になります。

設計思想から見た各マルチメディアプレイヤーの比較

以上、4種のマルチメディアプレイヤーについてソースコードの構成やビルドする際の特徴を比較してみましたが、こうやって眺めてみると、大きく2つの軸から整理することができそうです。

そのひとつは外部ソフトウェアへの依存性です。MPlayerやxineでは重要な機能は自身に取り込んで外部ソフトウェアへの依存性を減らし、外部ソフトウェアが十分揃っていない環境でも動作できることを重視しているのに対し、VLCやGStreamerではCODEC処理等は外部ソフトウェアに任せ、自らはそれら外部ソフトウェアとは異なる新しい機能を提供することに主眼が置かれています。

MPlayerやxineのように外部のソフトウェアを取り込んで主要な機能を自前で用意するようにすれば、それらソフトウェアがバージョンアップされてAPI等が変更になってもその影響をこうむることは無くなるものの、古いバージョンのコードを使いがちになるので新機能や性能向上などの恩恵を受けにくくなります。

共有ライブラリを使って外部のソフトウェアを積極的に使っているVLCやGStremerはこの逆で、外部のソフトウェアがバージョンアップされて性能が向上すれば、それはそのままVLCやGStreamerの性能向上につながりますが、バージョンアップによってAPI等が変更されれば、変更に追従しない限り、それらのソフトウェアを利用できなくなります。

このような特徴のため、MPlayerやxineは古くから安定に動作していたのでPlamo Linuxでも早めに取り込めたのに対し、VLCやGStreamerはそれらを支えるマルチメディア用ソフトウェア群が充実、安定してきてやっとその実力を発揮できようになってきました。

もうひとつの軸は単体として動くかライブラリとして働くかで、MPlayerやVLCがメディアプレイヤーとして動作することを目的としているのに対し、xine(-lib)やGStreamerでは、他のソフトウェアがマルチメディアデータを利用する際に必要な機能をライブラリとして提供することを主目的として開発されています。

上述のように、totemはGStreamerが提供する機能の上に構築されていますし、gxineやxine-ui,kaffeineなどxine-libが提供する機能の上に構築されているメディアプレイヤーもあります。また、最近のKDEではPhononというマルチメディア用フレームワークを採用しており、このPhononのバックエンドではGStremerとxineの双方を切り替えて使うことが可能です。

この2つの軸を元に、各プロジェクトの特徴を示してみると図3のような関係になるでしょう。

図3 各マルチメディアプレイヤー(ライブラリ)の位置付け
図3 各マルチメディアプレイヤー(ライブラリ)の位置付け

このように比較してみると、⁠マルチメディアデータを再生する」という機能的には重なるものの、その機能をそれぞれに異なる設計思想から提供している各プロジェクトの存在理由を改めて認識できました。一時期はPlamo Linux用のマルチメディアプレイヤーはどれかに統一しようかとも考えていましたが、やはりこれら4種は共存させておいた方がよさそうです。

おすすめ記事

記事・ニュース一覧