Please Advise: libvlc 3.0.0.0 deadlock when MediaPlayer plays sout from another libvlc instance
Posted: 13 May 2015 22:19
Scenario: WPF app using a PInvoke wrapper around libvlc 3.0.0.0 for video playback. Videos can be live streaming (UDP multicast or RTSP), archived (.ts files over HTTP), or static files on the local file system.
Problem: Since our application allows seeking backwards (even for live streaming videos) we must buffer the video from the network locally. To accomplish this we have a 'splitter' that re-streams the live video to 2 ports on the loopback interface using a dedicated libvlc instance:
VlcContext is the dedicated libvlc instance (created via libvlc_new with the given options). Our 'saver' uses the recording port to save the video to the file system in 10 minute segments. Our video player is a libvlc MediaPlayer that is created using its own instance of libvlc. It plays the live video off the 127.0.0.1:{PlaybackPort} stream coming from the splitter.
This works, but it comes with random but eventual deadlocks on native libvlc calls (libvlc_media_player_stop, libvlc_media_player_play, and libvlc_media_player_release have all deadlocked). I've confirmed that I don't get these deadlocks when the MediaPlayer on our video player never tries to play the stream from the splitter. I suspect this has something to do with there being 2 libvlc instances with 1 playing the stream output of another. Is what we're doing a legal way to use libvlc? If so what can we do to avoid these deadlocks? If not then what would be the best practice for our scenario?
P.S. I've seen lots of posts about deadlocks involving certain libvlc calls executing on threads processing windows messages. We are executing media player api calls (play, stop, release) on a thread that is definitely pumping windows messages, but the only time I've seen deadlocks is in the scenario described above (where it's playing the stream from the other libvlc instance) so I don't think this has anything to do with WPF.
Problem: Since our application allows seeking backwards (even for live streaming videos) we must buffer the video from the network locally. To accomplish this we have a 'splitter' that re-streams the live video to 2 ports on the loopback interface using a dedicated libvlc instance:
Code: Select all
public VlcSplitter(Uri mediaUri, UdpPortPool udpPortPool)
{
portPool = udpPortPool;
recordPortLease = portPool.Borrow();
playbackPortLease = portPool.Borrow();
var options =
string.Format(
"--sout=#duplicate{{dst=std{{access=udp,mux=ts,dst=127.0.0.1:{0}}},dst=std{{access=udp,mux=ts,dst=127.0.0.1:{1}}}}}",
RecordPort,
PlaybackPort);
context = new VlcContext(options);
using (var media = new Media(context, mediaUri))
{
mediaPlayer = new MediaPlayer(media, false);
mediaPlayer.Play();
}
}
This works, but it comes with random but eventual deadlocks on native libvlc calls (libvlc_media_player_stop, libvlc_media_player_play, and libvlc_media_player_release have all deadlocked). I've confirmed that I don't get these deadlocks when the MediaPlayer on our video player never tries to play the stream from the splitter. I suspect this has something to do with there being 2 libvlc instances with 1 playing the stream output of another. Is what we're doing a legal way to use libvlc? If so what can we do to avoid these deadlocks? If not then what would be the best practice for our scenario?
P.S. I've seen lots of posts about deadlocks involving certain libvlc calls executing on threads processing windows messages. We are executing media player api calls (play, stop, release) on a thread that is definitely pumping windows messages, but the only time I've seen deadlocks is in the scenario described above (where it's playing the stream from the other libvlc instance) so I don't think this has anything to do with WPF.