zoukankan      html  css  js  c++  java
  • 解决libvlc_media_player_stop时死锁的方法

    转自:http://www.jiazi.cn/blog/?id=56 扩散该解决方法

    最近需要使用VLC控件来做一个简单的流媒体播放器,在实施过程中,发现在调用libvlc_media_player_stop()方法时有时会卡死。

    百度告诉我可能是死锁问题,即在libvlc的回调事件中可能阻塞了,解决方法是另外开个线程来调用libvlc_media_player_stop()方法。

    可是,我并没有用到回调事件。虽然另外开个线程来调用libvlc_media_player_stop()能解决问题,但多线程可能会带来更多的隐患。

    通过几番测试后,我发现如果不将vlc视频嵌入到子窗口中播放,而是让它独立窗口播放,则在libvlc_media_player_stop()时是不会卡死的。

    于是判断可能是VLC在stop的过程中可能会产生子窗口消息,然而子窗口消息是在主线程(UI线程)中处理的,而libvlc_media_player_stop()方法也是在主线程中调用的,这就造成了竞争性死锁。

    如果视频不是嵌入到子窗口中,而是独立存在(VLC内部自己创建的),则其消息处理非主线程负责,就不会出现竞争性死锁。

    原因找出,解决方案如下:

    1、另外开个线调来调用libvlc_media_player_stop()方法。(这是我在百度上找到的方法,但我认为该方法不够完美)

    2、在libvlc_media_player_stop()之前,先把“包含VLC视频窗口”的子窗口销毁,后面如果需要再重建。由于窗口不存在了,VLC在stop的过程中的任何消息都不会发到主线程中来了,这样就不会出现竞争性死锁了。(反复测试后再也没有出现死锁的问题了)

    方法二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;
      }
    }

  • 相关阅读:
    洛谷 P3391 文艺平衡树
    [ZJOI2008]杀蚂蚁 Solution
    POJ P3667 Hotel——solution
    洛谷 P2469 [SDOI2010]星际竞速 解题报告
    POJ P2318 TOYS与POJ P1269 Intersecting Lines——计算几何入门题两道
    【linux】基础知识学习
    【linux】打包压缩命令
    【python】类file文件处理
    【python】使用asyncore进行异步通信
    【python】命令行解析工具getopt用法
  • 原文地址:https://www.cnblogs.com/zhangxuan/p/9947513.html
Copyright © 2011-2022 走看看