May 18, 2013

Thomas Vander SticheleOrganizing photo libraries

(Thomas Vander Stichele)

The weather’s picking up so it’s time for spring cleaning around the house. When I moved back to Barcelona three years ago I took with me my old analogue photos and negatives, with the idea of sorting through them at some point and getting them digitized. And while I’m at it, maybe it’s time to pull all my various folders of photos together too and organize them.

Well, I finally started. I grouped the negatives, labeled them by year, put them in individual envelopes, and handed them off to a professional lab to scan them after doing a quick test run on one set (which turned out great, but it’s *really* annoying me that they scan to JPEG by default, charge 40% extra for TIFF, and use a non-multiple-of-8 resolution to scan at which means I can’t losslessly rotate the negatives. Yes, I’m anal.)

So now I pulled together all my various folders of photos, and before I start doing tagging and stuff like that, I want to organize them in a decent folder layout. Googling for ideas pretty much suggests that the way to go is

YYYY/MM/DD

with possibly some description together with the DD

I’m not really happy about that, however, because there are certain things I’d like to be able to do:

  • easily see where photos come from – did I make them ? did I get them from someone ? Did I download them from Facebook ?
  • Are these original files from a camera without editing ?
  • Are these the original scans ? From negatives ? From actual photos ? Or are they retouched, rotated, denoised, …
  • Are these photos SFW ? Can I point my media center slideshow to this directory and have it safely show any photos under it ? (What do you mean, you’ve never snowboarded at night in only your underwear, and mooning the photographer ?) Or maybe not even SFW, but simply watchable and reasonable quality or subject material?

I realize some of these issues can not be resolved simply with a directory layout. But I’m sure some of you must have had similar issues or come up with a slightly better layout ?

Point me in the right direction please.

by Thomas at May 18, 2013 11:51 AM

May 15, 2013

Stefan Kost15 May 2013

(Stefan Kost) buzztard is now buzztrax

We applied as an organisation to take part in the Google Summer of Code program, but got rejected mainly due to the project name. As this was not the first time people where uncomfortable with the name, we renamed the project - buzztard is now called buzztrax. The homepage with the wiki and wordpress already got moved. The renamed codebase is online at github. The mailing lists have been migrated to buzztrax.org. A few things still need to be fixed (e.g. file releases).

Besides the renaming there are also some improvements on the code side. I am probably the last one to discover the g_signal_handlers_disconnect_by_* macros. Using these made the code a bit leaner. I also worked on the level-meter features. I did some cleanups on the widget. The syncing code is more efficient as we listen to sync-messages on the gstreamer side to avoid another thread round trip. Song rendering can disabled the level-meters for less noise on the screen and some performance savings. The song-rendering now uses the TOC support in gstreamer-1.0. That means that the labels of a song (intro, chorus, break, ...) will end up in wav and flac files right now. When other formats support toc, this will automatically work for those formats too. The flag in ogg muxing got fixed in upstream and now works for us again.

56 files changed, 715 insertions(+), 631 deletions(-)

May 15, 2013 12:10 PM

May 10, 2013

Thomas Vander Stichelemorituri and Hidden Track One Audio

(Thomas Vander Stichele)

I have tomorrow (saturday) blocked out for a whole day of morituri hacking as I will be home alone.

One of the things a lot of morituri users are puzzled by is its relentless drive to extract every single sample of audio from the CD. Currently, even if it’s a really short pre-gap, and most likely just an inaccurate master or burn, with no useful audio in it.

For me, that was a design goal of morituri – I want to be able to exactly reproduce a CD as is. That is to say, ripping a CD should extract *all* audio from the CD, and it should be possible to make a copy of that CD and then rip that copy, and end up with exactly the same result as from the original CD. (I’m sure there’s a fancy scientific term for that that I can’t remember right now)

To a lot of other people, it seems to be annoying and they don’t like having those small almost empty files lying around.

So I thought I’d do something about that, and that it might be useful as well to analyze my current collection of tracks and figure out what’s in there. Maybe I can find some hidden gems that I hadn’t noticed before?

So I added a quick task to morituri that calculates the maximum sample value (I didn’t want to use my own level element in GStreamer for this as I wanted to make sure it was actual digital zero; this should be done in an element instead though, but I preferred the five minute hack for this one).

And then I ran:

rip debug maxsample /mnt/nas/media/audio/rip/morituri/own/album/*/00*flac

Sadly, that turned up 0 as the biggest sample for all these tracks!

Wait, what? I spent all that time on getting those secret tracks ripped just to get none? That’s not possible! I know some of those tracks!

Maybe the algorithm is wrong. Nope, it works fine on all the regular tracks.

Oh, crap. Maybe morituri has been ripping silence all this time because my CD drive can’t get that data off. Yikes, that would be a bit of egg on my face.

No, it works if I check that Bloc Party track I know about.

Ten minutes of staring at the screen to realize that, while I was outputting names from a variable from the for loop over my arguments, the track I was actually passing to the task was always the first one. Duh. Problem solved.

As for what I found in my collection:

  • a cute radio jingle that brought back memories from a live bootleg I had made myself of Bloem. That’s from over ten years ago, but that must have been around the time I learned about the existence of HTOA and wanted to get one in
  • found unknown HTOA tracks on Art Brut’s Bang Bang Rock & Roll, Mew’s Half the world is watching me; not their best stuff
  • soundscapey or stagesetting tracks on QOTSA’s Songs for the Deaf, Motorpsycho’s Angels and Daemons at play And Blissard; not that worth it (the Blissard track was ok, but really quiet)
  • Pulp hid a single piano chord in a 2 second pre-gap on This is Hardcore; very curious. It’s not an intro to the first track, because it doesn’t fit with the sound at all.
  • Damien Rice hid a demo version of 9 Crimes (the first track) in the pregap; instead of piano and female vocals, he plays guitar and sings all the parts.
  • Got reacquainted with my favourite HTOA tracks: the orchestral quasi-wordless medley on the Luke Haines/Das Capital disc; the first Bloc Party album with a beautiful instrumental (up there with the hidden track at the end of Placebo’s first album; both bands delivering an atypical but stunning moodscape; the beautiful cover of Ben Kenobi’s Theme by Arab Strap on the Cherubs EP (no idea why that landed in my album dir, that needs to be fixed); the silly Soulwax skit for their second album.

Of course, Wikipedia has the last word on everything

I note that they think Pulp recorded a cymbal, not a piano. And now that I see the title of the QOTSA hidden track, I get the joke I think.

In total, on my album collection of 1564 full CD’s, I have 171 HTOA’s ripped, 138 tracks of pure digital silence, and only about 11 are actually useful tracks.

I expected to find more gems in my collection. I’ll go through ep’s, singles and compilations next just to be sure.

But with this code in hand, maybe it’s time to add something to morituri to save the silent HTOA tracks as pure .cue information.

by Thomas at May 10, 2013 08:08 PM

May 08, 2013

Andy Wingogenerators in v8

(Andy Wingo)

Hey y'all, ES6 generators have landed in V8! Excellent!

Many of you know what that means already, but for those of you that don't, a little story.

A few months ago I was talking with Andrew Paprocki over at Bloomberg. They use JavaScript in all kinds of ways over there, and as is usually the case in JS, it often involves communicating with remote machines. This happens on the server side and on the client side. JavaScript has some great implementations, but as a language it doesn't make asynchronous communication particularly easy. Sure, you can do anything you want with node.js, but it's pretty easy to get stuck in callback hell waiting for data from the other side.

Of course if you do a lot of JS you learn ways to deal with it. The eponymous Callback Hell site lists some, and lately many people think of Promises as the answer. But it would be nice if sometimes you could write a function and have it just suspend in the middle, wait for your request to the remote computer to come through, then continue on.

So Andrew asked if me if we could somehow make asynchronous programming easier to write and read, maybe by implementing something like C#'s await operator in the V8 JavaScript engine. I told him that the way into V8 was through standards, but that fortunately the upcoming ECMAScript 6 standard was likely to include an equivalent to await: generators.

ES6 generators

Instead of returning a value, when you first call a generator, it returns an iterator:

// notice: function* instead of function
function* values() {
  for (var i = 0; i < arguments.length; i++) {
    yield arguments[i];
  }
}

var o = values(1, 2, 3);  // => [object Generator]

Calling next on the iterator resumes the generator, lets it run until the next yield or return, and then suspends it again, resulting in a value:

o.next(); // => { value: 1, done: false }
o.next(); // => { value: 2, done: false }
o.next(); // => { value: 3, done: false }
o.next(); // => { value: undefined, done: true }

Maybe you're the kind of person that likes imprecise, incomplete, overly abstract analogies. Yes? Well generators are like functions, with their bodies taken to the first derivative. Calling next integrates between two yield points. Chew on that truthy nugget!

asynchrony

Anyway! Supending execution, waiting for something to happen, then picking up where you left off: put these together and you have a nice facility for asynchronous programming. And happily, it works really well with promises, a tool for asynchrony that lots of JS programmers are using these days.

Q is a popular promises library for JS. There are some 250+ packages that depend on it in NPM, node's package manager. So cool, let's take their example of the "Pyramid of Doom" from the github page:

step1(function (value1) {
    step2(value1, function(value2) {
        step3(value2, function(value3) {
            step4(value3, function(value4) {
                // Do something with value4
            });
        });
    });
});

The promises solution does at least fix the pyramid problem:

Q.fcall(step1)
.then(step2)
.then(step3)
.then(step4)
.then(function (value4) {
    // Do something with value4
}, function (error) {
    // Handle any error from step1 through step4
})
.done();

But to my ignorant eye, some kind of solution involving a straight-line function would be even better. Remember what generators do: they suspend computation, wait for someone to pass back in a result, and then continue on. So whenever you would register a callback, whenever you would chain a then onto your promise, instead you suspend computation by yielding.

Q.async(function* () {
  try {
    var value1 = yield step1();
    var value2 = yield step2(value1);
    var value3 = yield step3(value2);
    var value4 = yield step4(value3);
    // Do something with value4
  } catch (e) {
    // Handle any error from step1 through step4
  }
});

And for a super-mega-bonus, we actually get to use try and catch to handle exceptions, just as Gods and Brendan intended.

Now I know you're a keen reader and there are two things that you probably noticed here. One is, where are the promises, and where are the callbacks? Who's making these promises anyway? Well you probably saw already in the second example that using promises well means that you have functions that return promises instead of functions that take callbacks. The form of functions like step1 and such are different when you use promises. So in a way the comparison between the pyramid and the promise isn't quite fair because the functions aren't quite the same. But we're all reasonable people so we'll deal with it.

Note that it's not actually necessary that any of the stepN functions return promises. The promises library will lift a value to a promise if needed.

The second and bigger question would be, how does the generator resume? Of course you've already seen the answer: the whole generator function is decorated by Q.async, which takes care of resuming the generator when the yielded promises are fulfilled.

You don't have to use generators of course, and using them with Q does mean you have to understand more things: not only standard JavaScript, but newfangled features, and promises to boot. Well, if it's not your thing, that's cool. But it seems to me that the widespread appreciation of await in C# bodes well for generators in JS.

ES6, unevenly distributed

Q.async has been part of Q for a while now, because Firefox has been shipping generators for some time.

Note however that the current ES6 draft specification for generators is slightly different from what Firefox ships: calling next on the iterator returns an object with value and done properties, whereas the SpiderMonkey JS engine used by Firefox uses an exception to indicate that the iterator is finished.

This change was the result of some discussions at the TC39 meeting in March, and hasn't made it into a draft specification or to the harmony:generators page yet. All could change, but there seems to be a consensus.

I made a patch to Q to allow it to work both with the old SpiderMonkey-style generators as well as with the new ES6 style, and something like it should go in soon.

give it to me already!

So yeah, generators in V8! I've been working closely with V8 hackers Michael Starzinger and Andreas Rossberg on the design and implementation of generators in V8, and I'm happy to say that it's all upstream now, modulo yield* which should go in soon. Along with other future ES6 features, it's all behind a runtime flag. Pass --harmony or --harmony-generators to your V8 to enable it.

Barring unforeseen issues, this will probably see the light in Chromium 29, corresponding to V8 3.19. For now though this hack is so hot out of the fire that it hasn't even had time to cool down and make it to the Chrome Canary channel yet. Perhaps within a few weeks; whenever the V8 dependency in Chrome gets updated to the 3.19 tree.

As far as Node goes, they usually track the latest stable V8 release, and so for them it will probably also be a few weeks before it goes in. You'll still have to run Node with the --harmony flag. However if you want a sneak preview of the future, I uploaded a branch of Node with V8 3.19 that you can build from source. It might mulch your cat, but life is not without risk on the bleeding_edge.

Finally for Q, as I said ES6 compatibility should come soon; track the progress or check out your own copy here.

final notes

Thanks to the V8 team for their support in this endeavor, especially to Michael Starzinger for enduring my constant questions. There's lots of interesting things in the V8 pipeline coming out of Munich. Thanks also to Andrew Paprocki and the Bloomberg crew for giving me the opportunity to fill out this missing piece of real-world ES6. The Bloomberg folks really get the web.

This has been a hack from Igalia, your friendly neighborhood browser experts. Have fun with generators, and happy hacking!

by Andy Wingo at May 08, 2013 07:31 PM

May 07, 2013

Thomas Vander SticheleVotes for talks at open source conferences

(Thomas Vander Stichele)

I’ve never been a fan of voting for talks, because it tends to be poorly implemented under the guise of democracy. Of course it’s easy for me to talk, I’ve never organized anything at that scale.

I’ll give two examples on why I feel this way, one of which triggering today’s blog post.

First off, my colleague Marek submitted a talk to Djangocon. The talk was about how to use feat (a toolkit we wrote for livetranscoding) to serve Django pages, but in such a way that they can use Deferreds to remove the concurrency bottleneck of “1 request at a time” per process running Django.

Personally, to me, this is one of the most irritating design choices of Django – from the ground up it was built synchronously (which could have been fine in most places). But the fact that, when you get a request, you have to always synchronously respond to it (and block every other request for that process in the meantime) is a design choice that could have easily been avoided.

In our particular use case, it was really painful. If our website has to do an API request to some other service we don’t control that can easily take 30 seconds, our process throughput suddenly becomes 2 pages per minute. All the while, the server is sitting there waiting.

Yes, you can throw RAM at the problem and start 30 times more processes; or thread out API requests; or farm it out to Celery, and do some back-and-forthing to see when the call’s done. Or do any other number of workarounds for a fundamental design choice.

Since we like Twisted, we preferred to throw Twisted at the problem, and ended up with something that worked.

Anyway, that’s a lot of setup to explain what the talk was about. Marek submitted the talk to DjangoCon, and honestly I didn’t expect it to get much traction because, when you’re inside Django, you think like Django, and you don’t really realize that this is a real problem. Most people who do realize it switch away to something else.

But to my surprise, Marek’s talk was the most-voted talk! I wish I could link to the results, but of course that vote site is no longer online.

I guess I expected that would mean he’d be presenting at DjangoCon this year. So I asked him today when his talk was, and he said “Oh that’s right. I did not get accepted.”

Well, that was a surprise. Of course, the organising committee reserves the right to decide on their own – maybe they just didn’t like the talk. But if you ask your potential visitors to vote, you’d expect the most-voted talk to make it on the schedule no ?

The feedback Marek got from them was surprising too, though. Their first response was that this talk was too similar to another talk, titled “How to combine JavaScript & Django in a smart way”. Now, I’m not a JavaScript expert, but from the title alone I can already tell that it’s very unlikely that these two talks have many similarities beyond the word ‘Django’.

After refuting that point, their second reason was that they wanted more experienced speakers (but they didn’t ask Marek for his experience), and their third reason was that the talk was in previous editions of DjangoCon US/EU (it’s unclear whether they meant his talk or the JavaScript one, but Marek’s definitely wasn’t, and we couldn’t find any mention of the other talk in previous conferences. I’m also not sure why that even matters one way or the other. This email thread was in Polish, so I have to rely on Marek’s interpretation of it)

Personally, my reaction would have been to complain to the organizers or Django maintainers. Marek’s flegmatic attitude was much better though – after such an exchange, he simply doesn’t want to have anything to do with the conference.

He’s probably right – it’s hard to argue with someone who doesn’t want to invite you and is lying about the reasons.

The second example is BCNDevCon, a great conference here in Barcelona, organized by a guy who used to work for Flumotion who I have enormous respect for. I’ve never seen anyone create such a big conference over so little time.

He believes strongly in the democratic aspect, and as far as I can tell constructs the schedule solely based on the votes.

Sadly I didn’t go to the last one, and the reason is simply because I felt that the talks that made it were too obviously corporate. A lot of talks were about Microsoft products, and you could tell that they won votes because people’s coworkers voted on talks. I’m not saying that’s necessarily wrong – given that he worked at our company and has friends here, I’m sure people working here presenting at his conference have also done vote tending. It’s natural to do so. But there should be a way to balance that out.

I think the idea of voting is good, but implementation matters too. Ideally, you would only want people that actually are going to show up to vote. I have no idea how you can ensure that, though. Do you ask people to pre-pay ? Do you ask them to commit to pay if at least 50% of their votes make it in the final schedule, kickstarter-style ?

These two examples are on opposite extremes of voting. One conference simply disregards completely what people vote on. If I had voted or bought a ticket, I would feel lied to. Why waste the time of so many people? The other conference puts so much stock in the vote, that I feel the final result was strongly affected. I seriously doubt all those Windows 8 voters actually showed up.

Does anyone have good experiences with conference voting that did work? Feel free to share!

by Thomas at May 07, 2013 11:53 AM

May 03, 2013

Thomas Vander SticheleIf I was 16 years younger…

(Thomas Vander Stichele)

I’d totally try and be the intern for pinboard.

The money is great for a summer job, but that’s not the important part. pinboard seems interesting, it’s a real service, and it’s (I assume) small enough to understand from top to bottom. Contrary to, say, a Google Summer of Code project, you get to touch a real existing service, and from what I can tell from the blog you get to do it with a smart and funny guy.

You’ve got five weeks left; even if you’re in the middle of exams right now, apply!

(And if you do, why not add the features to merge and rename tags while you’re at it?)

by Thomas at May 03, 2013 09:30 PM

April 28, 2013

Jean-François Fortin TamNo more stuck rendering dialogs!

If you’ve tried rendering projects with Pitivi 0.15 or older, chances are you’ve encountered one of these dreadful situations where the rendering process would get stuck:

  • …at the beginning, with the progressbar saying it’s currently “estimating” — which was a lie that I corrected a little while ago.
  • …at the very end. Extra trolling points for having made you waste a huge amount of time to get a 0 bytes output file (if we’re lucky, that bug is gone).
  • …somewhere in the middle, because caps negotiation failed, some elements were not linked, GStreamer thinks you ran out of available RAM, or because you’ve been very naughty.

In any such case, the rendering dialog just sat there and smiled at you, as if everything was fine in the world. Well, no more:

slap

Pitivi is going to give you the honest, brutal truth.

This is the result of a horrifying thought suddenly springing to my mind yesterday night: “Hey, what if the code was not even checking for errors in the pipeline when rendering?”

Indeed, it wasn’t. How silly is that! I have thus prepared a simple fix to improve the situation: catch pipeline error messages, abort the render (you really don’t want to ignore a GStreamer error) and display an error dialog. This will at least let people know that something is wrong and that they should start writing patches to GStreamer instead of accusing Pitivi of hurting kittens. You’d be surprised how many people can sit for hours in front of that stuck progressbar.

Before I commit the fix however, I would need your feedback on the usability of that dialog:

2013-04-27

This is not terribly pretty, but it’s better than nothing. A few things to consider:

  • In that screenshot, all the text except the window title (“Error While Rendering Project”) comes from the GStreamer pipeline error message (the error and the error’s details). I know that the error details look ugly, but I suspect it wouldn’t be useful to GStreamer/Pitivi developers if we don’t have them “verbatim”. Maybe we could try to mangle the error details string (split using “:” and take only the first and last two items of the resulting list?) and encourage the user to run from a terminal to get better debug info, but that feels a bit backwards.
  • We should probably have some less-scary text to accompany the actual error details. Something that guides the user towards an action that can be done to address the problem (ex: reporting a bug). Maybe it can be placed between the header and the details (above the “qtdemux.c” line)? The problem is finding a universal text to be used.
  • If we consider the route where we suggest the user to report bugs, where should we point to? The Pitivi bugs investigation page? Pitivi bugzilla? GStreamer bugzilla? The distro’s bug tracker?
  • Let’s keep this simple, both visually and in terms of code/implementation.

What do you think? Is the current approach sufficient or is there something better that we can easily do?

Update: here’s an alternative dialog with some more comprehensible text, where the actual error (as seen in the previous screenshot) gets shoved under the rug by putting it in a GTK expander widget (clicking “Details” reveals the error’s details as above):

2013-04-29

by nekohayo at April 28, 2013 04:19 AM

April 26, 2013

GStreamerGStreamer Core and Plugins 1.0.7 bug-fix release

(GStreamer)

The GStreamer team is pleased to announce another bug-fix release for the new API and ABI-stable 1.x series of the GStreamer multimedia framework.

Check out the release notes for GStreamer core, gst-plugins-base, gst-plugins-good, gst-plugins-ugly, gst-plugins-bad, or gst-libav, or download tarballs for gstreamer, gst-plugins-base, gst-plugins-good, gst-plugins-ugly, gst-plugins-bad, or gst-libav,

Improvements include:

  • better support for static plugins
  • streamsynchronizer is now a public element, useful in HLS pipelines for example
  • osxaudio plugin ported to 1.0
  • androidmedia plugin is ported to 1.0
  • internal libav snapshot in gst-libav has been updated to libav 0.8.6
  • Now uses frame based threading if possible and disables slice based threading until libav 0.9.x is used (as is the case in git master already) This provides potentially better performance and fixes some display corruptions caused by bugs in the slice based threading
  • a number of bug fixes

April 26, 2013 02:00 PM

April 19, 2013

Christian SchallerBrno GUADEC Call for Papers!

(Christian Schaller)

I would like to give everyone a friendly reminder that Saturday the 27th of April is the official deadline for the GUADEC 2013 Call for Papers. So make sure to get your proposal submitted.

We hope to have a wide range of talks this year, including talks on related subjects such as Wayland and Multimedia, so don’t automatically assume that you will not get a talk approved because its not ‘pure GNOME’.

GUADEC this year will be in Brno in the Czech Republic, so I hope to see as many of you as possible here.

by uraeus at April 19, 2013 10:29 AM

Michael SheldonErudite now available for Symbian Belle

(Michael Sheldon)

Erudite displaying a book library

Overview

Erudite makes it possible to use Amazon’s Cloud Reader on various mobile platforms which aren’t officially supported by Amazon. You can either read books online, or download them for reading offline. Your progress in a book is then also kept synchronised between your phone and other Kindle devices.

Symbian Belle support

Until recently Erudite only supported MeeGo Harmattan and Mer based phones (such as the Nokia N9), but now it’s also available for Symbian Belle phones as well. I’ll try and put together a build for Symbian Anna phones in the near future.

There’s a fairly comprehensive review of Erudite for Symbian over on All About Symbian: Erudite review.

Upcoming features

In the next release for both Symbian and MeeGo I’ll be focusing on orientation switching support, so users can optionally view their books in landscape mode, as well as investigating some apparent issues with very large books.

Download

  • Symbian Belle version — Nokia 701, Nokia C6-01, Nokia C7-00, Nokia N8-00, Nokia X7-00, Nokia E6-00, Nokia 808 Pureview, Nokia 603, Nokia Oro, Nokia E7-00, and Nokia 700
  • MeeGo Harmattan version — Nokia N9, Nokia N950

by Mike at April 19, 2013 09:51 AM

April 18, 2013

Andy Wingoinside full-codegen, v8's baseline compiler

(Andy Wingo)

Greetings to all. This is another nargish article on the internals of the V8 JavaScript engine. If that's your thing, read on. Otherwise, here's an interesting interview with David Harvey. See you laters!

full-codegen

Today's topic is V8's baseline compiler, called "full-codegen" in the source. To recall, V8 has two compilers: one that does a quick-and-dirty job (full-codegen), and one that focuses on hot spots (Crankshaft).

When you work with V8, most of the attention goes to Crankshaft, and rightly so: Crankshaft is how V8 makes code go fast. But everything goes through full-codegen first, so it's still useful to know how full-codegen works, and necessary if you go to hack on V8 itself.

The goal of this article is to recall the full-codegen to mind, so as to refresh our internal "efficiency model" of how V8 runs your code (cf. Norvig's PAIP retrospective, #20), and to place it in a context of other engines and possible models.

stack machine

All JavaScript code executed by V8 goes through full-codegen, so full-codegen has to be very fast. This means that it doesn't have time to do very much optimization. Even if it did have time to do optimization (which it doesn't), full-codegen lacks the means to do so. Since the code hasn't run yet when full-codegen compiles it, it doesn't know anything about types or shapes of objects. And as in other JS engines, full-codegen only compiles a function at a time, so it can't see very far. (This lets it compile functions lazily, the first time they are executed. Overall syntactic validity is ensured by a quick "pre-parse" over the source.)

I have to admit my surprise however at seeing again how simple full-codegen actually is: it's a stack machine! You don't get much simpler than that. It's shocking in some ways that this is the technology that kicked off the JS performance wars, back in 2008. The article I wrote a couple years ago does mention this, but since then I have spent a lot of time in JSC and forgot how simple things could be.

Full-codegen does have a couple of standard improvements over the basic stack machine model, as I mentioned in the "two compilers" article. One is that the compiler threads a "context" through the compilation process, so that if (say) x++ is processed in "effect" context, it doesn't need to push the initial value of x on the stack as the result value. The other is that if the top-of-stack (ToS) value is cached in a register, so that even if we did need the result of x++, we could get it with a simple mov instruction. Besides these "effect" and "accumulator" (ToS) contexts, there are also contexts for pushing values on the stack, and for processing a value for "control" (as the test of a conditional branch).

and that's it!

That's the whole thing!

Still here?

What about type recording and all that fancy stuff, you say? Well, most of the fancy stuff is in crankshaft. Type recording happens in the inline caches that aren't really part of full-codegen proper.

Full-codegen does keep some counters on loops and function calls and such that it uses to determine when to tier up to Crankshaft, but that's not very interesting. (It is interesting to note that V8 used to determine what to optimizing using a statistical profiler, and that is no longer the case. It seems statistical profiling would be OK in the long run, but as far as I understand it didn't do a great job with really short-running code, and made it difficult to reproduce bugs.)

I think -- and here I'm just giving my impression, but fortunately I have readers that will call my bullshit -- I think that if you broke down basic JavaScript and ignored optimizable hot spots, an engine mostly does variable accesses, property accesses, and allocations. Those are the fundamental things to get right. In a browser you also have DOM operations, which Blink will speed up at some point; and there are some domain-specific things like string operations and regular expressions of course. But ignoring that, there are just variables, properties, and allocations.

We'll start with the last bit. Allocation is a function of your choice of value representation, your use of "hidden classes" ("maps" in V8; all engines do the same thing now), and otherwise it's more a property of the runtime than of the compiler. (Crankshaft can lower allocation cost by using unboxed values and inlining allocations, but that's Crankshaft, not full-codegen.)

Property access is mostly handled by inline caches, which also handle method dispatch and relate to hidden classes.

The only thing left for full-codegen to do is to handle variable accesses: to determine where to store local variables, and how to get at them. In this case, again there's not much magic: either variables are really local and don't need to be looked up by name at runtime, in which case they can be allocated on the stack, or they persist for longer or in more complicated scopes, in which case they go on the heap. Of course if a variable is never referenced, it doesn't need to be allocated at all.

So in summary, full-codegen is quick, and it's dirty. It does its job with the minimum possible effort and gets out of the way, giving Crankshaft a chance to focus on the hot spots.

comparison

How does this architecture compare with what other JS engines are doing, you ask?

I have very little experience with SpiderMonkey, but as far as I can tell, with every release they they get closer and closer to V8's model. Earlier this month Kannan Vijayan wrote about SpiderMonkey's new baseline compiler, which looks to be exactly comparable to full-codegen. It's a stack machine that emits native code. It looks a little different because it operates on bytecode and not the AST, as SpiderMonkey still has an interpreter hanging around.

JavaScriptCore, the WebKit JavaScript engine, is similar on the surface: it also has a baseline compiler and an optimizing compiler. (In fact it's getting another optimizing compiler soon, but that's a story for another article). But if you look deeper, I think JSC has diverged from V8's model in interesting ways.

Besides being a register machine, a model that has inherent advantages over a stack machine, JavaScriptCore also has a low-level interpreter that uses the same calling convention as the optimizing compiler. I don't think JSC is moving in V8's direction in this regard; in fact, they could remove their baseline compiler entirely, relying instead on the interpreter and the optimizing compiler. JSC also has some neat tricks related to scoping (lazy tear-off); again, a topic for some future article.

summary

The field is still a bit open as to what is the best approach to use for cold code. It seems that an interpreter could still be a win, because if not, why would SpiderMonkey keep one around, now that they have a baseline compiler? And why would JSC add a new one?

At the same time, it seems to me that one could do more compile-time analysis at little extra cost, to speed up full-codegen by allocating more temporaries into slots; you would push and pop at compile-time to avoid doing it at run-time. It's unclear whether it would be worth it, though, as that analysis would have to run on all code instead of just the hot spots.

Hopefully someone will embark on the experiment; it should just be a simple matter of programming :) Until next time, happy hacking!

by Andy Wingo at April 18, 2013 03:45 PM

April 11, 2013

Jean-François Fortin TamPiTiVi and the 2013 Summer of Code

This year will be a little bit different. In a rather unexpected turn of events, PiTiVi has been accepted as a mentoring organization but GStreamer has not. Fear not however, as GStreamer has no better ally than the PiTiVi team when it comes to pushing our favorite multimedia framework to its limits and beyond. As you may know, PiTiVi makes heavy use of the GStreamer Editing Services library and, in turn, GNonLin and the rest of GStreamer. With the switch to GES and the irrevocable shedding of our old skin, any backend work done for the sake of the PiTiVi project ends up benefitting GStreamer and other projects.

One way to look at things is that there is no such thing as a PiTiVi backend anymore. PiTiVi is a frontend that pushes the latest and greatest open-source multimedia technologies forward.

With the GES port nearing completion, this is the first time that we can truly say there are three interrelated components to contribute to. This new reality sets the tone for a different way to look at PiTiVi project ideas this year: you can finally…

Choose your character class

pitivi hacker style

Are you a ninja? A spellcaster? A tank? While most projects are a balance of backend and UI work, we know that some people prefer to lean more to one side or another of the continuum — that’s why I created a new visual notation for our ideas page this year. Instead of an “easy/hard” system (which would be inaccurate and misleading, as perceived difficulty is measured differently for everybody), we simply provided a visual indication of the expected involvement in the various components for a given project idea (for example, “PiTiVi: ◼◼◻◻◻ GES: ◼◼◼◼◼  GStreamer: ◼◼◼◻◻”). So if you were looking for something closer to a hardcore GStreamer GSoC project, you can spot ideas that might interest you here.

Not a programmer? You can help raise awareness about this. Maybe you know a brilliant hacker friend/relative or a top-notch computer science student waiting for a chance to make a big difference in the world. Tell that person about how cool and welcoming PiTiVi is and how getting involved is the best way to advance free, powerful and intuitive video editing for everyone!

by nekohayo at April 11, 2013 07:09 PM

Arun RaghavanPulseAudio in GSoC 2013

That’s right — PulseAudio will be participating in the Google Summer of Code again this year! We had a great set of students and projects last year, and you’ve already seen some their work in the last release.

There are some more details on how to get involved on the mailing list. We’re looking forward to having another set of smart and enthusiastic new contributors this year!

p.s.: Mentors and students from organisations (GStreamer and BlueZ, for example), do feel free to get in touch with us if you have ideas for projects related to PulseAudio that overlap with those other projects.

by Arun at April 11, 2013 11:34 AM

April 09, 2013

Stefan Kost9 Apr 2013

(Stefan Kost) buzztard & gstreamer hackfest

This month I mostly cleaned up small bits and pieces from the gstreamer-1.0 port. Most notably multitrack encoding works again. The handling of EOS and starting of the next track was racy. Speaking of the recording dialog - this one now has some basics for a silent mode implemented. For now it only disables the scrolling in the sequence view. Next thing would be to disable the level meters.

I hacked a bit more on the child-proxy iface. This now turned into utility functions that allows to write:
bt_child_proxy_set(obj, "prop1::prop2::prop3", val, NULL);
So what does this do?
GObject obj1, obj2;
g_object_get(obj, "prop1", &obj1, NULL);
g_object_get(obj1, "prop2", &obj2, NULL);
g_object_set(obj2, "prop3", val, NULL);
g_object_unref (obj2);
g_object_unref (obj1);

This saved quite a few lines of C in buzztard. I wonder if this is something we want to add to glib? If we do I would go for a single ':' as a separator and we might also want to consider starting the property with one:
g_object_set(obj, ":prop1:prop2:prop3", val, NULL);
The leading ':' would help to quickly detect whether we need to split the property name and recurse into child objects. The whole scheme is backwards compatible as property names are not allowed to contain ':'.

In the end of march I attended the GStreamer hackfest in Milano. First I looked into a few tests - both on GStreamer and buzztard side. On the GStreamer side adder has some test fixes. On the buzztard side I improved my encoding tests. Wim gave me the crucial tip that fixed the dynamic adding/removing of analyzers while playing. Maybe I can try that for machines again. I showed the parser for controller-setups to some people and did smaller changes on it. I also discussed what we could do with gst-tracelib for gst-1.0 and started a new design-draft for it.

41 files changed, 871 insertions(+), 816 deletions(-)

April 09, 2013 08:31 PM

Christian SchallerNo GStreamer in this years Google Summer of Code

(Christian Schaller)

Some sad news, GStreamer did not get accepted to the 2013 Google Summer of Code. We don’t know the exact reasons, but all we can do at this point is redouble our efforts to get accepted again next year.

In the meantime not all hope is lost. You can still do a Google Summer of Code involving GStreamer with some of the other organisations that did get approved. For instance if you have an idea for a great multimedia desktop application using GStreamer you can try submitting that to for instance GNOME or KDE depending on your UI toolkit of choice as one example. In the past GNOME has also been open to hosting some pure GStreamer projects so you can always try submitting such too. In general I recommend people to take a look at the list of accepted organisations and see if there are projects which technologies would be relevant to the GSoC project you want to do and the apply with them. Also remember you can submit the same project to multiple organisations if it fits multiple projects.

Also the PiTiVi video editor did get approved so I strongly encourage you to take a look at their wonderful ideas page and submit a proposal to do a PiTiVi project.

by uraeus at April 09, 2013 09:29 AM

April 05, 2013

Jean-François Fortin TamLe nipponophone de l’autobus

Hier dans l’autobus, j’ai eu la chance de tomber sur un homme blanc parlant au téléphone… dans le langage du soleil levant. Après un très long moment de tergiversation mentale après la fin de son appel, j’osai:

«Bonjour monsieur, parlez-vous français? C’est pas tous les jours que j’entends parler japonais dans cet autobus, et vous le parlez très bien! Où l’avez-vous appris?»

«J’ai vécu au Japon pendant cinq ans!»

S’en suit une quinzaine de minutes de discussion où je découvris des choses qui changèrent certaines de mes perceptions, jusque-là biaisées par les ouï-dires.

D’abord, le taux de change entre le peso canadien et le Yen est plutôt désavantageux pour les canadiens en ce moment: l’économie japonaise, bien que mal en point du point de vue intérieur, reste assez forte sur le point de vue international, spécialement en comparaison avec l’Europe en crise depuis 2008-2009. Les investisseurs se replient alors sur une monnaie stable comme le Yen (ça, je dois dire que j’ai du mal à comprendre cette subtilité). Si l’Europe reprenait du poil de la bête, la valeur du Yen se rebalancerait possiblement.

Oui, le coût de la vie au Japon est élevé. C’est pourquoi il est préférable d’y travailler plutôt que d’être touriste, parce que les salaires sont en conséquence.

Surtout, je me demandais comment était l’accueil et l’intégration des étrangers s’établissant au japon. Certains reportages, combinés aux films comme «Stupeur et tremblements» (qui est, admettons-le, un peu dramatisé/comédique) et les opinions des gens autour de moi, me laissaient croire à une société fermée/repliée. Selon cet homme, il n’en est rien; il s’agit strictement du même phénomène que ce que l’on retrouve pratiquement partout dans le monde: si l’immigrant fait des efforts pour apprendre et maîtriser la langue locale, son intégration se fera avec succès alors que «les gens vont se précipiter avec joie pour vous aider», tout comme les Québécois francophones adoptent une attitude positive envers quiconque fait des efforts pour parler le Français.

Et vous? Habitez-vous au Japon ou connaissez-vous quelqu’un qui vous a fait témoignage de l’intégration des immigrants là-bas?

by nekohayo at April 05, 2013 11:08 PM

April 04, 2013

Bastien NoceraGeocluing the desktop, slowly

(Bastien Nocera) Over the past couple of months, Satabdi has been working during her Outreach Program for Women on geocode-glib, and Zeeshan more recently joined us to help with cleaning up some of the code.

As Satabdi's program is now finished (though not her involvement!), and a new GNOME development cycle has started, I'll try to explain where geocode-glib fits in, and answer some questions on the future of Geoclue.

(Reverse-)Geocoding

First and foremost, geocode-glib is a geocoding and reverse geocoding library. It uses Yahoo! web services for this, though we're investigating using Nominatim for this in the future.

This replaces the convoluted implementations for those two services in geoclue (3 if you include Address as a service). The API should be mostly stable now, and we'll soon start porting a few applications to it (Evolution and Empathy come to mind).

The library also includes a GeocodeLocation object. This will be useful later.

GeoIP

geocode-glib, thanks to Satabdi's work, includes a GeoIP server, to be installed on GNOME servers eventually, which uses data from MaxMind to  locate a user connected to the Internet from the IP address. We also have a client library to access this server.

This is usually good enough to locate a user in a city, or a country, which would help us with many integration points in GNOME, such as the upcoming Date and Time panel re-design.

But this code isn't really for you, app developers.

Geoclue

A fine project, but the codebase is showing its age (dbus-glib!), and the decision, well, not to take decisions on which backends to use for various services make it fragile. This is a maintenance problem, both for in terms of making sure all the services are kept working, and that geoclue itself is kept stable.

So we'll start a reimplementation of Geoclue. The goals are:

  • Trimmed down API, just for positioning
  • Smaller, but more integrated, selection of ways to get the positioning (GPS from your integrated WWAN modem, Wi-Fi AP data, IP address, no discrete GPS or manual location)
  • Power-saving, by aggregating requests from all the applications
  • and finally, privacy, where only applications that you allow to request your location can get it, and only with an accuracy as needed for the application.
The code currently in geocode-glib for IP geocoding will likely move there when the project has been kickstarted.

I hope this clears any misconceptions people might have about geocode-glib, or, more likely, about the future of geoclue.

by Bastien Nocera (noreply@blogger.com) at April 04, 2013 02:40 AM

April 03, 2013

Jean-François Fortin TamGStreamer Hackfest 2013: Moving Images

I’m back from this year’s GStreamer hackfest, which was fantastic as usual — an intersection of great minds, big challenges, flaky Wi-Fi and good food. Christian already did a generic summary, so I’ll be narrating from the GNonLin/GES/PiTiVi perspective. See the end of this blog post for a nice video retrospective.

2013-04-02

Edward provided an initial patch to improve the behavior of timestamps and seeking in GNonLin, while Nicolas “Stormer” Dufresne fixed two bugs causing deadlocks. Nicolas spent a lot of time discussing with Wim Taymans, Edward Hervey, Sebastian Dröge and other hackfesters about the architecture of GNonLin in light of GStreamer 1.x. He also fixed looping for the Ogg demuxer in pull mode and, with some help from Mathieu “Forest Ranger” Duponchelle, fleshed out the design for a new tree data structure for GNonLin.

Mathieu the Moustached Avenger worked on implementing keyframes in GES, paving the way for him to create a user interface to animate any effect property in PiTiVi. That user interface will most likely depend on him working on the clutter timeline canvas, so I’m looking forward to improvements in that area.

Thibault “Keyboard Crusher” Saunier finished the implementation of GES Containers and clip groups, then worked on implementing — at long last — audio mixing in GES. This is an essential feature of multitrack audio/video editing, and I’m really happy to see that feature make its comeback for the next release of PiTiVi. This work will also depend on Mathieu’s keyframes UI. A proper reimplementation of video mixing remains to be done, however.

There are lots of outstanding things to solve in GNonLin and GES. Nicolas has a bunch of ideas for things to improve and redesign in GNonLin and I expect much collaboration between Thibault and him to optimize the entire stack for better reliability and performance (for example, adding caps filters to allow realtime downscaling of videos to improve preview performance, configurable downstream buffering for playback to avoid frame drops in CPU-intensive parts of a timeline, etc.). GNonLin and GES have much potential to allow us to be a lot smarter than before.

Personally, I spent most of my time testing, discussing and hacking on some new features for PiTiVi.

    • I added a button in the timeline toolbar that toggles the “gapless mode” (automatic ripple edits), which makes your clips behave like magnets and prevents needing to re-arrange them manually all the time. The feature works and will be merged after a customary code review.
    • I made some progress on the custom effects UI branch. Once it’s complete, you will be able to easily create custom user interfaces for effects that require it, simply by using a glade/gtkbuilder .ui file (or, if you prefer, a set of widgets from your own python module). Of course, for the majority of effects, our automatically generated user interfaces are still good enough, so we can keep using them and avoid unnecessary work.

(See my previous blog post for a situation report on where we stood with PiTiVi before the hackfest)

I also spent a bit of time setting up my film making gear and shooting various interesting moments of the hackfest. Here’s my montage, which will tell the story much better than a long blog post. Hope you’ll like it:

I would like to thank Collabora for allowing many GStreamer contributors to attend the hackfest, which I consider vital to the health of the GStreamer community. I was happy to meet again with many friends and help push the Free multimedia stack forward. Props to Christian Schaller and Alessandro Decina for organizing the whole thing, too!

Aside from Collabora and Fluendo sponsoring two of our dinners (thanks!), I would also like to thank you, PiTiVi supporters, for making it possible for me to spend some money to thank GStreamer contributors with some food and beer — maximum boost to the GStreamer community! Full disclosure: I used 84 euros worth of PiTiVi donations for that purpose.

by nekohayo at April 03, 2013 04:33 PM

April 01, 2013

Phil NormandGStreamer hackfest in Milan

(Phil Normand)

I spent Easter in Milan, attending the second official GStreamer hackfest. It has been a productive event and, as always, a pleasure to hang out with some members of the GStreamer core dev team fame :)

I focused on a few GStreamer bugs that were blocking some other WebKit bugs related to the media player and the WebAudio backend. I also had in mind to port the osxaudio sink to 1.0, a task started one week before the hackfest, but didn't have time to come back to it.

The first task I worked on was about cleaning up some code in uridecodebin related to URI protocols and on-disk buffering. In WebKit we use a custom HTTP(S) source element used by playbin when loading remote media files. The issue is that that element is also exposed to applications using WebKit itself so we made it handle a custom protocol, webkit+http://. But that exposed a bug in urideocdebin where some protocols, including http, are hardcoded in a white list used to enable on-disk buffering. Unfortunately the aforementioned bug is not solved yet even though some good progress was made!

The second task I worked on was first reported by Wim, the WebKit media player wasn't pausing when receiving buffering messages. The fix was quite simple. After that I finally added some basic codec installer support in WebKit. The GStreamer codec installer API is quite simple :)

Lastly I started working again on the WebAudio createMediaSourceElement support for the GStreamer/WebKit backend. The patch has been sleeping in Bugzilla since last Christmas. That feature is interesting for WebAudio applications that need to use audio data coming from media elements to eg, do stuff like equalizers. The current patch in bugzilla gathers the audio buffers in lists and copy them to the AudioBus when needed. Those memcpys could probably be avoided by pre-allocating the memory for the AudioBus and telling GStreamer to write directly there. So, with the help of my friend Alessandro Decina (who was doing some similar stuff on his Firefox branch) I started working on a simple GstAllocator that would be configured in the pipeline by intercepting allocation queries toward the appsinks used to gather the audio buffers. Well, this exposed some bugs on the GStreamer side! The deinterleave element always uses the default allocator when pushing data to its source pads. So I started a patch that performs allocation queries downstream and use the allocator returned, if any. Unfortunately my custom allocator doesn't work yet but I'll cary on work on this, the GstAllocator API is quite an interesting thing to play with :)

All in all it was a great and productive event. Christian wrote a nice report about the hackfest too. I also wanted to thank Collabora and Fluendo for sponsoring dinners. A special thank you as well for Igalia which covered my travel expenses and attendance to the hackfest.

by Philippe Normand at April 01, 2013 10:29 AM

March 26, 2013

Andy Wingosexuality and sexism

(Andy Wingo)

Greetings, dear readers. Today's article is not about compilers, but about the people that write and run them. Like me, and like you.

I write a lot about programming here because it's interesting to me and it makes me happy, but that's not the extent of my desires as a human. Among all the things, and perhaps even foremost among them, is the desire to live in a more beautiful world: a world of making and sharing, of nature abloom, and of people too: a world, in short, full of life.

Part of that life is sexual, and how wonderfully, playfully, rightfully so. But the world as a whole would be better if we kept sexuality out of programming and other male-dominated pursuits.

The reason for this is that sexuality (for example, in the form of sexual jokes) among a group of men creates a kind of "boy's club" atmosphere in which people that aren't in the straight male majority feel uncomfortable. A "boy's club" has a virtual "no girls or queers allowed" sign on it. It's just not a comfortable place to be, for non-club-members.

Of course, sometimes being uncomfortable is good. But being uncomfortable because of your gender is not one of those cases. And even, it must be said, sometime it goes beyond discomfort to danger -- conferences that women do not attend for fear of groping; things that women cannot say for fear of rape threats. There is no hyperbole here. It is an astonishing, indignation-provoking injustice.

How did it get this bad?

As usual, through small steps. One of the first is widespread toleration of unrelated sexuality in male-dominated fields: boy's clubs. So I think that we all -- and especially men, and especially people with respect within a community -- should actively discourage any of these factors that lead to "boy's clubs". A joke that "I'd fork that project" is not OK. It would be fine if it were just a lame joke; but it's not fine because it's part of this whole "boy's club" thing.

Incidentally, there is a name for the structural tendency to favor one gender over another in a group that isn't "boy's club", and it is "sexism". Sometimes people dismiss sexism in programming because, you know, "show me the code", but this misses the broader picture. I personally have profited immensely from the personal connections I have made at the many conferences that I have attended. I've even put up with some "boy's club" jokes on the same level as "fork-that-repo". I think a woman would find it more difficult to make some of these connections, and so would not end up producing the patches I do.

So, friends, if you are with me in recognizing this structural injustice called sexism, a stain upon our community of compiler hackers and users, I think this is an occasion in which imperative programming is acceptable and even appropriate. Learn to recognize "boy's clubs" and work constructively against them. Sex and tech is usually a bad idea, so point this out when you see it -- especially if you are a man -- and support others who do the same.

by Andy Wingo at March 26, 2013 08:07 PM

Jean-François Fortin TamLa carte Opus et les points de service qui n’en sont pas vraiment

Il se trouve que les cartes Opus expirent (simplement parce qu’ils ont décidé que ça serait cool que ça expire, même si c’est une carte anonyme à tarif régulier). Chez moi, la pharmacie du coin a toujours offert le service de recharge de titres de transports, et c’est donc avec un grosse absence d’excitation que j’ai reçu la nouvelle du CIT Richelain comme quoi «le CIT a maintenant un point de service sur son territoire! C’est la pharmacie Jean Coutu où vous faisiez déjà vos transactions depuis dix ans!».

poker face

Or, ma carte Opus du moment était sur le point d’expirer (en vérifiant le numéro de série sur le site web dédié). Le site en question nous assure à maintes reprises que le renouvellement obligatoire, étant un caprice des administrateurs de l’Opus, est entièrement gratuit. Dans la FAQ, on trouve ceci:

3. Où dois-je aller pour remplacer sans frais ma carte OPUS ?
Présentez-vous avec votre carte qui expire dans moins de trois mois ou qui est expirée depuis moins de 6 mois dans un centre de service de la STM ou dans une billetterie métropolitaine de l’AMT, ou dans un centre de service d’un CIT.

Pour être doublement certain, la même chose en d’autres termes:

8. Je ne veux pas payer les frais de 6 $, que dois-je faire pour éviter ces frais ?

Présentez-vous avec votre carte qui arrive à expiration dans moins de 3 mois ou qui est expirée depuis moins de 6 mois dans un centre de service de la STM ou dans une billetterie métropolitaine de l’AMT, ou dans un centre de service d’un CIT pour obtenir une nouvelle carte OPUS sans avoir à payer les frais de 6 $.

S’il y a des titres de transport valides sur votre carte, ceux-ci seront transférés sur votre nouvelle carte.
[...]

Telle ne fut pas ma surprise lorsque, après avoir échangé ma carte chez PJC, on me demande des frais de renouvellement de 6$. Je m’objecte:

neutral-suspicious

«Uuuuuh. Non, pas s’pôsé. Le site officiel de la carte Opus dit que le renouvellement est gratuit dans un point de service du CIT et il n’est pas question que je paie pour le faire, sinon j’aurais conservé ma carte qui a encore trois mois d’usage avant expiration»

S’en suit des regards confus des deux caissières devant moi, un appel à la direction qui décide d’annuler les frais «pour cette fois» (vu que la procédure est déjà toute faite, qu’ils ont déjà exigé une montagne de mes renseignements personnels pour une carte anonyme et qu’ils ont déjà invalidé l’ancienne).

On me dit toutefois que si je ne veux pas payer de tels frais, il faudrait que j’aille à la billetterie de l’AMT à Montréal. Brillant. Il sert à quoi, votre point de service «officiel» sur la rive sud?

Pour vérifier, je téléphone au CIT/Gestrans… qui eux-mêmes n’étaient visiblement pas au courant du fait que le site de la carte Opus indique que le renouvellement est gratuit. Après m’avoir fait patienter, on me dit que non, il faut vraiment aller à la billetterie métropolitaine au centre-ville.

«Donc le point de service officiel sur le territoire du CIT n’est pas plus utile qu’avant?

— Ouaip.»

Regardons de nouveau le site d’information sur le renouvellement de la carte opus. L’explication du tonnerre qui nous dévoile un peu le fouillis dans lequel on se trouve:

4. Pourquoi doit-on se présenter dans un centre de service de la STM, dans une billetterie métropolitaine de l’AMT, ou un centre de service d’un CIT pour faire remplacer sans frais la carte OPUS qui arrive à expiration ou qui est expirée ?

Parce que les centres de service et les billetteries possèdent l’équipement requis pour effectuer tous les types de transaction (renouvellement, reconstitution, transferts des titres de transport restants, etc.) alors que dans un point de vente, le marchand n’est autorisé qu’à effectuer la vente des titres de transport et, par le fait même, vous demandera de payer les frais de 6 $ pour votre nouvelle carte OPUS.

Pourtant, selon l’annonce, c’est bien un point de service officiel dont on parle:

Le CIT est fier de vous annoncer l’ouverture d’un centre de service sur son territoire. [...] Le centre de service est situé au: Esc. André Lachapelle Inc. – Jean Coutu [...]

Plus amusant encore:

7. Puis-je faire renouveler ou échanger ma carte dans un point de vente (dépanneur, pharmacie), ou dans une distributrice de titres de transport ?
Aucun renouvellement ou échange ne peut se faire dans un point de vente, ou à une distributrice de titres de transport. Le renouvellement ou l’échange des cartes qui expirent dans moins de trois mois, ou qui sont expirées depuis moins de 6 mois, doivent se faire dans un centre de service de la STM ou dans une billetterie métropolitaine de l’AMT, ou dans un centre de service d’un CIT.

Bref, si la pharmacie du coin n’était pas effectivement un centre de service officiel du CIT, on n’aurait pas été en mesure de m’y renouveler ma carte (ce qui a pourtant été le cas)!

Mais monsieur, on peut pas vous le faire gratuitement parce qu’on peut pas, mais on peut, mais on peut pas. Enfin pas vraiment.

by nekohayo at March 26, 2013 03:25 AM

March 22, 2013

GStreamerGStreamer OpenMAX IL wrapper plugin 1.0.0 release

(GStreamer)

The GStreamer team is pleased to announce the first GStreamer OpenMAX IL wrapper plugin release for the new API and ABI-stable 1.x series of the GStreamer multimedia framework.

Check out the release notes for gst-omx, or download tarballs for gst-omx,

March 22, 2013 05:40 PM

GStreamerGStreamer Core and Plugins 1.0.6 bug-fix release

(GStreamer)

The GStreamer team is pleased to announce a new bug-fix release for the new API and ABI-stable 1.x series of the GStreamer multimedia framework.

Check out the release notes for GStreamer core, gst-plugins-base, gst-plugins-good, gst-plugins-ugly, gst-plugins-bad, or gst-libav, or download tarballs for gstreamer, gst-plugins-base, gst-plugins-good, gst-plugins-ugly, gst-plugins-bad, or gst-libav,

Improvements include:

  • build fixes for out-of-tree autogen.sh and automake 1.13, and recent kernel/video4linux
  • gobject-introspection fixes for bindings
  • videoscale: Correct DAR and border calculations
  • playbin: make sure converters are always plugged when needed, fixes not-negotiated errors with some sinks
  • playbin: fix subtitleoverlay caps handling to avoid not-negotiated errors when subtitle plugins are missing
  • adder: make "caps" property work properly
  • alsasink: don't use 100% CPU in some cases
  • reliability fixes for flushing seeks and shutdowns in queue and bastransform
  • appsrc: fix locking order
  • audiovisualisation fixes
  • deinterlace: fix infinite loop on EOS with non-default methods or fields
  • avidemux push mode fixes, make dv-in-avidemux work
  • level: send a final level message on EOS
  • osxvideosink fixes
  • ximagesrc: Set the pixel aspect ratio correctly in the output caps
  • v4l2: don't check stride for encoded formats
  • leak fixes in GstBin, pango, auparse, gdppay
  • qtdemux: skip disabled tracks and ignore chapter subtitle tracks
  • RTSP and RTP fixes
  • Opus audio decoder, encoder and RTP payloader fixes
  • codecparser fixes for H.264, MPEG-2 and VC-1 parsing
  • opensles, eglglessink, and decklink plugins ported to 1.0
  • libav: fix H.264 decoding errors in some files and update to 0.8.5 release
  • miscellaneous bug fixes

March 22, 2013 04:00 PM

March 20, 2013

Zeeshan AliNew in Boxes 3.8

(Zeeshan Ali)
We just rolled out Boxes 3.7.92 and have now entered code freeze. This means that apart from translations and doc updates, Boxes is ready for the stable 3.8 release (due next Monday). So whats new you ask? Since Boxes 3.6, we have been hard at work, making Boxes an app that is so awesome that it makes you want to use virtual machines if you are not already. :) Boxes is now a lot more reliable, has improved and more impressive UI and has cool new features:

  • Add USB redirection support in new VMs and option to add it into existing VMs. i-e You can use your USB devices (camera, flash drive etc) plugged into host from the guest operating system.


  • Smartcard support. This means if you have an appropriate reader device, you can use that to read information from your smart cards (credit/bank cards etc) from your virtual machine boxes.
  • Automatically download and installation of all virtio and QXL drivers, and spice-vdagent as part of Windows XP and Windows 7 express installation. This means following working out of the box:
    • Copy&paste between host and VM.
    • Guest resolution automatically adjusted to fit the Boxes window.
    • Very efficient disk I/O (helps in reducing installation time e.g).
    Here is a screencast of Windows XP with QXL in action.
  • oVirt support. This means you can now access all your virtual machines running on a (most likely remote) oVirt broker from Boxes by simply providing it's URL. Christophe blogged about it last year.
  • Improved selection view:
    • Option to pause VMs.
    • Options to select all, none and running boxes.
    • Allow accessing properties for non-running VMs.
     
    Here is a screencast of new selection view in action.
  • Allow tweaking properties for remote machines in the wizard.
  • UI looks a lot more like UI mockups and more consistent with Documents.
  • Add initial experience greeting. As a consequence, we don't auto-launch wizard on first time usage anymore.

    Please ignore the notification about box deletion. You don't get that on first use, I promise!

  • Support for changing the CD-ROM device/ISO from properties. You can see this option in  the screenshot above along with USB redirection options.
  • Selecting item when maximized automatically enters fullscreen view. You see this in action in the QXL demo screencast I pointed to above.
  • Mark recommended RAM and storage of guest OS (when known) in properties.


  • Allow search with multiple terms. A search like "foo bar" now means name containing "foo" and "bar". This is nicer, and what you expect from e.g. gnome-shell search.
  • Allow drag to unfullscreen Boxes.
  • Troubleshooting log viewer to system properties.
  • For Developers:
    • We now make use of libosinfo for express/automated installations. Support for new OSes/distros can be added through libosinfo. No Vala or C hacking needed, only XSL/XML.
  • Loads of other fixes and minor improvements. For more details: http://git.gnome.org/browse/gnome-boxes/tree/NEWS 

Hope you like love Boxes 3.8!

March 20, 2013 03:06 AM

March 14, 2013

Stefan Kost14 Mar 2013

(Stefan Kost) buzztard

As I already mentioned in last months issue, I ported buzztard and gst-buzztard to use gstreamer-1.0. It will require 1.1.X for some fixes in gstreamer itself. So how did it went. The basic porting to make it compile against 1.0 took about 20 hours spread over a couple of days. It is quite straight forward. I updated the porting guide where things were not mentioned.

The more tricky part where the soft api changes. At this port I was running the apps with G_DEBUG=fatal_warnings. The property name changes here and there we easy to fix. Also request pad name changes (%d -> _%u) took not too long to handle. Other things like caps negotiation kept me busy for a few evenings. For once I was e.g. writing GST_AUDIO_NE ("S16") instead of GST_AUDIO_NE (S16) which leads to caps negotiation failing. Another recommendation is to avoid setting channel-mask=3 for stereo caps. It is purely optional, most elements drop it anyway and by leaving it out, you can merge the mono and stereo caps.

I ported freeverb in plugins-bad and made fixed to audiopanorama and adder. Adder and collectpads have a few more new tests upstream. Another things that took a while was getting seek-in-ready to work again. Buzztard needs to configure the playback segment from the application, as the sources happy beep for all eternity. In 0.10 I could send a seek to my bin in ready, in 1.0 it gets dropped (pads are flushing). Now I recursively iterate over sources and seek on all of them. This is only needed to get to playing. To get these things fixed I ported a few of my stand alone examples, but the majority of this is still left unported.

Now the basics seem to work. I am confident that I can fix the remaining issues in march and look forward to attend the hackfest in Milano over easter.

The porting for buzztard:
69 files changed, 1909 insertions(+), 1473 deletions(-)
The porting for gst-buzztard:
34 files changed, 1254 insertions(+), 1414 deletions(-)

The other thing I was doing this month was to experiment with embeddable scripting engines. I wrote a toy gtk app that opens a window, sets up the scripting engine, registers a function to get the window handle and start a script that calls the function to get the window and adds a vbox with two labels. I did that for lua, seed and gjs. For lua it took 30 min, for seek it took 30min, for gjs it took 2 hours and is still not working fully (the custom function returning a gobject).

69 files changed, 1907 insertions(+), 1507 deletions(-)

March 14, 2013 08:13 PM

February 28, 2013

Michael SheldonOgre3D on Jolla’s SailfishOS

(Michael Sheldon)

I spent a bit of time hacking around with the Sailfish SDK and managed to get a rough port of Ogre3D working:

Video of Ogre3D running under Sailfish

This is running within the emulator using the Mesa LLVM OpenGL ES 2.0 implementation, so naturally I won’t be able to say for certain if a port is possible for actual phones running Sailfish until I get my hands on some hardware, but it seems hopeful.

by Mike at February 28, 2013 09:26 PM

February 25, 2013

Andy Wingoon generators

(Andy Wingo)

Hello! Is this dog?

Hi dog this is Andy, with some more hacking nargery. Today the topic is generators.

(shift k)

By way of introduction, you might recall (with a shudder?) a couple of articles I wrote in the past on delimited continuations. I even gave a talk on delimited continuations at FrOSCon last year, a talk that was so hot that thieves broke into the the FrOSCon video squad's room and stole their hard drives before the edited product could hit the tubes. Not kidding! The FrOSCon folks still have the tapes somewhere, but meanwhile time marches on without the videos; truly, the terrorists have won.

Anyway, the summary of all that is that Scheme's much-praised call-with-current-continuation isn't actually a great building block for composable abstractions, and that delimited continuations have much better properties.

So imagine my surprise when Oleg Kiselyov, in a mail to the Scheme standardization list, suggested a different replacement for call/cc:

My bigger suggestion is to remove call/cc and dynamic-wind from the base library into an optional feature. I'd like to add the note inviting the discussion for more appropriate abstractions to supersede call/cc -- such [as] generators, for example.

He elaborated in another mail:

Generators are a wide term, some versions of generators are equivalent (equi-expressible) to shift/reset. Roshan James and Amr Sabry have written a paper about all kinds of generators, arguing for the generator interface.

And you know, generators are indeed a very convenient abstraction for composing producers and consumers of values -- more so than the lower-level delimited continuations. Guile's failure to standardize a generator interface is an instance of a class of Scheme-related problems, in which generality is treated as more important than utility. It's true that you can do generators in Guile, but we shouldn't make the user build their own.

The rest of the programming world moved on and built generators into their languages. James and Sabry's paper is good because it looks at yield as a kind of mainstream form of delimited continuations, and uses that perspective to place the generators of common languages in a taxonomy. Some of them are as expressive as delimited continuations. There are are also two common restrictions on generators that trade off expressive power for ease of implementation:

  • Generators can be restricted to disallow backtracking, as in Python. This allows generators to yield without allocating memory for a new saved execution state, instead updating the stored continuation in-place. This is commonly called the one-shot restriction.

  • Generators can also restrict access to their continuation. Instead of reifying generator state as external iterators, internal iterators call their consumers directly. The first generators developed by Mary Shaw in the Alphard language were like this, as are the generators in Ruby. This can be called the linear-stack restriction, after an implementation technique that they enable.

With that long introduction out of the way, I wanted to take a look at the proposal for generators in the latest ECMAScript draft reports -- to examine their expressiveness, and to see what implementations might look like. ES6 specifies generators with the the first kind of restriction -- with external iterators, like Python.

Also, Kiselyov & co. have a hip new paper out that explores the expressiveness of linear-stack generators, Lazy v. Yield: Incremental, Linear Pretty-printing. I was quite skeptical of this paper's claim that internal iterators were significantly more efficient than external iterators. So this article will also look at the performance implications of the various forms of generators, including full resumable generators.

ES6 iterators

As you might know, there's an official ECMA committee beavering about on a new revision of the ECMAScript language, and they would like to include both iterators and generators.

For the purposes of ECMAScript 6 (ES6), an iterator is an object with a next method. Like this one:

var p = console.log;

function integers_from(n) {
  function next() {
    return this.n++;
  }
  return { n: n, next: next };
}

var ints = integers_from(0);
p(ints.next()); // prints 0
p(ints.next()); // prints 1

Here, int_gen is an iterator that returns successive integers from 0, all the way up to infinity2^53.

To indicate the end of a sequence, the current ES6 drafts follow Python's example by having the next method throw a special exception. ES6 will probably have an isStopIteration() predicate in the @iter module, but for now I'll just compare directly.

function StopIteration() {}
function isStopIteration(x) { return x === StopIteration; }

function take_n(iter, max) {
  function next() {
    if (this.n++ < max)
      return iter.next();
    else
      throw StopIteration;
  }
  return { n: 0, next: next };
}

function fold(f, iter, seed) {
  var elt;
  while (1) {
    try {
      elt = iter.next();
    } catch (e) {
      if (isStopIteration (e))
        break;
      else
        throw e;
    }
    seed = f(elt, seed);
  }
  return seed;
}

function sum(a, b) { return a + b; }

p(fold(sum, take_n(integers_from(0), 10), 0));
// prints 45

Now, I don't think that we can praise this code for being particularly elegant. The end result is pretty good: we take a limited amount of a stream of integers, and combine them with a fold, without creating intermediate data structures. However the means of achieving the result -- the implementation of the producers and consumers -- are nasty enough to prevent most people from using this idiom.

To remedy this, ES6 does two things. One is some "sugar" over the use of iterators, the for-of form. With this sugar, we can rewrite fold much more succinctly:

function fold(f, iter, seed) {
  for (var x of iter)
    seed = f(x, seed);
  return seed;
}

The other thing offered by ES6 are generators. Generators are functions that can yield. They are defined by function*, and yield their values using iterators:

function* integers_from(n) {
  while (1)
    yield n++;
}

function* take_n(iter, max) {
  var n = 0;
  while (n++ < max)
    yield iter.next();
}

These definitions are mostly equivalent to the previous iterator definitions, and are much nicer to read and write.

I say "mostly equivalent" because generators are closer to coroutines in their semantics because they can also receive values or exceptions from their caller via the send and throw methods. This is very much as in Python. Task.js is a nice example of how a coroutine-like treatment of generators can help avoid the fraction-of-an-action callback mess in frameworks like Twistednode.js.

There is also a yield* operator to delegate to another generator, as in Python's PEP 380.

OK, now that you know all the things, it's time to ask (and hopefully answer) a few questions.

design of ES6 iterators

Firstly, has the ES6 committee made the right decisions regarding the iterators proposal? For me, I think they did well in choosing external iterators over internal iterators, and the choice to duck-type the iterator objects is a good one. In a language like ES6, lacking delimited continuations or cross-method generators, external iterators are more expressive than internal iterators. The for-of sugar is pretty nice, too.

Of course, expressivity isn't the only thing. For iterators to be maximally useful they have to be fast, and here I think they could do better. Terminating iteration with a StopIteration exception is not so great. It will be hard for an optimizing compiler to rewrite the throw/catch loop terminating condition into a simple goto, and with that you lose some visibility about your loop termination condition. Of course you can assume that the throw case is not taken, but you usually don't know for sure that there are no more throw statements that you might have missed.

Dart did a better job here, I think. They split the next method into two: a moveNext method to advance the iterator, and a current getter for the current value. Like this:

function dart_integers_from(n) {
  function moveNext() {
    this.current++;
    return true;
  }
  return { current: n-1, moveNext: moveNext };
}

function dart_take_n(iter, max) {
  function moveNext() {
    if (this.n++ < max && iter.moveNext()) {
      this.current = iter.current;
      return true;
    }
    else
      return false;
  }
  return {
    n: 0,
    current: undefined,
    moveNext: moveNext
  };
}

function dart_fold(f, iter, seed) {
  while (iter.moveNext())
    seed = f(iter.current, seed);
}

I think it might be fair to say that it's easier to implement an ES6 iterator, but it is easier to use a Dart iterator. In this case, dart_fold is much nicer, and almost doesn't need any sugar at all.

Besides the aesthetics, Dart's moveNext is transparent to the compiler. A simple inlining operation makes the termination condition immediately apparent to the compiler, enabling range inference and other optimizations.

iterator performance

To measure the overhead of for-of-style iteration, we can run benchmarks on "desugared" versions of for-of loops and compare them to normal for loops. We'll throw in Dart-style iterators as well, and also a stateful closure iterator designed to simulate generators. (More on that later.)

I put up a test case on jsPerf. If you click through, you can run the benchmarks directly in your browser, and see results from other users. It's imprecise, but I believe it is accurate, more or less.

The summary of the results is that current engines are able to run a basic summing for loop in about five cycles per iteration (again, assuming 2.5GHz processors; the Epiphany 3.6 numbers, for example, are mine). That's suboptimal only by a factor of 2 or so; pretty good. Thigh fives all around!

However, performance with iterators is not so good. I was surprised to find that most of the other tests are suboptimal by about a factor of 20. I expected the engines to do a better job at inlining.

One data point that stands out of my limited data set is the development Epiphany 3.7.90 browser, which uses JavaScriptCore from WebKit trunk. This browser did significantly better with Dart-style iterators, something I suspect due to better inlining, though I haven't verified it.

Better inlining and stack allocation is already a development focus of modern JS engines. Dart-style iterators will get faster without being a specific focus of optimization. It seems like a much better strategy for the ES6 specification to piggy-back off this work and specify iterators in such a way that they will be fast by default, without requiring more work on the exception system, something that is universally reviled among implementors.

what about generators?

It's tough to know how ES6 generators will perform, because they're not widely implemented and don't have a straightforward "desugaring". As far as I know, there is only one practical implementation strategy for yield in JavaScript, and that is to save the function's stack and the set of live registers. Resuming a generator copies the activation back onto the stack and restores the registers. Any other strategy that involves higher-level control-flow rewriting would make debugging too difficult. This is not a terribly onerous requirement for an implementation. They already have to know exactly what is live and what is not, and can reconstruct a stack frame without too much difficulty.

In practice, invoking a generator is not much different from calling a stateful closure. For this reason, I added another test to the jsPerf benchmark I mentioned before that tests stateful closures. It does slightly worse than iterators that keep state in an object, but not much worse -- and there is no essential reason why it should be slow.

On the other hand, I don't think we can expect compilers to do a good job at inlining generators, especially if they are specified as terminating with a StopIteration. Terminating with an exception has its own quirks, as Chris Leary wrote a few years ago, though I think in his conclusion he is searching for virtues where there are none.

dogs are curious about multi-shot generators

So dog, that's ECMAScript. But since we started with Scheme, I'll close this parenthesis with a note on resumable, multi-shot generators. What is the performance impact of allowing generators to be fully resumable?

Being able to snapshot your program at any time is pretty cool, but it has an allocation cost. That's pretty much the dominating factor. All of the examples that we have seen so far execute (or should execute) without allocating any memory. But if your generators are resumable -- or even if they aren't, but you build them on top of full delimited continuations -- you can't re-use the storage of an old captured continuation when reifying a new one. A test of iterating through resumable generators is a test of short-lived allocations.

I ran this test in my Guile:

(define (stateful-coroutine proc)
  (let ((tag (make-prompt-tag)))
    (define (thunk)
      (proc (lambda (val) (abort-to-prompt tag val))))
    (lambda ()
      (call-with-prompt tag
                        thunk
                        (lambda (cont ret)
                          (set! thunk cont)
                          ret)))))

(define (integers-from n)
  (stateful-coroutine
   (lambda (yield)
     (let lp ((i n))
       (yield i)
       (lp (1+ i))))))

(define (sum-values iter n)
  (let lp ((i 0) (sum 0))
    (if (< i n)
        (lp (1+ i) (+ sum (iter)))
        sum)))

(sum-values (integers-from 0) 1000000)

I get the equivalent of 2 Ops/sec (in terms of the jsPerf results), allocating about 0.5 GB/s (288 bytes/iteration). This is similar to the allocation rate I get for JavaScriptCore, which is also not generational. V8's generational collector lets it sustain about 3.5 GB/s, at least in my tests. Test case here; multiply the 8-element test by 100 to yield approximate MB/s.

Anyway these numbers are much lower than the iterator tests. ES6 did right to specify one-shot generators as a primitive. In Guile we should perhaps consider implementing some form of one-shot generators that don't have an allocation overhead.

Finally, while I enjoyed the paper from Kiselyov and the gang, I don't see the point in praising simple generators when they don't offer a significant performance advantage. I think we will see external iterators in JavaScript achieve near-optimal performance within a couple years without paying the expressivity penalty of internal iterators.

Catch you next time, dog!

by Andy Wingo at February 25, 2013 04:17 PM

February 16, 2013

Andy Wingoopengl particle simulation in guile

(Andy Wingo)

Hello, internets! Did you know that today marks two years of Guile 2? Word!

Guile 2 was a major upgrade to Guile's performance and expressiveness as a language, and I can say as a user that it is so nice to be able to rely on such a capable foundation for hacking the hack.

To celebrate, we organized a little birthday hack-feast -- a communal potluck of programs that Guilers brought together to share with each other. Like last year, we'll collect them all and publish a summary article on Planet GNU later on this week. This is an article about the hack that I worked on.

figl

Figl is a Guile binding to OpenGL and related libraries, written using Guile's dynamic FFI.

Figl is a collaboration between myself and Guile super-hacker Daniel Hartwig. It's pretty complete, with a generated binding for all of OpenGL 2.1 based on the specification files. It doesn't have a good web site yet -- it might change name, and probably we'll move to savannah -- but it does have great documentation in texinfo format, built with the source.

But that's not my potluck program. My program is a little demo particle simulation built on Figl.

Click to download video

Source available here. It's a fairly modern implementation using vertex buffer objects, doing client-side geometry updates.

To run, assuming you have some version of Guile 2.0 installed:

git clone git://gitorious.org/guile-figl/guile-figl.git
cd guile-figl
autoreconf -vif
./configure
make
# 5000 particles
./env guile examples/particle-system/vbo.scm 5000

You'll need OpenGL development packages installed -- for the.so links, not the header files.

performance

If you look closely on the video, you'll see that the program itself is rendering at 60 fps, using 260% CPU. (The CPU utilization drops as soon as the video starts, because of the screen capture program.) This is because the updates to the particle positions and to the vertices are done using as many processors as you have -- 4, in my case (2 real and 2 threads each). I've gotten it up to 310% or so, which is pretty good utilization considering that the draw itself is single-threaded and there are other things that need to use the CPU like the X server and the compositor.

Each particle has a position and a velocity, and is attracted to the center using a gravity-like force. If you consider that updating a particle's position should probably take about 100 cycles (for a square root, some divisions, and a few other floating point operations), then my 2.4GHz processors should allow for a particle simulation with 1.6 million particles, updated at 60fps. In that context, getting to 5K particles at 60 fps is not so impressive -- it's sub-optimal by a factor of 320.

This slowness is oddly exciting to me. It's been a while since I've felt Guile to be slow, and this is a great test case. The two major things to work on next in Guile are its newer register-based virtual machine, which should speed things up by a factor of 2 or so in this benchmark; and an ahead-of-time native compiler, which should add another factor of 5 perhaps. Optimizations to an ahead-of-time native compiler could add another factor of 2, and a JIT would probably make up the rest of the difference.

One thing I was really wondering about when making this experiment was how the garbage collector would affect the feeling of the animation. Back when I worked with the excellent folks at Oblong, I realized that graphics could be held to a much higher standard of smoothness than I was used to. Guile allocates floating-point numbers on the heap and uses the Boehm-Demers-Weiser conservative collector, and I was a bit skeptical that things could be smooth because of the pause times.

I was pleasantly surprised that the result was very smooth, without noticeable GC hiccups. However, GC is noticeable on an overloaded system. Since the simulation advances time by 1/60th of a second at each frame, regardless of the actual frame rate, differing frame processing times under load can show a sort of "sticky-zipper" phenomenon.

If I ever got to optimal update performance, I'd probably need to use a better graphics card than my Intel i965 embedded controller. And of course vertex shaders are really the way to go if I cared about the effect and not the compiler -- but I'm more interested in compilers than graphics, so I'm OK with the state of things.

Finally I would note that it has been pure pleasure to program with general, high-level macros, knowing that the optimizer would transform the code into really efficient low-level code. Of course I had to check the optimizations, with the ,optimize, command at the REPL. I even had to add a couple of transformations to the optimizer at one point, but I was able to do that without restarting the program, which was quite excellent.

So that's my happy birthday dish for the Guile 2 potluck. More on other programs after the hack-feast is over; until then, see you in #guile!

by Andy Wingo at February 16, 2013 07:20 PM

February 14, 2013

Stefan Kost14 Feb 2013

(Stefan Kost) buzztard 0.7 is out

We started the year with a release in the beginning of January. So far only a few issues were reported. Patches for these are on the 0.7.1 branch. One last minute change in 0.7 was the departure from trying to link/unlink elements in gstreamer while playing. I sadly have to conclude that in 0.10 this only works for some cases. It was working sort of okayish for buzztard, but the were still deadlocks or internal dataflow errors from time to time. One such scenario is that when you happen to reconnect elements while the song loops. These things are not easy to sync from the application level. Lets hope this is easier in 1.0. The sticky events should help with setting up the context from new elements.

On the mainline I bumped the required library version and removed the ifdefs for the backwards compatibility. As a first bigger change, I ported the settings from gconf to dconf. We had a settings abstraction to other gconf or play keyfiles, which we now removed. Altogether I kept to use an intermediate object that exposes settings as a gobject with properties for the keys. This allows to use notify to bind to property changes instead of using a custom api.

Then I started with porting gst-buzztard & buzztard to gstreamer-1.0. I made good progress. I will report the details in the next update.

77 files changed, 5892 insertions(+), 8131 deletions(-)

February 14, 2013 08:57 PM