試験運用中なLinux備忘録・旧記事

はてなダイアリーで公開していた2007年5月-2015年3月の記事を保存しています。

画像ビューアGImageViewにおけるxine-lib 1.2対応について(2014年10月時点)

先日PPAリポジトリ「ppa:kakurasan/unstable」のUbuntu 14.10向けのパッケージを単純に再ビルドするという形でアップロードした際、パッケージビルドの段階でエラーが発生したことによって判明したことだが、画像ビューアGImageViewで動画再生機能を利用するためのxine-libというライブラリのバージョン1.1(Debian/Ubuntuの「libxine1」)系のディストリのパッケージの提供が(Ubuntu 14.04までで)終了してしまい、依存関係が満たせなくなった。
一方で新しいxine-libのバージョン1.2(Debian/Ubuntuの「libxine2」)系はUbuntu 14.10でも利用可能となっており、こちらを利用してみることにしたのだが、そのままではうまくビルドできないことが分かった。

  1. configureスクリプトにおける検出について
  2. 最初のエラーメッセージ
  3. xine_vo_driver_t/xine_ao_driver_t型関係の対処
  4. 「undefined symbol: _」の対処(xine-lib 1.1系でも発生)
  5. 「undefined symbol: xine_gui_send_vo_data」の対処

configureスクリプトにおける検出について

$ ./configure --with-xine --prefix=[インストール先]

...

checking for XINE-LIB version >= 1.0.0... xine-config is DEPRECATED. Use pkg-con
fig instead.
xine-config is DEPRECATED. Use pkg-config instead.
xine-config is DEPRECATED. Use pkg-config instead.
xine-config is DEPRECATED. Use pkg-config instead.
xine-config is DEPRECATED. Use pkg-config instead.
xine-config is DEPRECATED. Use pkg-config instead.
xine-config is DEPRECATED. Use pkg-config instead.
xine-config is DEPRECATED. Use pkg-config instead.
xine-config is DEPRECATED. Use pkg-config instead.
xine-config is DEPRECATED. Use pkg-config instead.
yes

...

Configure Result :

   C Compiler    : gcc

   ...

   Movie Support : Xine

...

xine-configは非推奨」というメッセージが出るが、configure.ac

AM_PATH_XINE($XINE_REQUIRED,

の行を

PKG_CHECK_MODULES(XINE, libxine >= $XINE_REQUIRED,

としてpkg-configを用いた検出に置き換えることで対処すればよいとして、そのままでも一応正しく検出はされる。

最初のエラーメッセージ

下のようなメッセージ(「error:」の行がエラーメッセージ)でビルドに失敗した。

$ LC_MESSAGES=C make

...

Making all in image_view
make[3]: Entering directory `/tmp/work/gimageview-master/plugins/image_view'
/bin/bash ../../libtool  --tag=CC   --mode=compile gcc -DHAVE_CONFIG_H -I. -I../.. -pthread -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/libpng12 -I/usr/include/gtk-2.0 -I/usr/lib/x86_64-linux-gnu/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/freetype2 -I/usr/include/pixman-1 -I/usr/include/harfbuzz    -I../.. -I../../src  -DDATADIR=\""/usr/local/share/gimageview"\"  -g -O2 -Wall -MT gimv_xine.lo -MD -MP -MF .deps/gimv_xine.Tpo -c -o gimv_xine.lo gimv_xine.c
libtool: compile:  gcc -DHAVE_CONFIG_H -I. -I../.. -pthread -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/libpng12 -I/usr/include/gtk-2.0 -I/usr/lib/x86_64-linux-gnu/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/freetype2 -I/usr/include/pixman-1 -I/usr/include/harfbuzz -I../.. -I../../src -DDATADIR=\"/usr/local/share/gimageview\" -g -O2 -Wall -MT gimv_xine.lo -MD -MP -MF .deps/gimv_xine.Tpo -c gimv_xine.c  -fPIC -DPIC -o .libs/gimv_xine.o
In file included from gimv_xine.c:41:0:
gimv_xine_priv.h:91:4: error: unknown type name 'xine_vo_driver_t'
    xine_vo_driver_t        *vo_driver;
    ^
gimv_xine_priv.h:92:4: error: unknown type name 'xine_ao_driver_t'
    xine_ao_driver_t        *ao_driver;
    ^
gimv_xine.c:252:1: error: unknown type name 'xine_vo_driver_t'
 static xine_vo_driver_t *
 ^
gimv_xine.c: In function 'load_video_out_driver':
gimv_xine.c:264:4: error: unknown type name 'xine_vo_driver_t'
    xine_vo_driver_t *vo_driver;
    ^
gimv_xine.c:298:17: warning: assignment from incompatible pointer type [enabled by default]
       vo_driver = xine_open_video_driver (priv->xine,
                 ^
gimv_xine.c:308:4: warning: return from incompatible pointer type [enabled by default]
    return xine_open_video_driver (priv->xine, NULL,
    ^
gimv_xine.c: At top level:
gimv_xine.c:314:1: error: unknown type name 'xine_ao_driver_t'
 static xine_ao_driver_t *
 ^
gimv_xine.c: In function 'load_audio_out_driver':
gimv_xine.c:318:4: error: unknown type name 'xine_ao_driver_t'
    xine_ao_driver_t *ao_driver;
    ^

...

make[3]: *** [gimv_xine.lo] Error 1
make[3]: Leaving directory `/tmp/work/gimageview-master/plugins/image_view'
make[2]: *** [all-recursive] Error 1
make[2]: Leaving directory `/tmp/work/gimageview-master/plugins'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/tmp/work/gimageview-master'
make: *** [all] Error 2

xine_vo_driver_t/xine_ao_driver_t型関係の対処

xine_vo_driver_t型とxine_ao_driver_t型は、既に1.1系でも非推奨なものとされている。
[引用]ファイル名: xine-lib-1.1.21/include/xine.h より

#ifndef XINE_DISABLE_DEPRECATED_FEATURES
/* convenience types: simple player UIs might want to call ports drivers */
typedef xine_audio_port_t xine_ao_driver_t XINE_DEPRECATED;
typedef xine_video_port_t xine_vo_driver_t XINE_DEPRECATED;
#endif

非推奨とは言え、型の名前が変えてあるだけということが分かったため、xine_video_port_tとxine_audio_port_tへそれぞれ置換してみた。

$ sed -i -e 's:xine_vo_driver_t:xine_video_port_t:g' -e 's:xine_ao_driver_t:xine_audio_port_t:g' plugins/image_view/*.*
$ make

するとビルドは無事に完了して起動はできたのだが

$ make install-strip
$ [インストール先]/bin/gimv

動画ファイルの再生を開始しようとすると

[インストール先]/bin/gimv: symbol lookup error: [インストール先]/lib/gimageview/image_view/libgimv_xine.so: undefined symbol: _

となって落ちる。この件についてはUbuntu 14.04上でxine-lib 1.1でも試したところ同様の問題が起こる(Ubuntu 14.04までのPPAのパッケージでも不具合が発生していた)ことが分かったため、1.2系特有のものではない。

「undefined symbol: _」の対処(xine-lib 1.1系でも発生)

_()はメッセージの国際化で用いられるが、本来gettext()に展開されるべきものがそのままの名前で参照している状態となっている。
試しにlibgimv_xine.soを構成するソース(plugins/image_view/Makefile.amlibgimv_xine_la_SOURCES)群の中の_()などの呼び出しを含んだソースファイル(gimv_xine_post.c,image_view_xine.c,prefs_xine.cの3つ)にGLibのglib/gi18n.hを参照するための

#include <glib/gi18n.h>

という記述を入れて再ビルド・インストールして再び試したところこの問題は解決し

[インストール先]/bin/gimv: symbol lookup error: [インストール先]/lib/gimageview/image_view/libgimv_xine.so: undefined symbol: xine_gui_send_vo_data

にメッセージが変わった。

「undefined symbol: xine_gui_send_vo_data」の対処

[引用]ファイル名: xine-lib-1.1.21/src/xine-engine/xine_interface.c より

#ifndef XINE_DISABLE_DEPRECATED_FEATURES
int xine_gui_send_vo_data (xine_stream_t *stream,
			   int type, void *data) {

  return stream->video_driver->gui_data_exchange (stream->video_driver,
						  type, data);
}
#endif

この関数も非推奨扱いとなっていたものでバージョン1.2系で消えているのだが、これはreturn文だけの関数なので、この内容を用いてplugins/image_view/gimv_xine.c内の

xine_gui_send_vo_data (priv->stream,
                       XINE_GUI_SEND_EXPOSE_EVENT, &event);

priv->stream->video_driver->gui_data_exchange (priv->stream->video_driver,
                                               XINE_GUI_SEND_EXPOSE_EVENT,
                                               &event);

のように置き換えてみた(同様の箇所が他にもう1つある)。すると

$ LC_MESSAGES=C make

...

Making all in image_view
make[3]: Entering directory `/tmp/work/gimageview-master/plugins/image_view'
/bin/bash ../../libtool  --tag=CC   --mode=compile gcc -DHAVE_CONFIG_H -I. -I../.. -pthread -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/libpng12 -I/usr/include/gtk-2.0 -I/usr/lib/x86_64-linux-gnu/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/freetype2 -I/usr/include/pixman-1 -I/usr/include/harfbuzz    -I../.. -I../../src  -DDATADIR=\""/tmp/work/prefix/share/gimageview"\"  -g -O2 -Wall -MT gimv_xine.lo -MD -MP -MF .deps/gimv_xine.Tpo -c -o gimv_xine.lo gimv_xine.c
libtool: compile:  gcc -DHAVE_CONFIG_H -I. -I../.. -pthread -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/libpng12 -I/usr/include/gtk-2.0 -I/usr/lib/x86_64-linux-gnu/gtk-2.0/include -I/usr/include/atk-1.0 -I/usr/include/cairo -I/usr/include/pango-1.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/freetype2 -I/usr/include/pixman-1 -I/usr/include/harfbuzz -I../.. -I../../src -DDATADIR=\"/tmp/work/prefix/share/gimageview\" -g -O2 -Wall -MT gimv_xine.lo -MD -MP -MF .deps/gimv_xine.Tpo -c gimv_xine.c  -fPIC -DPIC -o .libs/gimv_xine.o
gimv_xine.c: In function 'filter_xine_event':
gimv_xine.c:362:19: error: dereferencing pointer to incomplete type
       priv->stream->video_driver->gui_data_exchange (priv->stream->video_driver,
                   ^
gimv_xine.c:362:66: error: dereferencing pointer to incomplete type
       priv->stream->video_driver->gui_data_exchange (priv->stream->video_driver,
                                                                  ^
gimv_xine.c:372:19: error: dereferencing pointer to incomplete type
       priv->stream->video_driver->gui_data_exchange (priv->stream->video_driver,
                   ^
gimv_xine.c:372:66: error: dereferencing pointer to incomplete type
       priv->stream->video_driver->gui_data_exchange (priv->stream->video_driver,
                                                                  ^
gimv_xine.c: In function 'gimv_xine_size_allocate':
gimv_xine.c:679:14: warning: variable 'this' set but not used [-Wunused-but-set-variable]
    GimvXine *this;
              ^
gimv_xine.c: In function 'gimv_xine_play':
gimv_xine.c:742:2: warning: #warning FIXME [-Wcpp]
 #warning FIXME
  ^
gimv_xine.c: In function 'gimv_xine_trick_mode':
gimv_xine.c:817:4: warning: implicit declaration of function 'xine_trick_mode' [-Wimplicit-function-declaration]
    return xine_trick_mode (priv->stream, mode, value);
    ^
make[3]: *** [gimv_xine.lo] Error 1
make[3]: Leaving directory `/tmp/work/gimageview-master/plugins/image_view'
make[2]: *** [all-recursive] Error 1
make[2]: Leaving directory `/tmp/work/gimageview-master/plugins'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/tmp/work/gimageview-master'
make: *** [all] Error 2

「stream」のメンバ「video_driver」がうまく処理されていないように見える(メンバ名がコンパイラから認識されていない状態)。
まずxine_stream_t型は
[引用]ファイル名: xine.h より

typedef struct xine_stream_s xine_stream_t;

xine_stream_s型の別名となっているため、この型の構造体の定義部分を探すと
[引用]ファイル名: xine/xine_internal.h より

struct xine_stream_s {

  ...

  /* dxr3 use this one, should be possible to fix to use the port instead */
  vo_driver_t               *video_driver;

  ...

xine/xine_internal.hにあったので、このファイルを参照するようにplugins/image_view/gimv_xine.c

#include <xine.h>

の下に

#include <xine/xine_internal.h>

を付けてみたところビルドは通り、1.2系のプラグインが正しくインストールされた状態での動画再生機能が動作することも確認できた。
ただ、(バージョン1.2系に関係しているかは不明だが)ファイルの再生が最後まで終わったときなどに固まる場合があり、設定ダイアログのビデオドライバの選択によっては全く動かないこともある。再生自体も個人的にはMPlayerと比べると不安定な印象がある。


xine-lib 1.2ではVDPAU対応など大きな改善点もあるため、今回、Ubuntu 14.10向けと同時にUbuntu 14.04向けのPPAリポジトリ「ppa:kakurasan/unstable」のパッケージにもxine-lib 1.2対応の修正は追加して公開した。
パッケージ自体はかなり前のDebianのものをもとにしているため
launchpad.net/~kakurasan/+archive/ubuntu/unstable/+files/gimageview_0.3.0-0.20140905-2.debian.tar.gz
debianディレクトリの直下のファイル群は当時のパッケージ作者のライセンス(GPL-2)が適用されるが、新しく手元で作成したパッチ群(debian/patches/*.patch・本記事の内容のパッチを含む)についてはパブリックドメインとする。ただ、xine-lib 1.2対応のパッチについては、そのままの形で適用するとバージョンの非常に古いxine-libでの検出に問題が出る可能性があるため、PKG_CHECK_MODULESで検出されなかった場合に従来のAM_PATH_XINEによる検出を試す形にしたほうが本家のソースへ適用する場合には適しているかもしれない(なお、バージョン1.1系時点では.pcファイルは存在するためPKG_CHECK_MODULESによる検出は行える)。

使用したバージョン:

  • GImageView 2014/9/5版
  • xine-lib 1.1.21, 1.2.4