转自:http://www.jiazi.cn/blog/?id=56 扩散该解决方法多线程
最近须要使用VLC控件来作一个简单的流媒体播放器,在实施过程当中,发如今调用libvlc_media_player_stop()方法时有时会卡死。tcp
百度告诉我多是死锁问题,即在libvlc的回调事件中可能阻塞了,解决方法是另外开个线程来调用libvlc_media_player_stop()方法。ide
但是,我并无用到回调事件。虽然另外开个线程来调用libvlc_media_player_stop()能解决问题,但多线程可能会带来更多的隐患。函数
经过几番测试后,我发现若是不将vlc视频嵌入到子窗口中播放,而是让它独立窗口播放,则在libvlc_media_player_stop()时是不会卡死的。测试
因而判断多是VLC在stop的过程当中可能会产生子窗口消息,然而子窗口消息是在主线程(UI线程)中处理的,而libvlc_media_player_stop()方法也是在主线程中调用的,这就形成了竞争性死锁。url
若是视频不是嵌入到子窗口中,而是独立存在(VLC内部本身建立的),则其消息处理非主线程负责,就不会出现竞争性死锁。线程
缘由找出,解决方案以下:code
一、另外开个线调来调用libvlc_media_player_stop()方法。(这是我在百度上找到的方法,但我认为该方法不够完美)视频
二、在libvlc_media_player_stop()以前,先把“包含VLC视频窗口”的子窗口销毁,后面若是须要再重建。因为窗口不存在了,VLC在stop的过程当中的任何消息都不会发到主线程中来了,这样就不会出现竞争性死锁了。(反复测试后再也没有出现死锁的问题了)blog
方法二code:
const QString play_url("rtmp://live.hkstv.hk.lxdns.com/live/hks");
libvlc_instance_t *m_inst = NULL;
libvlc_media_player_t *m_mp = NULL;
libvlc_media_t *m_m = NULL;
QWidget *m_videoWdg = NULL;
const char * const vlc_args[] = {
"--no-audio",
"--demux=h264",
"--rtsp-frame-buffer-size=1000000", //RTSP帧缓冲大小,默认大小为100000
"--network-caching=300",
"--rtsp-tcp"
};
m_inst = libvlc_new(sizeof(vlc_args) / sizeof(vlc_args[0]), vlc_args);
m_m = libvlc_media_new_location(m_inst, play_url.toStdString().c_str());
m_mp = libvlc_media_player_new_from_media(m_m);
libvlc_media_parse(m_m);
libvlc_media_release(m_m);
m_videoWdg = new QWidget;
HWND screen_hwnd = (HWND)m_videoWdg->winId();
libvlc_media_player_set_hwnd(m_mp, screen_hwnd);
if (libvlc_media_player_play(m_mp) == -1)
{
//libvlc_media_player_play error
return;
}
//中止播放时,先释放掉绑定vlc的播放窗口,而后调用vlc库函数,中止播放。
void stopPlay()
{
if (m_mp)
{
//释放掉绑定vlc的播放窗口
if (m_videoWdg != nullptr)
{
delete m_videoWdg;
m_videoWdg = nullptr;
}
//停掉流媒体
libvlc_media_player_stop(m_mp);
libvlc_media_player_release(m_mp);
libvlc_release(m_inst);
m_inst = NULL; m_mp = NULL; m_m = NULL; }}