February 02, 2012

Jean-François Fortin TamAventuras en Málaga y Ronda

Last week was a blast. Spending a couple of days working on Pitivi fulltime and meeting with the awesome GStreamer folks again was a thrilling experience. Not only that, but it happened in the beautiful city of Málaga.

Coming from Montréal, I’m still a bit shocked at the sight of people wearing coats, scarves and tuques in broad daylight at +15°C.

Hell, the weather in Malaga was so consistently mild that even if we were in the middle of January, in the morning I went outside straight from the shower with wet hair, which dried in minutes!

While we’re talking about showers again… Malagans, unlike Bostonians, got the usability of their shower handles/lever/thingie right. However, they completely fail at road signage and urban planning. I thought I’d never see the day when I’d find something worse than the province of Québec, but it seems we have a new winner here:

  • Street names written in minuscule font sizes on buildings (when they are present at all)? Check.
  • Road signs inside the ramps/exits (when it’s too late)? Check. (Québec has that too)
  • One-ways everywhere? Check.
  • Inability to get back on a highway if you take the wrong exit? Check.
  • Roundabouts where you have to yield to people outside the roundabout? Check.
  • Roundabouts with streetlights every 30 degrees? Check.
  • Tiny road signs inside the roundabout instead of on exits? Check.

I found this all quite amusing. Except when Antigoni and I had to get back to the airport and mistakenly ended up on an exit ramp on avenida de Andalucía.

Okay, back to the hackfest.

Notwithstanding the work we did on planes or busy airports and the many discussions we’ve had around tapas, we spent three days doing solid coding, debugging and ass-kickin’ on Pitivi and GES. I’m very happy that, in the process, Antigoni learned some new tricks and knowledge to make her more comfortable with hacking on the pitivi codebase. We also got our shares of laughs too. Like the fact that I ate three hours of Edward’s time trying to investigate why importing clips crunched my hard drive for many seconds… and then realizing that the culprit was not my code nor the gst discoverer, but GTK+ itself.

More precisely:

  • Thibault spent the whole time hacking on GES and answering our questions.
  • Antigoni went concrete/practical by attempting to fix undo/redo for effects, getting more familiar with GES in the process. I’m happy to have been able to answer some of her questions and being able to point out pitfalls in the code: at times, it even seemed like I knew what I was talking about, which is always a great thing!
  • Edward spent nearly the whole time grunting and swearing in French, except when the sound was muffled by his palms:

As for me, I:

  • Fixed image thumbnailing/permissions on the wiki and deleted 1846 spam image files scattered in 1539 folders.
  • Reimplemented pitivi’s clip import process using the asynchroneous gst discoverer, which means that not only does the import progressbar work again, but it is blazing fast and doesn’t block the UI.
  • Cleaned up code, standardized variables and fixed various bugs (such as seeking to the end of the timeline, or making the viewer check the pipeline position only when actually playing… your CPU will thank me)
  • Implemented the ability to save/export the current frame as an image file. Hey, the code was just sitting there in GES, waiting to be used!
  • Got convinced by Thibault to try implementing transitions and timeline video thumbnails myself. We’ll see how it goes.

We stayed one or two days after the end of the hackfest. Thus, on Saturday, pretty much the only day where weather sucked, the superhacker trio went on a touristic ride to Ronda, in awe at some of the alpine beauties of Andalucía:

More pics here.

This week made me realize/feel something even more strongly than before: since Thibault’s massive cleanup, hacking on Pitivi with GES is easy. No more files/modules confusion. No more “massive core” getting in your way. The code can still benefit from some cleanup/simplifications to make it feel more “pythonic” (patches welcome), but it already feels incredibly more agile and elegant. It now feels enjoyable rather than a maintenance ordeal. More like poetry, less like a thesis.

If you were hesitating to contribute to Pitivi, now is an exciting time to take a fresh look at it. We need help and there’s a lot of low hanging fruit that can be fixed. We’ll be happy to help you get started.

by nekohayo at February 02, 2012 03:35 PM

February 01, 2012

Andy Wingoeval, that spectral hound

(Andy Wingo)

Friends, I am not a free man. Eval has been my companion of late, a hellhound on my hack-trail. I give you two instances.

the howl of the-environment, across the ages

As legend has it, in the olden days, Aubrey Jaffer, the duke of SCM, introduced low-level FEXPR-like macros into his Scheme implementation. These allowed users to capture the lexical environment:

(define the-environment
  (procedure->syntax
   (lambda (exp env)
     env)))

Tom Lord inherited this cursed bequest from Jaffer, when he established himself in the nearby earldom of Guile. It so affected him that he added local-eval to Guile, allowing the user to evaluate an expression within a captured local environment:

(define env (let ((x 10)) (the-environment)))
(local-eval 'x env)
=> 10
(local-eval '(set! x 42) env)
(local-eval 'x env)
=> 42

Since then, the tenants of the earldom of Guile have been haunted by this strange leakage of the state of the interpreter into the semantics of Guile.

When the Guile co-maintainer title devolved upon me, I had a plan to vanquish the hound: to compile Guile into fast bytecode. There would be no inefficient association-lists of bindings at run-time. Indeed, there would be no "environment object" to capture. I succeeded, and with Guile 2.0, local-eval, procedure->syntax and the-environment were no more.

But no. As Guile releases started to make it into distributions, and users started to update their code, there arose such a howling on the mailing lists as set my hair on end. The ghost of local-eval was calling: it would not be laid to rest.

I resisted fate, for as long as I could do so in good conscience. In the end, Guile hacker Mark Weaver led an expedition to the mailing list moor, and came back with a plan.

Mark's plan was to have the syntax expander recognize the-environment, and residualize a form that would capture the identities of all lexical bindings. Like this:

(let ((x 10)) (the-environment))
=>
(let ((x 10))
  (make-lexical-environment
   ;; Procedure to wrap captured environment around
   ;; an expression
   wrapper
   ;; Captured variables: only "x" in this case
   (list (capture x))))

I'm taking it a little slow because hey, this is some tricky macrology. Let's look at (capture x) first. How do you capture a variable? In Scheme, with a closure. Like this:

;; Capture a variable with a closure.
;;
(define-syntax-rule (capture var)
  (case-lambda
    ;; When called with no arguments, return the value
    ;; of VAR.
    (() var)
    ;; When called with one argument, set the VAR to the
    ;; new value.
    ((new-val) (set! var new-val))))

The trickier part is reinstating the environment, so that x in a local-eval'd expression results in the invocation of a closure. Identifier syntax to the rescue:

;; The wrapper from above: a procedure that wraps
;; an expression in a lexical environment containing x.
;;
(lambda (exp)
  #`(lambda (x*) ; x* is a fresh temporary var
      (let-syntax ((x (identifier-syntax
                        (_ (x*))
                        ((set! _ val) (x* val)))))
        #,exp)))

By now it's clear what local-eval does: it wraps an expression, using the wrapper procedure from the environment object, evaluates that expression, then calls the resulting procedure with the case-lambda closures that captured the lexical variable.

So it's a bit intricate and nasty in some places, but hey, it finally tames the ghostly hound with modern Scheme. We were able to build local-eval on top of Guile's procedural macros, once a couple of accessors were added to our expander to return the set of bound identifiers visible in an expression, and to query whether those bindings were regular lexicals, or macros, or pattern variables, or whatever.

"watson, your service revolver, please."

As that Guile discussion was winding down, I started to hear the howls from an unexpected quarter: JavaScript. You might have heard, perhaps, that JavaScript eval is crazy. Well, it is. But ES5 strict was meant to kill off its most egregious aspect, in which eval can introduce new local variables to a function.

Now I've been slowly hacking on implementing block-scoped let and const in JavaScriptCore, so that we can consider switching gnome-shell over to use JSC. Beyond standard ES5 supported in JSC, existing gnome-shell code uses let, const, destructuring binding, and modules, all of which are bound to be standardized in the upcoming ES6. So, off to the hack.

My initial approach was to produce a correct implementation, and then make it fast. But the JSC maintainers, inspired by the idea that "let is the new var", wanted to ensure that let was fast from the beginning, so that it doesn't get a bad name with developers. OK, fair enough!

Beyond that, though, it looks like TC39 folk are eager to get let and const into all parts of JavaScript, not just strict mode. Do you hear the hound? It rides again! Now we have to figure out how block scope interacts with non-strict eval. Awooooo!

Thankfully, there seems to be a developing consensus that eval("let x = 20") will not introduce a new block-scoped lexical. So, down boy. The hound is at bay, for now.

life with dogs

I'm making my peace with eval. Certainly in JavaScript it's quite a burden for an implementor, but the current ES6 drafts don't look like they're making the problem worse. And in Scheme, I'm very happy to provide the primitives needed so that local-eval can be implemented in terms of our existing machinery, without needing symbol tables at runtime. But if you are making a new language, as you value your life, don't go walking on the local-eval moors at night!

by Andy Wingo at February 01, 2012 03:33 PM

FlumotionFlumotion Transcoder 0.11.1 "Habushu" released

(Flumotion)

The Flumotion team announces a new release of the development 0.11 branch of the Flumotion Transcoding Platform.

0.11.1 release notes for more details.

February 01, 2012 12:00 AM

January 29, 2012

Christian SchallerSummary of GStreamer Hackfest

(Christian Schaller)

So as I talked about in my last blog post we had a great GStreamer hackfest. A lot of things got done and quite a few applications got an initial port over to 0.11. For instance Edward Hervey ended up working on porting the Totem video player, or rather trying to come up with a more optimized design for the Clutter-gst as the basis port was already done.

Another cool effort was by Philippe Normand from Igalia who put a lot of effort into porting WebKit to use 0.11. His efforts where rewarded with success as you can see in this screenshot.

Jonathan Matthew had flown up all the way from Australia and made great progress in porting Rhythmbox over to the 0.11 API, a port which became hugely more useful after Wim Taymans and Tim-Phillip Muller fixed a bug that caused mp3 playback not to work :) .

Peteris Krisjanis made huge strides in porting Jokosher to 0.11. Although like Jason DeRose from Novacut and myself on Transmageddon he did end up spending a lot of time on debugging issues related to gobject-introspection. The challenge for non-C applications like Jokosher, Novacut, Transmageddon and PiTiVi is a combination of the API having changed quite significantly due to the switch to gobject-introspection generated bindings, some general immaturity challenges with the gobject-introspection library and finally missing or wrong annotations in the GStreamer codebase. So once all these issues are sorted things should look a lot brighter for language bindings, but as we discovered there is a lot of heavy lifting to get there. For instance I thought I had Transmageddon running quite smoothly before I suddenly triggered this gobject-introspection bug.

There was a lot of activity around PiTiVi too, with Jean-François Fortin Tam, Thibault Saunier and Antigoni Papantoni working hard on porting PiTiVi to 0.11 and the GStreamer Editing Services library. And knowing Jean-François Fortin I am sure there will soon be a blog with a lot more details about that :) .

Thomas Vander Stichele, who also wrote a nice blog entry about the event, was working with Andoni Morales Alastruey, both from Flumotion, on porting Flumotion to 0.11, but due to some of the plugins needed not having been ported yet most of their effort ended up being on porting the needed plugins in GStreamer and not so much application porting, but for those of you using plugins such as multifdsink, this effort will be of great value and Andoni also got started on porting some of the non-linux plugins, like the directsoundsink for Windows.

Josep Torra from Fluendo ended up working with Edward Hervey on hammering out the design for the clutter-gst sink at the conference, but he also found some time to do a port of his nice little tuner tool as you can see from the screenshot below.

Tuner tool for GStreamer 0.11

George Kiagiadakis kept hammering away at the qtGStreamer bindings, working both on a new release of the bindings for the GStreamer 0.10 series, but also some preparatory work for 0.11.

In addition to the application work, Wim Taymans, Tim-Phillip Müller and Sebastian Dröge from Collabora did a lot of core GStreamer clean ups and improvements in addition to providing a lot of assistance, bugfixing and advice for the people doing application porting. All critical items are now sorted in 0.11 although there are some nice to have’s still on the radar, and Wim plans on putting out some new releases next week, to kickstart the countdown to the first 1.0 release.

As for my own little pet project Transmageddon, it is quite far along now, with both manually configured re-encodes and profile re-encodes working. Still debugging remuxing though and I am also waiting for the deinterlacer to get ported to re-enable deinterlacing in the new version. For a screenshot take a look at the one I posted in my previous blogpost.

by uraeus at January 29, 2012 05:17 PM

January 28, 2012

Bastien NoceraGetting conned: eBay/Paypal fun

(Bastien Nocera) After seeing, this article about "How secure is Paypal for eBay sellers" in this morning's Guardian, I'll share my personal experience with you.

In October, I sold my first generation MacBook Air on eBay, and got a buyer within a day for the £500 "Buy It Now" price. "Buy It Now" requires using Paypal, and the £500 (minus commission) appeared in my Paypal account¹. After a bit of to and fro, the buyer got in contact, and suggested that he come and pick it up. Saving about £30 of shipping, and sorting out the sale faster, strike me as good ideas.

The "buyer" said he couldn't come, sent one of his "employees". A very courteous man came to pick the laptop. In hindsight, he seemed slightly uncomfortable, and looked like he was very happy to see how easy it was going to be.

The spooky thing is that within 40 minutes -- note, not 3 hours, not a day after, not the day before) -- within 40 minutes of the laptop getting picked up, the holder of the eBay and Paypal accounts submitted an "unauthorised account activity claim", leading to "payment reversal" (me owing £500 to Paypal²).

During my call to eBay's customer support, I was told that "I had nothing to worry about" (I'm guessing that would be the case as long as I repaid the £500). Paypal promptly sent a mail mentioning they needed my help, but with very little possibilities from my side ("no courier tracking number? Give us the money now").

Surrey Police failed to find the culprits, with the 2 mobile numbers associated with the con only being pay-as-you-go phones (topped up in a little convenience store in North London that only keeps a day's worth of CCTV).

So my advices:

  • If you sell anything via eBay using Paypal, send it recorded, and keep the receipt.
  • If you bought a MacBook Air first generation with the serial W88500DJ12G, it's stolen, send me an e-mail.

And as opposed to Mssrs Lodge and Reakes, Paypal didn't reimburse me anything, and I'm £500 out of pocket.

¹: I'll pass you the details on eBay referring to a closed Paypal account that meant I got conned two days later than the "buyers" anticipated.
²: On an account that was already closed, see ¹.

Update: Added mention of eBay's ludicrously bad customer service.

by hadess (noreply@blogger.com) at January 28, 2012 04:27 PM

January 27, 2012

Bastien NoceraWacom tablets in GNOME 3.4

(Bastien Nocera) Working from designs.


The cool stuff first

Cosimo Cecchi presents the updated Wacom settings

Go to YouTube directly if you can't see the video here.

A new arrival

As mentioned by Cosimo, we have a new library to help us implement the settings you saw: libwacom.

libwacom is there to give us metadata about tablets, whether or not they are connected to your system, the list of styli it supports, as well as information about the styli themselves. As you can see from the UI, it's pretty important that we know:

  • whether the tablet is builtin (so we know whether you can calibrate it)
  • which form factor it has
  • the list of styli it supports
  • for each stylus, its full name, the number of buttons, what it looks like
In the past, all this information was only available within the drivers (as comments), exported in different ways (sysfs attributes), non-machine readable in public documentation, or, worst of all, hidden in Wacom's internal drivers for OS X or Windows.

So if you have a Wacom tablet, send us a definition file for your tablet, so you can configure it with the impression that the software actually knows about your device.

Where's that configuration again

After knowing what each tablet had to offer, we had to have a way to match the definitions to XInput devices, assign settings per-tablet, and importantly, switch stylus configuration when the user switches stylus. This is done using the new GsdWacomDevice and GsdWacomStylus objects, shared between gnome-settings-daemon (which will apply the configuration) and gnome-control-center (which will set the configuration).

This also means we have a few debugging applications, such as list-wacom in gnome-settings-daemon, to show you the attached GsdWacomDevices, or test-wacom in gnome-control-center, to test display of particular tablets if you don't own them (this is the place where I spend a lot of time).

What's next

Peter Hutterer, my input buddy at Red Hat, who made the original Wacom panel for GNOME 3.2, and the first version of libwacom, is currently spending a lot of time on Multi-Touch, and fixing bugs I report in the Wacom driver.

Jason Gerecke, from Wacom, who did most of the initial work on calibration support, is working on the related display-mapping. This will allow choosing whether a tablet's working area is the whole desktop, or a single monitor when in multiple monitors are used.

For my part, after fixing the layout bugs that so annoy me in the settings panel, I'll be starting work on tablet button mapping. I look forward to making the LEDs on the tablet match up with the selected keyboard shortcut!

Many thanks to Cosimo and Monty for helping out with presenting the work, and doing the video.

by hadess (noreply@blogger.com) at January 27, 2012 01:07 PM

January 26, 2012

Christian SchallerGStreamer Hackfest in Malaga update

(Christian Schaller)

Things have been going really well here at the GStreamer Hackfest in Malaga. Thanks to the help of Ara and Yaiza from Nido Malaga, we have a great venue in downtown Malaga and they have also helped us greatly with sorting out food.
We have a great group of people here and are making great progress, and by tomorrow I hope we will have screenshots of quite a few applications running with GStreamer 0.11, for instance both Rhythmbox and Jokosher for instance is already screen shootable, if not fully functional :)

GStreamer Hackfest Malaga 2012

GStreamer Hackfest Malaga 2012

Also making good progress on Transmageddon, even if the move to GObject Introspection bindings are making things a bit more complicated. Screenshot below of the progress so far.

Transmageddon at Hackfest in Malaga 2012

Transmageddon at Hackfest in Malaga 2012

Also a big thanks to Fluendo who is sponsoring the lunches at the hackfest and Collabora who is sponsoring tonight’s dinner. Ensuring that no hacker is left hungry during this hackfest.

Update: Yaiza took these photos from the hackfest

by uraeus at January 26, 2012 02:12 PM

Thomas Vander SticheleGStreamer 0.11 Application Porting Hackfest

(Thomas Vander Stichele)

I’m in the quiet town of Malaga these three days to attend the GStreamer hackfest. The goal is to port applications over to the 0.11 API which will eventually be 1.0 There’s about 18 people here, which is a good number for a hackfest.

The goal for me is to figure out everything that needs to be done to have Flumotion working with GStreamer 0.11. It looks like there is more work than expected, since some of the things we rely on haven’t been ported successfully.

Luckily back in the day we spent quite a bit of time to layer parts as best as possible so they don’t depend too much on each other. Essentially, Flumotion adds a layer on top of GStreamer where GStreamer pipelines can be run in different processes and on different machines, and be connected to each other over the network. To that end, the essential communication between elements is abstracted and wrapped inside a data protocol, so that raw bytes can be transferred from one process to another, and the other end ends up receiving those same GStreamer buffers and events.

First up, there is the GStreamer Data protocol. Its job is to serialize buffers and events into a byte stream.

Second, there is the concept of streamheaders (which is related to the DELTA_UNIT flag in GStreamer). These are buffers that always need to be send at the beginning of a new stream to be able to interpret the buffers coming after it. In 0.10, that meant that at least a GDP version of the caps needed to be in the streamheader (because the other side cannot interpret a running stream without its caps), and in more recent versions a new-segment event. These streamheaders are analogous to the new sticky event concept in 0.11 – some events, like CAPS and TAG and SEGMENT are now sticky to the pad, which means that a new element connected to that pad will always see those events to make sense of the new data it’s getting.

Third, the actual network communication is done using the multifdsink element (and an fdsrc element on the other side). This element just receives incoming buffers, keeps them on a global buffer list, and sends all of them to the various clients added to it by file descriptor. It understands about streamheaders, and makes sure clients get the right ones for wherever they end up in the buffer list. It manages the buffers, the speed of clients, the bursting behaviour, … It doesn’t require GDP at all to work – Flumotion uses this element to stream Ogg, mp3, asf, flv, webm, … to the outside world. But to send GStreamer buffers, it’s as simple as adding a gdppay before multifdsink, and a gdpdepay after fdsrc. Also, at the same level, there are tcpserversink/tcpclientsrc and tcpclientsink/tcpserversrc elements that do the same thing over a simple TCP connection.

Fourth, there is an interface between multifdsink/fdsrc and Python. We let Twisted set up the connections, and then steal the file descriptor and hand those off to multifdsink and fdsrc. This makes it very easy to set up all sorts of connections (like, say, in SSL, or just pipes) and do things to them before streaming (like, for example, authentication). But by passing the actual file descriptor, we don’t lose any performance – the low-level streaming is still done completely in C. This is a general design principle of Flumotion: use Python and Twisted for setup, teardown, and changes to the system, and where we need a lot of functionality and can sacrifice performance; but use C and GStreamer for the lower-level processor-intensive stuff, the things that happen in steady state, processing the signal.

So, there is work to do in GStreamer 0.11:

  • The GStreamer data protocol has not really been ported. gdppay/depay are still there, but don’t entirely work.
  • streamheaders in those elements will need adapting to handle sticky events.
  • multifdsink was moved to -bad and left with broken unit tests. There is now multisocketsink. But sadly it looks like GSocket isn’t meant to handle pure file descriptors (which we use in our component that records streams to disk for example)
  • 0.11 doesn’t have the traditional Python bindings. It uses gobject-introspection instead. That will need a lot of work on the Flumotion side, and ideally we would want to keep the codebase working against both 0.10 and 0.11 as we did for the 0.8->0.10 move. Apparently these days you cannot mix gi-style binding with old-style binding anymore, because they create separate class trees. I assume this also means we need to port the glib2/gtk2 reactors in Twisted to using gobject-introspection.

So, there is a lot of work to be done it looks like. Luckily Andoni arrived today too, so we can share some work.

After discussing with Wim, Tim, and Sebastien, my plan is:

  1. create a common base class for multihandlesink, and refactor multisocketsink and multifdsink as subclasses of it
  2. create g_value_transform functions to bytestreams for basic objects like Buffers and Events
  3. use these transform functions as the basis for a new version of GDP, which we’ll make typefindable this time around
  4. support sticky events
  5. ignore metadata for now, as it is not mandatory; although in the future we could let gdppay decide which metadata it wants to serialize, so the application can request to do so
  6. try multisocketsink as a transport for inside Flumotion and/or for the streaming components.
  7. In the latter case, do some stress testing – on our platform, we have pipelines with multifdsink running for months on end without crashing or leaking, sometimes going up to 10000 connections open.
  8. Make twisted reactors
  9. prototype flumotion-launch with 0.11 code by using gir

That’s probably not going to be finished over this week, but it’s a good start. Last night I started by fixing the unit tests for multifdsink, and now I started refactoring multisocketsink and multifdsink with that. I’ll first try and make unit tests for multisocketsink though, to verify that I’m refactoring properly.

by Thomas at January 26, 2012 10:16 AM

January 25, 2012

Christian SchallerInterview with Arun Raghavan about PulseAudio

(Christian Schaller)

With all the talk generated by Arun Raghavans blog post comparing PulseAudio and Audioflinger I thought it would be good to follow up with an interview with Arun about the latest developments in PulseAudio and the way forward for the project. You can find the PulseAudio interview here. I also made a new page listing all the Collabora developer interviews done so far. Enjoy :)

by uraeus at January 25, 2012 03:45 PM

Jean-François Fortin TamRestoring from backups

I’m currently in Málaga for the GStreamer hackfest. Hopefully, many bugs will perish. In the meantime, here’s a quick status update of stuff I’ve been doing in recent times in Pitivi.

  • Cleanup the code for gtk actions so that the code is more readable and robust, fixing 629208 in the process.
  • Cleanup the menus (again).
  • Avoid having the viewer eating the CPU while idle.
  • Fix various problems such as “Select unused clips” not working in treeview mode or reimplement removing all timeline instances of a clip when removing it from the media library.
  • With the help of Brian Grohe, merge and delete spam user accounts on the wiki. I only have to fix image uploads and the https certificate issue now.
  • Start fixing 629855; see below for details.

It turns out that pitivi was secretly writing autosave/backups of your project files (and deleted them when successfully saving/closing), but it did not actually use them. You’d have to know they exist, when they exist and where to find them, which is hardly intuitive.

So, I set out to fix this. Along the way, I ended up making the “unsaved changes” dialog more helpful. This is the result:

Then I worked on the actual dialog to prompt the user about the existence of an autosaved project file. It uses uses the same mind-blowing human-readable time formatting nekohayan technology, as you can see in the various following scenarios:

If you ignore the backup file, it will obviously be deleted when you cleanly save/close the project.

The big question is however, what we should do if the user selects to restore from backup:

  • Should we simply rename the backup file to overwrite the “old” project file and then load it? This would mean the “old” project would be lost. In theory nothing should go wrong with that…
  • If we want to be paranoid perhaps we could load the backup file as a temporary file and force the user to use “Save as” instead of a regular Save, but I’m not sure if that’s what users need. Thoughts welcome on this one, but I’d really like to have a simple solution.

by nekohayo at January 25, 2012 11:49 AM

January 23, 2012

David SchleefNew Schrödinger Release

(David Schleef)

I recently added support for 10- and 16-bit encoding and decoding to Schrödinger, so I did a little release. Presenting Schrödinger-1.0.11. Also pushed changes to GStreamer to handle the new features. Although these changes have been in the works for some time, a little prompting from j-b caused me to finish this off, so this will probably appear in VLC soon, too.
This was the last piece needed to create a 10-bit master of Sintel, which I’ve been planning to do for some time.

by admin at January 23, 2012 04:23 PM

Christian SchallerGStreamer Hackfest in Malaga

(Christian Schaller)

Tomorrow I will be heading off to attend the GStreamer Application Porting Hackfest in Malaga, Spain. I think we have managed to pull together an absolutely incredible group of people for this event and I have great hopes that by next weekend we will have squashed a ton of bugs in GStreamer 0.11/1.0 and also have initial ports of a long range of important applications and bindings. This is the first time in GStreamer history that we are trying to hold a hackfest focused on application developers, but hopefully it will be the first of many and that they can become a good way for the core GStreamer community and the application development community to interact and collaborate more closely.

Also want to say a special thanks to the community members attending the event on their own and also to the companies sending their employees to the hackfest; Collabora, Fluendo, Flumotion and Igalia and finally a special thanks to the GNOME Foundation for sponsoring some of the attendees.

Hopefully I will be able to post some screenshots of a fully functional GStreamer 1.0 Transmageddon next weekend :)

by uraeus at January 23, 2012 09:39 AM

January 18, 2012

Felipe ContrerasEFI adventures

If you are like me, you probably have heard of EFI, but don’t know what it means in practice, how to eat it, or what to mix it with. But I recently bought a new PC, and it happened to come with EFI, so I decided to enable it and then I learned many things about it.

Whole new world

First of all, EFI is not something just can just “enable”. Even if your kernel has support for EFI, that won’t make a difference unless you boot it through EFI, and you can’t seamlessly boot through EFI unless you create a boot entry, which is done with efibootmgr, which only works once you are in EFI mode. So it’s a bit of a chicken-and-egg problem.

So how do you enter this world in the first place? First of all, you would need a shell. Some BIOSes come with one, but otherwise you would need to install one, and you can find public links on this wiki page.

But where to put this “shell”? Well, the EFI system partition–yes, you need a dedicated partition (more info here). This partition should be formatted using FAT32, and marked in a special way, so the EFI BIOS would be able to identify it, and use it’s contents.

You copy the shell to this partition on /shellx64.efi (I tried UEFI Shell 2.0 (Beta), but it didn’t work for me, so I used the old one).

Your BIOS should now be able to boot this shell… Somehow. It took me a long time to figure out that in my BIOS, that’s a hidden option on the exit menu, where you can “exit” into a shell.

Congratulations, now you are in EFI mode, and probably type some commands, like in the old DOS days, but not be able to do anything really (unless you have some EFI version of Prince of Persia).

The bootloader

There are a few EFI bootloaders out there, like ELILO, and efilinux, but I decided to go with the safest and familiar choice: GRUB2 (well GRUB was familiar, GRUB2 not so much). Arch Linux’s wiki describes in great detail how to setup GRUB2 for EFI, so I’ll just mention that you need to use a different command (‘grub_efi_x86_64-install’ in the case of Arch Linux), and the files need to be installed in the aforementioned EFI system partition.

You would end up with a file /efi/arch/grubx64.efi, and this is an EFI binary that you can use in the shell. Theoretically you should be able to enter the command “\efi\arch\grubx64.efi”, but for some reason that didn’t work for me, so I had to “cd \efi\arch”, and then “grubx64.efi”. Of course, you first need to choose the right partition, but the shell makes it easier by having aliases to the EFI system partitions, so you first type “fs0:” (or something like that), like I said; very similar to DOS.

Directly, please

But going into the shell and typing those commands every time you boot is cumbersome, which is why you would want to add a boot entry. So, once you have been able to boot Linux through EFI, you should be able to load the ‘efivars’ module, and thus access ‘/sys/firmware/efi/vars/’, which is what ‘efibootmgr’ needs.

Then you can do something like:

efibootmgr --create --gpt --disk /dev/sdX --part Y --write-signature --label "Arch Linux (GRUB2)" --loader '\efi\arch\grubx64.efi'

WARNING: You shouldn’t use this on Mac’s, there’s a different process for those.

In your BIOS you should see the option of booting into “Arch Linux (GRUB2)”, like you have the option of booting into a CD-ROM, and then you can choose that as the first one in the boot order :)

Stub

But wait a second, that starts to look like two bootloaders: the BIOS has a boot entry, and so does GRUB. Why not boot directly into Linux?

A couple of patches from Matt Fleming enable just that. They should be in version 3.3. Enable CONFIG_EFI_STUB, and copy bzImage to /efi/linux/linux.efi.

So now you can boot directly from the BIOS into Linux (or Windows) with no bootloader at all :)

GPT

While you are on that, why not enable this new partitioning scheme? It’s more EFI friendly, and you can’t actually install a version of Windows that works with EFI without it. For Windows 7 it’s either EFI and GPT, or non-EFI and MBR; you can’t mix them (don’t ask me why).

Fortunately it’s very easy to switch from MBR to GPT; just run gdisk (from a rescue disk, of course). It’s also easy to switch back, as long ad you haven’t used more than four partitions.


by FelipeC at January 18, 2012 05:22 PM

January 17, 2012

Reynaldo VerdejoAdding XSUB support to GStreamer

So I have been working on adding XSUB support to GStreamer as a landing task at my new job. To be honest, I didn't expect it to go as easy. Don't get me wrong, I do know most subpicture encoding schemes are kind of trivial, what I expected to be hard was to work with the GStreamer's plugin API, which was a completely new monster for me. Long history short; with the help of several coworkers and some good documentation, I have patch ready to be tested. There are still a few things here and there that might benefit from some tweaking but overall the code does its job and its in dire need of some testing love :) Dunno how long it would take for it to land in -bad but for the time being you can follow current development here.

If you want to test the code you might consider using a pipeline along these lines:

gst-launch-0.10 -v --gst-debug=xsub:5 xsub name=overlay show-background=FALSE ! ffmpegcolorspace ! xvimagesink filesrc location=/somepath/small.divx ! avidemux name=d d.video_00 ! queue ! decodebin2 ! ffmpegcolorspace ! overlay.video_sink d.video_01 ! queue ! overlay.xsub_sink
I'd put some screenshots here but I have been unable to find samples I can share.

by reynaldo (noreply@blogger.com) at January 17, 2012 04:06 AM

Reynaldo VerdejoGStreamer on Android, The NDK way


Long story short; thanks to my employer, Collabora, I have been working on getting GStreamer built and installed as a native support library under Android using the NDK. We had this working and announced for last GSTConf at Prague but there were a few details to iron out to get our work in shape for external testing.

The idea behind this adventure is showing the world you can benefit from this marvelous, swissknife-like media framework under the green droid's platform utilizing a least intrusive path.
We worked a few months ago on having GStreamer built as part of Android itself and while I do believe that approach should benefit system integrators rolling out their own customized Android version, it has the drawback of requiring both patching and building the entire Android OS and having administrative (root) access to your device. This is arguably not a problem for the most adventurous among you but we figured out providing a way to benefit from all the goods in GStreamer without forcing you to perform any major hacks was worth trying. So we did.

To be really honest, most of this work wouldn't have been possible (or at least really, like _REALLY_ harder) without the help of Collabora's own Derek Foreman's Androgenizer. You will need this tool if you want to try building our NDK bundle. And if you are working on porting some other complex project to Android; You need it too! so go check it out.

Right now you can get instructions on how to build GStreamer using the NDK and install it on your device at our freedesktop wikipage. Here is a quick run down of what is currently workig:

  • Building most of gstreamer, -base, -good, -bad, -ugly & -openmax. The first 5 entirely from upstream!
  • Building of our set of support libraries for this bundle (glib, x264, ogg, libmad, faad, libid3tag)
  • Building gstaudioflingersink from gst-android. We are still working on gstsurfaceflingersink to adapt it to some late API changes in Gingerbread
  • APK generation and Installation. Mind you this is not a real Android GUI application, just the set of GStreamer libraries and executables for you to build upon
  • Execution of gst- binaries on the device using run-as

Suported Android versions:

  • Gingerbread and Honeycomb

Test devices:

  • Samsung Galaxy Tab 10.1
  • Google Nexus S

This is still a work in progress but as I trust the community to be a great vehicle for driving innovation forward and have the luxury of working for a Company that supports this very same principle, I decided to have this aired so I can benefit from both your testing and feedback.

If you give this process a try and feel like supporting our work, please consider subscribing to our mailing list and sharing your experience!

by reynaldo (noreply@blogger.com) at January 17, 2012 04:05 AM

Reynaldo VerdejoGiving a lecture at this year's expolibre


For those of you around Talca and wanting to talk FOSS, Youness Aloui, Thibault Saunier and your's truly are going to be speaking at this year's Expolibre thanks to the gentle support of our company and the organizer's invitation.

I was talking yesterday with a fellow coworker on how community events like the good old ones get shadowed under the massive, corporate backed ones you see in the tech news by the day. Sadly as it might sound to a few (at least --And I hope), we are slowly beginning to forget there are still some guys out there that resisting the thrust of being only motivated by what to sell next year and how to make it so it goes good and cheap at the same time (like if it was possible, someway), still gather to share views, knowledge and maybe-naive-but-still-valid desires of steer collaborative innovation a bit away from the dreaded coin-only focus. We need to take an step back sometimes and think about some important things we forget on the rush of our everyday paid developer's life; there's a community that saw us shooting at the stars once and has continued backing up most of the technology we rely on. Supplying not only that but: tools, a beyond-technical environment and a reason for trying not only to do things right but do good while we are at it. Attending this kind of events is my way of taking that needed step back and I couldn't be more happier about working for a company that not only allows me to but go as far as directly supporting the event with the time of its devs.

So, if you find yourself wandering around Talca (VII Region, Chile. Some 3 hours away from Santiago) by the 24/12/2011 and wanna go do some knowledge sharing and hear and talk about FOSS without having to pay a penny, then go there. I have been giving speaks at this conference for the last 3 years and one thing I can guarantee you is that it's worth the time you will spend.

Thibault Saunier will be talking about video editing with PiTiVi, Youness Aloui will be talking about FOSS and the fights some users have to go through to make sure their rights don't get crippled by merely buying a product and I'm going to be sharing the goods of GStreamer through a gently introduction for beginners. Don't worry about not having an strong software developent background because our talks are geared towards anyone that doesn't run away from a mouse.

C you there!

by reynaldo (noreply@blogger.com) at January 17, 2012 04:05 AM

January 16, 2012

Arun RaghavanPulseAudio vs. AudioFlinger: Fight!

I’ve been meaning to try this for a while, and we’ve heard a number of requests from the community as well. Recently, I got some time here at Collabora to give it a go — that is, to get PulseAudio running on an Android device and see how it compares with Android’s AudioFlinger.

The Contenders

Let’s introduce our contenders first. For those who don’t know, PulseAudio is pretty much a de-facto standard part of the Linux audio stack. It sits on top of ALSA which provides a unified way to talk to the audio hardware and provides a number of handy features that are useful on desktops and embedded devices. I won’t rehash all of these, but this includes a nice modular framework, a bunch of power saving features, flexible routing, and lots more. PulseAudio runs as a daemon, and clients usually use the libpulse library to communicate with it.

In the other corner, we have Android’s native audio system — AudioFlinger. AudioFlinger was written from scratch for Android. It provides an API for playback/recording as well as a control mechanism for implementing policy. It does not depend on ALSA, but instead allows for a sort of HAL that vendors can implement any way they choose. Applications generally play audio via layers built on top of AudioFlinger. Even if you write a native application, it would use OpenSL ES implementation which goes through AudioFlinger. The actual service runs as a thread of the mediaserver daemon, but this is merely an implementation detail.

Note: all my comments about AudioFlinger and Android in general are based on documentation and code for Android 4.0 (Ice Cream Sandwich).

The Arena

My test-bed for the tests was the Galaxy Nexus running Android 4.0 which we shall just abbreviate to ICS. I picked ICS since it is the current platform on which Google is building, and hopefully represents the latest and greatest in AudioFlinger development. The Galaxy Nexus runs a Texas Instruments OMAP4 processor, which is also really convenient since this chip has pretty good support for running stock Linux (read on to see how useful this was).

Preparations

The first step in getting PulseAudio on Android was deciding between using the Android NDK like a regular application or integrate into the base Android system. I chose the latter — even though this was a little more work initially, it made more sense in the long run since PulseAudio really belongs to the base-system.

The next task was to get the required dependencies ported to Android. Fortunately, a lot of the ground work for this was already done by some of the awesome folks at Collabora. Derek Foreman’s androgenizer tool is incredibly handy for converting an autotools-based build to Android–friendly makefiles. With Reynaldo Verdejo and Alessandro Decina’s prior work on GStreamer for Android as a reference, things got even easier.

The most painful bit was libltdl, which we use for dynamically loading modules. Once this was done, the other dependencies were quite straightforward to port over. As a bonus, the Android source already ships an optimised version of Speex which we use for resampling, and it was easy to reuse this as well.

As I mentioned earlier, vendors can choose how they implement their audio abstraction layer. On the Galaxy Nexus, this is built on top of standard ALSA drivers, and the HAL talks to the drivers via a minimalist tinyalsa library. My first hope was to use this, but there was a whole bunch of functions missing that PulseAudio needed. The next approach was to use salsa-lib, which is a stripped down version of the ALSA library written for embedded devices. This too had some missing functions, but these were fewer and easy to implement (and are now upstream).

Now if only life were that simple. :) I got PulseAudio running on the Galaxy Nexus with salsa-lib, and even got sound out of the HDMI port. Nothing from the speakers though (they’re driven by a TI twl6040 codec). Just to verify, I decided to port the full alsa-lib and alsa-utils packages to debug what’s happening (by this time, I’m familiar enough with androgenizer for all this to be a breeze). Still no luck. Finally, with some pointers from the kind folks at TI (thanks Liam!), I got current UCM configuration files for OMAP4 boards, and some work-in-progress patches to add UCM support to PulseAudio, and after a couple of minor fixes, wham! We have output. :)

(For those who don’t know about UCM — embedded chips are quite different from desktops and expose a huge amount of functionality via ALSA mixer controls. UCM is an effort to have a standard, meaningful way for applications and users to use these.)

In production, it might be handy to write light-weight UCM support for salsa-lib or just convert the UCM configuration into PulseAudio path/profile configuration (bonus points if it’s an automated tool). For our purposes, though, just using alsa-lib is good enough.

To make the comparison fair, I wrote a simple test program that reads raw PCM S16LE data from a file and plays it via the AudioTrack interface provided by AudioFlinger or the PulseAudio Asynchronous API. Tests were run with the brightness fixed, wifi off, and USB port connected to my laptop (for adb shell access).

All tests were run with the CPU frequency pegged at 350 MHz and with 44.1 and 48 kHz samples. Five readings were recorded, and the median value was finally taken.

Round 1: CPU

First, let’s take a look at how the two compare in terms of CPU usage. The numbers below are the percentage CPU usage taken as the sum of all threads of the audio server process and the audio thread in the client application using top (which is why the granularity is limited to an integer percentage).

44.1 kHz 48 kHz
AF PA AF PA
1% 1% 2% 0%

At 44.1 kHz, the two are essentially the same. Both cases are causing resampling to occur (the native sample rate for the device is 48 kHz). Resampling is done using the Speex library, and we’re seeing minuscule amounts of CPU usage even at 350 MHz, so it’s clear that the NEON optimisations are really paying off here.

The astute reader would have noticed that since the device’ native sample rate is 48 kHz, the CPU usage for 48 kHz playback should be less than for 44.1 kHz. This is true with PulseAudio, but not with AudioFlinger! The reason for this little quirk is that AudioFlinger provides 44.1 kHz samples to the HAL (which means the stream is resampled there), and then the HAL needs to resample it again to 48 kHz to bring it to the device’ native rate. From what I can tell, this is a matter of convention with regards to what audio HALs should expect from AudioFlinger (do correct me if I’m mistaken about the rationale).

So round 1 leans slightly in favour of PulseAudio.

Round 2: Memory

Comparing the memory consumption of the server process is a bit meaningless, because the AudioFlinger daemon thread shares an address space with the rest of the mediaserver process. For the curious, the resident set size was: AudioFlinger — 6,796 KB, PulseAudio — 3,024 KB. Again, this doesn’t really mean much.

We can, however, compare the client process’ memory consumption. This is RSS in kilobytes, measured using top.

44.1 kHz 48 kHz
AF PA AF PA
2600 kB 3020 kB 2604 kB 3020 kB

The memory consumption is comparable between the two, but leans in favour of AudioFlinger.

Round 3: Power

I didn’t have access to a power monitor, so I decided to use a couple of indirect metrics to compare power utilisation. The first of these is PowerTOP, which is actually a Linux desktop tool for monitoring various power metrics. Happily, someone had already ported PowerTOP to Android. The tool reports, among other things, the number of wakeups-from-idle per second for the processor as a whole, and on a per-process basis. Since there are multiple threads involved, and PowerTOP’s per-process measurements are somewhat cryptic to add up, I used the global wakeups-from-idle per second. The “Idle” value counts the number of wakeups when nothing is happening. The actual value is very likely so high because the device is connected to my laptop in USB debugging mode (lots of wakeups from USB, and the device is prevented from going into a full sleep).

44.1 kHz 48 kHz
Idle AF PA AF PA
79.6 107.8 87.3 108.5 85.7

The second, similar, data point is the number of interrupts per second reported by vmstat. These corroborate the numbers above:

44.1 kHz 48 kHz
Idle AF PA AF PA
190 266 215 284 207

PulseAudio’s power-saving features are clearly highlighted in this comparison. AudioFlinger causes about three times the number of wakeups per second that PulseAudio does. Things might actually be worse on older hardware with less optimised drivers than the Galaxy Nexus (I’d appreciate reports from running similar tests on a Nexus S or any other device with ALSA support to confirm this).

For those of you who aren’t familiar with PulseAudio, the reason we manage to get these savings is our timer-based scheduling mode. In this mode, we fill up the hardware buffer as much as possible and go to sleep (disabling ALSA interrupts while we’re at it, if possibe). We only wake up when the buffer is nearing empty, and fill it up again. More details can be found in this old blog post by Lennart.

Round 4: Latency

I’ve only had the Galaxy Nexus to actually try this out with, but I’m pretty certain I’m not the only person seeing latency issues on Android. On the Galaxy Nexus, for example, the best latency I can get appears to be 176 ms. This is pretty high for certain types of applications, particularly ones that generate tones based on user input.

With PulseAudio, where we dynamically adjust buffering based on what clients request, I was able to drive down the total buffering to approximately 20 ms (too much lower, and we started getting dropouts). There is likely room for improvement here, and it is something on my todo list, but even out-of-the-box, we’re doing quite well.

Round 5: Features

With the hard numbers out of the way, I’d like to talk a little bit about what else PulseAudio brings to the table. In addition to a playback/record API, AudioFlinger provides mechanism for enforcing various bits of policy such as volumes and setting the “active” device amongst others. PulseAudio exposes similar functionality, some as part of the client API and the rest via the core API exposed to modules.

From SoC vendors’ perspective, it is often necessary to support both Android and standard Linux on the same chip. Being able to focus only on good quality ALSA drivers and knowing that this will ensure quality on both these systems would be a definite advantage in this case.

The current Android system leaves power management to the audio HAL. This means that each vendor needs to implement this themselves. Letting PulseAudio manage the hardware based on requested latencies and policy gives us a single point of control, greatly simplifying the task of power-management and avoiding code duplication.

There are a number of features that PulseAudio provides that can be useful in the various scenarios where Android is used. For example, we support transparently streaming audio over the network, which could be a handy way of supporting playing audio from your phone on your TV completely transparently and out-of-the-box. We also support compressed formats (AC3, DTS, etc.) which the ongoing Android-on-your-TV efforts could likely take advantage of.

Edit: As someone pointed out on LWN, I missed one thing — AudioFlinger has an effect API that we do not yet have in PulseAudio. It’s something I’d definitely like to see added to PulseAudio in the future.

Ding! Ding! Ding!

That pretty much concludes the comparison of these two audio daemons. Since the Android-side code is somewhat under-documented, I’d welcome comments from readers who are familiar with the code and history of AudioFlinger.

I’m in the process of pushing all the patches I’ve had to write to the various upstream projects. A number of these are merely build system patches to integrate with the Android build system, and I’m hoping projects are open to these. Instructions on building this code will be available on the PulseAudio Android wiki page.

For future work, it would be interesting to write a wrapper on top of PulseAudio that exposes the AudioFlinger audio and policy APIs — this would basically let us run PulseAudio as a drop-in AudioFlinger replacement. In addition, there are potential performance benefits that can be derived from using Android-specific infrastructure such as Binder (for IPC) and ashmem (for transferring audio blocks as shared memory segments, something we support on desktops using the standard Linux SHM mechanism which is not available on Android).

If you’re an OEM who is interested in this work, you can get in touch with us — details are on the Collabora website.

I hope this is useful to some of you out there!

by Arun at January 16, 2012 12:22 PM

January 13, 2012

Stefan Kost13 Jan 2012

(Stefan Kost) buztard

Finally after a long time, I managed to release a 0.6 of buzztard. So far only one regression was found and bml-0.6.1 was released to fix it.

A few things happened before the release still. At first after updating my distro, I made a lot of changes to avoid deprecated gtk+ api. For now we ship a copy of the ruler widget (that got removed in 3.0). The internal ruler widget
is a lot saner than the upstream one too.

Another big change was to move from string parameter for notes to an enum. This is faster and lets us do things like blending of note ranges or transposing.

I also made quite a few bug-fixes - laspa effects work again, fluidsynth fixes, etc.

Now I look forward to a lot of new changes in 0.7.X.

January 13, 2012 07:57 AM

January 12, 2012

Jean-François Fortin TamSpring clean-up in January

Now that we’ve gotten rid of a ton of code in Pitivi (thanks to the port to GES), Thibault has been doing an incredible job at cleaning and reorganizing the remaining source files in a way that finally makes sense. I’m very happy about this: it means that it will not only make it easier for new contributors to get started, but also for regular contributors to not get lost in the various modules.

Behold, before (left) and after (right):

The old file tree was so big that it did not fit on a rotated 1920×1200 monitor, even with Nautilus fully zoomed out. Note that the tests/ directory is not shown here, it went from 33 test cases to 18 and now runs in one second (since the core tests are now in GES).

If you fail to be utterly amazed and emotional about what I’ve just shown here, I’ll make sure to explain properly the jawdropping significance of this cleanup (and the whole GES port in general), whenever I get a chance to make a talk at some hip conference.

Stuff I’ve been doing in general in the last three weeks:

  • Fixed a couple of GES integration bugs in Pitivi. There’s still lots of work to do, but we’re getting closer to being able to make a first alpha release for your enjoyment.
  • Redesigned the clip previewing feature. Instead of showing in the tiny timeline previewer, it now shows in a separate window that tries to show the clip at 1:1 size whenever possible. This window can be dismissed by clicking the close button or clicking anywhere outside the window, so there is no reduction of efficiency compared to the old approach.
  • Merged, at long last, the power management branch. Pitivi will now inhibit the screensaver when playing and inhibit suspend when rendering.
  • Make pitivi use Nautilus/Totem’s thumbnails. The result is prettier and we don’t have to do processing in most cases, which means even faster import/loading times.
  • Pushed all that goodness to Pitivi’s origin (main repository) in a “ges” branch.
  • Closed over a hundred old PackageKit bug reports on Freedesktop bugzilla. Hughsie should breathe a little bit more easily now.
  • Finally killed all the spam pages (1000+) and images (500+) on the pitivi wiki, using the DeletePagePermanently Mediawiki extension (had to patch it for 1.17, see the talk page) and a horrible, horrible homemade python script to delete the pages automatically by opening hundreds of tabs in Firefox, accessing the “&action=delete_permanently” URL directly.
    • The remaining problem is that I haven’t found a way to efficiently purge the remaining 800+ fake user accounts yet. Ideas welcome, the UserAdmin extension does not work with anything but Mediawiki 1.16 (and it seems unmaintained).

Me, fixing bugs. Or spending way too much time playing Vindictus.

In related news:

  • At the end of January, I will be attending the GStreamer hackfest in Malaga, Spain. I predict that intense bug squashing will ensue. Come say hi if you’re around.
  • Can someone please tell me if bug 666916 is a pygtk bug, a gtk bug or something I’ve done wrong? The same code was working a year ago. Current code here, offending line is #911.

by nekohayo at January 12, 2012 05:32 PM

Andy Wingojavascript eval considered crazy

(Andy Wingo)

Peoples. I was hacking recently on JavaScriptCore, and I came to a realization: JavaScript's eval is absolutely crazy.

I mean, I thought I knew this before. But... words fail me, so I'll have to show a few examples.

eval and introduced bindings

This probably isn't worth mentioning, as you probably know it, but eval can introduce lexical bindings:

 > var foo = 10;
 > (function (){ eval('var foo=20;'); return foo; })()
 20
 > foo
 10

I find this to be pretty insane already, but I knew about it. You would think though that var x = 10; and eval('var x = 10;'); would be the same, though, but they're not:

 > (function (){ var x = 10; return delete x; })()
 false
 > (function (){ eval('var x = 10;'); return delete x; })()
 true

eval-introduced bindings do not have the DontDelete property set on them, according to the post-hoc language semantics, so unlike proper lexical variables, they may be deleted.

when is eval really eval?

Imagine you are trying to analyze some JavaScript code. If you see eval(...), is it really eval?

Not necessarily.

eval pretends to be a regular, mutable binding, so it can be rebound:

 > eval = print
 > eval('foo')
 foo // printed

or, shadowed lexically:

 > function () { var eval = print; eval('foo'); }
 foo // printed

or, shadowed dynamically:

 > with({'eval': print}) { eval('foo'); }
 foo // printed

You would think that if you can somehow freeze the eval binding on the global object, and verify that there are no with forms, and no statements of the form var eval = ..., that you could guarantee that eval is eval, but that is not the case:

 > Object.freeze(this);
 > (function (x){ return [eval(x), eval(x)]; })('var eval = print; 10')
 var eval = print; 10 // printed, only once!
 10,

(Here the first eval created a local binding for eval, and evaluated to 10. The second eval was actually a print.)

Crazy!!!!

an eval by any other name

So eval is an identifier that can be bound to another value. OK. One would expect to be able to bind another identifier to eval, then. Does that work? It seems to work:

 > var foo = eval;
 > foo('foo') === eval;
 true

But not really:

 > (function (){ var quux = 10; return foo('quux'); } )()
 Exception: ReferenceError: Can't find variable: quux

eval by any other name isn't eval. (More specifically, eval by any other name doesn't have access to lexical scope.)

Note, however, the mere presence of a shadowed declaration of eval doesn't mean that eval isn't eval:

 > var foo = 10
 > (function(x){ var eval = x; var foo = 20; return [x('foo'), eval('foo')] })(eval)
 10,20

Crazy!!!!

strict mode restrictions

ECMAScript 5 introduces "strict mode", which prevents eval from being rebound:

 > (function(){ "use strict"; var eval = print; })
 Exception: SyntaxError: Cannot declare a variable named 'eval' in strict mode.
 > (function(){ "use strict"; eval = print; })
 Exception: SyntaxError: 'eval' cannot be modified in strict mode
 > (function(){ "use strict"; eval('eval = print;'); })()
 Exception: SyntaxError: 'eval' cannot be modified in strict mode
 > (function(x){"use strict"; x.eval = print; return eval('eval');})(this)
 Exception: TypeError: Attempted to assign to readonly property.

But, since strict mode is embedded in "classic mode", it's perfectly fine to mutate eval from outside strict mode, and strict mode has to follow suit:

 > eval = print;
 > (function(){"use strict"; return eval('eval');})()
 eval // printed

The same is true of non-strict lexical bindings for eval:

 > (function(){ var eval = print; (function(){"use strict"; return eval('eval');})();})();
 eval // printed
 > with({'eval':print}) { (function(){ "use strict"; return eval('eval');})() }
 eval // printed

An engine still has to check at run-time that eval is really eval. This crazy behavior will be with us as long as classic mode, which is to say, forever.

Strict-mode eval does have the one saving grace that it cannot introduce lexical bindings, so implementors do get a break there, but it's a poor consolation prize.

in summary

What can an engine do when it sees eval?

Not much. It can't even prove that it is actually eval unless eval is not bound lexically, there is no with, there is no intervening non-strict call to any identifier eval (regardless of whether it is eval or not), and the global object's eval property is bound to the blessed eval function, and is configured as DontDelete and ReadOnly (not the default in web browsers).

But the very fact that an engine sees a call to an identifier eval poisons optimization: because eval can introduce variables, the scope of free variables is no longer lexically apparent, in many cases.

I'll say it again: crazy!!!

by Andy Wingo at January 12, 2012 04:34 PM

January 06, 2012

Christian SchallerTransmageddon runs with GStreamer 0.11

(Christian Schaller)

After updating GStreamer and doing a couple of small fixes I managed to make Transmageddon work with the GTK3 and the 0.11 branch of GStreamer. Obligatory screenshot below. As you might guess from looking at the screenshot there are still some issues that needs solving, but
I am happy that I managed to get this far.

Screenshot of development Transmageddon

Transmageddon running GTK3 and GStreamer 0.11/1.0

Hopefully it is a sign that the upcoming GStreamer hackfest in Malaga will be a great successful everyone who is participating.

I hope the remainder of the porting effort will be relatively simple as I would love to get back to working on real features instead of just updating old functionality to use a new backend to do the same. Having had a need for Transmageddon for a couple of work related tasks recently a couple of items, like batch job programming has moved up my priorities list.

by uraeus at January 06, 2012 06:48 PM

January 04, 2012

Christian SchallerGustavo Noronha Silva Interview about WebKit

(Christian Schaller)

Just posted another interview on the Collabora website, this time with Gustavo Noronha Silva talking about WebKit and some of the work he and Collabora are doing around that project. So be sure to check it out if you want to learn more about things like WebKit and Clutter integration and how WebKit impacts the GNOME platform.

by uraeus at January 04, 2012 02:09 PM

January 03, 2012

Felipe ContrerasAndroid vs. Maemo power management: static vs. dynamic

Some of you might have heard about Google’s Android team proposal to introduce wakelocks (aka suspend-blockers) to the Linux kernel. While there was a real issue being solved in the kernel side, the benefits on the user-space side were dubious at best, and after a huge discussion, they finally didn’t get in.

During this discussions the dynamic and static power management were described and discussed at length, and there was a bit of talk about Maemo(MeeGo) vs Android approaches to power management, but there was so much more than that.

Some people have problems with the battery on Android devices, for some people it’s just fine, some people have problems with the Maemo, other don’t, so in general; your mileage might vary. But given the extremely different approaches, it’s easy to see in which cases you would have better luck with Maemo, and in which with Android–Although I do think it’s obvious which approach is superior, but I am biased.

An interesting achievement was shared by Thiago Maciera, who managed to get ‘5 days and a couple of minutes‘ out of the Nokia N9 while traveling, and actually using it–and let’s remember this is a 1450 mAh battery. Some Android users might have trouble believing this, but hopefully this blog post would explain what’s going on.

So lets go ahead and explore the two approaches.

Dynamic Power Management

Perhaps the simplest way to imagine dynamic power management, is the gears of a manual transmission car. You go up and down depending on how much power does the system actually needs.

In some hardware, such as OMAP chips, it’s possible to have quite a lot of fine control on the power states of quite a lot of devices, plus different operating power points on the different cores. For example, it might be possible to have some devices, such as the display on, and active, some other devices partially off, like speaker, and other completely off, like USB. And based on the status of the whole system, whole blocks can be powered off, other with low voltage levels, etc.

Linux has a framework to deal properly with this kind of hardware, the runtime power management, that originally came from the embedded world, and a lot from OMAP development, but is now available to everyone.

The idea is very simple; devices should sleep as much as possible. This means that if you have a sound device that needs chunks of 100ms, and the system is not doing anything else but playing sound, then most of the devices go to sleep, even the CPU, and the CPU is only waken up when it needs to write data for the audio device. Even better is to configure the sound device for chunks of 1 second, so the system can sleep even more.

Obviously, some co-operation between kernel and user-space is needed. Say, if you have an instant messenger program that needs to do work every minute, and a mail program that is configured to check mail every 10 minutes, you would want them to do work at the same time when they align at every 10 minutes. This is sometimes called IP heartbeat; the system wakes up for a beat, and then immediately goes back to sleep. And there are kernel facilities as well, such as range timers.

All this is possible thanks to very small latencies required for devices to go to sleep and wakeup, and have intermediary modes (e.g. on, inactive, retention, off), so, for example a device might be able to go to inactive mode in 1ms, retention in 2ms, and off in 5ms (totally invented numbers). Again, the more sleep, the better. Obviously, this is impossible on x86 chips, which have huge latencies–at least right now, and it’s something Intel is probably trying to improve effusively. All these latencies are known by the runtime pm framework in the kernel, and based on that it and the usage, it figures out what is the lowest power state possible without breaking things.

Note I’m not a power management expert, but you cant watch a colleague of mine explain the OMAP 3 power-managment on this video:

Advanced Power Management for OMAP3

And there’s plenty of more resources.

Update: That was the wrong link, here are the resources.

Static Power Management

Static power management has two modes: on and off. That’s it.

OK, that’s not exactly the case in general, but it is in the Android context; the system is either suspended, or active, and it’s easy to know in which mode you are; if the screen is on, it’s active, and if it’s off; it’ is suspended (ideally).

There’s really not much more than that. The complexity comes from the problem of when to suspend; you might have turned off the display, but there might be a system service that still needs to do work, so this service grabs a suspend blocker which, as the name suggests, prevents the system from suspending (until the lock is released). This introduces a problem; a rouge program might grab a ‘suspend blocker’ and never release it, which means your phone will never suspend, and thus the battery would drain rather quickly. So, some security mechanisms are introduced to grant permissions selectively to use suspend blockers.

And moreover, Android developers found race conditions in the suspend sequences in certain situations that were rather nasty (e.g. the system tries to suspend at the same time the user clicks a button, and the system never wakes up again), and these were acknowledged as real issues that would happen on all systems (including PC’s and servers, albeit rarely, because they don’t suspend so often), and got fixed (or at least they tried).

Versus

First of all, it’s important to know that if you have dynamic pm working perfectly, you reach exactly the same voltage usage than static pm, so in ideal cases they both behave exactly the same.

The problem is that it’s really hard for dynamic pm to reach that ideal case, in reality systems are able to sleep for certain periods of time, after which they are woken up, often times unnecessarily, and as I already explained; that’s not good. So the goal of a dynamic pm system is to increase those periods of time as much as possible, thus maximizing battery life. But there’s a point of diminished returns (read this or this for expert explanations), so, if the system manages to sleep 1s in average, there’s really not much more to gain if it sleeps 2s, or even 10s. These goals were quite difficult to achieve in the past (not these, I invented those numbers), but not so much any more thanks to several mechanisms that have been introduced and implemented through the years. So it’s fair to say that the sweet spot of dynamic pm has been achieved.

This means that today a system that has been fine-tuned for dynamic pm can reach reach a decent battery life compared to one that uses static pm in most circumstances. But for some use-cases, say, you leave your phone on your desk and you don’t use it at all, static pm would allow it to stay alive for weeks, or even months, while dynamic pm can’t possibly achieve that any time soon. Hopefully you would agree, that nobody cares about those use-cases were you are not actually using the device.

And of course, you only need one application behaving badly and waking up the system constantly, and the battery life is screwed. So in essence, dynamic pm is hard to achieve.

Android developers argued that was one of the main reasons to go for static pm; it’s easier to achieve, specially if you want to support a lot of third party applications (Android Market) without compromising battery life. While this makes sense, I wasn’t convinced by this argument; you still can have one application that is behaving badly (grabbing suspend blockers the whole time), and while permissions should help, the application might still request the permission, and the user grant it (who reads incomprehensible warnings before clicking ‘Yes’ anyway?).

So, both can get screwed by bad apps (although it’s likely that it’s harder in the static pm case, albeit not that much).

But actually, you can have both static and dynamic power management, and in fact, Android does. But that doesn’t mean Android automatically wins, as I explained, the system needs to be fine-tuned for dynamic pm, and that has never been a focus of Android (there’s no API’s or frameworks for that, etc.). So, for example, a Nokia N9 phone might be able to sleep 1s in average, while an Android phone 100ms (when not suspended). This means when you are actually using the device (the screen is on), chances are, a system fine-tuned for dynamic pm (Nokia N9) would consume less battery, than an Android device.

That is the main difference between the two. tl;dr: dynamic pm is better for active usage.

So, if Android developers want to improve the battery usage while on active usage (which I assume is what the users want), they need to fine-tune the system for dynamic pm, and thus sleep as much as possible, hopefully reaching the sweet spot. But wait a second… If Android is using dynamic pm anyway, and they tune the system to the point of diminishing returns; there is not need for static pm. Right? Well, that’s my thinking, but I didn’t manage to make Android developers realize that in the discussion.

Plus, there’s a bunch of other reasons while static pm is not palatable for non-Android systems (aka. typical Linux systems), but I won’t go into those details.

Nokia’s bet was on dynamic, Google’s bet was on static, and in the end we agreed to disagree, but I think it’s clear from the outcome in real-world situations who was right–N9 users experiencing more than one day of normal usage, and even more than two. Sadly, only Nokia N9 users would manage to experience dynamic pm in full glory (at the moment).

Upstream

But not all is lost, and this in my opinion is the most important aspect. Dynamic pm lives on the Linux kernel mainline through the runtime power management API. This is not a Nokia invention that will die with the Nokia N9; it’s a collaborative effort where Nokia, TI, and other companies worked together, and now not only benefits OMAP, but other embedded chips, and even non-embedded ones. Being upstream means it’s good, and it has been blessed by many parties, and has gone through many iterations, and finally it probably doesn’t look like the original OMAP SRF code at all. Sooner or later your phone (if you don’t have an N9) will benefit from this effort, and it might even be an Android phone, your netbook (if not already benefiting in some way), and even your PC.

Android’s suspend blockers are not upstream, and it’s quite unlikely that they will ever be, or that you would see them used in any system other than Android, and there’s good reasons for that. Matthew Garrett did an excellent job of summarizing what went wrong with the story of suspend blockers on his presentation ‘Android/Linux kernel: Lessons learned’, but unfortunately the Linux foundation seems to be doing a poor job of providing those videos (I cannot watch them any more, even though I registered, and they haven’t been helpful through email conversations).

Update: I managed to get the video from the Linux Foundation and pushed it to YouTube:

Here is part of the discussion on LKML, if you want to read it for some strange reason. WARNING; it’s huge.


by FelipeC at January 03, 2012 11:10 PM

January 02, 2012

Thomas Vander SticheleHow do you manage mailing lists?

(Thomas Vander Stichele)

Every new year is a time of cleaning. After getting back to Inbox 0, my next target is my mailing list subscriptions.

It must be something psychological, but I cannot bring myself to unsubscribe from some of these mailing lists. I don’t check on them daily, but once in a while it’s darn useful to search through my local copy of mails on, say, selinux, and find solutions for a problem I’m having.

However, all this mailing list mail brings me a lot of headache. My email client is slow, and I would want it to be fast for the real mail I’m getting (from actual people, needing actual work). It’s hard to track the mails that matter – all my list mail gets put into folders automatically with some procmail magic, but it also means that some of the things I should be paying more attention to are just another bold folder in Evolution somewhere down the mail tree. And lastly, the server where I host my mail shared with friends gets too much traffic, and syncing 3 different evolutions over IMAP with it is a big part of the burden.

I vastly prefered the newsreader model of old, and I think the de facto standard of mailing lists really is a mistake. But I’m not sure what to replace it with.

What I want:

  1. have selected mailing list archives be available on my machines, locally
  2. have them synced/updated automatically
  3. have them out of the way of my normal mail usage unless when I need them

I’ve been considering getting a separate email account just for email lists for this purpose, although I don’t look forward much to having to change all my subscriptions, and would first like to hear from other people how this approach works out for them.

There used to be a push towards web-based mailing list subscriptions, but I don’t know if anyone is really seriously using that, and I would like to have the option of reading these mailing list archives offline.

How do you separate your ‘real’ mail from your mailing list mail? How do you handle them?

by Thomas at January 02, 2012 04:00 PM

December 30, 2011

Thomas Vander Sticheleusing xargs on a list of paths with spaces in a file

(Thomas Vander Stichele)

Every few weeks I have to spend an hour figuring out exactly the same non-googleable thing I’ve already needed to figure out. So this time it’s going on my blog.

The problem is simple: given an input file listing paths, one per line, which probably contain spaces – how do I run a shell command that converts each line to a single shell argument ?

Today, my particular case was a file /tmp/dirs on my NAS which lists all directories in one of my dirvish vaults that contains files bigger than a GB. For some reason not everything is properly hardlinked, but running hardlink on the vault blows up because there are so many files in there.

Let’s see if wordpress manages to not mangle the following shell line.

perl -p -e 's@\n@\000@g' /tmp/dirs | xargs -0 /root/hardlink.py -f -p -t -c --dry-run

by Thomas at December 30, 2011 06:18 PM

December 29, 2011

Thomas Vander SticheleN900 life support

(Thomas Vander Stichele)

I don’t want to simply be complaining about Nokia’s sad Linux story ending.

It’s obvious that things aren’t going to get better though for Maemo device owners.

Here are two things that caused me trouble over the last few months, and the fix that did it for me, in case you were suffering from the same problems.

      The Facebook photo sharing functionality just stopped working for me. It would upload the file, then give me an error without specifying any reason. I had simply assumed the Facebook API had changed, and since afaik this plugin is sadly closed-source (what on earth possessed Nokia to make a social media sharing component closed to begin with is beyond me – what kind of IP secrets could you possibly have in there?) I thought I would have to do without for now. And it really is a hassle to manually copy photos off then share them from the desktop.

Turns out that I simply had to re-authenticate the Sharing Account in Settings. No idea why – maybe Facebook changed some authentication system in the last few months ? Now it works again.

(As a side note, this plugin’s behaviour is really annoying when it comes to uploading photos. It will always try to upload as soon as you connect to a network, although usually all you get is access to some web page on which you have to authenticate, usually by paying, to get on to the net. The sharing plugin already blasts photos at facebook, then fails, gives you a non-useful error message, and then sits there forever without any option to retry. All you can do is cancel the transfer, in which case you will have to re-upload the photos from your library. After some time I figured out that a reboot caused it to retry all pending uploads on the next network connect, and then after that I figured out a kill of a sharing manager process did the same thing. But really, Nokia engineers – a simple ‘retry’ button was too hard ?)

    For the last two weeks my GPS stopped getting a lock completely. This wreaked havoc on my barriosquare/foursquare checkins as well, which simply don’t register without a GPS lock (yes I still have a half-done port of bsq to the new foursquare API, but last time I tried I was still stuck on the simply terrible browser coming with the device that seems to be unable to properly complete SSL requests in emulator mode).

I stumbled across this page and simply changed the AGPS server to google’s. Worked like a charm on the next connect. Nokia, I don’t know what you did to your AGPS server – surely other phones you have are using it too, not just the Maemo ones ?

I swore I wasn’t going to buy an N9 because there’s no point in buying an EOL’d phone if I plan to develop for it. The reviews when it actually came out almost persuaded me to get it, and the five minutes I got to play with Luis de Bethencourt’s phone got me really close. I’ve even seen plans in Belgium offering this phone! But really, there isn’t much point if Nokia isn’t going to support this phone any more and services are just going to get worse, and important parts of the stack remain closed and thus unfixable down the road.

This month’s Android course at work at least got me familiar developing for the phone and I was actually impressed by Eclipse this time around, and while Java still seems like a bitch to program in, the whole emulator setup is easy to use… Who knows, my next phone may in fact be an Android.

In the meantime, it’s nice to see that some of my fixes go noticed. That motivates me to possibly fix that other annoyance in erminig-ng – all-day events triggering an alarm at midnight and waking me up :)

by Thomas at December 29, 2011 09:35 AM

December 25, 2011

Stefan Kost25 Dec 2011

(Stefan Kost) buzztard


hi,

The buzztard team has released version 0.6.0 "black beats blue" of its
buzz-alike music composer. All modules got extensive improvements over the last
release from more than two years ago. Give it a try, join hacking and report bugs.

bml
Improved machine compatibility.

bsl
Several bug fixes and better compatibility.

buzztard
Main feature of this release is full undo/redo support. Related to it is the
journaling of edit action and the crash recovery. This way chances of losing
changes in the song are quite low. Other UI improvements are: tip of day,
improved spectrum analyzer, clipboard support, more commands in context menus
and many more). This release features a gstreamer decoder that enables playback
of buzztard songs in any gstreamer based media player.
We also kept the buzztard codebase clean and ported from deprecated APIs to the
successors (gnomevfs->gio, hal->gudev). The libraries and the applications got
performance improvements in many areas.
Also the docs have been improved a lot with tutorials, keyboard shortcut tables,
better coverage and man-pages.

gst-buzztard
Lots of code cleanups. Get rid of the temporary help interface. Switch from
liboil to orc. Performance improvements.

project-page: http://www.buzztard.org
screenshots: http://www.buzztard.org/index.php/Screenshots
downloads : http://sourceforge.net/projects/buzztard/files/

December 25, 2011 10:56 AM

December 24, 2011

Jean-François Fortin TamInvestigating Liferea’s startup performance

Last week, Lars Lindner provided us with an early christmas gift when he announced that a new stable release of our beloved feed reader was now available. First, I would like to applaud him for his continued efforts over the years in maintaining this handy and high quality application. Many users like me have been patiently waiting for the 1.8 release in the hope that it would finally solve the infamous performance problems of the 1.4 and 1.6 series. However, while I can’t speak of the performance once the app is launched, the startup performance has not met my expectations (in some cases, it has regressed). This blog post is intended to share my findings (which I discussed with Lars) and to invite you to comment on possible solutions.

Here’s an introduction to the problem:

  • An average Liferea user is expected to have hundreds of feeds and thousands of unread items (I have about 200 feeds and 2500 unread items). From discussions I’ve had, this is not considered excessive by Liferea standards.
  • Liferea uses SQLite as a database for storing feed data into a single “liferea.db” file. Mine currently weighs 115 Mo in its vacuumed form. SQLite has this terrible tendency to suck because you need to vacuum (compact) it every once in a while or the performance degrades terribly. Firefox has the same problem.
  • There also was ext4 as a suspect, although from all my tests on that matter in the 1.6 series, ext4 was definitely not the culprit. An ext3 partition had the same performance problems (or, at least, the same Liferea startup times).

On a beefy machine with a Core2Quad CPU, 4 GB of RAM and SATA2 hard drives, the only thing that made my 45-50 seconds startup time go down was… buying a solid state drive. Then, the startup time went down to about 10 seconds. I could live with that.

Enthusiastic about the prospect of a 1 second startup time (and a pony), I did not wait for Liferea to be packaged in my favorite distro and compiled it myself. Then I realized that not only had startup times stayed mostly unchanged on a conventional hard drive, they actually increased with the solid state drive. Here are my general startup times (with repeated measurements to ensure validity):

Hard drive type Cold start Warm start
HDD 38 secs 35 secs
SSD 21 secs 19 secs

The hard drive times went down slightly, but the SSD times went way up (compared to a 10 seconds cold start time in 1.6). Whatsmore, for both the HDD and SSD, the “warm start” times are almost the same as the “cold start” times! What’s going on here?

Luckily, liferea has a built-in profiling system. You can use “liferea –debug-performance”, or even “liferea –debug-performance –debug-db” to get measurements of individual operations. Liferea will tell you if any particular function call is slow. I’ll spare you the details of my analysis (ie: how I determined the total count, which functions to ignore/merge together, etc. This is left as an exercise for the curious reader) and show you the pretty executive charts:

As we can see, the things that stick out first are VACUUM, doing the “default source import” (parsing the .opml xml file containing the list of feeds?) and counting the unread items. I have about 200 feeds, each requiring 0.02 second to count unread items on a conventional hard drive (notice how the solid state drive completely nullifies this? :).

…Wait a second, VACUUM?! In previous Liferea releases, vacuuming the database was never done by the application, users had to do it themselves. But now, Liferea 1.8 vacuums automatically on startup.

Let’s represent this breakdown in a different way:

Vacuuming eats between 33 and 80% of the startup time (HDD vs SSD). We now have some explanations for our initial observations:

  • Liferea has seen some performance optimizations that probably improve startup times.
  • Those using solid state drives do not truly benefit from these optimizations, but are heavily affected by the newly added “vacuum” operation. Result: startup times went up.
  • For users with conventional hard drives, the optimizations improved startup times (I think) but vacuuming increased startup times, thus masking those improvements. Result: startup times stayed mostly the same.

By disabling the vacuum (commenting out the code), Liferea now starts in 4.48 seconds on my computer. That’s night and day.

Back in 2008, Lars himself thought that vacuuming automatically was not a good idea:

“The problem with it is that it also takes very long. With a 50MB DB file I experienced a runtime of over 1 minute. This is why this can be only a tool for experienced users that know how to do it manually knowing what to expect. For executing such a long term operation automatically on runtime would surely be unacceptable to the unsuspecting user. Also there is no good way how to decide when to do a VACUUM to save disk space and improve performance.”

Here’s a key rule about software performance optimization: performance problems are very often “needless work done at the wrong time”.

I’m no database expert (correct me if I’m wrong), but as I understand it, running vacuum everyday provides no significant benefit (it only provides a benefit when there’s a significant amount of stuff to vacuum). If you’re vacuuming on every startup, you’re using a nuclear weapon to dig a hole in a small garden.

Well, here’s the problem:

  1. You can’t vacuum while you’re actively using the application (as it blocks the database).
  2. You can’t vacuum when Liferea exits. According to Lars, “Liferea is too often killed by the session manager or [computer] shutdowns”.
  3. You can’t vacuum on startup “only once in a while” because, according to Lars, “if a program is sometimes slow (because of VACUUM) and sometimes not, users will complain or cancel the slow startup. So not doing it everytime is no real option.”

Short of finding a magical database backend that never hits those kinds of issues, here’s the potential solution I came up with:

  1. We already have a way to measure the startup times. Make it so that Liferea measures its startup time on every startup even without debugging mode.
  2. Factor in the count of items in the database, and the filesize of db file. [insert clever mathematical formula here]
  3. Once startup is done, if the startup time was unreasonably/statistically slow, offer to vacuum the database to improve performance.

An unintrusive infobar widget could be shown to the user:

Yes, imposing the responsibility of database performance optimization onto the user sounds like a bad idea… but I think we can agree that Liferea is a special case: it is an application that is meant to handle huge amounts of ever-changing data over time. It is not entirely unreasonable, in my humble opinion, to present the user with this occasional, unobtrusive prompt.

Of course, we should avoid nagging the user about it:

  • If the user clicks Optimize, do not ask again for at least a few weeks/month.
  • If the user clicks “Later”, do not ask for a few days.

As I said in the beginning, this blog post is intended as a summary of my findings and as a call for the collective wisdom of the hive. I know there’s a lot of very smart developers out there who might know of a solution we haven’t thought of.

What do you think? Is there a better way (be it in terms of backend scalability or in terms of UI/UX)?

by nekohayo at December 24, 2011 05:53 PM

December 22, 2011

Zeeshan AliHelp needed for Debian and Ubuntu

(Zeeshan Ali)
If you read any of my previous blog entries, you must be now familiar with this 'express installation' concept we have in Boxes. Its pretty neat actually, you just set a few options at the beginning and then you can leave Boxes (or your machine) and when you are back, everything is setup for you automatically in a new box.

I have invested a lot of time/efforts on this already and will be spending a lot more time in future as well but I am just one man so can not possibly cover all operating systems out there. That is why I am asking for help from anyone who will be interested in adding express installation support for Ubuntu and Debian while I focus on Fedora and Windows variants. Oh and if you are interested in adding support for some other distribution/OS, that contribution will also be more than welcomed.

In any case, happy hacking!

December 22, 2011 08:23 PM

Thomas Vander Stichelessh friction

(Thomas Vander Stichele)

I haven’t been too good this year at removing friction from my workflow. Today I wanted to change that. And the random friction thrown my way today has to do with ssh.

You see, somewhere along the line I read that it is a good idea to create separate keys for separate identities. So I have an identity for all work-related stuff (which I consider ‘ring 1′: it’s unlikely to change but everyone can get fired or change jobs), one for personal stuff on machines I actually control (‘ring 0′: they’d have to pry it out of my dead hands), another for my ‘public online default’ identity (‘ring 2′: I can always pull a whytheluckystiff and pull myself of the net and reinvent myself), and then per-project identities (‘ring 3′: I may lose interest in being a fedora or gstreamer contributor without massive changes in my personality).

I started splitting ring 3 per project when it made sense – for example, Fedora recently enforced a key change even if your account wasn’t compromised and even if you already have a strong passphrase on your key (like I had), and of course a massive flamefest ensued. I shrugged and decided to split off a new key and set that on all my machines.

But the problem is, this whole tower of ssh doesn’t really work well in practice. I chose a long passphrase for the new fedora keys, but obviously I do not want to type that every time I clone a package or commit changes. So I use ssh-agent. In theory, ssh-agent adds your keys and asks you for the passphrase once, and is then able to offer those identities to the other side.

The problem is a lot of ssh servers out there only give you a few tries. So your ssh agent will offer identity by identity until it gets refused. If my fedora identity was added as the fourth identity I lose – I can’t clone a package.

Specifying IdentityFile in the ssh config is useless. It is poorly documented, but IdentityFile files actually come after your ssh-agent identities. So your agent blasts all the wrong keys at the host first, and you get denied.

So you can specify IdentityOnly to make sure that only the identity file you want is being used. Sadly in that case it will not use the ssh-agent at all, so it will ask you for the password to your key file – the whole reason you want agents to be used in the first place.

Now obviously ssh has all the pieces it needs to Do The Right Thing. If my config says to use this identity and this identity only, ssh should be able to request ssh-agent to present that identity, and that identity only, and make the login happen without any password.

Surely I must be missing something obvious. Surely one of you uberhackers out there has set up the same thing as me. Why don’t you comment about it here and help the rest of us?

by Thomas at December 22, 2011 11:57 AM