解決libvlc_media_player_stop時死鎖的方法

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

相關文章
相關標籤/搜索