开发者

Combining GStreamer, AnyEvent and EV (perl)

I'm trying to use GStreamer within an existing perl application that uses AnyEvent with the EV event loop. It is not a Glib application. I have loaded EV::Glib to get the Glib main loop to use EV. I freely admit that, with respect to Glib, I am pretty ignorant. I think that I have all 开发者_如何学Cthe bits that I need but I am struggling (failing) to get them to work together.

If I use a standalone perl program to build a GStreamer pipeline and then put it into PLAYING state then it all simply works. I do not need to do anything with a Glib mainloop or otherwise tickle the GStreamer bus.

Building the same pipeline in my existing application, within the context of an AnyEvent event-handler, then it fails to run the pipeline. I have played around with various ways of trying to exercise it, including calling $pipeline->get_bus->poll(). If I call ...->poll() repeatedly in the original event handler (that is, the handler does not return) then it works but this is clearly not a valid solution. Calling ...->poll() in an AnyEvent timer callback does not run the pipeline.

My best guess at the moment is that EV::Glib enables some level of integration but does not actually run the necessary bits of the main loop. What am I missing?


I came here with a similar question regarding EV::Glib usage, but ended up having no issues using it.. So maybe I'm missing what you're trying to do here.

Here is the simple script I knocked up to test how EV::Glib works:

use EV::Glib;
use Gtk2 '-init';

my $t = EV::timer 1, 1, sub { print "I am here!\n" };
Glib::Timeout->add(1000, sub { print "I am also here!\n" });

my $window = Gtk2::Window->new('toplevel');
$window->signal_connect(delete_event => sub { EV::unloop });

my $button = Gtk2::Button->new('Action');
$button->signal_connect(clicked => sub { 
    print("Hello Gtk2-EV-Perl\n");
});

$window->add($button);
$window->show_all;

EV::loop;

With this the signal handler on the button will work, and so too will both the timer events. So the EV loop will correctly drive the entire thing.

The main issue I can see is in the documentation: "This [module] makes Glib compatible to EV. Calls into the Glib main loop are more or less equivalent to calls to EV::loop (but not vice versa, you have to use the Glib mainloop functions)." What this means is if you're hookling up an EV::loop event, it won't equate to a Glib::mainloop and so might not 'tickle' (or 'be tickled by') your GStreamer event. Maybe that could be the issue you're experiencing, especially if you're using AnyEvent and its generic callbacks which are likely translating to EV::loop calls instead of Glib::MainLoop calls.

This is all just a guess though -- I've never used GStreamer myself, and I certainly don't know what you're trying to achieve without seeing more code. But I think my halfassed conclusion is pretty sound advice regardless: If you're using something specific to Glib, you should probably be hooking up events to it using Glib.


EV::Glib embeds Glib into EV - you (and everybody else) has to use EV to make it work. Chances are that gstreamer doesn't know about this and disrespectfully calls glib mainloop functions internally, which doesn't work.

Fortunately there is another module that does just the opposite: Glib::EV. That module makes Glib use EV internally. When using it, you can/should use the glib mainloop functions (you can use EV watchers, but you cannot call glib functions from the EV callbacks, as glib doesn't support that).

It might be better suited to your application, as applications using glib will "just work", as the EV usage is completely internal.

Another possible issue is that perl modules are dynamically linked, and only "accidentally" get the same library. For all of this to work, you need to ensure that all perl modules link against the same shared glib library.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜