libsrt使用解析

SRT协议简介

SRT(Secure Reliable Transport)是一种开源视频传输协议,由Haivision和Wowza共同推动,旨在通过不可预测的网络(如互联网)实现安全、可靠的低延迟视频流传输。它结合了低延迟、抗丢包和加密功能,广泛应用于直播、远程制作和IP视频传输领域。

SRT的核心特性

低延迟:SRT通过优化传输机制,将端到端延迟控制在毫秒级,适合实时互动场景。
抗丢包:利用ARQ(自动重传请求)和FEC(前向纠错)技术,在丢包率高的网络中保持流畅传输。
端到端加密:支持AES加密,确保数据安全,防止窃听或篡改。
动态码率适应:根据网络状况自动调整码率,避免拥塞。

SRT的工作原理

SRT基于UDP协议,通过以下机制实现可靠传输:

  • 握手阶段:建立连接时协商参数(如延迟、加密密钥)。
  • 数据传输:发送方将数据分片并添加序列号,接收方通过ACK/NACK反馈丢包情况。
  • 丢包恢复:通过重传或FEC修复丢失的数据包。
  • 拥塞控制:基于网络状况动态调整发送速率。

SRT的应用场景

  1. 直播与广播:用于电视台、赛事直播等低延迟要求的场景。
  2. 远程制作:支持多地协同的云端视频制作。
  3. 企业通信:适用于视频会议、远程监控等实时交互应用。

SRT与同类协议对比

  • RTMP:延迟较高(1-3秒),基于TCP,适合推流但不适应复杂网络。
  • WebRTC:专注于浏览器端实时通信,但缺乏SRT的抗丢包优化。
  • RIST:同为可靠传输协议,但SRT在开源生态和工具链上更成熟。
  • libsrt

  • libsrt 是一个开源库,用于支持 SRT(Secure Reliable Transport)协议。SRT 是一种基于 UDP 的低延迟流传输协议,广泛应用于视频直播、远程制作和低延迟流媒体传输场景。libsrt 提供了 SRT 协议的实现,支持加密、错误恢复和拥塞控制等功能。

  • 服务端实现

  • 自定义选项:
  • struct ProtocolOption
    {
        //同步方式发送和接收,为false就是异步
        bool synSendReceive;
        //发送缓冲区大小
        int sendBufferSize;
        //接收缓冲区大小
        int receiveBufferSize;
        //丢包后最大重传次数,0表示一直重传
        int lossMaxTTL;
        //延迟容忍时间(毫秒)
        int latency;
        //单个包最大长度
        int payload;
        //时间戳防抖动模式开启
        bool tsbpdMode;
        //关闭socket时等待数据全部发送完再退出
        bool linger;

        ProtocolOption()
        {
            synSendReceive = true;
            sendBufferSize = 80 * 1024 * 1024;
            receiveBufferSize = 80 * 1024 * 1024;
            lossMaxTTL = 10;
            latency = 100;
            payload = 1316;
            tsbpdMode = true;
            linger = false;
        }
    };

  • //创建服务

  • srt_startup();
    SRTSOCKET handle = srt_create_socket();

    configureReceiveSocket(handle , opt);

    sockaddr_in local_addr;
    local_addr.sin_family = AF_INET;
    local_addr.sin_port = htons(port);
    local_addr.sin_addr.s_addr = INADDR_ANY;

    if (srt_bind(handle , (sockaddr*)&local_addr, sizeof(local_addr)) == SRT_ERROR)
        return;

    if (srt_listen(handle , 10) == SRT_ERROR)
        return;

    int nEpollid = srt_epoll_create();
    int events = SRT_EPOLL_IN | SRT_EPOLL_OUT | SRT_EPOLL_ERR;
    if (SRT_ERROR == srt_epoll_add_usock(m_nEpollid, m_handle, &events))
        return;

  • //开启处理线程

  • std::shared_ptr<std::thread> ptrReceiveThread;

  • ptrReceiveThread.reset(new std::thread(threadFunction, this, handle, nEpollid ));

  • //线程函数

  • void threadFunction(SRTSOCKET handle, int epollid)

  • {

  •     const int srtrfdslenmax = 100;
        SRTSOCKET srtrfds[srtrfdslenmax];
        std::fill(srtrfds, srtrfds + srtrfdslenmax, SRT_INVALID_SOCK);  

  •     while (1)
        {
            int srtrfdslen = srtrfdslenmax;
            //不处理系统socket,只处理srt的socket
            int n = srt_epoll_wait(nEpollid, &srtrfds[0], &srtrfdslen, 0, 0, 100, 0, 0, 0, 0);
            if (n <= 0)
                continue;

            //处理事件
            for (int i = 0; i < n; i++)
            {
                SRTSOCKET s = srtrfds[i];
                if (s == SRT_INVALID_SOCK)
                    continue;

                //句柄去重
            for (int j = 1; j < n; j++)
            {
                const SRTSOCKET next_s = srtrfds[j];
                if (s == next_s)
                    srtrfds[j] = SRT_INVALID_SOCK;
            }

            SRT_SOCKSTATUS status = srt_getsockstate(s);
            if ((status == SRTS_BROKEN) ||
                (status == SRTS_NONEXIST) ||
                (status == SRTS_CLOSED))
            {
                cout << "source disconnected. status=" << status << endl;
                srt_close(s);
                srt_epoll_remove_usock(nEpollid, s);
                continue;
            }
            else if (s == m_handle && status == SRTS_LISTENING)
            {
                SRTSOCKET fhandle;
                sockaddr_storage clientaddr;
                int addrlen = sizeof(clientaddr);

                fhandle = srt_accept(m_handle, (sockaddr*)&clientaddr, &addrlen);
                if (SRT_INVALID_SOCK == fhandle)
                {
                    cout << "srt_accept: " << srt_getlasterror_str() << endl;
                    continue;
                }

  •         }

  •     else if(status == SRTS_CONNECTED)
        {

            char buffer[2000];
    • int bytes_read = 0;
      int total_bytes_read = 0;
      SRT_MSGCTRL mctrl;
      srt_msgctrl_init(&mctrl);

    • bytes_read = srt_recvmsg2(s, buffer, sizeof(buffer), &mctrl);
      total_bytes_read += bytes_read;
      if (bytes_read <= 0)
              break;

  •     }

  • }

  • }
  • //配置选项方法

  • void configureReceiveSocket(SRTSOCKET sock, ProtocolOption opt)
    {
        int live = SRTT_LIVE;
        srt_setsockflag(sock, SRTO_TRANSTYPE, &live, sizeof(live));

        int lossmaxttl = opt.lossMaxTTL;
        srt_setsockflag(sock, SRTO_LOSSMAXTTL, &lossmaxttl, sizeof(lossmaxttl));

        int rcvbuf = opt.receiveBufferSize;
        srt_setsockflag(sock, SRTO_UDP_RCVBUF, &rcvbuf, sizeof(rcvbuf));

        int latency = opt.latency;;
        srt_setsockflag(sock, SRTO_LATENCY, &latency, sizeof(latency));

        int syn = opt.synSendReceive ? 1 : 0;
        srt_setsockflag(sock, SRTO_RCVSYN, &syn, sizeof(syn));

        //单个数据包大小
        int payload = opt.payload;
        srt_setsockflag(sock, SRTO_PAYLOADSIZE, &payload, sizeof(int));

        //等待数据发送完毕再关闭
        int linger = opt.linger ? 1 : 0;
        srt_setsockflag(sock, SRTO_LINGER, &linger, sizeof(int));

        //时间戳防抖动策略
        int tsbpd = opt.tsbpdMode ? 1 : 0;
        srt_setsockflag(sock, SRTO_TSBPDMODE, &tsbpd, sizeof(int));
    }

内容概要:本文系统梳理了多个科研领域的前沿研究与技术实现,重点涵盖FDTD方法中的完美匹配层(PML)研究,以及Matlab/Simulink在电磁、电力、控制、通信、信号处理、图像处理、路径规划、能源系统优化等领域的仿真与算法实现。文中列举了大量基于Matlab和Python的科研案例,如风电功率预测、负荷预测、无人机三维路径规划、电池系统故障诊断、雷达模拟、通信编码、微电网优化调度等,并强调结合智能优化算法(如粒子群、遗传算法、深度学习等)提升系统性能。同时,提供了丰富的代码资源与仿真模型,涵盖永磁同步电机控制、逆变器设计、多智能体任务分配、虚拟电厂调度等复杂系统,助力科研人员快速开展复现实验与创新研究。; 适合人群:具备一定编程基础,熟悉Matlab/Python工具,从事电气工程、自动化、通信、人工智能、新能源、控制科学等相关领域研究的研发人员及研究生。; 使用场景及目标:① 学习并实现FDTD仿真中的PML边界条件以有效抑制数值反射;② 掌握Matlab/Simulink在多物理场建模、控制系统设计与优化算法中的综合应用;③ 借助提供的代码资源完成科研复现、课程设计、竞赛项目或工程原型开发; 阅读建议:此资源以科研实战为导向,不仅提供理论方法,更强调代码实现与仿真验证。建议读者结合自身研究方向,按目录顺序查阅相关模块,下载配套代码进行调试与二次开发,以达到学以致用、融会贯通的目的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值