//如果视频帧的大小大于rtp的最大payloadSize,则调用此方法通过拆分视频帧到多个rtp包的方式发送。
int32_t yang_push_h264_package_fu_a(YangRtcSession *session, YangPushH264Rtp *rtp,
YangFrame *videoFrame, int32_t fu_payload_size) {
int32_t err = Yang_Ok;
//拿到videoFrame的size
int32_t plen = videoFrame->nb;
//拿到videoFrame的payload
uint8_t *pdata = videoFrame->payload;
//指向第二个字符开始的数据。
char *p = (char*) pdata + 1;
//将长度减一
int32_t nb_left = plen - 1;
//拿到payload的第一个字节数据。
uint8_t header = pdata[0];
//通过获取指定位的方式拿到nalType
uint8_t nal_type = header & kNalTypeMask;
//通过除以最大rtpsize和取最大rtpsize得到视频帧要拆分为几个rtp包进行发送。
int32_t num_of_packet = ((plen - 1) % fu_payload_size==0)?0:1 + (plen - 1) / fu_payload_size;
//循环处理每个packet
for (int32_t i = 0; i < num_of_packet; ++i) {
//得到要发送的包大小,除了最后一个包之外,其他的都是最大rtpsize,最后一个包则为实际剩余包大小。
int32_t packet_size = yang_min(nb_left, fu_payload_size);
//重置videoFuaPacket
yang_reset_rtpPacket(&rtp->videoFuaPacket);
//设置payloadType为h264
rtp->videoFuaPacket.header.payload_type = YangH264PayloadType;
//设置ssrc
rtp->videoFuaPacket.header.ssrc = rtp->videoSsrc;
//设置帧类型为视频。
rtp->videoFuaPacket.frame_type = YangFrameTypeVideo;
//设置sequence
rtp->videoFuaPacket.header.sequence = rtp->videoSeq++;
//设置时间戳为视频帧的显示时间戳。
rtp->videoFuaPacket.header.timestamp = videoFrame->pts;
//最后一个包的话marker设置为1,其他包设置为0,表示是否是一帧的最后一个包。
rtp->videoFuaPacket.header.marker = (i == num_of_packet - 1) ? 1 : 0;
//设置payloadType为FUA2类型。
rtp->videoFuaPacket.payload_type = YangRtspPacketPayloadTypeFUA2;
//将videoFua2Data数据清零
memset(&rtp->videoFua2Data, 0, sizeof(YangFua2H264Data));
//设置videoFua2Data的nri为视频帧的首个字节
rtp->videoFua2Data.nri = (YangAvcNaluType) header;
//设置videoFua2Data的nalu_type为视频帧的首个字节中按位与取出的nalType
rtp->videoFua2Data.nalu_type = (YangAvcNaluType) nal_type;
//此字段标识是否是视频帧的第一个包。
rtp->videoFua2Data.start = (i == 0) ? 1 : 0;
//此字段标识是否是视频帧的最后一个包。
rtp->videoFua2Data.end = (i == (num_of_packet - 1)) ? 1 : 0;
//将videoFua2Data.payload指针指向rtp->videoBuf。
rtp->videoFua2Data.payload = rtp->videoBuf;
//设置videoFua2Data的size为包size
rtp->videoFua2Data.nb = packet_size;
//将p指向的视频帧拷贝包size大小的数据到videoFua2Data.payload中。
memcpy(rtp->videoFua2Data.payload, p, packet_size);
//将p指针向后偏移包size的大小。
p += packet_size;
//从nb_left中减去此包的size。
nb_left -= packet_size;
//调用yang_push_h264_encodeVideo方法发送rtp包给p2p对端。
if ((err = yang_push_h264_encodeVideo(session, rtp, &rtp->videoFuaPacket))
!= Yang_Ok) {
return yang_error_wrap(err, "encode packet");
}
rtp->videoFuaPacket.header.extensions=NULL;
}
return err;
}