Behdad Esfahbod's daily notes on GNOME, Pango, Fedora, Persian Computing, Bob Dylan, and Dan Bern!

My Photo
Location: Toronto, Ontario, Canada

Ask Google.

Contact info
Hacker Emblem Become a Friend of GNOME I Power Blogger
follow me on Twitter
July 2003
August 2003
October 2003
November 2003
December 2003
March 2004
April 2004
May 2004
July 2004
August 2004
September 2004
November 2004
March 2005
April 2005
May 2005
June 2005
July 2005
August 2005
September 2005
October 2005
November 2005
December 2005
January 2006
February 2006
March 2006
April 2006
May 2006
June 2006
July 2006
August 2006
September 2006
October 2006
November 2006
December 2006
January 2007
February 2007
March 2007
April 2007
May 2007
June 2007
July 2007
August 2007
September 2007
October 2007
November 2007
December 2007
January 2008
February 2008
March 2008
April 2008
May 2008
June 2008
July 2008
August 2008
October 2008
November 2008
December 2008
January 2009
March 2009
April 2009
May 2009
June 2009
July 2009
August 2009
November 2009
December 2009
March 2010
April 2010
May 2010
June 2010
July 2010
October 2010
November 2010
April 2011
May 2011
August 2011
September 2011
October 2011
November 2011
November 2012
June 2013
January 2014
May 2015
Current Posts
McEs, A Hacker Life
Monday, March 06, 2006
 Cutting VCDs or How I Learned to Stop Worrying and Love GStreamer

For a few weeks, I was looking for a way to cut three VideoCD images I had sitting on my hard disk for a while (three years!?) and write the results (with other things) to a DVD. As I'm always short in space, decided to cash those 4.5GB this time and so started my GStreamer pilgrimage...

Normally, if it was audio, I would have done this:

mplayer -ao pcm:nowaveheader:file=/dev/fd/10 -really-quiet "$infile" </dev/null 10>&1 &>/dev/null |
tail --bytes=+$((start*bitrate/8)) |
head --bytes=$((length*bitrate/8)) |
lame --quiet -r /dev/stdin "$outfile.mp3"
(works like a charm.) This is clean. This is what Unix is supposed to be. This shows various rules of Unix philosophy in action. For example, I don't like spending two hours to figure out how to compress using mencoder, so I simply use lame without selling the rest of my pipeline to it. But for video, it's more complex. I decided to finally go the GStreamer way instead of finding my way through man mplayer for the zillionth time (I suspect it may not be feasible using mplayer.)

Meeting: Being the good GNOME hacker that I am, I decide to try out gstreamer 0.10, although I already have 0.8 installed on my system. So I check out and build gnome-python (and lots of prereqs), gstreamer, gst-plugins-base, gst-plugins-good, and gst-plugins-bad stuff from HEAD. Multiple bugs are filed in the process and I go mad by the sheer amount of packages spitting Werror on my face... At this point I call it a night (morning should have been more appropriate.)

Attraction: I read the gstreamer FAQ and start experimenting with gst-launch. Pretty excited about finding the Pango element and wanting to try it out. So I figure what playbin is, and build a few pipelines from the FAQ to use decodebin. Apart from it crashing randomly (which turned out updating liboil fixes), it seems to be working. I figure out that GNonLin should do what I want, i.e. reinventing head and tail. What I fail to figure out is how to use PiTiVi. But in the end, I fail to find any video on my harddisk that it can play, and I give up.

Separation: Days later. For the first time in my involvement with Free Software, I feel what the users are possibly feeling most of the time and I'm aimless as a developer. At this point I the least I care about is the Free Software license of the code and what it allows me to do. All I see is that I just want to cut the damn clip out of the VCD image and I cannot. Decide to go back to gstreamer 0.8. At least I have an installation of it that does play my movies, out of synch though. I manage to find and compile a version of GNonLin that works with 0.8, but trying to run any useful pipeline that contains a gnlfilesource element with gst-launch stalls at PREROLLING and never enters PLAYING mode. Need another few days of break.

Reconciliation: From the Accounts Team work I remember bilboed, who is the author of PiTiVi and GNonLin. I find him on #gnome-hackers, and he enlightens me that the most decoders I want (MPEG, MAD, ...) are in gst-plugins-ugly, one module that I simply missed. Installing -ugly (after figuring out *why* it's not enabling each external plugin first) did it. Now I could play my videos using gst 0.10. Using Pango to show subtitles using playbin still doesn't work though. I also found out that #gstreamer on freenode is a much better place to ask questions than #gnome-hackers is. Turned out (via its author) that GNonLin needs a glib main-loop to run, and so cannot be used via gst-launch. I still don't understand why, but bilboed was so nice that he wrote a short Python piece to use the gnlfilesource to delay the audio track of an input movie. It actually revealed a couple bugs in GNonLin it seems and took a few days until he thought the script should work. It segfaults on most of the video files I have (segfaulting Python that is), but I could finally find a very short piece (a 600kb MPEG) that it *plays*. No video window though, only voice. Playbin refuses to play the test piece for what seems to be a playbin bug with very short files. Bilboed's experience with the test case was different: he had video but no voice. So he patched the script to *fix* the voice issue and was wondering how it worked for me :). Anyway, after boring myself with it for a few hours, sleep overcomes and I give up.

[The movie ends here, so this stage doesn't have a name]

In my dreamz we were relaxing in the Ein-stein Cafe (man, they do have the best chicken wings in T.O.) on College St. on a Friday night and walked to my place afterward, for tea and watching a few episodes of Barareh (an Iranian TV show.) Everybody left soon after midnight and it was only me and Alireza. I dreamed I started my weekly harddisk cleanup and passed by the 4.5GB thing again and so asked Alireza whether he had any tool to cut a VCDs into clips. Hell he did. There was this tiny Windoze app in his old stuff called vcdcut that did that and just that. Setting up a a samba share and voila, two hours later all that was left was my the clips and no VCD images anymore. I felt something heavy hitting my head from the back and glanced at the floor that was approaching with increasing speed...

When I opened my eyes I was in a court room. There were masters McIlroy and Thompson sitting in the jury and master Kernighan too. There were the GStreamer developers standing in the defendant's place, accused of violating several laws of Unix philosophy and customer lock-down via running on a proprietary pipeline, different from that of the Unix systems. I heard Eric Raymond whispering "got to add this case to my book."

All of a sudden I could hear a loud noise boom booming all around my head, like when xmms jumps to a song with a much higher volume level... And I wake up.
When I really woke I was frozen in between
I didn't know who I was, it was a dream inside a dream

It's all a dream
Oh what a dream
I had a dream


GStreamer is an exciting framework. One that opens up a lot of new possibilities in Linux multimedia. There are a few bugs here and there, but they will hopefully by fixed by the time for 10x10.

Writing both stdinsrc and stdoutsink gstreamer elements should be extremely easy, and that would make it possible to use gstreamer with Unix pipelines, like the one I used for cropping audio. Same thing about writing head and tail elements (which is what the GNonLin elements are supposed to do, among other things.)

A notable side-effect of lack of Unix philosophy on Windoze land is that people write (non-free, fwiw) tiny applications that do one instantiation of one problem and only that. By that I mean you find an application to cut a piece out of a VCD image. You find another to cut a piece out of an MP3. You find another to convert a WMA to MP3. Another one to convert MP3 to WMA. Seriously. While that makes a Unix hacker laugh and look down his nose to the poor Windoze user, there has been moments in my pilgrimage that I wished there was a 50kb binary I could download and run that would cut that piece out of the VCD image and just that...

On the other end of the spectrum, it's a source of controversy where the modularity line should be drawn. There are various widely-used featureful tools that are both a proof for and against the do one thing and do it well essence of the Unix philosophy. Emacs is one of them, a rather clean one. Mplayer and ImageMagick are two other, nasty ones. They are not extensible, feature-packed to the state of decreasing user's performance, and simply ugly. Yet they do the job no other pipeline will do. Whether GStreamer is the true way to implement what Mplayer does, we still need to figure out. But better integration with the traditional Unix practices (whatever that means) is something to be explored.

Update: Apparently GStreamer already has stdinsrc and stdoutsink. They are called fdsrc and fdsink.

To make those little but very needed tasks it's better to make an infraestructure similar to apple's automator, so this is not restricted to gstreamer, because I may want a task to join two pdfs into one.

The last two comments of this blog entry[1] say how this could be achieved with XML files describing an "action" structure and DBUS services mapping to those "actions". That XML file would wrap commandline commands or gstreamer pipelines for example.

mplayer / mencoder can directly work on VCD bin files.
Of course they can directly work on VCD images. But what I didn't find was how to crop them...
You don't know jack :-)

I have no clue what you refer to with "cropping", but here a sample command line of getting a few seconds from a .bin, resizing it and encoding it to xvid as a bonus:

% mencoder infile.bin -ss 500 -endpos 30 -oac mp3lame -o test.avi -ovc xvid -xvidencopts bitrate=400:me_quality=6 -lameopts preset=64 -sws 2 -vop scale=240:180

Now if you need cropping, as in cutting from an offset X, Y, with width 240x180:

% mencoder infile.bin -ss 500 -endpos 30 -oac mp3lame -o test1.avi -ovc xvid -xvidencopts bitrate=400:me_quality=6 -lameopts preset=64 -vf crop=240:180:112:60

See ya.
Oh, the X,Y in the above second command line are ofcourse 112, 60.

See you around the way.
Ah thanks. -ss and -endpos are what I've been looking for. I knew mencoder should have options for these, just that I didn't feel like finding them in a 6000 line man page...

Of course after deciding to switch to GStreamer, it was a matter of testing GStreamer more than getting the job done :-).
Post a Comment

<< Archive
<< Home