diff --git a/src/Extension/H264Rtp.cpp b/src/Extension/H264Rtp.cpp index 8836385f..2dac8cb7 100644 --- a/src/Extension/H264Rtp.cpp +++ b/src/Extension/H264Rtp.cpp @@ -195,13 +195,13 @@ H264RtpEncoder::H264RtpEncoder(uint32_t ui32Ssrc, void H264RtpEncoder::inputFrame(const Frame::Ptr &frame) { GET_CONFIG(uint32_t,cycleMS,Rtp::kCycleMS); auto ptr = frame->data() + frame->prefixSize(); - auto pts = frame->pts() % cycleMS; auto len = frame->size() - frame->prefixSize(); + auto pts = frame->pts() % cycleMS; auto nal_type = H264_TYPE(ptr[0]); - auto max_rtp_size = _ui32MtuSize - 2; + auto payload_size = _ui32MtuSize - 2; //超过MTU则按照FU-A模式打包 - if (len > max_rtp_size) { + if (len > payload_size + 1) { //最高位bit为forbidden_zero_bit, //后面2bit为nal_ref_idc(帧重要程度),00:可以丢,11:不能丢 //末尾5bit为nalu type,固定为28(FU-A) @@ -211,11 +211,10 @@ void H264RtpEncoder::inputFrame(const Frame::Ptr &frame) { bool mark_bit = false; int offset = 1; while (!mark_bit) { - if (len <= offset + max_rtp_size) { - //已经拆分结束 - max_rtp_size = len - offset; - mark_bit = true; + if (len <= offset + payload_size) { //FU-A end + mark_bit = true; + payload_size = len - offset; s_e_r_flags = (1 << 6) | nal_type; } else if (fu_a_start) { //FU-A start @@ -227,7 +226,7 @@ void H264RtpEncoder::inputFrame(const Frame::Ptr &frame) { { //传入nullptr先不做payload的内存拷贝 - auto rtp = makeRtp(getTrackType(), nullptr, max_rtp_size + 2, mark_bit, pts); + auto rtp = makeRtp(getTrackType(), nullptr, payload_size + 2, mark_bit, pts); //rtp payload 负载部分 uint8_t *payload = (uint8_t*)rtp->data() + rtp->offset; //FU-A 第1个字节 @@ -235,11 +234,11 @@ void H264RtpEncoder::inputFrame(const Frame::Ptr &frame) { //FU-A 第2个字节 payload[1] = s_e_r_flags; //H264 数据 - memcpy(payload + 2, (unsigned char *) ptr + offset, max_rtp_size); + memcpy(payload + 2, (unsigned char *) ptr + offset, payload_size); //输入到rtp环形缓存 RtpCodec::inputRtp(rtp, fu_a_start && nal_type == H264Frame::NAL_IDR); } - offset += max_rtp_size; + offset += payload_size; fu_a_start = false; } } else { diff --git a/src/Extension/H265Rtp.cpp b/src/Extension/H265Rtp.cpp index 461d8ed0..dc07b180 100644 --- a/src/Extension/H265Rtp.cpp +++ b/src/Extension/H265Rtp.cpp @@ -18,10 +18,10 @@ namespace mediakit{ //44 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ //45 |F| Type | LayerId | TID | //46 +-------------+-----------------+ -//48 F = 0 -//49 Type = 49 (fragmentation unit (FU)) -//50 LayerId = 0 -//51 TID = 1 +//48 F = 0, 1bit +//49 Type = 49 (fragmentation unit (FU)), 6bit +//50 LayerId = 0, 6bit +//51 TID = 1, 3bit //56 /* //57 create the FU header //58 @@ -29,7 +29,6 @@ namespace mediakit{ //60 +-+-+-+-+-+-+-+-+ //61 |S|E| FuType | //62 +---------------+ -//63 //64 S = variable //65 E = variable //66 FuType = NAL unit type @@ -150,40 +149,39 @@ H265RtpEncoder::H265RtpEncoder(uint32_t ui32Ssrc, } void H265RtpEncoder::inputFrame(const Frame::Ptr &frame) { - GET_CONFIG(uint32_t,cycleMS,Rtp::kCycleMS); - uint8_t *pcData = (uint8_t*)frame->data() + frame->prefixSize(); - auto uiStamp = frame->pts(); - auto iLen = frame->size() - frame->prefixSize(); - unsigned char naluType = H265_TYPE(pcData[0]); //获取NALU的5bit 帧类型 - uiStamp %= cycleMS; + GET_CONFIG(uint32_t, cycleMS, Rtp::kCycleMS); + auto ptr = (uint8_t *) frame->data() + frame->prefixSize(); + auto len = frame->size() - frame->prefixSize(); + auto pts = frame->pts() % cycleMS; + auto nal_type = H265_TYPE(ptr[0]); //获取NALU的5bit 帧类型 + auto payload_size = _ui32MtuSize - 3; - int maxSize = _ui32MtuSize - 3; //超过MTU,按照FU方式打包 - if (iLen > maxSize) { + if (len > payload_size + 2) { //获取帧头数据,1byte unsigned char s_e_flags; - bool bFirst = true; - bool mark = false; - int nOffset = 2; - while (!mark) { - if (iLen <= nOffset + maxSize) { //是否拆分结束 - maxSize = iLen - nOffset; - mark = true; + bool fu_start = true; + bool mark_bit = false; + int offset = 2; + while (!mark_bit) { + if (len <= offset + payload_size) { //FU end - s_e_flags = (1 << 6) | naluType; - } else if (bFirst) { + mark_bit = true; + payload_size = len - offset; + s_e_flags = (1 << 6) | nal_type; + } else if (fu_start) { //FU start - s_e_flags = (1 << 7) | naluType; + s_e_flags = (1 << 7) | nal_type; } else { //FU mid - s_e_flags = naluType; + s_e_flags = nal_type; } { //传入nullptr先不做payload的内存拷贝 - auto rtp = makeRtp(getTrackType(), nullptr, maxSize + 3, mark, uiStamp); + auto rtp = makeRtp(getTrackType(), nullptr, payload_size + 3, mark_bit, pts); //rtp payload 负载部分 - uint8_t *payload = (uint8_t*)rtp->data() + rtp->offset; + uint8_t *payload = (uint8_t *) rtp->data() + rtp->offset; //FU 第1个字节,表明为FU payload[0] = 49 << 1; //FU 第2个字节貌似固定为1 @@ -191,16 +189,16 @@ void H265RtpEncoder::inputFrame(const Frame::Ptr &frame) { //FU 第3个字节 payload[2] = s_e_flags; //H265 数据 - memcpy(payload + 3,pcData + nOffset, maxSize); + memcpy(payload + 3, ptr + offset, payload_size); //输入到rtp环形缓存 - RtpCodec::inputRtp(rtp,bFirst && H265Frame::isKeyFrame(naluType)); + RtpCodec::inputRtp(rtp, fu_start && H265Frame::isKeyFrame(nal_type)); } - nOffset += maxSize; - bFirst = false; + offset += payload_size; + fu_start = false; } } else { - makeH265Rtp(naluType,pcData, iLen, false, true, uiStamp); + makeH265Rtp(nal_type, ptr, len, false, true, pts); } }