Tuesday, January 25, 2011

.svg Overlays in Cheese

I finally added the capacity for Cheese to show image overlays: any .svg file the user wants to use above the image.

This one was tricky. I started studying from zero the GStreamer API, because I had no idea what was all that about sinks, pads, bins, caps, ghost pads, linking elements, pipelines and so on. What were those things?

So I started reading beginner tutorials, the GStreamer Application Development Manual, and the GStreamer Core Reference Manual.

I was having problems getting the rsvgoverlay plugin in gst-plugins-bad to work. I was getting errors. I debugged, generated huge GST_DEBUG logs, studied the rsvgoverlay plugin code, tested different gst-launch pipelines. I slowly started to understand what was going on.

There was some problem with gst-parse-bin-from-description () and the way it created the rsvgoverlay element. I won't bore you with the details, but rsvgoverlay element has two sinks, and gst_parse_bin_from_description () creates only one ghost pad in each direction (sink or src), it says so in its documentation:

Ghost pads on the bin for unlinked source or sink pads within the bin can automatically be created (but only a maximum of one ghost pad for each direction will be created; if you expect multiple unlinked source pads or multiple unlinked sink pads and want them all ghosted, you will have to create the ghost pads yourself.


Whoa! That wasn't too easy to understand for a beginner. But now it sounds clear, it's funny.


With help from several people but especially from fujii and thiagoss we finally solved it. And here are the results:



Happy birthday bunny!

The overlays don't follow you around, but that's the plan for the future, to link somehow facedetect to rsvgoverlay x and y coordinates.

A bigger picture of the hat
(Because I made that hat) tee-hee!



We are also accepting art contributions in .svg format to include in cheese as sample effects! Christmas/halloween decorations? Balloons, flowers, hats, beards? Your imagination is the limit.

*Whispers* The users can use their own images too very easily editing the .effect text file!

Wednesday, January 19, 2011

New effect in Cheese: face detection!

Now you can play with face detection in Cheese!

Here is a screencast:


Isn't that awesome! =P

I added this new effect using OpenCV plugin from the "gst-plugins-bad" GStreamer plugin-set. It wasn't an easy task! (just kidding, it was easy).

The video preview performance suffered a little, it'll be something to be careful about when I try to do more stuff than just drawing a blue circle. The idea is to draw hats, beards, and other funny elements that follow you around. Improving performance will be a must. We'll see what happens! As usual, your ideas are welcomed ;)

Friday, January 14, 2011

GNOME Outreach Program for Women - week 4

This week was mostly an exploration/learning week.

Releasing a Cheese new version

I learned how to create a Cheese release. The release was 2.91.3 and scheduled for Monday 10, to enter the GNOME 2.91.5 Development Release, scheduled for Wednesday 12. ( http://live.gnome.org/TwoPointNinetyone )

The steps to do this (specific to Cheese) are:

  • Update to last version:
    $ git pull
  • Check that you don't have any modified files:
    $ git status
  • Edit configure.ac and and set the release version in the line:
    AC_INIT(cheese, 2.91.3)
    If libcheese api changed, also change the line:
    CHEESE_LT_VERSION=18.0.0
  • Update the NEWS file:
    $ tools/mantainer.sh -n 2.91.2
    (Use previous version as parameter to see what changed) (I had to change the first line from #!/bin/sh to #!/bin/bash, depends on your system).
  • Tidy up the generated NEWS file, deleting the lines containing translation commits and technical commits intended for developers. Leave only "new feature/fix" commits and group similar commits in single bullet points.
  • Create the tarball:
    $ ./autogen.sh (with your usual flags)
    $ make && make distcheck
  • Upload the tarball (I bumped into some errors here and couldn't create the tarball, so Daniel Siegel uploaded his instead).
    $ scp cheese-2.91.3.tar.gz (user)@master.gnome.org
    Then ssh into master.gnome.org and call install-module.
    $ install-module cheese-2.91.3.tar.gz
  • Tag the new release: (set the tag message to something like "tagged for 2.91.3 release").
    $ git tag -a 2.91.3
    $ git push origin 2.91.3
  • Create the announcement mail and send it to gnome-announce-list and cheese-list:
    $ tools/mantainer.sh -m
  • Update the Cheese website:
    Get gnomeweb-wml from git if you don't have it and run
    $ gnomeweb-wml/projects.gnome.org/cheese/update.pl
    and commit the changes.

Finished! A more generic step by step for releasing is here: http://live.gnome.org/MaintainersCorner/Releasing


The following day I rebuilt Cheese from scratch using jhbuild, skipping gobject-introspection which had some problems, and could finally generate a tarball, so next time I'll be more prepared.

Building Cheese from scratch
  • Remove .la files from /usr/lib if you have any. (http://live.gnome.org/GnomeShell/RemovingLaFiles)
  • $ jhbuild build cheese (my .jhbuildrc file is here: http://pastie.org/1462382 )
  • Get directly from their git repositories these packages:
    • - libcanberra
    • - vala
    • - dconf
    • - clutter-gst
    • - gst-plugins-bad
  • Build and install them. When configuring dconf, use VALAC=/path/to/installed/bin/valac if you installed vala in a different prefix.

This week I also started playing with the idea of creating a new effect, or adding existing effects from frei0r plugins. I looked at frei0r code gallery, especially http://frei0r.dyne.org/gallery?filter=facedetect

I also installed OpenCV and ran the examples. Here is the result for facedetect.cpp :

Cool huh? It also detects two faces at the same time, and even faces using the cheese "stretch" effect!! =P


 (not very "glasses-compatible" tee-hee! x)

Note: the "cheese effect" picture is just that, a picture taken with cheese and then used as input for ./facedetect, it's not the effect already working inside cheese! ;)

Well, we'll see what happens these next weeks, I still have to decide what to focus on, but this effect could be one option.

Friday, January 7, 2011

GNOME Outreach Program for Women report - Weeks 2 & 3

I spent most of Week 2 away for the holidays, for christmas we went 350 km (217 miles) south to a beach town, Rafa traveled and saw the ocean for the first time! Nice but exhausting. Here he is, turning into a sand milanesa:




So, on to the report:

I finished the feature to select photo and video sizes independently, This was one of the tickets I started working with when applying for the program. Bug 582268
Back then, the settings were saved using GConf (now being deprecated in GNOME). This is how it looked in gconf editor:




Then Daniel Siegel migrated Cheese to GSettings, which is really great!

To add the new settings I just had to edit org.gnome.Cheese.gschema.xml adding the keys I needed, for example for video x resolution:
 
    <key name='video-x-resolution' type='i'>
      <summary>Video width resolution</summary>
      <description>
        The width resolution of the video captured from the camera
      </description>
      <default>0</default>
    </key>

make install, and that's it, I could read and save the new values (in vala) using:
private GLib.Settings settings;
int width = 0;

settings.set_int ("video-x-resolution", 480);
width = settings.get_int ("video-x-resolution");


or (in C) using :
int width = 0;
GSettings *settings = g_settings_new ("org.gnome.Cheese");

g_settings_set_int (settings, "video-x-resolution", 480);
g_settings_get (settings, "video-x-resolution", "i", &width);

Really easy and clean. Good to know for any app we want to develop and have save settings capability.

Other issue I found is that in Cheese, the preferences dialog is an "Instant apply" window, as described here: http://library.gnome.org/devel/hig-book/2.32/windows-utility.html.en#windows-instant-apply

I quote:

3.3.1. Instant apply windows

For windows that allow the user to change values or settings, such as property and preference windows, update those values or settings immediately to reflect the changes made in the window. This is known as "instant apply". Do not make the user press an OK or Apply button to make the changes happen, unless either:
  • the change will take more than about one second to apply, in which case applying the change immediately could make the system feel slow or unresponsive, or
  • the changes in the window have to be applied simultaneously to prevent the system entering a potentially unstable state. For example, the hostname and proxy fields in a network properties window.
If either these conditions affect only a few of the controls in your window, arrange those controls together into one or more groups, each with its own Apply button. Leave the rest of the controls as instant apply.
Guidelines
  • Do not attempt to validate or apply changes caused by editing a text field control until the user has moved focus to a different control in the window, or the window is closed. Validating after each keypress is usually annoying and unnecessary. Exception: if the field accepts only a fixed number of characters, such as a hexadecimal color code, validate and apply the change as soon as that number of characters have been entered.
  • When the user moves focus to a different control, do not indicate an invalid entry by displaying an alert or undoing the change the user made. Both of these methods are particularly disruptive for focus-follows-mouse users, for whom focus may leave the control more often than it does for a click-to-focus user.

3.3.2. Explicit apply windows

If most of the controls in your window are not suitable for instant apply, consider making the whole window "explicit apply". An explicit apply window has these three buttons in its button box, plus an optional Help button:
  • Apply
    Applies all the settings in the window, but does not close the window in case the user wishes to change their mind.
  • Cancel
    Resets all settings in the window to those that were in force when the window was opened. Note: this must undo the effects of all applications of the Apply since the window was opened, not just the most recent one.
  • OK
    Applies all settings in the window, and closes the window.

Figure 3-5Buttons in an explicit apply window


Also Cheese preferences dialog is not modal, meaning the user can interact with Cheese main window while the preferences dialog is open, and then change settings, and then change something in main window, and change settings again, etc etc. That needed extra steps to ensure the app states remained consistent. (Apply changes to video resolution and photo resolution according to current mode: photo, video or burst mode).

Regarding usability, this kind of dialogs have advantages: no Ok/Apply/Cancel buttons to worry about, the user doesn't have to think, the application is still available instead of blocked. The disadvantage is that once the user changes anything, there is no way back, no cancel button to restore everything to how it was. A "reset to defaults" would be nice to have in some cases.

Other than this, I started to look into Clutter because Daniel had this idea to implement a scrolling effect when changing from one effects page to the next, and it sounds very interesting. I ran the clutter samples found in clutter/tests/interactive, really interesting stuff there. I will be playing around with that next.

Last, I'd like to share a tiny script I use to help me find in files in cheese checkout folder: I search for text in files all the time while developing, but I wanted to exclude some folders (docs, help), and the .c files in src folder (they are generated after .vala files). Everything else I wanted to include in the search. This is very specific to cheese project. So here it is:

#!/bin/bash
grep --color=always -irIn $1 ./src | grep -v "\.c:";
grep --color=always -irIn --exclude-dir=po --exclude-dir=help --exclude-dir=src --exclude-dir=docs $1 .

That's all for now! :)

Ps: use http://tohtml.com to highlight code or get http://pastie.org embedded snippets filtered by planet.gnome.org ;)

Wednesday, December 22, 2010

GNOME Outreach Program for Women report - Week 1

This past week and a half I started coding for GOPW. I started with some bug-fixing as a way to "warm up". :)

So far, 8 commits:

AgeCommit messageFilesLines
4 min.Start monitoring storage folders if they exist when cheese starts, and a fix for bug 637798 commit.2-2/+8
29 hoursBurst mode session can be cancelled with a "Stop taking pictures" button. Fixes bug 6377981-47/+42
2 daysButton area does not get hidden after returning from fullscreen mode.1-0/+3
2 daysStart "Save as" dialog in home folder1-0/+1
4 daysCheck if each Webcam directory exists before filling thumb view1-22/+28
5 daysDon't create Webcam dirs (in Pictures and Video user dirs) unless there is content to put on it, fixes bug 5630585-27/+51
6 daysCommand line options for starting in wide and fullscreen modes, fixes bug 5978202-5/+49
14 daysAll ui buttons now have tooltips, fixes bug #6229743-2/+14

Daniel Siegel and me were chatting a lot during all this, discussing ideas and options for the bug fixes.

After this, the plan is to finish the feature for selecting video and photo resolution separately, and then start with the sharing features. We want to upload pictures to picasaweb, facebook, etc. Other option is for me to play with overlays, I would like to get any animated gif and put it over the video, that would be fun, especially when cheese can be used as a video chat app. We'll see, this last idea is for the distant future anyway.

Tuesday, December 21, 2010

Full planet weather timelapse

This is the most recent weather time-lapse video I made:




Now with music! =P
Making this was really simple thanks to the image filenames following a predictable pattern. At first I thought I would need to do something really complicated like image recognition, or something with image layers to automate this, but luckily it was not necessary.

Here is the complete script:

#!/bin/bash

wget --limit-rate=100k -e robots=off -U "Mozilla/5.0 (compatible; Konqueror/3.2; Linux)" -np -l1 -r  -A .jpg -N  http://goes.gsfc.nasa.gov/goescolor/goeswest/overview2/color_lrg/older_images/

wget --limit-rate=100k -e robots=off -U "Mozilla/5.0 (compatible; Konqueror/3.2; Linux)" -np -l1 -r  -A .jpg -N  http://goes.gsfc.nasa.gov/goescolor/goeswest/overview2/color_lrg/

wget --limit-rate=100k -e robots=off -U "Mozilla/5.0 (compatible; Konqueror/3.2; Linux)" -np -l1 -r  -A .jpg -N http://goes.gsfc.nasa.gov/goescolor/goeseast/overview2/color_lrg/older_images/

wget --limit-rate=100k -e robots=off -U "Mozilla/5.0 (compatible; Konqueror/3.2; Linux)" -np -l1 -r  -A .jpg -N http://goes.gsfc.nasa.gov/goescolor/goeseast/overview2/color_lrg/

mkdir temp
mkdir temp/west
mkdir temp/east

cp goes.gsfc.nasa.gov/goescolor/goeswest/overview2/color_lrg/older_images/*.jpg temp/west
cp goes.gsfc.nasa.gov/goescolor/goeswest/overview2/color_lrg/*.jpg temp/west

cp goes.gsfc.nasa.gov/goescolor/goeseast/overview2/color_lrg/older_images/*.jpg temp/east
cp goes.gsfc.nasa.gov/goescolor/goeseast/overview2/color_lrg/*.jpg temp/east

rm temp/west/latest*.jpg
rm temp/east/latest*.jpg

mkdir temp/west/lower
mkdir temp/west/upper
mkdir temp/west/full

mkdir temp/east/upperbig
mkdir temp/east/uppersmall
mkdir temp/east/full
mkdir temp/east/lower

mv temp/west/*22.jpg   temp/west/lower
mv temp/west/*52.jpg   temp/west/lower
mv temp/west/*30.jpg   temp/west/upper
mv temp/west/*45.jpg   temp/west/upper
mv temp/west/*15.jpg   temp/west/upper
mv temp/west/*0000.jpg temp/west/full
mv temp/west/*0300.jpg temp/west/full
mv temp/west/*0600.jpg temp/west/full
mv temp/west/*0900.jpg temp/west/full
mv temp/west/*1200.jpg temp/west/full
mv temp/west/*1500.jpg temp/west/full
mv temp/west/*1800.jpg temp/west/full
mv temp/west/*2100.jpg temp/west/full
mv temp/west/*00.jpg   temp/west/upper


mv temp/east/*0545.jpg temp/east/full
mv temp/east/*0845.jpg temp/east/full
mv temp/east/*1145.jpg temp/east/full
mv temp/east/*1445.jpg temp/east/full
mv temp/east/*1745.jpg temp/east/full
mv temp/east/*2045.jpg temp/east/full
mv temp/east/*2345.jpg temp/east/full
mv temp/east/*0245.jpg temp/east/full
mv temp/east/*45.jpg   temp/east/upperbig
mv temp/east/*15.jpg   temp/east/upperbig
mv temp/east/*9.jpg    temp/east/lower
mv temp/east/*1.jpg    temp/east/uppersmall

ls temp/west/lower/*.jpg -rt > filelist.txt
ls temp/west/upper/*.jpg -rt >> filelist.txt
ls temp/west/full/*.jpg  -rt >> filelist.txt

ls temp/east/upperbig/*.jpg   -rt >> filelist.txt
ls temp/east/uppersmall/*.jpg -rt >> filelist.txt
ls temp/east/full/*.jpg       -rt >> filelist.txt
ls temp/east/lower/*.jpg      -rt >> filelist.txt


mencoder "mf://@filelist.txt" -mf fps=12 -o no_sound.avi -ovc lavc -lavcopts vcodec=mpeg4:vbitrate=4000 -vf scale=640:480
mencoder -oac copy -ovc copy  -o output_movie5.avi -audiofile music.mp3 no_sound.avi

I'ts really basic and intended for running it once, and then deleting all the folders. Enjoy!

Monday, November 29, 2010

How to edit grub files so Ubuntu boots after installing Fedora

Recently I installed Fedora 14 as a third OS, having Ubuntu 10.10 and Windows XP in other partitions. I told Fedora to install the grub loader, and now I had this in /boot/grub/grub.conf :

# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE:  You do not have a /boot partition.  This means that
#          all kernel and initrd paths are relative to /, eg.
#          root (hd0,5)
#          kernel /boot/vmlinuz-version ro root=/dev/sdb6
#          initrd /boot/initrd-[generic-]version.img
#boot=/dev/sdb
default=0
timeout=5
splashimage=(hd0,5)/boot/grub/splash.xpm.gz
hiddenmenu
title Fedora (2.6.35.6-48.fc14.i686)
    root (hd0,5)
    kernel /boot/vmlinuz-2.6.35.6-48.fc14.i686 ro root=UUID=e0a1c43c-0bc5-4762-b497-16f99a6e8bc8 rd_NO_LUKS rd_NO_LVM rd_NO_MD rd_NO_DM LANG=en_US.UTF-8 SYSFONT=latarcyrheb-sun16 KEYBOARDTYPE=pc KEYTABLE=us rhgb quiet
    initrd /boot/initramfs-2.6.35.6-48.fc14.i686.img
title Fedora (2.6.35.6-45.fc14.i686)
    root (hd0,5)
    kernel /boot/vmlinuz-2.6.35.6-45.fc14.i686 ro root=UUID=e0a1c43c-0bc5-4762-b497-16f99a6e8bc8 rd_NO_LUKS rd_NO_LVM rd_NO_MD rd_NO_DM LANG=en_US.UTF-8 SYSFONT=latarcyrheb-sun16 KEYBOARDTYPE=pc KEYTABLE=us rhgb quiet
    initrd /boot/initramfs-2.6.35.6-45.fc14.i686.img
title Ubuntu 
    rootnoverify (hd0,2)
    chainloader +1
title Windows XP
    rootnoverify (hd0,1)
    chainloader +1

 But when I tried to boot to my Ubuntu, it didn't work. This is how I solved it:


We will need to edit some files as root, the easiest way to do this, IMHO, is to open terminal and run
sudo nautilus
so we can browse everything as root and edit what we please, or
sudo gedit file_to_edit
to just edit a single file as root.
But Fedora does not allow you to "sudo" by default.


And if you try

su
nautilus
or
su
gedit


It doesn't work. (http://forums.fedoraforum.org/showthread.php?t=253687)
So let's add our user to the sudoers file.

Open a terminal, run
su
(enter password)
visudo
page-down to the bottom
press "insert" key to start editing, and add this line to the bottom:

laura ALL=(ALL) ALL

where "laura" is your username. Press esc, and then type
:wq
to save and exit. (A more complete guide for this can be found here: http://fedorasolved.org/post-install-solutions/sudo )

Ok now finally we can "sudo nautilus". We need to edit /boot/grub/grub.conf from our Fedora root partition.

We can comment the lines

#splashimage=(hd0,5)/boot/grub/splash.xpm.gz
#hiddenmenu

(by placing "#" in front) if we like. This is so the grub menu appears when booting without pressing any key, it is easier that way to reboot several times and always see the grub menu. You can uncomment it again later.

Now open a nautilus as a normal user, and make sure the partition where your ubuntu root resides is mounted. (Click its name if it doesn't have the "eject" arrow to the right) Now that mount will be visible from your root nautilus. (??? Why do we need to do this? it is a mystery: nautilus as root does not list all available disks or partitions like normal-user nautlus does).

(Here we see the root nautilus to the right, where the partition mounted as "127 GB Filesystem" in the normal-user nautilus, is shown as a long UUID).

Then open /boot/grub/grub.cfg, we will not edit this file, we'll just copy some lines from it to the fedora /boot/grub/grub.conf file.
It will contain something like this:

#
# DO NOT EDIT THIS FILE
#
# It is automatically generated by grub-mkconfig using templates
# from /etc/grub.d and settings from /etc/default/grub
#

### BEGIN /etc/grub.d/00_header ###
if [ -s $prefix/grubenv ]; then

[snip]


### BEGIN /etc/grub.d/10_linux ###
menuentry 'Ubuntu, with Linux 2.6.35-23-generic' --class ubuntu --class gnu-linux --class gnu --class os {
    recordfail
    insmod part_msdos
    insmod ext2
    set root='(hd0,msdos3)'
    search --no-floppy --fs-uuid --set 3089130e-0a2e-4f80-8eee-a3030a6810ea
    linux    /boot/vmlinuz-2.6.35-23-generic root=UUID=3089130e-0a2e-4f80-8eee-a3030a6810ea ro   quiet splash
    initrd    /boot/initrd.img-2.6.35-23-generic
}

[snip]

This is the part we are interested in:
linux    /boot/vmlinuz-2.6.35-23-generic root=UUID=3089130e-0a2e-4f80-8eee-a3030a6810ea ro   quiet splash
initrd   /boot/initrd.img-2.6.35-23-generic 



copy these lines to your Fedora /boot/grub/grub.conf and replace the word "linux" to "kernel". It should look like this now:

# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE:  You do not have a /boot partition.  This means that
#          all kernel and initrd paths are relative to /, eg.
#          root (hd0,5)
#          kernel /boot/vmlinuz-version ro root=/dev/sdb6
#          initrd /boot/initrd-[generic-]version.img
#boot=/dev/sdb
default=0
timeout=5
#splashimage=(hd0,5)/boot/grub/splash.xpm.gz
#hiddenmenu
title Fedora (2.6.35.6-48.fc14.i686)
root (hd0,5)
kernel /boot/vmlinuz-2.6.35.6-48.fc14.i686 ro root=UUID=e0a1c43c-0bc5-4762-b497-16f99a6e8bc8 rd_NO_LUKS rd_NO_LVM rd_NO_MD rd_NO_DM LANG=en_US.UTF-8 SYSFONT=latarcyrheb-sun16 KEYBOARDTYPE=pc KEYTABLE=us rhgb quiet
initrd /boot/initramfs-2.6.35.6-48.fc14.i686.img
title Fedora (2.6.35.6-45.fc14.i686)
root (hd0,5)
kernel /boot/vmlinuz-2.6.35.6-45.fc14.i686 ro root=UUID=e0a1c43c-0bc5-4762-b497-16f99a6e8bc8 rd_NO_LUKS rd_NO_LVM rd_NO_MD rd_NO_DM LANG=en_US.UTF-8 SYSFONT=latarcyrheb-sun16 KEYBOARDTYPE=pc KEYTABLE=us rhgb quiet
initrd /boot/initramfs-2.6.35.6-45.fc14.i686.img
title Ubuntu 2.6.35-23-generic
root (hd0,2)
kernel /boot/vmlinuz-2.6.35-23-generic root=UUID=3089130e-0a2e-4f80-8eee-a3030a6810ea ro quiet splash
initrd /boot/initrd.img-2.6.35-23-generic
title Windows XP rootnoverify (hd0,1) chainloader +1

I marked with red the modified parts. After updating the Ubuntu Kernel, you need to modify this file again so you can boot Ubuntu using that new kernel. Well, that's all for today, hope this helped someone. If you know better ways to do this, your input is welcome in the comments. I read somewhere that it's better to install Ubuntu last, because it recognizes installed OSs better, but I haven't tested this.