ZLMediaKit webrtc RTP包接受与重传

简介: ZLMediaKit webrtc RTP包接受与重传

webrtc RTP包接受与重传

RTP包处理

void WebRtcTransportImp::onRtp(const char *buf, size_t len, uint64_t stamp_ms) {
    _bytes_usage += len;
    _alive_ticker.resetTime();

    RtpHeader *rtp = (RtpHeader *)buf;
    // 根据接收到的rtp的pt信息,找到该流的信息
    auto it = _pt_to_track.find(rtp->pt);
    if (it == _pt_to_track.end()) {
        WarnL << "unknown rtp pt:" << (int)rtp->pt;
        return;
    }
    it->second->inputRtp(buf, len, stamp_ms, rtp);
}

  ‍

正常包

void WrappedRtpTrack::inputRtp(const char *buf, size_t len, uint64_t stamp_ms, RtpHeader *rtp) {
#if 0
    auto seq = ntohs(rtp->seq);
    if (track->media->type == TrackVideo && seq % 100 == 0) {
        //此处模拟接受丢包
        return;
    }
#endif

    auto ssrc = ntohl(rtp->ssrc);

    // 修改ext id至统一
    string rid;
    auto twcc_ext = track->rtp_ext_ctx->changeRtpExtId(rtp, true, &rid, RtpExtType::transport_cc);

    if (twcc_ext) {
        _twcc_ctx.onRtp(ssrc, twcc_ext.getTransportCCSeq(), stamp_ms);
    }

    auto &ref = track->rtp_channel[rid];
    if (!ref) {
        _transport.createRtpChannel(rid, ssrc, *track);
    }

    // 解析并排序rtp
    ref->inputRtp(track->media->type, track->plan_rtp->sample_rate, (uint8_t *)buf, len, false);
}

重传包

void WrappedRtxTrack::inputRtp(const char *buf, size_t len, uint64_t stamp_ms, RtpHeader *rtp) {
    // 修改ext id至统一
    string rid;
    track->rtp_ext_ctx->changeRtpExtId(rtp, true, &rid, RtpExtType::transport_cc);

    auto &ref = track->rtp_channel[rid];
    if (!ref) {
        // 再接收到对应的rtp前,丢弃rtx包
        WarnL << "unknown rtx rtp, rid:" << rid << ", ssrc:" << ntohl(rtp->ssrc) << ", codec:" << track->plan_rtp->codec
              << ", seq:" << ntohs(rtp->seq);
        return;
    }

    // 这里是rtx重传包
    //  https://datatracker.ietf.org/doc/html/rfc4588#section-4
    auto payload = rtp->getPayloadData();
    auto size = rtp->getPayloadSize(len);
    if (size < 2) {
        return;
    }

    // 前两个字节是原始的rtp的seq
    auto origin_seq = payload[0] << 8 | payload[1];
    // rtx 转换为 rtp
    rtp->pt = track->plan_rtp->pt;
    rtp->seq = htons(origin_seq);
    rtp->ssrc = htonl(ref->getSSRC());

    memmove((uint8_t *)buf + 2, buf, payload - (uint8_t *)buf);
    buf += 2;
    len -= 2;
    ref->inputRtp(track->media->type, track->plan_rtp->sample_rate, (uint8_t *)buf, len, true);
}

处理包

    RtpPacket::Ptr inputRtp(TrackType type, int sample_rate, uint8_t *ptr, size_t len, bool is_rtx) {
        auto rtp = RtpTrack::inputRtp(type, sample_rate, ptr, len);
        if (!rtp) {
            return rtp;
        }
        auto seq = rtp->getSeq();
        _nack_ctx.received(seq, is_rtx);
        if (!is_rtx) {
            // 统计rtp接受情况,便于生成nack rtcp包
            _rtcp_context.onRtp(seq, rtp->getStamp(), rtp->ntp_stamp, sample_rate, len);
        }
        return rtp;
    }
相关文章
wireshark解析rtp协议,流媒体中的AMR/H263/H264包的方法
抓到完整的流媒体包之后,用wireshark打开,其中的包可能不会自动映射成RTP+AMR/H263/H264的包,做如下修改操作即可:1.  把UDP 包解析成RTP/RTCP包。选中UDP包,右键,选择Decode As,选RTP2.  把RTP Payload映射成实际的媒体格式。
2977 0
|
6月前
|
网络协议 API 网络安全
探讨TCP传输视频流并利用FFmpeg进行播放的过程
探讨TCP传输视频流并利用FFmpeg进行播放的过程
623 0
|
6月前
|
编解码 C语言
H264多播传输RTP包
H264多播传输RTP包
76 0
|
6月前
|
存储 网络协议 视频直播
音视频学习之rtsp学习rtp协议的理解(rtp)
音视频学习之rtsp学习rtp协议的理解(rtp)
114 0
|
搜索推荐 网络架构
RTP协议应用方案
RTP协议应用方案
86 0
|
定位技术 开发工具 Windows
如何在RTSP/RTMP直播过程中加入SEI扩展数据发送和接收解析
在直播系统中,除了直播音视频之外,有时候还想从主播端发布文本信息等,这些信息可以不通过视频传输通道发送给用户播放端,但如果传输的数据想和视频保持精准同步,那最好的办法就是这些信息和视频数据打包在一起传输,并通过h264 sei方式就可以把数据放入h264 Access Unit中传输。
288 0
|
编解码 网络协议 计算机视觉
ffmpeg推流rtmp指定udp传输
ffmpeg推流rtmp指定udp传输
620 0
|
存储 编解码 网络协议
音视频基础(网络传输): RTMP封包
RTMP 概念 与 HTTP(超文本传输协议)同样是一个基于 TCP 的 Real Time Messaging Protocol(实时消息传输协议)。由 Adobe Systems 公司为 Flash 播放器和服务器之间音频、视频和数据传输开发的一种开放协议 。在国内被广泛的应用于直播 领域。HTTP 默认端口为 80,RTMP 则为 1935。
262 0
音视频基础(网络传输): RTMP封包
|
编解码 小程序 算法
自己动手写RTP服务器——关于RTP协议
本文会带领着你一步步动手实现一个简单的RTP传输服务器,旨在了解RTP流媒体传输协议以及一些关于多媒体编解码的知识。   关于RTP协议的必备知识 要动手实现一个协议,当然首先需要阅读该协议的文档。
1886 0
|
Web App开发 存储 缓存