live5 数据发送及封装

1. live 555 数据发送流程

每一行类及重要函数

SPServer::RTSPClientSession::handleCmd_PLAY ->subsession->startStream
OnDemandServerMediaSubsession::startStream->->streamState->startPlaying
StreamState::startPlaying->fRTPSink->startPlaying
MediaSink::startPlaying->continuePlaying()
H264or5VideoRTPSink::continuePlaying()
MultiFramedRTPSink::continuePlaying()->buildAndSendPacket->RTP封装h264数据
MultiFramedRTPSink::buildAndSendPacket->packFrame()
MultiFramedRTPSink::packFrame()->fSource->getNextFrame
FramedSource::getNextFrame ->doGetNextFrame()
H264or5Fragmenter::doGetNextFrame()->fInputSource->getNextFrame
FramedSource::getNextFrame ->doGetNextFrame()
ByteStreamFileSource::doGetNextFrame()->doReadFromFile()
ByteStreamFileSource::doReadFromFile()-> fFrameSize = read(fileno(fFid), fTo, fMaxSize)->FramedSource::afterGetting(this)
H264or5Fragmenter::afterGettingFrame->afterGettingFrame1->doGetNextFrame(分支)->FramedSource::afterGetting(this);
MultiFramedRTPSink::afterGettingFrame->afterGettingFrame1->sendPacketIfNecessary();
MultiFramedRTPSink::sendPacketIfNecessary()->fRTPInterface.sendPacket->nextTask() = envir().taskScheduler().scheduleDelayedTask(uSecondsToGo, (TaskFunc*)sendNext, this);
MultiFramedRTPSink::sendNext->buildAndSendPacket RTP数据封装

附一张网上流程图





2.  buildAndSendPacket  rtp封装数据

RTP packet的结构如下:

RTP Header:RTP 包的头部
contributing sources:个数为0-n个,所以可以为空。具体定义参考rfc3550
RTP payload:即RTP要传输的数据
RTP Header
这是RTP流的头部,在网上搜索RTP格式,就会搜到很多文章介绍这个头部的定义。我们这里参考rfc3550的定义,在5.1节(http://tools.ietf.org/html/rfc3550#section-5.1)。

    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |V=2|P|X|  CC   |M|     PT      |       sequence number         |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                           timestamp                           |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |           synchronization source (SSRC) identifier            |
   +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
   |            contributing source (CSRC) identifiers             |
   |                             ....                              |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

每行是32 bits,由此可以直观看到每个表示部分所占的位数。简单介绍一下:

V(version):2 bits,RTP的版本,这里统一为2

P(padding):1 bit,如果置1,在packet的末尾被填充,填充有时是方便一些针对固定长度的算法的封装

X(extension):1 bit,如果置1,在RTP Header会跟着一个header extension

CC(CSRC count): 4 bits,表示头部后contributing sources的个数

M(marker): 1 bit,具体这位的定义会在一个profile里

PT(playload type): 7 bits,表示所传输的多媒体的类型,对应的编号在另一份文档rfc3551中有列出(http://tools.ietf.org/html/rfc3551)

sequence number: 16 bits,每个RTP packet的sequence number会自动加一,以便接收端检测丢包情况

timestamp: 32 bits,时间戳

SSRC: 32 bits,同步源的id,没两个同步源的id不能相同

CSRC: 上文说到,个数由CC指定,范围是0-15

live 会在数据封装12字节的头





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
WinPcap 是一个 Windows 平台下的网络抓包工具,它可以捕获网络数据包,并提供了一组 API,允许应用程序读取和发送网络数据包。通过使用 WinPcap,可以实现 ARP/ICMP/TCP 协议数据封装发送,具体步骤如下: 1. 创建一个 WinPcap 句柄,用于捕获和发送数据包。 2. 构造数据帧的头部信息,包括目的 MAC 地址、源 MAC 地址、以太网类型等。 3. 构造 ARP/ICMP/TCP 协议的数据,并将其添加到数据帧的数据区中。 4. 将数据发送到目标计算机的网卡上。 具体实现过程需要使用 WinPcap 的 API,以下是一个简单的示例代码: ```c++ #include <winpcap.h> int main() { // 创建 WinPcap 句柄 pcap_t *pcap_handle = pcap_open_live("eth0", 65535, 1, 1000, errbuf); // 构造数据帧头部信息 struct ether_header eth_header; eth_header.ether_dhost[0] = 0x00; eth_header.ether_dhost[1] = 0x11; eth_header.ether_dhost[2] = 0x22; eth_header.ether_dhost[3] = 0x33; eth_header.ether_dhost[4] = 0x44; eth_header.ether_dhost[5] = 0x55; eth_header.ether_shost[0] = 0x00; eth_header.ether_shost[1] = 0x11; eth_header.ether_shost[2] = 0x22; eth_header.ether_shost[3] = 0x33; eth_header.ether_shost[4] = 0x44; eth_header.ether_shost[5] = 0x66; eth_header.ether_type = htons(0x0800); // 构造 TCP 数据 struct tcphdr tcp_header; // ... // 构造数据帧 char packet[ETH_HEADER_LEN + TCP_HEADER_LEN + PAYLOAD_LEN]; memcpy(packet, &eth_header, ETH_HEADER_LEN); memcpy(packet + ETH_HEADER_LEN, &tcp_header, TCP_HEADER_LEN); memcpy(packet + ETH_HEADER_LEN + TCP_HEADER_LEN, payload, PAYLOAD_LEN); // 发送数据帧 pcap_sendpacket(pcap_handle, packet, ETH_HEADER_LEN + TCP_HEADER_LEN + PAYLOAD_LEN); // 关闭 WinPcap 句柄 pcap_close(pcap_handle); return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值