轉自: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; }}