Tuesday, November 26, 2013

cross-compile VLC para ardrone usando o Sourcery G++ Lite

Depois de instalado o Sourcery G++ Lite, chegou a hora de compilar o VLC utilizando ele. Com o VLC poderemos faz broadcast do video capturado pelas cameras do ardrone.


Instalar o VLC e Mplayer no Ubuntu também para fazer o teste de recebimento do stream em broadcast feito pelo Drone.
root@ubuntu:~/Downloads# apt-get install vlc mplayer


Baixar e extrair o VLC

root@ubuntu:~/Downloads# wget http://download.videolan.org/pub/videolan/vlc/2.1.1/vlc-2.1.1.tar.xz
root@ubuntu:~/Downloads# tar xfvJ vlc-2.1.1.tar.xz
root@ubuntu:~/Downloads# cd vlc-2.1.1




A configuração do VLC é tensa, é preciso remover várias features para compilar sem problemas. E ativar a opção de executar como root, já que no Drone não tem "su".

root@ubuntu:~/Downloads/vlc-2.1.1# ./configure --target=arm-none-linux-gnueabi --host=arm-none-linux-gnueabi --disable-lua --disable-mad --disable-avcodec --disable-swscale --disable-a52 --disable-xcb --disable-libgcrypt --disable-dbus --disable-alsa --disable-pulse --disable-libxml2 --disable-udev --disable-freetype --disable-sdl --disable-caca --disable-bonjour --enable-run-as-root --prefix=/data/video/vlc && make && make install



Agora temos o VLC compilado para Drone instalado no nosso /data/video/vlc.

root@ubuntu:~# cd /data/video/vlc/
root@ubuntu:/data/video/vlc# du -hs
48M    .


Nosso recém compilado VLC tem o singelo tamanho de 48MB.

Primeiro é preciso conectar no Access Point WIFI criado pelo ardrone.
Uma vez conectado e conseguindo pingar o 192.168.1.1, provavelmente não haverá problemas.


root@ubuntu:~# ping 192.168.1.1
PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.
64 bytes from 192.168.1.1: icmp_req=1 ttl=64 time=1.99 ms
64 bytes from 192.168.1.1: icmp_req=2 ttl=64 time=1.77 ms
^C
--- 192.168.1.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 1.773/1.882/1.992/0.117 ms








 Se pingou o Drone segue para o telnet no Drone,
uma vez na linha de comando do Drone, é bom verificar o espaço livre antes de enviar o VLC para o /data/video via FTP.

root@ubuntu:~# telnet 192.168.1.1
Trying 192.168.1.1...
Connected to 192.168.1.1.
Escape character is '^]'.



BusyBox v1.14.0 (2011-08-30 12:00:29 CEST) built-in shell (ash)
Enter 'help' for a list of built-in commands.

# df -ah
Filesystem                Size      Used Available Use% Mounted on
ubi1:system              12.0M      6.3M      5.1M  55% /
tmp                      61.6M     32.0K     61.5M   0% /tmp
proc                         0         0         0   0% /proc
dev                      61.6M         0     61.6M   0% /dev
devpts                       0         0         0   0% /dev/pts
sys                          0         0         0   0% /sys
ubi0:factory              4.8M     44.0K      4.5M   1% /factory
ubi2:update              13.2M     32.0K     12.5M   0% /update
ubi2:data                67.5M      1.4M     62.6M   2% /data
#


Segundo o telnet ainda tem livre 62,6MB dos 67,5MB da partição /data, que é onde vamos colocar o VLC ocupando 48MB.

Somente a título de curiosidade, o ardrone é todo feito encima de UBIFS.

Aqui temos a configuração do MTD que vai ser passada para o UBI.
 # cat /proc/cmdline
parrotparts=nand0:256K(Pbootloader),8M(Pmain_boot),8M(Pfactory),16M(Psystem),98048K(Pupdate) console=ttyPA0,115200 loglevel=4 ubi.mtd=Pfactory,2048 ubi.mtd=Psystem,2048 ubi.mtd=Pupdate,2048 root=ubi1:system rootfstype=ubifs parrot5.low_latency=1


Olhando o log do kernel, o volume /data tem na verdade 73MB, mas quando tira os espaços reversados fica somente 67,5MB.
# dmesg | grep UBIFS
[    1.361041] UBIFS: recovery needed
[    1.378984] UBIFS: recovery deferred
[    1.379025] UBIFS: mounted UBI device 1, volume 0, name "system"
[    1.379048] UBIFS: mounted read-only
[    1.379071] UBIFS: file system size:   14348288 bytes (14012 KiB, 13 MiB, 113 LEBs)
[    1.379103] UBIFS: journal size:       1015809 bytes (992 KiB, 0 MiB, 6 LEBs)
[    1.379132] UBIFS: media format:       w4/r0 (latest is w4/r0)
[    1.379155] UBIFS: default compressor: none
[    1.379176] UBIFS: reserved for root:  677704 bytes (661 KiB)
[    1.571892] UBIFS: completing deferred recovery
[    1.578212] UBIFS: deferred recovery completed
[    2.314383] UBIFS: mounted UBI device 0, volume 0, name "factory"
[    2.314416] UBIFS: mounted read-only
[    2.314441] UBIFS: file system size:   6221824 bytes (6076 KiB, 5 MiB, 49 LEBs)
[    2.314472] UBIFS: journal size:       1015809 bytes (992 KiB, 0 MiB, 6 LEBs)
[    2.314501] UBIFS: media format:       w4/r0 (latest is w4/r0)
[    2.314524] UBIFS: default compressor: none
[    2.314545] UBIFS: reserved for root:  293871 bytes (286 KiB)
[    2.343121] UBIFS: recovery needed
[    2.369371] UBIFS: recovery completed
[    2.369411] UBIFS: mounted UBI device 2, volume 0, name "update"
[    2.369441] UBIFS: file system size:   15745024 bytes (15376 KiB, 15 MiB, 124 LEBs)
[    2.369474] UBIFS: journal size:       1015809 bytes (992 KiB, 0 MiB, 6 LEBs)
[    2.369503] UBIFS: media format:       w4/r0 (latest is w4/r0)
[    2.369527] UBIFS: default compressor: none
[    2.369548] UBIFS: reserved for root:  743676 bytes (726 KiB)
[    2.398642] UBIFS: recovery needed
[    2.450956] UBIFS: recovery completed
[    2.450996] UBIFS: mounted UBI device 2, volume 1, name "data"
[    2.451027] UBIFS: file system size:   77328384 bytes (75516 KiB, 73 MiB, 609 LEBs)
[    2.451059] UBIFS: journal size:       3809280 bytes (3720 KiB, 3 MiB, 30 LEBs)
[    2.451089] UBIFS: media format:       w4/r0 (latest is w4/r0)
[    2.451112] UBIFS: default compressor: none
[    2.451133] UBIFS: reserved for root:  3652410 bytes (3566 KiB)
#

 
O próximo passo é copiar o diretório vlc para o FTP do Drone.
Lembrando que o modo de transferência deve ser sempre o binário, senão os executáveis serão destruidos durante a cópia.
Para facilitar a cópia recomendo usar o Filezilla (lembre de mudar para modo binário, isto é fundamental)

 root@ubuntu:~# apt-get install filezilla

O Host é o IP do Drone, 192.168.1.1

No mais é só entrar em /data/video e arrastar para dentro do drone.
Quando terminar de transferir tudo, vamos testar via telnet no drone.



 root@ubuntu:~# telnet 192.168.1.1
Trying 192.168.1.1...
Connected to 192.168.1.1.
Escape character is '^]'.



BusyBox v1.14.0 (2011-08-30 12:00:29 CEST) built-in shell (ash)
Enter 'help' for a list of built-in commands.




De volta ao drone, é hora de colocar as permissões de execução no VLC

# chmod -R +x /data/video/vlc

E por fim testar o VLC

# /data/video/vlc/bin/vlc
/data/video/vlc/bin/vlc: error while loading shared libraries: libvlc.so.5: cannot open shared object file: No such file or directory




Problema de .so faltando, é normal quando não se tem o ldconfig,
para resolver o jeito é linkar na mão e testar denovo

# ln -s /data/video/vlc/lib/libvlc.so.5.4.0 /data/video/vlc/lib/libvlc.so.5
# /data/video/vlc/bin/vlc/data/video/vlc/bin/vlc: error while loading shared libraries: libvlccore.so.7: cannot open shared object file: No such file or directory

Outra lib faltando, ok. Linkar na mão e testar.

# ln -s /data/video/vlc/lib/libvlccore.so.7.0.0 /data/video/vlc/lib/libvlccore.so.7
# /data/video/vlc/bin/vlc
/data/video/vlc/bin/vlc: /lib/libc.so.6: version `GLIBC_2.10' not found (required by /data/video/vlc/lib/libvlccore.so.7)
/data/video/vlc/bin/vlc: /lib/libc.so.6: version `GLIBC_2.9' not found (required by /data/video/vlc/lib/libvlccore.so.7)

Agora a coisa ficou feita, provavelmente por causa da versão da GLIBC que tem no
gcc version 4.5.2 (Sourcery G++ Lite 2011.03-41)


# cat /firmware/version.txt
1.7.6
# cat /update/version.txt
1.7.6

# cat /proc/version
Linux version 2.6.27.47-parrot (aferran@FR-B-800-0053) (gcc version 4.3.3 (Sourcery G++ Lite 2009q1-203) ) #1 PREEMPT Tue Aug 30 12:05:09 CEST 2011
#


problema é descobrir qual a versão do GCC que buildou o resto do sistema.
Depois pensar, resolvido matar o inetd e subir com um config nova export a raiz do sistema, dai pude copiar o sistema todo do drone para minha máquina pelo Filezilla.
 Agora com as ferramentas todas fica mais fácil.

root@ubuntu:~/Downloads/drone/lib# strings -a * | grep GLIBC | sort | uniq
GLIBC_2.0
GLIBC_2.4
GLIBC_2.5
GLIBC_2.6
GLIBC_2.7
GLIBC_2.8
GLIBC_PRIVATE


root@ubuntu:~/Downloads/drone/lib# strings -a * | grep GCC | sort | uniq
GCC_3.0
GCC_3.3
GCC_3.3.1
GCC_3.3.4
GCC_3.4
GCC_3.4.2
GCC_3.5
GCC_4.0.0
GCC_4.2.0
GCC_4.3.0


Realmente lascou, a versão Sourcery G++ Lite 2011.03-41 não vai servir para buildar o VLC para o firmware 1.7.6, já que a lista de símbolos é diferente.
Vai ser preciso refazer todo o processo provavelmente com a versão 
gcc version 4.3.3 (Sourcery G++ Lite 2009q1-203)

 Removido a versão 2011 e instalado o 2009.


 root@ubuntu:~# arm-none-linux-gnueabi-gcc -v
Using built-in specs.
Target: arm-none-linux-gnueabi
Configured with: /scratch/mitchell/builds/4.3-arm-none-linux-gnueabi-respin/src/gcc-4.3/configure --build=i686-pc-linux-gnu --host=i686-pc-linux-gnu --target=arm-none-linux-gnueabi --enable-threads --disable-libmudflap --disable-libssp --disable-libstdcxx-pch --with-gnu-as --with-gnu-ld --with-specs='%{funwind-tables|fno-unwind-tables|mabi=*|ffreestanding|nostdlib:;:-funwind-tables}' --enable-languages=c,c++ --enable-shared --enable-symvers=gnu --enable-__cxa_atexit --with-pkgversion='Sourcery G++ Lite 2009q1-203' --with-bugurl=https://support.codesourcery.com/GNUToolchain/ --disable-nls --prefix=/opt/codesourcery --with-sysroot=/opt/codesourcery/arm-none-linux-gnueabi/libc --with-build-sysroot=/scratch/mitchell/builds/4.3-arm-none-linux-gnueabi-respin/lite/install/arm-none-linux-gnueabi/libc --with-gmp=/scratch/mitchell/builds/4.3-arm-none-linux-gnueabi-respin/lite/obj/host-libs-2009q1-203-arm-none-linux-gnueabi-i686-pc-linux-gnu/usr --with-mpfr=/scratch/mitchell/builds/4.3-arm-none-linux-gnueabi-respin/lite/obj/host-libs-2009q1-203-arm-none-linux-gnueabi-i686-pc-linux-gnu/usr --disable-libgomp --enable-poison-system-directories --with-build-time-tools=/scratch/mitchell/builds/4.3-arm-none-linux-gnueabi-respin/lite/install/arm-none-linux-gnueabi/bin --with-build-time-tools=/scratch/mitchell/builds/4.3-arm-none-linux-gnueabi-respin/lite/install/arm-none-linux-gnueabi/bin
Thread model: posix
gcc version 4.3.3 (Sourcery G++ Lite 2009q1-203)
root@ubuntu:~#


Build do VLC com a versão 2009, foi de primeira sem nenhum problema.
Agora é copiar pelo FTP e testar no telnet como já tinha feito antes.



# /data/video/vlc/bin/vlc --version
VLC media player 2.1.1 Rincewind (revision 2.1.0-207-g89c9520)
VLC version 2.1.1 Rincewind (2.1.0-207-g89c9520)
Compiled by root on ubuntu (Nov 26 2013 16:26:14)
Compiler: gcc version 4.3.3 (Sourcery G++ Lite 2009q1-203)
This program comes with NO WARRANTY, to the extent permitted by law.
You may redistribute it under the terms of the GNU General Public License;
see the file named COPYING for details.
Written by the VideoLAN team; see the AUTHORS file.
#


Agora sim, funcionou como esperado!!!

Comandos para fazer o stream das câmeras do drone.
# /data/video/vlc/bin/vlc v4l2:///dev/video0:width=640:height=480 -I dummy -v --noaudio --sout '#std{access=mmsh,dst=:8080}'
# /data/video/vlc/bin/vlc v4l2:///dev/video1:width=176:height=144 -I dummy -v --noaudio --sout '#std{access=mmsh,dst=:8080}'


Agora existe algum problema com as câmeras que ficaram rebeldes e sem funcionar.