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

解决libvlc_media_player_stop时死锁的方法的更多相关文章

  1. 剑指Offer:解决难题时的三大方法

    1.画图 让抽象的东西变得直观生动起来.比如设计二叉树,链表,栈,队列这些数据结构时. 2.举例子 同样可以化抽象为直观.能够更清晰的展现思路.从例子归纳出一般做法. 3.分解 有时问题本身是比较复杂 ...

  2. SQLServer查看和解决死锁的方法

    http://luohonghong.blog.163.com/blog/static/78312058201142411533316/ SQLServer查看和解决死锁的方法 2011-05-24 ...

  3. 一文了解MySQL性能测试及调优中的死锁处理方法,你还看不明白?

    一文了解MySQL性能测试及调优中的死锁处理方法,你还看不明白? 以下从死锁检测.死锁避免.死锁解决3个方面来探讨如何对MySQL死锁问题进行性能调优. 死锁检测 通过SQL语句查询锁表相关信息: ( ...

  4. 解决 SQL 注入的另类方法

    本文是翻译,版权归原作者所有 原文地址(original source):https://bitcoinrevolt.wordpress.com/2016/03/08/solving-the-prob ...

  5. listView解决滑动时黑色背景问题

    listView.setCacheColorHint(Color.TRANSPARENT);//解决滑动时黑色背景问题 listView滑动时黑色背景问题 原因在于ListView存在缓存颜色机制,因 ...

  6. Jenkins2.138配置slave节点时,启动方法只有两个选项

    Jenkins2.138配置slave节点时,启动方法只有两个选项,并没有通过javaweb代理启动这个选项 解决办法 全局安全配置->代理->选择随机选取

  7. vue 使用 axios 时 post 请求方法传参无法发送至后台

    axios 时 post 请求方法传参无法发送至后台报错如下 Response to preflight request doesn't pass access control check: No ' ...

  8. Ubuntu下Sublime Text 3解决无法输入中文的方法

    Ubuntu下Sublime Text 3解决无法输入中文的方法_百度经验http://jingyan.baidu.com/article/f3ad7d0ff8731609c3345b3b.html ...

  9. HTTP 请求方式: GET和POST的比较当发送数据时,GET 方法向 URL 添加数据;URL 的长度是受限制的(URL 的最大长度是 2048 个字符)。

    什么是HTTP? 超文本传输协议(HyperText Transfer Protocol -- HTTP)是一个设计来使客户端和服务器顺利进行通讯的协议. HTTP在客户端和服务器之间以request ...

随机推荐

  1. Codeforces 785E. Anton and Permutation

    题目链接:http://codeforces.com/problemset/problem/785/E 其实可以CDQ分治... 我们只要用一个数据结构支持单点修改,区间查询比一个数大(小)的数字有多 ...

  2. 【二十二】mysqli事务处理与预处理总结

    事务处理 事务基本原理 如果不开启事务,执行一条sql,马上会持久化数据.可见:默认的mysql对sql语句的执行是自动提交的! 如果开启了事务,就是关闭了自动提交的功能,改成了commit执行自动提 ...

  3. mysql 事件 按月分表

    /****** 对象: Table Order_201512 脚本日期: 2015/12/18 11:44:23 ******/ /****** 字段数据长度 = 2599 字节 ******/ CR ...

  4. 力扣(LeetCode) 66. 加一

    给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一. 最高位数字存放在数组的首位, 数组中每个元素只存储一个数字. 你可以假设除了整数 0 之外,这个整数不会以零开头. 示例 1: 输入 ...

  5. List、Map、Set的区别与联系

    重复和有序 List 存储的元素是有顺序的,并且值允许重复: Map 元素按键值对存储,无放入顺序 ,它的键是不允许重复的,但是值是允许重复的: Set 存储的元素是无顺序的,并且不允许重复,元素虽然 ...

  6. 使用VSCode如何从github拉取项目

    转载自:https://blog.csdn.net/sunqy1995/article/details/81517159 1.开vscode使用CTRL+`或者点击查看到集成终端打开控制终端 2. 在 ...

  7. Linux实际常用命令

    1.删除0字节文件 find -type f -size 0 -exec rm -rf {} \;  2.查看进程 按内存从大到小排列 ps -e -o “%C : %p : %z : %a”|sor ...

  8. Within K stops 最短路径 Cheapest Flights Within K Stops

    2018-09-19 22:34:28 问题描述: 问题求解: 本题是典型的最短路径的扩展题,可以使用Bellman Ford算法进行求解,需要注意的是在Bellman Ford算法的时候需要额外申请 ...

  9. C#模拟HTTP请求并发送二进制

    public static String Submit(String methodName) { string postData = "this is post data";//请 ...

  10. ADO.NET梳理

    目录: 简单的介绍下ADO.NET SqlConnection(连接对象) SqlCommand(命令对象) SqlParameter(Sql参数) SqlDataReader(数据流读取器) Sql ...