Jul
08
2010

How to run a single unit test/unit test module with py.test

Note to self: It is actually possible to select a single test module or a single test function in py.test.

But passing the file name as argument to a py.test invocation selects only the doctest from that file (wtf!?). Instead, you need to call it like this:

1
2
$ py.test -k test_module    # to run the tests from test_module.py
$ py.test -k test_func      # to run tests having the function name test_func

This is documented in the section advanced test selection and running modes of the py.test documentation, although I fail to see how this is advanced.

Jul
05
2010

Postprocessing conference videos

I was planning to attend DebConf New York this year, but for a number of reasons I decided not to go. Fortunately, Ferdinand Thommes organized a MiniDebConf in Berlin at LinuxTag and I managed to attend. Thanks, Ferdinand!

There were a number of interesting Talks. I especially liked the talk of our DPL, and those about piuparts and git-buildpackage. In contrast to the other LinuxTag talks, we had a livestream of our talks and recorded (most) of them. The kudos for setting this up goes to Alexander Wirt, who spent quite a few hours to get it up and running.

I have to apologize for being late in bringing my Notebook, which was intended to do the theora encoding of the livestream. This was a misunderstanding on my part, I should have known that this is not going to be setup in the night before show time… So to compensate the extra hours he had to put in for me, I offered to do the post processing of the videos.

Basic approach for post processing

The main goal of post processing the videos was (of course) to compress them to a usable size from the original 143 GB. I also wanted to have a title on each video, and show the sponsors at the end of the video.

My basic idea to implement that consisted of the following steps:

  1. Create a title animation template.
  2. Generate title animations from template for all talks.
  3. Use a video editor to create a playlist of the parts title – talk – epilogue.
  4. Run the video editor in batch mode to generate the combined video.
  5. Encode the resulting video as ogg theora.

As always with technology, it turned out that the original plan needed a few modifications.

Title animations

Originally I wanted to use Blender for the title animation, but I knew it is quite a complicated bit of software. So I looked for something simpler, and stumbled across an article that pointed me towards Synfig Studio for 2D animation. This is also in Debian, so I gave it a try.

I was delighted that Synfig Studio has a command line renderer which is just called synfig and that the file format is XML, which would make it simple to batch-create the title animations. My title template can be found in this git repository.

Batch creation of title animations

I used a combination of make and a simple python script to replace the author name and the title of the talk into the synfig XML file. The data for all talks is another XML file talks.xml. Basically, I used a simple XPath expression to find the relevant text node and change the data using the ElementTree API of lxml python module.

The same could be done using XSLT of course (for a constant replacement, see this file) but I found it easier to combine two XML files in python.

Note that I create PNG files with synfig and use ffmpeg to generate a DV file from those. Originally, I had synfig create DV files directly but those turned out quite gray for some reason. I am now unable to reproduce this problem.

Combining the title animation with the talk

For joining the title animation with the talk, I originally went with OpenShot, which somebody of the video team had running at the conference. My idea was to mix a single video manually and just replace the underlying data files for each talk. I expected that this would be easy using the openshot-render command, which renders the output video from the input clips and the OpenShot project file. However, OpenShot stores the video lengths in the project file and will take those literally, so this did not work for talks of different play times…

I considered working with Kino or Kdenlive but they did not look more appropriate for this use case. I noticed that OpenShot and Kdenlive both use the Media Lovin’ Toolkit under the hood, and OpenShot actually serializes the MLT configuration to $HOME/.openshot/sequence.xml when rendering. I first tried to read that XML file from python (using the mlt python bindings from the python-mlt2 package) but did not find an API function to do that. So I just hard coded the video sequence in python.

I ran into a few gotchas on the way:

  • it’s easy to segfault MLT from Python (something is wrong with the refcounting)
  • generating ogg theora using MLT from Python (which uses libavformat) resulted in a bad audio/video synchronisation of the output (more than 1 second for 1 hour of video)
  • generating dv from MLT and running ffmpeg2theora on the result is disk-bound on my quad core system – so use a pipe to ffmpeg2theora

Things to improve

While the results look quite okay for me now, there is a lot of room for improvement.

  • What bothers me the most is the unequal audio volume between talks. We should apply something like replay gain for normalization. I did not find an easy way to add this to the processing pipeline, otherwise it would have been included already.
  • Original recordings have different aspect ratios, so after combining them, there is a letterbox added. This is the case for Goswin’s talk on Multiarch for example. I’d rather have the title distorted or letter boxed, if I get around to it, I will fix it in the script.
  • Most of the recordings concentrate on showing the slides. As we did not keep the raw camera data, but recorded the DVswitch output, we missed the opportunity to show the speaker more often in full screen. Looking at the same slide becomes quite boring after half a minute, so it would be better
    to show the speaker more often. That would require quite a bit of man power for post processing though, I have to admit that I did not watch all the hours of video.
  • We could cut a bit off the talk at start and end, when the speaker discusses where he is available for questions. It is not of interest anymore after the conference is over.

Availability

Mar
17
2010

New notebook: Dell Latitude E6400

It has been some time since I blogged about something. I wanted to write this post for a while, but never got around.

Since beginning of february 2010, I have a new job and got a new work notebook: A shiny Dell Latitude E6400. Interestingly, the company usually relies on getting Lenovo Notebooks due to good Linux support, but we were unable to find a notebook without integrated camera and decent specs. We also researched some HP Notebooks. We ended up with a Dell since the website makes it really easy to find a system that fits your requirements.

There is still room for improvement though – you still have to select between Vostro, Latitude, Precision Mobile and XPS before you are allowed to configure the system. There is a filter on the left side of the shop, but filtering for a Core 2 Duo and 4 GB RAM won’t show you the notebook I got. Instead there is some overpriced Latitude (~ €3000) and an XPS system. I just tried the XPS, but was unable to find a Core 2 Duo processor in the options.

Anyway, somehow I made it through and got the following configuration:

Processor Intel(R) Core(TM)2 Duo CPU P8700 @ 2.53GHz

RAM 4 GB 800MHz DDR2

Graphics Mobile Intel Integrated Graphics Media Accelerator X4500HD

Display 14.1″ Widescreen WXGA+ (1440X900), LED backlight, non-glare

Hard Drive Seagate ST9250410ASG 250GB

Webcam None, but microphone fitted

Battery 9-cell 85 Wh

WLAN Intel Wireless WiFi Link 5100 (according to lspci, I did not care too much)

LAN Intel 82567LM Gigabit Network Connection

I installed Ubuntu karmic (amd64) the day it arrived and I am impressed. I have yet to find a serious problem with hardware support. Everything just worked out of the box, installation was done after half an hour (I needed 10 minutes to find a network cable since the installer did not support the wireless). I wanted to install Debian on it but so far I did not get around to actually do it. But I expect sid to perform just as well with lenny probably lacking some of the needed drivers.

So why am I writing this? The main point is that you can buy a notebook today and have it fully supported wrt. Linux. Open Source has come a long way!

Second: If I replace my personal notebook (a Sony Vaio), I will probably buy Dell as well. Definitely nothing from Sony, because I did not find any way to change the display brightness for the 3 years old system, which makes it usable only next to a power outlet.

Feb
21
2010

Watching TV with vlc on Linux via T-Home Entertain

For quite a while we are receiving TV via Internet. The original reason is that I got at most 2 MBit/s via ADSL due to line noise, but VDSL supports 25 MBit/s on the same line. Of course, you couldn’t order the DSL line without also getting a phone flat rate and IPTV.

Most of the channels are encrypted and can only be received with the original “Media Receiver”, which is a proprietary (and Microsoft) solution. But at least, I can watch the public service broadcasts using these playlists for VLC or mplayer.

Jan
25
2010

Eclipse 3.5.1 mouse event problems with gtk >= 2.18

Recently, Eclipse started ignoring clicks on dialog buttons for me. This seems to be due to some changes in gtk 2.18. It does not use native windows for all widgets anymore, and SWT seems to rely on it.

Thanks to this blog post, I have this fix in my bashrc:

1
alias eclipse="GDK_NATIVE_WINDOWS=true eclipse"

The Debian bug tracker also knows about this problem, which is partly fixed for the eclipse packages. Bad luck that I am using a download from eclipse.org.

Jan
19
2010

quiltrc for Debian packaging

Working on another laptop, I was missing my quiltrc settings. I think, I got them from a this email by Marco d’Itri. Perhaps it is of help to somebody (for example, when I go searching for it again).

BTW, I changed it locally to check only for debian folder in parent directories and create debian/patches automatically if needed:

1
2
3
4
5
6
7
8
for d in . .. ../.. ../../.. ../../../.. ../../../../..; do
    if [ -d $d/debian ]; then
        if ! [ -d $d/debian/patches ]; then
            mkdir $d/debian/patches
        fi
        export QUILT_PATCHES=debian/patches
    fi
done

I’d rather end up with a patches dir inside the debian folder instead of having it at a random place in the package sources when adding the first quilt patch.

I wonder if we should ship this with the quilt package!?

Update: After discussion with James Vega on IRC, the quiltrc evolved into this version:

1
2
3
4
5
6
7
8
9
10
11
d=.
while [ ! -d "$d/debian" -a `readlink -e $d` != / ]; do
    d="$d/.."
done

if [ -d "$d/debian" ]; then
    export QUILT_PATCHES=debian/patches
    if ! [ -d $d/debian/patches ]; then
        mkdir $d/debian/patches
    fi
fi

This works with any directory depth while the original would only support 5 levels from the package base directory.

Dec
30
2009

libtool silently skips shared libraries without -rpath

Ouch! This is the second time I am running into this so I’ll write it up this time.

I used libtool via automake for building a python module. Quite unhelpfully, libtool happens to build only the static library. It does that even though I passed the -module option, which should make it clear that a static library does not help at all. There is also no mention why it skips the shared library.

After some research, my memory came back: libtool requires to pass the -rpath option to actually build shared libraries. I did not want to pass that options, since it is considered harmful where multiple variants of a library are available. It is even less useful in my specific case, as the module is only used inside the source tree for unit testing.

Solution: I changed the Makefile.am to use

1
_helper_la_LDFLAGS = -module -rpath /freaking/libtool/requires/at/least/a/dummy/path

Interestingly, the same scheme (apart from the wording) is used in libtool’s own source.

Dec
23
2009

Hitting the dynamic linker wall…

I was working on replacing some mockup code for testing an internal library with python. Basically, the C code is incredibly big and I would rather mock the 3rd party API we are using in python. I wrote a generator to create wrapping code that forwards the C API calls to my python module.

Now that most of the work is finished, I get the following error message from my python mock:

1
2
3
4
5
6
Traceback (most recent call last):
  File "simple_mockup.py", line 2, in <module>
    import threading
  File "/usr/lib/python2.5/threading.py", line 11, in <module>
    from time import time as _time, sleep as _sleep
ImportError: /usr/lib/python2.5/lib-dynload/time.so: undefined symbol: PyExc_ValueError

What’s going on here? This issue reminds me of a bug of my ancient Debian times which affected loading of GTK theme engines from python-gtk. The bug (#38138) is so old, it’s not even in the BTS archive anymore…

The problem is illustrated by the following example program (consisting of three files):

demo.c
1
2
3
4
5
6
7
#include <Python.h>

void test_python()
{
    Py_Initialize();
    PyRun_SimpleString("import threading\n");
}
main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
#include <dlfcn.h>

int main(void)
{
    const char *error;

    void *handle = dlopen("./demo.so", RTLD_LAZY | EXTRA_RTLD_FLAGS);
    void (*test_python)();
    *(void**) &test_python = dlsym(handle, "test_python");
    if ((error = dlerror())) {
        fprintf(stderr, "%s\n", error);
        return 1;
    }

    printf("Calling test_python @ %p in shared object @ %p.\n", test_python, handle);
    (*test_python)();
    dlclose(handle);
    printf("Feels fine, finishing.\n");
    return 0;
}
run_it.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
#! /bin/sh

gcc -shared `python-config --includes` -o demo.so demo.c `python-config --ldflags`

echo "Running example with default RTLD flags:"
gcc -DEXTRA_RTLD_FLAGS=0 -o main main.c -ldl
./main
echo

echo "Passing RTLD_GLOBAL in addition:"
gcc -DEXTRA_RTLD_FLAGS=RTLD_GLOBAL -o main main.c -ldl
./main
echo

On my system, this results in the following output:

torsten@pulsar:~/sh_bug$ ./run_it.sh
Running example with default RTLD flags:
Calling test_python @ 0xb77084bc in shared object @ 0x96bc018.
Traceback (most recent call last):
  File "", line 1, in 
  File "/usr/lib/python2.5/threading.py", line 11, in 
    from time import time as _time, sleep as _sleep
ImportError: /usr/lib/python2.5/lib-dynload/time.so: undefined symbol: PyExc_ValueError
Feels fine, finishing.

Passing RTLD_GLOBAL in addition:
Calling test_python @ 0xb783f4bc in shared object @ 0x95e1018.
Feels fine, finishing.

Sucky. So embedding Python into an application is easy but if you want to use the interpreter and its modules from a plugin, you are out of luck. Somebody knows a way around this problem? The only solution I can think of is to link libpython.so into each of the python plugins.

Update: Work around

Small update: For my current problem, the work around is to run the application with the python library preloaded: LD_PRELOAD=/usr/lib/libpython2.5.so.1.0 app. Back to adding functionality…

Dec
20
2009

Restoring a package selection on new system

I am moving from my old Debian development system to a new one, changing architectures from i386 to amd64. So I need to do a fresh install, but basically I want to keep my package selection.

Conventional wisdom is to use dpkg --get-selections and dpkg --set-selections to preserve the package selection. However, this does not keep the information about automatically installed packages.

Instead, I used

aptitude search '?installed?not(?automatic)' -F %p > packages.txt

to dump the packages I installed manually. Installing these was a matter of running:

aptitude install `cat packages.txt`

In fact this was taking so long that I loaded the packages in batches using

cat packages.txt|xargs -n 100 aptitude install --schedule-only; aptitude

While I was at it, it ran

aptitude remove '?obsolete'

on the original system, killing of a few hundred packages that accumulated since 2003.

Dec
03
2009

OpenVPN and DHCP: Good idea?

Great, I spent a few hours today to set up a nice OpenVPN server. Nice in that I wanted the (Windows) clients to be able to access the company network like they were connected locally.

My idea was to use the OpenVPN tap mode and let the DHCP server at work assign IPs to the VPN clients.

This turned out to be a dumb idea. After I got everything going, I noticed the following message in syslog (which probably scrolled by previously in the debug drivel):

NOTE: your local LAN uses the extremely common subnet address 192.168.0.x or 192.168.1.x. Be aware that this might create routing conflicts if you connect to the VPN server from public locations such as internet cafes that use the same subnet.

Hmm, sure, I guess that will exclude every second incoming VPN connection.

Summary: Think about IP space clashes before setting up a VPN.

 
Powered by Wordpress and MySQL. Theme by openark.org