【问题标题】:deleting and creating new RTP streams after event loop started事件循环开始后删除和创建新的 RTP 流
【发布时间】:2017-03-24 21:24:02
【问题描述】:

我正在使用 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() 添加一个参数以允许事件循环退出。然后我可以清理旧流,启动新流,然后重新启动事件循环。一旦事件循环已经启动,是否可以执行这些操作?停止和重新启动流会中断现有会话吗? (因此我应该为每个视频流使用不同的线程它自己的调度程序/环境?)

【问题讨论】:

    标签: c++ live555


    【解决方案1】:

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

    • 使用来自其他线程的触发器
    • 使用计划任务

    使用来自其他线程的触发器

    1. 实现事件回调来完成工作
     static void eventCallback(void* clientData) {
      ....
     }
    
    1. 注册您的事件回调:

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

    1. 在需要时调用触发器:

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

    使用计划任务

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

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

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

    【讨论】:

      猜你喜欢
      • 2017-04-11
      • 1970-01-01
      • 1970-01-01
      • 2019-03-30
      • 1970-01-01
      • 2017-02-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多