domingo, 30 de novembro de 2008

O Lenny, o VLC e o repositório Debian-Multimedia.org

ATENÇÃO!!!
ANTES DE FAZER QUALQUER COISA LEIA ISTO, E NÃO RECOMENDO QUE USEM ESTE PROCEDIMENTO.
MANTIDO APENAS PARA REGISTRO

Para quem como eu usa o Debian Lenny, e gosta de assistir vídeos utilizando o VLC, já se deparou com problemas para reproduzir vídeos após instalar pacotes do repositório debian-multimedia.org.


O Problema


Quando você abre um video que foi encodado usando o XVID irá receber a seguinte mensagem:

VLC media player 0.8.6h Janus
[00000315] main decoder error: no suitable decoder module for fourcc `XVID'.
VLC probably does not support this sound or video format.

Então após ler e reler em vários foruns e na própria pagina do debian-multimedia.org que o problema estava nos pacotes libavc* e a solução era fazer o downgrade destes pacotes para os oficiais.
E é claro que com isso teria que remover todos os outros pacotes que dependem dele e não se encontram no repositório oficial, como o mythtv, o xdvdshrink(que ainda não testei) e o transcode.

Em busca de mais informações temos o seguinte:

$ vlc -vv --no-plugins-cache --list |grep ffmpeg
VLC media player 0.8.6h Janus
[00000001] main private debug: checking builtin modules
[00000001] main private debug: checking plugin modules
[00000001] main private debug: recursively browsing `/usr/lib/vlc'
[00000001] main private warning: cannot load module `/usr/lib/vlc/codec/libffmpeg_plugin.so' (/usr/lib/vlc/codec/libffmpeg_plugin.so: undefined symbol: img_resample)
[00000001] main private debug: module bank initialized, found 222 modules

Analisando a linha em vermelho é possível perceber que o problema ocorre quando a biblioteca libffmpeg_plugin.so tenta usar uma possível função chamada img_resample

Com isso vamos ver a dependência das bibliotecas compartilhadas:

$ ldd -r /usr/lib/vlc/codec/libffmpeg_plugin.so
linux-vdso.so.1 => (0x00007fff699fe000)
libpthread.so.0 => /lib/libpthread.so.0 (0x00002ae441454000)
libpostproc.so.51 => /usr/lib/libpostproc.so.51 (0x00002ae441670000)
libavformat.so.52 => /usr/lib/libavformat.so.52 (0x00002ae44187d000)
libraw1394.so.8 => /usr/lib/libraw1394.so.8 (0x00002ae441b17000)
libtheora.so.0 => /usr/lib/libtheora.so.0 (0x00002ae441d1d000)
libvorbisenc.so.2 => /usr/lib/libvorbisenc.so.2 (0x00002ae441f60000)
libavutil.so.49 => /usr/lib/libavutil.so.49 (0x00002ae442338000)
libvorbis.so.0 => /usr/lib/libvorbis.so.0 (0x00002ae442545000)
libogg.so.0 => /usr/lib/libogg.so.0 (0x00002ae442771000)
libm.so.6 => /lib/libm.so.6 (0x00002ae442976000)
libvlc.so.0 => /usr/lib/libvlc.so.0 (0x00002ae442bf9000)
libavcodec.so.51 => /usr/lib/libavcodec.so.51 (0x00002ae442edd000)
libc.so.6 => /lib/libc.so.6 (0x00002ae4436be000)
/lib64/ld-linux-x86-64.so.2 (0x0000555555554000)
libz.so.1 => /usr/lib/libz.so.1 (0x00002ae443a11000)
libdl.so.2 => /lib/libdl.so.2 (0x00002ae443c29000)
libhal.so.1 => /usr/lib/libhal.so.1 (0x00002ae443e2d000)
libdbus-1.so.3 => /usr/lib/libdbus-1.so.3 (0x00002ae44403e000)
librt.so.1 => /lib/librt.so.1 (0x00002ae44427c000)
libdvbpsi.so.4 => /usr/lib/libdvbpsi.so.4 (0x00002ae444485000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00002ae444690000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00002ae44499d000)
liba52-0.7.4.so => /usr/lib/liba52-0.7.4.so (0x00002ae444bb4000)
libamrnb.so.3 => /usr/lib/libamrnb.so.3 (0x00002ae444cbf000)
libamrwb.so.3 => /usr/lib/libamrwb.so.3 (0x00002ae444efe000)
libdirac_encoder.so.0 => /usr/lib/libdirac_encoder.so.0 (0x00002ae44512d000)
libfaac.so.0 => /usr/lib/libfaac.so.0 (0x00002ae4453c5000)
libfaad.so.0 => /usr/lib/libfaad.so.0 (0x00002ae4455d7000)
libgsm.so.1 => /usr/lib/libgsm.so.1 (0x00002ae445818000)
libmp3lame.so.0 => /usr/lib/libmp3lame.so.0 (0x00002ae445a25000)
libschroedinger-1.0.so.0 => /usr/lib/libschroedinger-1.0.so.0 (0x00002ae445c9e000)
libx264.so.60 => /usr/lib/libx264.so.60 (0x00002ae445f15000)
libxvidcore.so.4 => /usr/lib/libxvidcore.so.4 (0x00002ae44619a000)
liboil-0.3.so.0 => /usr/lib/liboil-0.3.so.0 (0x00002ae4464f2000)
libX11.so.6 => /usr/lib/libX11.so.6 (0x00002ae446781000)
libxcb-xlib.so.0 => /usr/lib/libxcb-xlib.so.0 (0x00002ae446a8e000)
libxcb.so.1 => /usr/lib/libxcb.so.1 (0x00002ae446c8f000)
libXau.so.6 => /usr/lib/libXau.so.6 (0x00002ae446eab000)
libXdmcp.so.6 => /usr/lib/libXdmcp.so.6 (0x00002ae4470ae000)
undefined symbol: img_resample (/usr/lib/vlc/codec/libffmpeg_plugin.so)
undefined symbol: img_resample_init (/usr/lib/vlc/codec/libffmpeg_plugin.so)
undefined symbol: img_resample_full_init (/usr/lib/vlc/codec/libffmpeg_plugin.so)
undefined symbol: img_resample_close (/usr/lib/vlc/codec/libffmpeg_plugin.so)
undefined symbol: img_convert (/usr/lib/vlc/codec/libffmpeg_plugin.so)

Parece que alguma dessas bibliotecas foi substituída com a instalação dos pacotes não-oficiais. Mas e agora qual delas está com problema? A dica veio da pagina do debian-multimedia.org:

Broken ffmpeg libraries :
Since Debian use the same soname packages name than my packages, official packages (vlc, totem, etc...) linked against libavc* doesn't work with my libavc* packages.
Então suponho que seja nosso amigo /usr/lib/libavcodec.so.51o grande problema, mas esse arquivo na verdade é um link para o arquivo /usr/lib/libavcodec.so.51.58.0


A Solução (ou seria gambiarra)

A primeira coisa que fiz foi baixar o pacote libavcodec51 no repositório oficial.

Com isso abri o pacote usando o compactador de arquivos(file-roller) dentro dele abri existe um outro arquivo chamado data.tar.gz que também abri usando
o file-roller dentro dele existe o seguinte diretório /./usr/lib/ entre nele e extrai o arquivo libavcodec.so.51.50.0 para o seu diretório pessoal.

Agora como root mova ele para o diretório /usr/lib/

# mv libavcodec.so.51.50.0 /usr/lib/
Agora eu tenho no meu computador os seguintes arquivos:

# ls -l /usr/lib/libavcodec.so*
lrwxrwxrwx 1 root root 21 Nov 29 18:46 /usr/lib/libavcodec.so -> libavcodec.so.51.58.0
lrwxrwxrwx 1 root root 30 Nov 30 11:45 /usr/lib/libavcodec.so.51 -> /usr/lib/libavcodec.so.51.58.0
-rw-r--r-- 1 fernando fernando 4412128 Out 3 11:03 /usr/lib/libavcodec.so.51.50.0
-rw-r--r-- 1 root root 3894008 Out 22 11:31 /usr/lib/libavcodec.so.51.58.0
Vamos ver o que objdump nos retorna nestes arquivos que eu destaquei:
# objdump -T /usr/lib/libavcodec.so.51.58.0 |grep img_
000000000007b790 g DF .text 0000000000000005 Base img_pad
000000000007aec0 g DF .text 0000000000000005 Base img_copy
000000000007ab80 g DF .text 0000000000000005 Base img_crop
000000000007ace0 g DF .text 0000000000000086 Base ff_img_copy_plane
000000000007ab90 g DF .text 0000000000000148 Base img_get_alpha_info
fullhouse:/home/fernando# objdump -T /usr/lib/libavcodec.so.51.50.0 |grep img_
00000000000a8340 g DF .text 0000000000000019 Base img_resample_close
0000000000084600 g DF .text 0000000000000005 Base img_pad
0000000000083c20 g DF .text 0000000000000005 Base img_copy
00000000000837d0 g DF .text 0000000000000005 Base img_crop
00000000000839b0 g DF .text 0000000000000086 Base ff_img_copy_plane
00000000000a8360 g DF .text 0000000000000a20 Base img_resample
00000000000a8f50 g DF .text 0000000000000043 Base img_resample_init
00000000000a8d80 g DF .text 00000000000001c4 Base img_resample_full_init
00000000000837e0 g DF .text 0000000000000148 Base img_get_alpha_info
0000000000084d30 g DF .text 0000000000000835 Base img_convert

Podemos perceber que na biblioteca proveniente do repositório oficial existe o img_resample enquanto na biblioteca proveniente do debian-multemedia.org ela não existe.


Então vamos lá o próximo passo que tomei foi modificar o link do libavcodec.so.51:

# ln -f -s /usr/lib/libavcodec.so.51.50.0 /usr/lib/libavcodec.so.51

Agora voltamos ao vlc e temos:

$vlc -vv --no-plugins-cache --list |grep ffmpeg
VLC media player 0.8.6h Janus
[00000001] main private debug: checking builtin modules
[00000001] main private debug: checking plugin modules
[00000001] main private debug: recursively browsing `/usr/lib/vlc'
[00000001] main private debug: module bank initialized, found 223 modules
ffmpeg FFmpeg audio/video decoder/encoder ((MS)MPEG4,SVQ1,H263,WMV,WMA)
ffmpeg FFmpeg chroma conversion
ffmpeg FFmpeg audio/video encoder
ffmpeg FFmpeg demuxer
ffmpeg FFmpeg muxer
ffmpeg FFmpeg video filter
ffmpeg FFmpeg crop padd filter
ffmpeg FFmpeg deinterlace video filter

Agora abrimos o vlc normalmente e conseguimos abrir o video sem problemas.


Cuidados a serem tomados


Não sei qual o impacto dessa alteração em outros programas então faça isso por sua conta e risco, caso eu perceba algum problema irei postar o que percebi.

Portanto por via das dúvidas pretendo criar um script que irei usar para abrir o vlc que irá modificar os link simbólicos e retorna ao correto automaticamente, mas isso fica para depois já que este post já ficou bem longo.