The Coding Weasel

Wednesday, December 13, 2006

gstreamer and messages, pt 1

If you take a simple GStreamer pipeline (for instance, something based on the first piece of code in this post) and run it, one of the first things you'll notice is that it doesn't exit when the file finishes playing. To do this, you'll want to use messages. Here's a simple example showing this. This example sets up a filesrc, connects it to a 'mad' element (which decodes MP3s) and then dumps out to ALSA via an alsasink.


import pygst
pygst.require("0.10")
import gst
import gobject

class Playback:
def __init__(self, filename):
self.pipeline = gst.Pipeline('player')

# Get the message bus from the pipeline
self.bus = self.pipeline.get_bus()
# register a watch function - self.message
self.bus.add_watch(self.message)

# create a filesrc->mad->alsasink pipeline
filesrc = gst.element_factory_make("filesrc", "input")
filesrc.set_property('location', filename)
converter = gst.element_factory_make("mad", "converter")
output = gst.element_factory_make("alsasink", "output")
output.set_property('device', 'plughw:0')
# Add them all to the pipeline with one call.
self.pipeline.add(filesrc, converter, output)
# Link them all together in one call.
gst.element_link_many(filesrc, converter, output)
self.pipeline.set_state(gst.STATE_PLAYING)

def message(self, bus, message):
# Check for an 'End Of Stream' message
if message.type == gst.MESSAGE_EOS:
print "Got EOS, quitting mainloop"
self.quit()
# We want to continue receiving messages, so return True
# If you return False, this function is removed from the list
# of functions that receive bus messages.
return True

def run(self):
self.mainloop = gobject.MainLoop()
self.mainloop.run()
def quit(self, *args):
self.mainloop.quit()

if __name__ == "__main__":
import sys
player=Playback(sys.argv[1])
player.run()

Let's look at this in more detail. After we create the pipeline, we get the message bus associated with it.

    # Get the message bus from the pipeline
self.bus = self.pipeline.get_bus()

We then add a 'watch' function to the pipeline. This function will receive all messages on the bus. You can't add more than one watch function to a pipeline (yet).

    # register a watch function - self.message
self.bus.add_watch(self.message)

The watch function itself is pretty simple - it takes the bus and the message as arguments, and returns True or False. The return value indicates whether we want to keep receiving messages. If you return False, this watch function is removed from the bus.

def message(self, bus, message):
# Check for an 'End Of Stream' message
if message.type == gst.MESSAGE_EOS:
print "Got EOS, quitting mainloop"
self.mainloop.quit()
# We want to continue receiving messages, so return True
# If you return False, this function is removed from the list
# of functions that receive bus messages.
return True

We compare the message.type with the singleton gst.MESSAGE_EOS. If it's true, we stop the mainloop and exit.

There's many other messages you can receive, not just end-of-stream. If we put a "print message.type" statement before the message.type check in the message() method, you'll see something like this:


flags GST_MESSAGE_CLOCK_PROVIDE of type GstMessageType
flags GST_MESSAGE_STATE_CHANGED of type GstMessageType
flags GST_MESSAGE_STATE_CHANGED of type GstMessageType
flags GST_MESSAGE_STATE_CHANGED of type GstMessageType
flags GST_MESSAGE_STATE_CHANGED of type GstMessageType
flags GST_MESSAGE_STATE_CHANGED of type GstMessageType
flags GST_MESSAGE_STATE_CHANGED of type GstMessageType
flags GST_MESSAGE_TAG of type GstMessageType
flags GST_MESSAGE_STATE_CHANGED of type GstMessageType
flags GST_MESSAGE_STATE_CHANGED of type GstMessageType
flags GST_MESSAGE_NEW_CLOCK of type GstMessageType
flags GST_MESSAGE_STATE_CHANGED of type GstMessageType
flags GST_MESSAGE_STATE_CHANGED of type GstMessageType
flags GST_MESSAGE_STATE_CHANGED of type GstMessageType
flags GST_MESSAGE_STATE_CHANGED of type GstMessageType
flags GST_MESSAGE_EOS of type GstMessageType

If you look a bit closer, you'll see there's a couple of sets of messages. First off, there's 4 STATE_CHANGED messages - one from each element, and from the pipeline itself. These are going from a state of VOID to PAUSED, as the pipeline starts up. There's another set of 4 going from PAUSED to PLAYING, and a final set of 4 going from PLAYING to VOID when the pipeline finishes. There's also a couple about the pipeline clock (which I'll touch on in a future piece) and a MESSAGE_TAG message. That's from the 'mad' converter, and if we print it, we'll see:
<gst.Message taglist, layer=(guint)3, mode=(string)joint,
emphasis=(string)none, audio-codec=(string)"MPEG-1\ layer\ 3",
bitrate=(guint)128000 from converter at 0x81cae98>

Note that these messages are from the pipeline as a whole, not from individual elements. If you want to know about when a particular element runs out of data, you use pad.add_event_probe() and look for EVENT_EOS. More on that in a future post.

That's enough for one starting post.



Please note - I'm still learning about gstreamer as I go. If you see something wrong, or unclear, please let me know in the comments. Also let me know if blogger has messed up the formatting - I think I've got it OK now.

Labels: ,

you're part of the problem, not part of the solution

Phillip Eby wrote a response to Richard's post about the OSDC problem with a softcore porn image being displayed in a lightning talk. He managed to completely miss the point as well as throw in any number of irrelevant sidepoints.


I was going to let it slide (as far as I can see, he is just being needlessly contrary and provocative), but ... to hell with it. He doesn't seem to have comments on his blog, so consider this my response.


The problem is not that "porn" is driving women away from the computer industry.


The problem is the mindset which says "it's fine to show porn in a talk at a conference". This is appalling.


If you don't think that putting up a softcore porn image of a woman is going to offend more women than men, you're out of your mind. I missed the slide in question (I was sitting outside finishing my own talk) but I heard enough from people about it afterwards. Plenty of people, both men and women, were offended. Almost every single female in the audience was offended, in some cases, extremely offended. (That PJE's own wife wouldn't have been offended is no excuse. That's nice for her but it doesn't excuse the slide in question). No-one would even contemplate putting up something offensively racist in a talk, or almost any other form of offensive imagery, but this sort of thing isn't that big an issue for some folks.


PJE also asks in his piece:



P.S. Does anybody know why it's supposed to be so gosh-darn important to have more women in IT?

He then compares it to the under-representation of men in the nursing industry.


Gah. Gah. Gah. I'm almost speechless.


Last time I looked, the nursing industry didn't provide a hostile work environment that actively discouraged men from joining. Plenty of people in the IT industry do this to women. PJE's minimisation of this issue is a great example.


As far as "why is it important to have more women in IT"... well, if he's being genuine here (rather than just contrary for the sake of it) I'm stunned. There's a basic issue of equity here. IT provides an ever increasing number of highly paid skilled jobs. Saying "if there's a hostile work environment that discourages women, too bad for them" is a mind-blowing attitude to me. (I'd have also thought that someone who's all about efficiency and that sort of thing would recognise that a more heterogenous team produces better outcomes all around.)


PJE finishes with this little pearler:



Now, some people will think I'm joking about what I just said, but that will serve only as a helpful illustration of their own bias. You see, when a person thinks that trying to protect men in porn is silly, it's because deep down, they think women need more "protection" than men -- thereby demonstrating their own patriarchal sexist patronizing bullshit attitude!

This is, to not put too fine a point on it, unmitigated bullshit of the highest order. If I saw that the industry I'm in was discriminating against any group, I'd be annoyed. The fact is, though, that it's primarily biased against women. I'm not trying to "protect" women because I think they need to be protected by big strong ol' me (hell, half or more of my female friends could easily beat 10 kinds of crap out of me in a serious fight). I'm annoyed because I see an industry full of people for whom putting up a softcore porn image in a talk in front of an audience isn't that big a deal.


And that is the issue.

Tuesday, December 12, 2006

some more on IronPython

Michael Foord has some notes on getting IronKant working with IronPython on Windows here

During my talk, I showed a slide that IronPython on .Net runs pybench at 41% of CPython 2.5's speed (71%, if you exclude the TryRaiseExcept case, where it totally loses), while Mono 1.1.17 gets around 14% of of CPython 2.5's speed. I finally got around to trying Mono 1.2.2 (I didn't have time before the talk). It's actually about 12% _slower_ than 1.1.17. This makes me sad. Very sad. I need to get pybench checked into IPCE and point the Mono and .Net folks at it.

It's pretty obvious that both .Net and Mono optimised for pystone - in both cases, IronPython is more than 20% faster than CPython. Unfortunately, pystones is a terrible benchmark. If they can optimise for pybench, most people's applications will see a real improvement.

Labels: , ,

Monday, December 11, 2006

talk #2: futurepython

The final talk from the three I did at OSDC is up now. This was the end of day talk on Thursday, "futurepython". I talked about IronPython and Python 3.0. Unlike the other two talks, this one wasn't done using Bruce. Instead, I did an extremely quick port of Bruce to run on top of IronPython and SdlDotNet. In keeping with the philosopher's naming scheme of Bruce, I called it "ironkant".

The talk is here, including the ironkant code. I should point out that ironkant almost certainly has bugs - I started it late Wednesday night after the conference dinner and finished it (and the talk) a good 5 minutes before I presented it the next afternoon. What can I say, I just thrive on the stress. Having the presentation running on top of IronPython was a pretty good demonstration of just how far along IronPython has come.

And sorry Jim for calling you a crazy man - I mean that with love and respect :-)

I was extremely impressed with how easy it is to grab a C# assembly, read the C# docs and get coding. I also only had to make one fix to a CPython standard library module to get the code to work - in this case, I had to fix codeop.py to not pass the DONT_IMPLY_DEDENT flag to the builtin compile() method. This flag is both undocumented and implemented in codeop.py in a most foul way - I've opened Python bug 1612012 about it. The fixed version of codeop.py is now in the SVN version of IPCE.

I started porting popen2 as well, that's not finished yet (but will be this week). For the moment, I'm just using os.spawnl() directly inside IronKant for spawning external programs.

The longer Windows.Forms example in the talk is from Michael Foord's excellent tutorial on the subject. If you're at all interested in producing native GUIs on both Windows and Unix, you should definitely check the tutorial out. And buy his book about IronPython when it's done!

Labels: , ,

Sunday, December 10, 2006

talk #3 - gstreamer and python

The third talk from OSDC is up as well, now. This was "GStreamer and Python". The talk itself can be found here, or via SVN with
"svn co http://codingweasel.googlecode.com/svn/trunk/talks/2006/gstpy"
Once again, it uses the current SVN version of Bruce, which you can get with
"svn co http://svn.bruce.python-hosting.com/trunk"
Unlike the previous talk, it's unlikely you'll be able to run it in it's full glory, because
a) it needs 3 sound cards :-)
b) I haven't checked in the many, many sound files (and single video file) I used for the talk, as they're all copyrighted to the original owners. The text and code should still be useful, though.


The goal is to turn the various examples from this talk into individual blog posts, with explanatory text. I mentioned during the talk a couple of posts by Jono Bacon that provide a good introduction - they can be found here and here.

Labels: , ,

Wednesday, December 06, 2006

What's New In Python, 2006

I've put the first of my OSDC 2006 talks up - What's New In Python 2006 Edition.

It can be fetched from http://codingweasel.googlecode.com/svn/trunk/talks/2006/whatsnew/
(or svn co thaturl)

This talk uses the Bruce presentation software, in particular the new 'socrates.py' script that takes a simple text file describing the presentation. At the moment, you'll need the current SVN version of Bruce. There will be a new release of that soon.

Alternately, you can just read the 'whatsnew.soc' file - it's a simple text file.

Update: You can get Bruce's current SVN with
"svn co http://svn.bruce.python-hosting.com/trunk"

Labels: ,

Saturday, December 02, 2006

welcome

I'm planning on using this blog to post code samples and general programming notes. I'm not going to be starting until after OSDC, next week.