Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation

Re^5: XS callback to mpv_set_wakeup_callback

by MaxPerl (Novice)
on Jan 09, 2019 at 19:15 UTC ( #1228271=note: print w/replies, xml ) Need Help??

in reply to Re^4: XS callback to mpv_set_wakeup_callback
in thread XS callback to mpv_set_wakeup_callback

Dear Dave,
Thank you for your helpful answers. Indeed I think that the perl thread starts an event loop function in mpv which lets mpv's own threads take over to do all the active work and callbacks regarding playing medias. At the same time multiple mpv threads can absolutely call callbacks simultaneously, so locking is surely an important point. Where can I find informations on this topic in XS? Furthermore the perl thread isn't suspended, while mpv renders the video etc, but must be responsive for events for example from the GUI part of an application.
The API is mostly described here: libmpv is a media player (the successor of mplayer). In General it is necessary to run mpv in an event loop. This is done with the mpv_wait_event function, whereby only one thread is allowed to call this on the same mpv_handle at a time. The mpv_set_wakeup_callback method is designed to make it possible to run mpv with existing event loops (especially from GUIs etc).
The description describes it as follows: "It sets a custom function that should be called when there are new events. The callback is meant strictly for notification only, and is called from arbitrary core parts of the player, that make no considerations for reentrant API use or allowing the callee to spend a lot of time doing other things. It's also possible that the callback is called from a thread while a mpv API function is called (i.e. it can be reentrant). If you actually want to do processing in a callback, spawn a thread that does nothing but call mpv_wait_event() in a loop and dispatches the result to a callback."
The mpv library starts one thread for event handling (I think this is the mpv core thread), since MPV sends events that must be processed quickly. In my understanding the main perl thread is only a thinn wrapper to the c functions and is especially important for the GUI stuff etc. The MPV threads seem to be created and administered independently from the perl Thread.
The description of the MPV-API states also the following: "The client API is generally fully thread-safe, unless otherwise noted. Currently, there is no real advantage in using more than 1 thread to access the client API, since everything is serialized through a single lock in the playback core."
Sorry, that I cannot give more informations. The topic threads is new for me (which is why I tried a pure perl workaround in MPV::Simple::Pipe).. For this very reason thank you very much for your understanding, patience and help,

PS.: Here is a test application ("./einladung2.mp4" is a video file located in the same directory as the script). Everything seems to work fine, if I initialize the MPV handler before setting the properties. If I set the property before the initialization (as partly in the C example here) I get a segfault. Furthermore I would expect that there are more events (everytime I hit the Restart button, there should be an event occur. (But perhaps the thread writes to a different STDOUT?):
use Tcl::Tk; use MPV::Simple; my $int =Tcl::Tk->new(); my $mw = $int->mainwindow(); # Bind MPV Event to the event handler $mw->bind('<<MPV>>' => \&on_mpv); my $f = $mw->Frame(-background => "green",-width => 640, -height => 48 +0)->pack(-expand =>1,-fill => "both"); my $id; $id = $f->id(); # MPV part $MPV::Simple::callback_data=$f; my $ctx = MPV::Simple->new(); $ctx->initialize(); $ctx->set_wakeup_callback(\&wakeup_callback, $f); $ctx->set_property_string("wid",$id); $ctx->set_property_string('input-default-bindings','yes'); $ctx->set_property_string('input-vo-keyboard','yes'); $ctx->set_property_string('osc','yes'); $ctx->command("loadfile", "./einladung2.mp4"); $mw->Button(-text => "Restart", -command => sub {$ctx->command("loadfi +le", "./einladung2.mp4")})->pack; $int->MainLoop(); # Wake up callback sub wakeup_callback { my $frame = shift; print "IN WAKEUP CALLBACK\n";$int->Eval("event +generate $frame <<MPV>> -when head"); } # Event handler sub on_mpv { while (1) { my $event = $ctx->wait_event(0) or die "SHit\n"; my $eid = $event->id; print "EVENT FIRED $MPV::Simple::event_names[eid]\n"; if ($eid == 0) { last; } } return }

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1228271]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others rifling through the Monastery: (4)
As of 2020-08-14 19:06 GMT
Find Nodes?
    Voting Booth?
    Which rocket would you take to Mars?

    Results (76 votes). Check out past polls.