Friday, December 7, 2012

Launch Playback of Multimedia Files on a SAMBA Share from Nautilus

I hit this problem on a new Debian installation: if I use Nautilus to navigate to a SAMBA share (on a Windows or Linux box) I can launch playback of multimedia files by double clicking them. So far so good. This brings up Totem (the default Gnome multimedia player), which is fine, but I'd rather use VLC (from the Debian Multimedia repository).

It's easy enough to convince Nautilus to launch VLC, but VLC fails to find the multimedia files. This only happens if the SAMBA share is mounted by Nautilus. If I mount the SAMBA share manually from the command line, VLC finds the files just fine.

The problem is that Nautilus points VLC to a non-existent path that lives on the Gnome virtual file system (GVFS).

The fix is to install the GVFS FUSE daemon, which, for some reason, is not installed by default:
aptitude install gvfs-fuse
add your user account to the fuse group, and re-login.

Saturday, April 28, 2012

Illegal Instruction in Code Compiled with Clang

I was inspired by the effort to rebuild the Debian archive with clang, to try compiling UnDBX with clang:
CC=clang ./configure
make
I was a bit surprised when clang complained about an (legitimate) operator precedence issue, which gcc never pointed out to me. I fixed this by judicious use of parenthesis, and recompiled.

But the generated binary failed to run - I got an "Illegal instruction" error. This error persisted with optimizations turned off (i.e. -O0). I tried running the binary under valgrind and got the following:
vex x86->IR: unhandled instruction bytes: 0x66 0xF 0xEF 0xC0
==28891== valgrind: Unrecognised instruction at address 0x8048fc3.
followed by a verbose error message explaining that this may be caused either by trying to execute code in a non-code area of memory, or by a bug in valgrind.

I used objdump to find the offending instruction/address:
$ objdump -d -S undbx | grep -i 8048fc3
 8048fc3:       66 0f ef c0             pxor   %xmm0,%xmm0

I don't grok x86 assembly much, so it took me some googling to find that the combination of pxor and xmm type registers is in fact an SSE instruction. The CPU on this box is an aging 32-bit Mobile AMD Athlon XP, and the CPU flags in /proc/cpuinfo include SSE, so I'm not sure what to make of this.

The same code compiles and runs nicely on my newly upgraded laptop which sports a slightly less lame 64-bit Mobile AMD Sempron processor, running a 64-bit kernel.

In any case, I tried compiling like this:
CC='clang -mno-sse' ./configure
make
and I got a working executable.

My guess is that this is a bug in clang (maybe Debian bug #632472?), but as I said, I'm not sure.

Saturday, April 21, 2012

Remote GDM3 Login with VNC

I usually leave my computer at home turned on, logged in to the graphical desktop, with a VNC server running, to allow remote access to the desktop with a VNC viewer.

A few days ago, while waiting for code to compile, I logged in to my computer from work, and performed a long overdue package upgrade, which required a reboot to complete. This left me logged out of the desktop, with the GDM3 greeter waiting for someone to log in, but no VNC server to allow remote access to it.

Here's how to run a VNC server and start the desktop, in this situation:
  1. connect to the remote machine with ssh, forwarding the default VNC port (this is the usual way I access my home PC):
    # ssh -L 5901:localhost:5900 example.home-computer.com
  2. run the following command as root to detect the path to the X authority file:
    $ ps ax | grep auth
     1398 tty7     Ss+    4:30 /usr/bin/Xorg :0 -br -verbose -novtswitch -auth /var/run/gdm3/auth-for-Debian-gdm-e7ERxa/database -nolisten tcp vt7
     5053 pts/5    S+     0:00 grep --color=auto auth
    
  3. launch a VNC server (as root) that allows access to your real X11 display, using the path to the X authority file (I use x11vnc):
    $ x11vnc -xkb -ncache 0 --forever -localhost -display :0 -auth /var/run/gdm3/auth-for-Debian-gdm-e7ERxa/database
  4. back on the local machine - connect to the remote machine with a VNC viewer (I use realvnc here):
    # vncviewer -FullScreen -LowColourLevel 2 -PreferredEncoding ZRLE localhost:1
    you should now see the remote GDM greeter and be able to login to your desktop.

Friday, April 13, 2012

Update rkhunter Database After Installing/Upgrading Packages

Once upon a time I described how to automatically update the rkhunter database after installing/upgrading packages. There's an easier way of achieving this which either did not exist at the time, or I somehow missed. Just add the following line to /etc/default/rkhunter:
APT_AUTOGEN="yes"
My original method is still useful for running any custom script after installing/upgrading packages.

Friday, April 6, 2012

DVD Backup

Here's how I currently backup my kids' DVDs to single CD-sized AVI files (mostly tested with PAL animation DVDs):
  1. find the main title (usually the longest):
    $ lsdvd
    ...
    Title: 21, Length: 01:31:58.200 Chapters: 42, Cells: 43, Audio streams: 05, Subpictures: 15
    ...
    
    (lsdvd is also kind enough to report the number of the longest title)
    Alternatively, you can use mplayer to do this too:
    mplayer -msglevel identify=6 -frames 0 dvd://
    (it also lists the language audio tracks on the disc)
  2. extract the MPEG2 stream with mplayer
    mplayer -dumpstream -dumpfile temp/title.mpg dvd://21
  3. calculate encoded video bit-rate with the script that's listed below:
    $ calc_video_bitrate.py 1:31:58 128 700
    bitrate: 929.650763
    
    (the command line arguments are, in order: duration of video, audio target bitrate in kbit/sec and encoded file size in MB)
  4. rip the MPEG2 stream into an AVI file, in two passes, using ffmpeg - note that I use the -map command line option to keep only a single audio track (my kids don't speak English, yet):
    ffmpeg -i temp/title.mpg -pass 1 -ac 2 -ab 128k -ar 44100 -acodec libmp3lame -b 929.65k -s 640x360 -map 0:0 -map 0:3  temp/title.pass1.avi
    ffmpeg -i temp/title.mpg -pass 2 -ac 2 -ab 128k -ar 44100 -acodec libmp3lame -b 929.65k -s 640x360 -map 0:0 -map 0:3  temp/title.avi
    
The code for calculating video bit-rate is based on JavaScript code found at http://quadpoint.org/projects/simplerip.


#! /usr/bin/env python

import sys

def bitrate2bytes(bitrate, length):
    # bitrate in kbit/s
    # length in seconds
    # returns number of bytes
    return (bitrate * length * 1000) / 8.0

def bytes2bitrate(size, length):
    # size in bytes
    # length in seconds
    # returns bitrate in kbit/s
    return size * 8.0 / length / 1000

def calcbr(targetsize, audiosize, length, coverhead):
    # targetsize in bytes
    # audiosize in bytes
    # length in seconds
    # coverhead in percent (container overhead)
    # returns bitrate in kbit/s
    overhead = 1.0 + (coverhead / 100.0)
    size = (targetsize - audiosize) / overhead
    return bytes2bitrate(size, length)

def main():
    if len(sys.argv) != 4:
        print >>sys.stderr, 'Usage: %s hh:mm[:ss] <audio-bitrate-kb-per-sec> <target-size-mb>\n' % sys.argv[0]
        return -1
    
    tokens = sys.argv[1].split(':')
    length = (float(tokens[0]) * 3600 + 
              float(tokens[1]) * 60 +
              (float(tokens[2]) if len(tokens) > 2 else 0))
    audiobr = float(sys.argv[2])
    audiosize = bitrate2bytes(audiobr, length)
    targetsize = float(sys.argv[3])
    tsize = targetsize * 1024 * 1024
    overhead = 0.7
    bitrate = calcbr(tsize, audiosize, length, overhead)
    print 'bitrate: %f\n' % bitrate
    return 0

if __name__ == '__main__':
    sys.exit(main())

Friday, March 30, 2012

DVD Playback: The Missing Package

This took a while to figure out: I had all sorts of weird errors while trying to play a DVD on my laptop, until I did this:
aptitude install libdvdcss2
(requires the Debian Multimedia package repository).

Friday, March 23, 2012

Digging Tunnels: socat

When digging tunnels, an alternative for stunnel on the client side is socat. Here's how to use it in ~/.ssh/config:
Host tunnel.example.com
  Port 443
  ProxyCommand socat - OPENSSL:%h:%p,verify=0