Friday, October 28, 2011

Hacking contest for women

Power of XX is a hacking contest for WOMEN ONLY, hosted by SISS (Sookmyung Information Security Study) as an event in POC2011. Power of XX is an event where women interested in hacking and information security gather, share knowledge on information security, and showcase defense strategy against hacking.

read more at http://powerofxx.com

Saturday, March 5, 2011

Setting up my development environment in Fedora

The last couple of days I started having problems after updating and rebuilding cheese master branch and the other packages it uses (running jhbuild -acf build cheese). This was in my Ubuntu partition.

Every time the mouse entered the clutter stage I got a segmentation fault. I debugged it a little but I didn't find the cause, just a null pointer in the handling of CLUTTER_ENTER event inside clutter. But the gtk-clutter-events example in clutter-gtk worked fine, so it was a problem related to cheese I guess, or something I forgot to update, or some mixture caused by my attempts to build cheese gtk3 branch, I don't really know.

A little tired, I decided I'd set up the development enviroment in my fedora partition (which I barely used before, so it was in a "fresh install" state), something I wanted to try anyway to see how it worked.

It's a long and tedious process:


download from git, build and install jhbuild
create .jhbuildrc 
(already had it)

install some packages needed by jhbuild sanitycheck
(jhbuild bootstrap)

jhbuild sanitycheck keeps complaining about automake 1.8/1.9 after bootstrap, 
(install automake 1.8.5 and 1.8 from sources, still complains, ignore it and continue)(this was a mistake I had to deal with later)

cannot connect to gnome git, public key issue after copying existing keys from ubuntu partition to .ssh in fedora partition
(change keys owner from root to laura)

g++ is missing 
(install "c++ support for gcc")

$ jhbuild build cheese

*** Error during phase configure of gnome-doc-utils:
No package 'libxml-2.0' found
No package 'libxslt' found
(instal libxml-devel, libxslt-devel)

*** Error during phase configure of fontconfigerror: 
You must have freetype installed; 
(install freetype-devel)

*** Error during phase force_checkout of cairo: 
/bin/sh: patch: command not found
(install patch)

*** Error during phase configure of cairo: 
libpng not found 
(install libpng-devel)

*** Error during phase configure of gdk-pixbuf:
libtiff not found
(install libtiff-devel)

*** Error during phase configure of gdk-pixbuf:
libjpeg not found
(install libjpeg-devel)

*** Error during phase configure of gtk+
configure:22402: checking for XOpenDisplay
configure:22406: error: *** libX11 not found. Check 'config.log' for more details.
(install libXrender-devel)

*** Error during phase configure of libIDL:
configure: error: flex is required to create the libIDL scanner 
(install flex "a tool for creating scanners")

*** Error during phase configure of libIDL: 
yacc is not usable as yacc - consider using bison
(install bison "GNU general purpose parser generator")

*** Error during phase configure of libIDL: 
makeinfo: command not found
(install texinfo)

*** Error during phase build of gtk+-3:
gdkdeviceprivate-xi.h:28:35: fatal error: X11/extensions/XInput.h: No such file or directory
(install libxi-devel)

*** Error during phase configure of dbus-glib:configure: 
error: DBus development libraries not found
(install dbus-devel)

*** Error during phase configure of gconf:
introspection.m4 not found
(install gobject-introspection-devel)

*** Error during phase configure of gudev:
configure: error: gperf is needed
(install gperf)

*** Error during phase configure of gudev:
configure: error: libacl not found
(install libacl-devel)

*** Error during phase configure of gudev:
No package 'libusb' found
(install libusb-devel)

*** Error during phase build of gudev:
No package 'libudev' found
(install libudev-devel)

This happened a couple of times while trying to checkout different packages:
Submodule 'common' (git://anongit.freedesktop.org/gstreamer/common) registered for path 'common'
git submodule update
Cloning into common...
and it stays there indefinitely
(Ctrl-c rerun phase, repeat until it starts)

*** Error during phase configure of clutter:
checking for XCOMPOSITE extension >= 0.4... configure: error: not found
(install libXcomposite development package)

*** Error during phase build of clutter-gst:
Couldn't find include 'Clutter-1.0.gir' (search path: ['.', 'path=.', '/home/laura/00_code/opt/gnome/share/gir-1.0', '/usr/share/gir-1.0', '/usr/share/gir-1.0', '/usr/share/gir-1.0'])
(./configure clutter adding --enable-introspection option (jhbuild shell, config.log command)
  clutter asks for gobject-introspection with higher version than that of fedora repository
  jhbuild buildone gobject-introspection
    *** Error during phase configure of gobject-introspection:
    configure: error: Python headers not found
    (install python-devel) 
make && make install clutter
Couldn't find include 'Atk-1n.0.gir'
jhbuild build -acf cheese *facepalm* (it means start over from the beginning))

*** Error during phase configure of clutter-gtk:
configure.ac:33: require Automake 1.11, but have 1.10.3
automake --version
Useless use of /d modifier in transliteration operator at /usr/local/share/automake-1.8/Automake/Wrap.pm line 60.
automake (GNU automake) 1.8.5
(make uninstall automake 1.8.5 and 1.8 both from opt and /usr, uninstalled and reinstalled automake 1.11.1 and libtool while trying to fix this, I don't know if it's needed)

*** Error during phase configure of startup-notification:
configure: error: X11 development libraries/headers not found
(check config.log to see what failed, X11/Intrinsic.h was not there, install libXt-devel)

*** Error during phase configure of libproxy:
/bin/sh: cmake: command not found
(install cmake)

*** Error during phase configure of glib-networking:
configure: error: "No package 'gnutls' found"
(install gnutls-devel)

*** Error during phase configure of libsoup:
No package 'sqlite3' found
(install sqlite-devel)

*** Error during phase configure of gnome-disk-utility:
No package 'udisks' found
(install udisks-devel)

*** Error during phase configure of gnome-disk-utility:
No package 'avahi-ui-gtk3' found
(install avahi-ui-gtk3 ? no. install avahi-ui-devel)

*** Error during phase build of gnome-disk-utility:
/usr/lib/libgtk-x11-3.0.so.0: undefined reference to `g_application_add_action'
/usr/lib/libgtk-x11-3.0.so.0: undefined reference to `g_application_set_action_enabled'
/usr/lib/libgtk-x11-3.0.so.0: undefined reference to `g_application_quit_with_data'
(removed .la files, rerun phase configure, same error)
(give up, add gnome-disk-utility to skip.extend in .jhbuildrc)


*** Error during phase configure of evolution-data-server:
checking Berkeley DB... configure: error: Cannot find libdb
(install libdb-devel)

*** Error during phase configure of evolution-data-server:
configure: error: NSPR headers not found. Use --with-nspr-includes to specify the include dir of NSPR. (same for nss)
(install nspr-devel nss-devel
run ./configure --enable-maintainer-mode --prefix /home/laura/00_code/opt/gnome --libdir /home/laura/00_code/opt/gnome/lib --disable-static --with-nspr-includes=/usr/include/nspr4 --with-nss-includes=/usr/include/nss3 )

////////
$ jhbuild build libcanberra:

*** Error during phase configure of libcanberra:
configure: error: Unable to find libltdl.
(install libtool-ltdl-devel)

*** Error during phase configure of libcanberra: 
No package 'vorbisfile' found
(install libvorbis-devel)

*** Error during phase configure of cheese:
No package 'clutter-gtk-0.10' found 
(known bug https://bugzilla.gnome.org/show_bug.cgi?id=632834)
(switch to clutter-gtk-0.10 remote branch rebuild it and install it)

$ jhbuild run cheese
Gtk-Message: Failed to load module "pk-gtk-module"
(ignore it https://bugzilla.redhat.com/show_bug.cgi?id=476066)

GLib-GIO-Message: Using the 'memory' GSettings backend.  Your settings will not be saved or shared with other applications.
(jhbuild build dconf)

(cheese:17888): Gtk-WARNING **: Could not find the icon 'image-loading'. The 'hicolor' theme
(?)

Error: One or more needed GStreamer elements are missing: oggmux, theoraenc, vorbisenc.
(install libtheora-devel reconfigure/rebuild gst-plugins-base)

$ git clone git://anongit.freedesktop.org/gstreamer/gst-plugins-bad
*** Plug-ins with dependencies that will NOT be built:
...
opencv
(install opencv and opencv-devel)

video preview looks garbled
(install libxv-devel, reconfigure rebuild reinstall gst-plugins-base, select xvimagesink in gstreamer-properties)




I tried to think ways to make this a little bit better. For starters,
1) Add the unneeded packages to skip.extend in .jhbuildrc

This is the complete list of 47 packages built by "jhbuild build cheese":
$ jhbuild list cheese
gnome-common
intltool
rarian
gnome-doc-utils
gtk-doc
glib
fontconfig
pixman
cairo
gobject-introspection
pango
atk
gdk-pixbuf
shared-mime-info
gtk+
libIDL
ORBit2
gtk+-3
dbus-glib
gconf
gstreamer
liboil
gudev
gst-plugins-base
gst-plugins-good
json-glib
clutter
clutter-gst
clutter-gtk
libgee
gnome-video-effects
libcroco
librsvg
startup-notification
libnotify
libnl
libgnome-keyring
libproxy
glib-networking
libsoup
gvfs
gnome-desktop
libgweather
libical
libgdata
evolution-data-server
cheese

But I don't know yet which can be skipped and which are really needed.

2) Add some needed packages to that list: vala, libcanberra, gst-plugins-bad
3) Everytime I got an error complaining about a package not found, I searched its name in the package manager gui and added the related devel package. It would be great if somehow, jhbuild didn't stop with a prompt every time this happened, and listed instead all the errors about missing packages together after trying to configure the complete list of packages. Then try to add all the devel packages together somehow. (script? different gui for package manager that allows to list all currently installed packages with their devel counterparts and then "select all"?)
4) thinking about potential new contributors that are just starting, the error messages don't imply the solution at all, this causes lots of google searches. I can't think of an automated solution for this, since the error messages are written by people, and trying to set standards or guidelines for them will not be really effective. They vary a lot and are sometimes misleading. (Check the X11 cases).
5) ?

And on top of all this, this is the result:


Some minor variations in the results when starting cheese with different effects already selected.
I know that for the frei0r effects to work I need to install frei0r-plugins from fedora repos. (those would be the brownish "Cartoon", "Che Guevara", "Chrome", etc.). About the other effects, I had the same exact subset of effects that behaved a little different in ubuntu too, but with different symptoms. I haven't investigated what is exactly the difference between them.

These are the three different sets:

Look fineGarbled (pink hue in ubuntu)frei0r

Bulge
Heat
Kaleidoscope
Mirror
Pinch
Sepia
Square
Stretch
Twirl
X-Ray

No Effect
Dice
Edge
Historical
Hulk
Kung-Fu
Mauve
Noir/Blanc
Optical Illusion
Quark
Radioactive
Ripple
Saturation
Shagadelic
Vertigo
Warp
Waveform

Cartoon
Che Guevara
Chrome
Distortion
Invertion
Sobel
Time Delay

The exact behavior of these bugs depends on which effect was already seleted when starting cheese.

But anyway, now the mouse entering the stage does not cause a segmentation fault. Now I can keep testing my faceoverlay plugin that still have some problems when selecting and deselecting the effect (changing from READY to NULL and from NULL to READY in the pipeline), and that was the goal of all this. ;)

Monday, February 28, 2011

opencv Haarcascade files in Ubuntu 10.10 (Maverick)

The haarcascade files used by opencv library to detect faces and other features are not being shipped in Ubuntu 10.10 (Maverick). There is an open bug for the issue:

https://bugs.launchpad.net/opencv/+bug/698016

This means Ubuntu 10.10 users won't be able to see the Face Overlay effect in Cheese :(

These are the missing files:

/usr/share/opencv/haarcascades/haarcascade_eye.xml
/usr/share/opencv/haarcascades/haarcascade_eye_tree_eyeglasses.xml
/usr/share/opencv/haarcascades/haarcascade_frontalface_alt.xml
/usr/share/opencv/haarcascades/haarcascade_frontalface_alt2.xml
/usr/share/opencv/haarcascades/haarcascade_frontalface_alt_tree.xml
/usr/share/opencv/haarcascades/haarcascade_frontalface_default.xml
/usr/share/opencv/haarcascades/haarcascade_fullbody.xml
/usr/share/opencv/haarcascades/haarcascade_lefteye_2splits.xml
/usr/share/opencv/haarcascades/haarcascade_lowerbody.xml
/usr/share/opencv/haarcascades/haarcascade_mcs_eyepair_big.xml
/usr/share/opencv/haarcascades/haarcascade_mcs_eyepair_small.xml
/usr/share/opencv/haarcascades/haarcascade_mcs_lefteye.xml
/usr/share/opencv/haarcascades/haarcascade_mcs_mouth.xml
/usr/share/opencv/haarcascades/haarcascade_mcs_nose.xml
/usr/share/opencv/haarcascades/haarcascade_mcs_righteye.xml
/usr/share/opencv/haarcascades/haarcascade_mcs_upperbody.xml
/usr/share/opencv/haarcascades/haarcascade_profileface.xml
/usr/share/opencv/haarcascades/haarcascade_righteye_2splits.xml
/usr/share/opencv/haarcascades/haarcascade_upperbody.xml

Add yourself to the "people affected by this" list in the bug to make its heat value go up! ;)

Friday, February 18, 2011

Face overlays

I've finished the first version of the GStreamer plugin that encapsulates facedetect and rsvgoverlay plugins.

I created a GstBin derived plugin that handles the bus messages sent by facedetect, then I allow the user to change the image size and position relative to the face itself. So any image can be placed above, below, to the left or right of your face, and it will have the right size when you get near or far away from the camera. Width and height can also be set as fractions of the face size.

I handle the bus messages sent by facedetect element in the container bin itself. At first I thought I would need to catch events in a custom internal element placed between the facedetect and the rsvgoverlay elements. This solution ended up being simpler and better, and we didn't have to add event sending functions to facedetect.


To see it working I downloaded some random images from openclipart and tweaked their sizes and positions so they would fit my face.



So, this took me a little longer than I thought, but I learned a lot about GStreamer plugins. Now I'll ask some people to review my code so it can be uploaded to gst-plugins-bad. Enjoy!

edit: here is the patch https://bugzilla.gnome.org/show_bug.cgi?id=642759

New SVG overlays

Several new designs for frame overlays were kindly submitted and as promised I'll announce the names of the winners:

We have two winners! ;)
And they are: Peter Shinners, for the images in the left column, and Michał Prędotka for the images in the right column!


All images will be included in gnome-video-effects as examples, and (I think) two will be shown in cheese as effects. I like the kiss and polaroid ones myself!

Monday, February 7, 2011

A new GStreamer plugin

Some time ago, I bumped into a dead end when trying to implement the face-tracking overlays feature. The problem started when I tried to set the overlay width and height in run time.

The opencv facedetect gst-plugin sends bus messages with the x, y, width and height of the faces it detects. I captured the messages and set the rsvgoverlay element x and y properties without problems. But rsvgoverlay element lacks width and height properties.

This meant that if you moved your face away or close from the camera, the mask would still look the same size, or if the svg dimensions were huge or tiny, it would look that way instead of resizing to the face size.

I contacted rsvgoverlay maintainer Olivier Aubert to see if width and height could be added as properties for that element. He preferred not to and explained to me the reasons. (He pointed me to this bug where coincidentally Luciana had asked for something similar before our internships in GNOME Outreach program started, and she implemented a plugin for png overlays already, I haven't checked it yet).

Well, Olivier suggested I used the SVG data itself to set size and position. So I started implementing this:

case GST_MESSAGE_ELEMENT:
{
  if (strcmp (gst_structure_get_name (message->structure), "facedetect") == 0)
  {
    CheeseCameraPrivate *priv = CHEESE_CAMERA_GET_PRIVATE (camera);
    
    guint x, y, width, height;
    gchar *svg_data;
    const GstStructure *face;
    int face_count;
    
    /* TODO: get coordinates of multiple faces: 
       for (i=0; i < gst_value_list_get_size (gst_structure_get_value (message->structure, "faces")); i++) { ... }
    */
    face_count = gst_value_list_get_size (gst_structure_get_value (message->structure, "faces"));
    /* The last face in the list seems to be the right one, objects mistakenly 
     * detected as faces for a couple of frames seem to be in the list 
     * beginning. TODO: needs confirmation. */
    face = gst_value_get_structure (gst_value_list_get_value (gst_structure_get_value (message->structure, "faces"), face_count-1));
    gst_structure_get_uint (face, "x",      &x);
    gst_structure_get_uint (face, "y",      &y);
    gst_structure_get_uint (face, "width",  &width);
    gst_structure_get_uint (face, "height", &height);
             
    /* TODO: allow different positioning according to type of overlay
    if hat
    if beard
    x = the face right temple, so think a way to allow hats to go above, 
    beards to go midway below, etc.
    */
    
    /* TODO: ViewBox size affects anything? */
    svg_data = g_strdup_printf ("<svg viewBox=\"0 0 800 600\"><image x=\"%u\" y=\"%u\" width=\"%u\" height=\"%u\" xlink:href=\"%s\" /></svg>",
                                x, 
                                y, 
                                width, 
                                height, 
                                "/path/to/foo.svg");
    /* FIXME: Problem is right here ^^^^^^^^^^^^^^ I have no way of knowing the 
     * file path on run time with what we currently have. */
    
    /* The rsvgoverlay element in face recognition + svg overlay effects 
     * must be named "face_overlay" for this to work. Not very nice. 
     * TODO: iterate effect_filter bin elements looking for the rsvgoverlay 
     * element */
    GstElement *overlay_element = gst_bin_get_by_name (GST_BIN (priv->effect_filter), "face_overlay");                    
    g_object_set (overlay_element, "data", svg_data, NULL);
    
    g_object_unref (overlay_element);
    g_free(svg_data);
  }
}
break;


Then I realized: for this to work, I needed the SVG file path and we don't have a way to know it on runtime right now. It is parsed as part of the pipeline description from the .effect files in gnome-video-effects and the entire pipeline description is used to create the rsvgoverlay element. The same applies to all other effects. So to access that path, we would have to start knowing which effect we are handling at a specific time inside of cheese, and we don't want to do that.

Other option would be to parse the .effect files in a different way. That's something that is already being discussed here and it will allow for more functionality than I need for this.

So I started writing my very own GStreamer plugin, to have more control and manage several options and use cases better. Maybe I'll be using the existing rsvgoverlay and facedetect plugins somehow.

Last days I was following the steps in GStreamer Plugin Writer's Guide and climbing the vertical autotools learning curve. Hoo boy.


About Autotools:

Task #1: add a subdirectory named "pixmaps" with .svg images to gnome-video-effects to be installed in /usr/share/gnome-video-effects/pixmaps when running make install.

The files to edit were: gnome-video-effects/configure.ac and gnome-video-effects/Makefile.am

diff --git a/Makefile.am b/Makefile.am
index 8638fc8..b5b52fb 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = effects
+SUBDIRS = effects pixmaps
 
 DIST_SUBDIRS = $(SUBDIRS) po
 
diff --git a/configure.ac b/configure.ac
index 499b6f2..9d33ffb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -23,5 +23,6 @@ AC_OUTPUT([
 Makefile
 gnome-video-effects.pc
 effects/Makefile
+pixmaps/Makefile
 po/Makefile.in
 ])

And a new Makefile.am needs to be added in the new pixmaps directory:

pixmapsdir = $(datadir)/gnome-video-effects/pixmaps

pixmaps_DATA = \
  kiss.svg \
  snow.svg \
  birthday-card.svg \
  microphone.svg
    
EXTRA_DIST = \
    $(pixmaps_DATA)

It looks simple now, but finding out how to do this, from which files to edit to what to add there, was a guessing-in-the-dark ordeal.

Task #2: include <cv.h> in my new plugin header file. Run "make" without errors.
Holy tap-dancing christ with crutches. This is so easy to do in Visual Studio. Just add the include path and the library to link against. But what to say about autotools that hasn't been said already? (With this I'm not saying that everything about programming in Windows is better, absolutely on the contrary: programming in linux is paradise compared to that. But creating a new little project to tinker and test things quickly? Yes, that is lacking in linux that I know of).

Files that needed to be edited: configure.ac in top-level directory, and Makefikle.am in src directory.

Here I include the entire Makefile.am file with added parts in blue:


# Note: plugindir is set in configure

##############################################################################
# TODO: change libgstplugin.la to something else, e.g. libmysomething.la     #
##############################################################################
plugin_LTLIBRARIES = libgstfaceoverlay.la

##############################################################################
# TODO: for the next set of variables, name the prefix if you named the .la, #
#  e.g. libmysomething.la => libmysomething_la_SOURCES                       #
#                            libmysomething_la_CFLAGS                        #
#                            libmysomething_la_LIBADD                        #
#                            libmysomething_la_LDFLAGS                       #
##############################################################################

# sources used to compile this plug-in
libgstfaceoverlay_la_SOURCES = gstfaceoverlay.c gstfaceoverlay.h

# compiler and linker flags used to compile this plugin, set in configure.ac
libgstfaceoverlay_la_CFLAGS = $(GST_CFLAGS) $(OPENCV_CFLAGS)
libgstfaceoverlay_la_LIBADD = $(GST_LIBS) $(OPENCV_LIBS) 
libgstfaceoverlay_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
libgstfaceoverlay_la_LIBTOOLFLAGS = --tag=disable-static

# headers we need but don't want installed
noinst_HEADERS = gstfaceoverlay.h

Such a simple starter Makefile.am with instructions, such a small change to add. But to discover what had to be changed!

And to configure.ac I added:

dnl *** opencv ***
translit(dnm, m, l) AM_CONDITIONAL(USE_OPENCV, true)

  dnl we specify a max. version too because we set CV_NO_BACKWARD_COMPATIBILITY
  dnl and don't want the build to break when a new opencv version comes out.
  dnl Need to adjust this upwards once we know that our code compiles fine with
  dnl a new version and the no-backward-compatibility define. (There doesn't
  dnl seem to be a switch to suppress the warnings the cvcompat.h header
  dnl causes.)
  PKG_CHECK_MODULES(OPENCV, opencv >= 2.0.0 opencv <= 2.1.0 , [
    AC_PROG_CXX
    AC_LANG_CPLUSPLUS
    OLD_CPPFLAGS=$CPPFLAGS
    CPPFLAGS=$OPENCV_CFLAGS
    AC_CHECK_HEADER(highgui.h, HAVE_HIGHGUI="yes", HAVE_HIGHGUI="no")
    AC_CHECK_HEADER(cvaux.h, HAVE_CVAUX="yes", HAVE_CVAUX="no")
    CPPFLAGS=$OLD_CPPFLAGS
    AC_LANG_C
    if test "x$HAVE_HIGHGUI" = "xno"; then
      AC_MSG_RESULT(highgui.h could not be found.)
      HAVE_OPENCV="no"
    elif test "x$HAVE_CVAUX" = "xno"; then
      AC_MSG_RESULT(cvaux.h could not be found.)
      HAVE_OPENCV="no"
    else
      HAVE_OPENCV="yes" 
      AC_SUBST(OPENCV_CFLAGS)
      AC_SUBST(OPENCV_LIBS)  
    fi
  ], [
    HAVE_OPENCV="no"
    AC_MSG_RESULT(no)
  ])

And I don't even know if this last one is really ok because I placed the AC_SUBST macros inside an if and I don't know if that's valid. All this was made copying from already working projects with similar stuff and changing things until it worked, 9879864 "./autogen.sh &&./configure && make && make install" attempts later.



A programmer in fierce battle against GNU Autotools

How is it possible...? That it's so difficult? I cannot believe it. I felt that I needed to change a lightbulb; the documentation explained the history of electricity, the reference was as big as a manual to build your own nuclear reactor, and the examples explained how to light a candle.
Just this minute I found this: http://smalltalk.gnu.org/blog/bonzinip/all-you-should-really-know-about-autoconf-and-automake
I had to google "GNU Autotools hate" to find it.
And there is a lot more I'd like to say about autotools! But I'll let that for a RANT&RAGE type post, if I ever get to write about it ;)

Thursday, February 3, 2011

Cheese decoration design contest

Cheese will soon include effects that show .svg files above the video (and of course in the captured pictures and recordings). The idea is to add three or four effects with cool designs until an easy way for the user to use his/her own images is implemented.


So far, we have these images:




Adapted from http://www.openclipart.org contributions ( all clipart found there is released under http://creativecommons.org/publicdomain/zero/1.0 ).

Think you can do better? Do you want your design to be chosen and seen by all Cheese users, bringing fame, fortune and complete bliss into your life? =P I promise, if you submit a design, it will rain cookies and marmalade in your country for a week.

Ahem! I mean, submit your design and a strict jury of artists and graphical designers will select the best among the thousands of submissions. It's not likely your design will be selected, competition will be fierce. Maybe, If you are good enough, you know. One of the jurors is Andy Warhol himself. Yep, I have his living brain here in my house in a jar, like a futurama head.

Now seriously, send your design if you want, and I hope I can include it in the list of effect previews. I can't promise anything because I don't know how many collaborations I will receive, but it will make it for sure in the examples folder so the users will have them available when drag-and-drop of svg files is implemented. Of course your name will appear in the credits under "artwork by" tab in "About" dialog.


These images won't move and will be resized automatically according to the video resolution, so any .svg dimension is ok as long as the proportions allow them to look good in commonly used video aspect ratios. (4:3, 3:2, 16:9 I guess, depends on the user's capture device).


So bring them on! ;)

Edit:
Deadline is Feb 16 2011, and Feb 18 the selected images will be announced ;)

Submit your images here: https://bugzilla.gnome.org/show_bug.cgi?id=641444

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 ;)