我对Live555进行了一次封装,但是Live555 是单线程的,里面定义的全局变量太多,我封装好dll库后,在客户端调用,因为多个对话框中要使用码流,我就定义了多个对象从设备端接收码流,建立多个连接,但是当一路码流退出,然后在退出另外的一路码流时,库里面出现问题,原因是Live555 里面的全局变量被破坏了!

针对上面问题:我目前的解决办法是将全局的信息隔离:

定义一个结构:

#define CLIENT_STREAM_NUM 4

class ourRTSPClient;

typedef struct  _RtspGlobal
{
 ourRTSPClient *pRtspClient;
 NetSdk *pNetSdk;
}RtspGlobal;

//
RtspGlobal struRtspGlobal[CLIENT_STREAM_NUM];

这样每一路码流对应数组中的一项,就做成多线程的了,在全局的回调函数中,根据RTSPClient*rtspClient的指针和struRtspGloball数组中的指针进行比较,如果相同,就知道是哪个流对应的连接了,比如在continueAfterSETUP函数里面建立sink时,我们可以如下判断:

for (int i=0;i<CLIENT_STREAM_NUM;i++)
  {
   if (struRtspGlobal[i].pNetSdk!=NULL)
   {
    if (struRtspGlobal[i].pRtspClient==rtspClient)
    {
     scs.subsession->sink = CRtpMediaSink::createNew(env, *scs.subsession,
      (RtpMediaSinkCallback)struRtspGlobal[i].pNetSdk->rtspDataCallback,
      (void *)&struRtspGlobal[i],RTPMEDAA_SINK_RECEIVE_BUFFER_SIZE, rtspClient->url());

break;
    }
   }

}

这样使得testRtspClient例子支持到多线程了。

2)Live555 的断网重连问题

1)重连死锁

1.1)重连时如果将解码回调线程放在NetSdk里面,使用两个Event,当接受线程结束时,发送接受线程结束的信号,然后在解码线程里面判断接收线程信号 ,如果有信号,就发送一个退出解码线程,发送一个解码结束的信号;

1.2)当超时重连时,首先Stop码流,然后Restart码流;停止码流时,将eventLoopWatchVariable=1;让数据接收线程顺利退出;同时在stop函数里面等待解码线程结束,

WaitForThreadExit(m_DecodeExitEvent);

这时会造成死锁;因为Live555是单线程的,在超时函数中需要等待本线程的结束,造成死锁;

解决办法:

1)使用单独的心跳线程来实现重连功能或者在回调数据给客户端的的解码线程里面实现重连功能;

2)网络断开判断方法 使用延迟队列来判断,初始化时候调用noteLiveness,然后每次收到Sink的一帧数据时,再次调用noteLiveness,这样如果网络断开,超时后,就能判断出来;在数据接收线程的doEventLoop后面将重连标记置位:

m_bReConnect=true;

3)断网重连的工作不能放在livenessTimeoutTask这个函数里面,不然会造成重连死锁,因为live555是单线程的;只能放在其它的线程里面实现重连;我是放在回调给客户端的解码线程里面实现重连;

void NetSdk::noteLiveness(void* clientData,UsageEnvironment& env) 
{

if (m_ReconnectTime> 0) 
 {
  env.taskScheduler().rescheduleDelayedTask(fLivenessCheckTask,m_ReconnectTime*1000000,(TaskFunc*)livenessTimeoutTask, clientData);
 }

}

void NetSdk::livenessTimeoutTask(void* clientData) {

TRACE("livenessTimeoutTask run\n");
 RtspGlobal *pRtspGlobal=(RtspGlobal *)clientData;
 pRtspGlobal->pNetSdk->fLivenessCheckTask= NULL;
 UsageEnvironment& env = pRtspGlobal->pRtspClient->envir(); // alias

pRtspGlobal->pNetSdk->RestopVideo();

}

重连线程如下:

void NetSdk::DecodeThread(void *arg)
{
 NetSdk *pThis=(NetSdk*)arg;

while (!pThis->m_bQuit)
 {

if (pThis->m_bReConnect)
  {
   //
   pThis->RestartVideo();
   pThis->m_bReConnect=false;

}else
  {
   pThis->ImageDecodeAndShow();
  }

}

Live555 的一个缺陷–例子不能支持多线程(已经修改成支持多线程)的更多相关文章

  1. 阅读DSSS.py 并修改成支持python3.6

    项目地址:https://github.com/stamparm/DSSS 功能:一款小型注入工具 代码如下URL:https://github.com/stamparm/DSSS/blob/mast ...

  2. 百度编辑器UEditor修改成支持物理路径

    一.前言 我虽然工作了2年.有快1年没有做后台的开发了.最近要写个新项目用到富文本编辑器,然后选择用了百度的UEditor.在使用过程中感觉有些不太好.然后就自己手动改一下源码,写得不好请见谅.这只是 ...

  3. C语言多线程的一个简单例子

    多线程的一个简单例子: #include <stdio.h> #include <stdlib.h> #include <string.h> #include &l ...

  4. libcurl的封装,支持同步异步请求,支持多线程下载,支持https

    最近在做一个项目,需要用到http get post等 需求分析需要做到同步和异步,异步请求的返回以可选的回调通知的方式进行. 本人以Linux为例,一步一步的来实现. 配置并且编译libcurl我以 ...

  5. SQL Server Reporting Service(SSRS) 第一篇 我的第一个SSRS例子

    很早就知道SQL SERVER自带的报表工具SSRS,但一直没有用过,最近终于需要在工作中一展身手了,于是我特地按照自己的理解做了以下总结: 1. 安装软件结构 SSRS全称SQL Server Re ...

  6. 一个简单例子:贫血模型or领域模型

    转:一个简单例子:贫血模型or领域模型 贫血模型 我们首先用贫血模型来实现.所谓贫血模型就是模型对象之间存在完整的关联(可能存在多余的关联),但是对象除了get和set方外外几乎就没有其它的方法,整个 ...

  7. 在 Cloudera Data Flow 上运行你的第一个 Flink 例子

    文档编写目的 Cloudera Data Flow(CDF) 作为 Cloudera 一个独立的产品单元,围绕着实时数据采集,实时数据处理和实时数据分析有多个不同的功能模块,如下图所示: 图中 4 个 ...

  8. 一个ioc例子jdk和spring版本导致问题

    今天橘子松在做一个简单例子的时候,出现bug让我久久找了半小时... 天啊 不会吧 错误如下:   java.lang.NoSuchMethodError: org.springframework.a ...

  9. 调用webapi 错误:使用 HTTP 谓词 POST 向虚拟目录发送了一个请求,而默认文档是不支持 GET 或 HEAD 以外的 HTTP 谓词的静态文件。的解决方案

    第一次调用webapi出错如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http:// ...

随机推荐

  1. 微信小程序引用外部js,引用外部样式,引用公共页面模板

    https://blog.csdn.net/smartsmile2012/article/details/83414642 ================小程序引用外部js============= ...

  2. 计算xx年xx月xx日是星期几

    代码: #include <iostream> #include <string> #include <vector> using namespace std; i ...

  3. 阿里云服务器ubantu创建新用户登录显示问题

    在root用户下输入:vi /etc/passwd,找到添加的用户,在后面加上/bin/bash 重新登录即回复正常

  4. 8年经验面试官详解 Java 面试秘诀

      作者 | 胡书敏 责编 | 刘静 出品 | CSDN(ID:CSDNnews) 本人目前在一家知名外企担任架构师,而且最近八年来,在多家外企和互联网公司担任Java技术面试官,前后累计面试了有两三 ...

  5. 揭秘autoit3的运行机制和反编译原理

    今天发这个帖子的目的在于和论坛里面的朋友交流一下学习心得,主要内容是围绕着autoit3的编译原理.先开门见山的说一下结果,我不知道如何反编译au3,但相信论坛有很多高手,能解开我心中的疑团.我没有想 ...

  6. nginx 打印详细请求

    log_format main escape=json '{ "@timestamp": "$time_iso8601", ' '"remote_ad ...

  7. 五 RequestMapping的使用

    1 设置路径映射为数组,在Controller类中一个方法对应多个映射路径,可以被多个url访问 2 分目录管理,在Controller类上添加Request Mapping注解,url访问必须添加相 ...

  8. mabatis--动态sql

    1.mybatis核心,对sql语句进行灵活操作,通过表达式进行判断,对sql进行灵活拼接.组装: 2.使用if判断: <where> <if test="customer ...

  9. Java FTPClient 大量数据传输的问题(未解决)

    业务需要 需要将一个存储的目标文件里的文件全部拷贝到另一个存储里面去,保持文件结构. 目前采用 org.apache.commons.net.ftp包下相关类来达到ftp连接 获取文件目录信息,拷贝文 ...

  10. javaweb框架--自定义标签与freemaker结合

    http://blog.csdn.net/myfmyfmyfmyf/article/details/8960299 很有用但是不不知道怎么说,写个例子,总之方便多了,并且容易管理,重复利用强 1.自定 ...