After I was informed about the existence of ClutterGstVideoSink, I quickly modified my super-video application to make it use that. But as soon as i did that, i stopped getting even the static image. After careful analysis for days, I figured that I was supposed to call gst_bus_add_signal_watch() on the pipeline bus since ClutterGstVideoSink uses messages on the bus combined with signal handlers to render the frames in the application thread. This is obviously a 'dirty' hack; a hack because gst elements are supposed to do all the media processing in the pipeline thread, dirty because gst bus is not meant for media transport.
After this realization, I had been working on it from time to time. First I tried to make the actual rendering happen in the gst pipeline thread by using the clutter's thread safety primitives and that worked quite nicely in the end except for one minor problem: The call to clutters rendering thread blocks if it happens after the clutter main loop has been exited and that is exactly when you set the pipeline to NULL state. If anyone have any clue on how to solve this problem, do let me know. In the meanwhile, I have made the hack non-dirty (or should I say, less dirty) by replacing 1. pipeline bus usage with an internal async queue and 2. bus signal handlers with idle functions (read g_idle_add()). This one was way easier to implement and it worked without any problems with all the test applications I have. I've submitted the patches upstream via a bug. If you are interested, please try them out and report your observations to the bug.
UPDATE: Just tried the 'rendering in the pipeline thread' changes again and now I remember that there is another critical problem with that: the whole application hangs (both app and gst pipeline) when I seek and/or play and pause very quickly. :(