Wednesday, May 20, 2009

Making your own one-step build in Ubuntu

It's been a while, so I thought I could at least share something quick that Koya Charles and I came up with yesterday. Koya's done a lot of work to make sure that Scenic's autoconf/build setup stays sane. The one important feature we were missing was a "one button build". Typically, I'd do something like:

cd PATH_TO_TRUNK
./autogen.sh && ./configure && make -j4 && sudo make install

Note the -jn flag which tells make to build n sources in parallel, good if you have a multicore machine (see Jeff Atwood's argument on the quad-core vs. dual-core debate, particularly the 'Comments' section for relevant discussion).

So Koya and I made a shell script to do this:

cd "`dirname $BASH_SOURCE`/../../trunk"
notify-send -t 2000 "Building scenic..."
make -j4 && gksu make install && notify-send -t 10000 "Done building scenic"


First, the variable $BASH_SOURCE evaluates to the location of the build script in question. We then use this to get the path to our source tree (as both are in our repository). We then call notify-send (requires libnotify-bin) to show a popup telling us that the build is being attempted. We then compile and call gksu, as this is intended to be used via a hotkey, instead of plain sudo for the make install. Provided the make and make install were successful, we again use notify to post a popup that the build is done. You should make this script executable with

chmod u+x your_build_script.sh

This script can be called from the command line, but to be even more useful I made a hotkey for it.


Running gconf-editor, you can edit what keybindings you have for your global workspace, with the following steps:
  1. run gconf-editor from a terminal (or just Alt-F2, then type in gconf-editor in the "Run Application" window that appears).
  2. click on the tab for apps, under /
  3. click on the tab for metacity, under apps
  4. click on global_keybindings
  5. in the adjacent window, right-click on run_command_1 (assuming it's disabled, otherwise use the first run_command_x listed as disabled) and click Edit key.
  6. I use F5 (as in the F5 key) for my binding, but it can be whatever you choose. Just type 'F' and '5' in the Value: field, NOT the F5 key itself, to get this binding.
  7. Next, click on the tab keybinding_commands, right below global_keybindings, and right-click on command_1 (or whichever you chose) and click Edit Key.
  8. In the field labelled Value:, enter the path to your build script, for example: /home/tristan/devel/scenic/inhouse/misc/build_scenic.sh
Now, I can build my project no matter what window is in focus, without opening a terminal, just by hitting the F5 key.

Monday, February 9, 2009

Snapshots from a live video source in gstreamer

EDIT: A helpful reader pointed out that using videorate in the pipeline should do the trick, something like:
gst-launch -v v4l2src ! tee name=t ! queue ! xvimagesink t. 
! queue ! videorate ! video/x-raw-yuv, width=640, height=480, framerate=1/1 ! jpegenc ! 
filesink location=test.jpeg
I'm fairly sure I tried this before with no success, but it works fine now. There have been some major bugfixes to videorate since I wrote this. In any case, I'll leave the rest of the article up in the hope that it is still useful.

As part of the propulse[ART] project, we wanted to add a "preview" feature to the existing audio/video engine. This involves writing a frame of video every second to a jpeg file, while displaying the video at a full 30 fps in a window. I was surprised to discover that this feature was not already implemented in gstreamer for live sources (to the best of my knowledge).
This should probably be implemented by a real gstreamer element, but for our purposes a relatively straightforward hack prototyped in streamshot.cpp was sufficient. The video pipeline consists of a video4linux source, a capsfilter to enforce some properties on the video, an ffmpegcolorspace element, and an xvimagesink. We attach a callback to the source pad of the video4linux source that is called every time our source has a new buffer of data (i.e. a frame). Since timing is not a big concern, the cb_have_data callback knows to only write a file every second by checking a boolean value that is periodically set to true by a separate callback. The cb_have_data function makes a copy of the buffer, swaps its red bytes with its blue bytes (swapping the red_mask and blue_mask in the caps did not work for some reason) and writes the modified buffer to a jpeg, line-by-line. The jpeg writing code was based on Andrew White's Xlib screenshot example. Thanks also to Koya Charles for help debugging this example, as well as the byte swapping.
The final version of the preview feature will probably happen entirely in a separate thread and not involve file-writing, but rather be streamed as these frames will be part of our web-interface.


Update: To make up for this entry's lack of flashiness, enjoy this code_swarm video of the propulse[ART] software's (codename miville) development so far (code_swarm instructions courtesy of amix.dk):