在事件循环开始后删除和创建新的RTP流

时间:2017-03-24 21:24:02

标签: c++ live555

我使用Live555传输1个或多个视频流。按照testH264VideoStreamer.cpp的示例,创建各种对象,然后启动事件循环。这是我的初始化代码的摘录,它处理单个视频流的对象创建:

// Setup usage environment
this->scheduler = BasicTaskScheduler::createNew();
this->env = BasicUsageEnvironment::createNew(*scheduler);

// Setup framed source
this->framedSource = H264FramedSource::createNew(*this->env, 0, 0);
this->discreteFramer = H264VideoStreamDiscreteFramer::createNew(*env, framedSource);

// Setup sockets
this->rtpGroupsock = new Groupsock(
        *this->env,
        this->destinationAddress,
        this->rtpPort,
        this->ttl);

this->rtcpGroupsock = new Groupsock(
        *this->env,
        this->destinationAddress,
        this->rtcpPort,
        this->ttl);

this->videoSink = H264VideoRTPSink::createNew(
        *this->env,
        this->rtpGroupsock,
        DEF_RTP_PT);

this->rtcp = RTCPInstance::createNew(
        *this->env,
        this->rtcpGroupsock,
        DEF_SESSION_BW,
        cname,
        videoSink,
        0,                   // We are a server
        True);               // We are an SSM source
// Create RTSP server
this->rtspServer = RTSPServer::createNew(*this->env, rtsp_port);
this->sms = ServerMediaSession::createNew(
        *this->env, "test",
        ip.c_str(),
        0,
        True);
this->sms->addSubsession(PassiveServerMediaSubsession::createNew(
        *this->videoSink,
        this->rtcp));
this->rtspServer->addServerMediaSession(this->sms);
this->videoSink->startPlaying(*this->discreteFramer, 0, this->videoSink);
this->env->taskScheduler().doEventLoop();

所以我的问题是:假设我希望我的环境/调度程序处理第二个视频流的事件,或者我想删除现有的流。我看到我可以向doEventLoop()添加一个参数以允许事件循环退出。然后我可以清理旧流,启动新流,然后重新启动事件循环。一旦事件循环已经启动,是否可以执行这些操作?停止并重新启动流会中断现有会话吗? (因此我应该为每个视频流使用不同的线程自己的调度程序/ env?)

1 个答案:

答案 0 :(得分:0)

当事件循环运行时,您可以通过近两种不同的方式执行操作:

  • 使用来自其他线程的触发器
  • 使用预定任务

使用其他线程的触发器

  1. 实施事件回调以完成工作
  2.  static void eventCallback(void* clientData) {
      ....
     }
    
    1. 注册您的活动回调:
    2.   

      int triggerId = this->scheduler->createEventTrigger(eventCallback);

      1. 在需要时拨打触发器:
      2.   

        this->scheduler->triggerEvent(m_eventTriggerId, this);

        使用预定任务

        1. 创建任务回调
        2. static void TaskCallback(void* clientData) { 
            ...
          }
          
          1. 在运行eventloop之前安排它:
          2.   

            this->scheduler->scheduleDelayedTask(1000000, TaskCallback, this);

            在静态回调中,您可以使用包含this指针的clientData重定向到您的类实例。