mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-29 22:55:52 +08:00
Merge branch 'dev' of https://gitee.com/xiongguangjie/ZLMediaKit into dev
This commit is contained in:
commit
46e3538dca
@ -189,8 +189,52 @@ void H264RtpEncoder::inputFrame(const Frame::Ptr &frame) {
|
|||||||
auto len = frame->size() - frame->prefixSize();
|
auto len = frame->size() - frame->prefixSize();
|
||||||
auto pts = frame->pts();
|
auto pts = frame->pts();
|
||||||
auto nal_type = H264_TYPE(ptr[0]);
|
auto nal_type = H264_TYPE(ptr[0]);
|
||||||
auto packet_size = getMaxSize() - 2;
|
if(nal_type == H264Frame::NAL_SEI || nal_type == H264Frame::NAL_AUD){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(nal_type == H264Frame::NAL_SPS){
|
||||||
|
_sps = std::string(ptr,len);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(nal_type == H264Frame::NAL_PPS){
|
||||||
|
_pps = std::string(ptr,len);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!_last_frame){
|
||||||
|
_last_frame = frame;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 上一帧打包,保证rtp 的mark是正确的
|
||||||
|
bool isMark = _last_frame->pts() != frame->pts();
|
||||||
|
ptr = _last_frame->data() + _last_frame->prefixSize();
|
||||||
|
len = _last_frame->size() - _last_frame->prefixSize();
|
||||||
|
pts = _last_frame->pts();
|
||||||
|
nal_type = H264_TYPE(ptr[0]);
|
||||||
|
if(nal_type == H264Frame::NAL_IDR && (ptr[1]&0x80))
|
||||||
|
{// 保证每一个I帧前都有SPS与PPS ,为了兼容webrtc 需要在一个rtp包中,并且只能是 STAP-A
|
||||||
|
// https://blog.csdn.net/momo0853/article/details/88872873
|
||||||
|
// 多slice 一帧的情况下检查 first_mb_in_slice 是否为0 表示其为一帧的开始,SPS PPS 只有在帧开始时,才插入
|
||||||
|
auto rtp = makeRtp(getTrackType(), nullptr,_sps.size()+_pps.size()+2*2+1,false,pts);
|
||||||
|
uint8_t *payload = rtp->getPayload();
|
||||||
|
payload[0] = 24;
|
||||||
|
payload[1] = _sps.size() >> 8;
|
||||||
|
payload[2] = _sps.size() & 0xff;
|
||||||
|
memcpy(payload+3,(uint8_t *) _sps.data(),_sps.size());
|
||||||
|
|
||||||
|
payload[_sps.size()+3] = _pps.size() >> 8;
|
||||||
|
payload[_sps.size()+4] = _pps.size() & 0xff;
|
||||||
|
|
||||||
|
memcpy(payload+3+_sps.size()+2,(uint8_t *) _pps.data(),_pps.size());
|
||||||
|
RtpCodec::inputRtp(rtp,true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
auto packet_size = getMaxSize() - 2;
|
||||||
|
//InfoL<<"nal type = "<<nal_type<<" pts="<<pts<<" len="<<len;
|
||||||
//末尾5bit为nalu type,固定为28(FU-A)
|
//末尾5bit为nalu type,固定为28(FU-A)
|
||||||
auto fu_char_0 = (ptr[0] & (~0x1F)) | 28;
|
auto fu_char_0 = (ptr[0] & (~0x1F)) | 28;
|
||||||
auto fu_char_1 = nal_type;
|
auto fu_char_1 = nal_type;
|
||||||
@ -208,7 +252,7 @@ void H264RtpEncoder::inputFrame(const Frame::Ptr &frame) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//传入nullptr先不做payload的内存拷贝
|
//传入nullptr先不做payload的内存拷贝
|
||||||
auto rtp = makeRtp(getTrackType(), nullptr, packet_size + 2, fu_flags->end_bit, pts);
|
auto rtp = makeRtp(getTrackType(), nullptr, packet_size + 2, fu_flags->end_bit && isMark, pts);
|
||||||
//rtp payload 负载部分
|
//rtp payload 负载部分
|
||||||
uint8_t *payload = rtp->getPayload();
|
uint8_t *payload = rtp->getPayload();
|
||||||
//FU-A 第1个字节
|
//FU-A 第1个字节
|
||||||
@ -218,15 +262,25 @@ void H264RtpEncoder::inputFrame(const Frame::Ptr &frame) {
|
|||||||
//H264 数据
|
//H264 数据
|
||||||
memcpy(payload + 2, (uint8_t *) ptr + offset, packet_size);
|
memcpy(payload + 2, (uint8_t *) ptr + offset, packet_size);
|
||||||
//输入到rtp环形缓存
|
//输入到rtp环形缓存
|
||||||
RtpCodec::inputRtp(rtp, fu_flags->start_bit && nal_type == H264Frame::NAL_IDR);
|
RtpCodec::inputRtp(rtp, false);
|
||||||
|
|
||||||
offset += packet_size;
|
offset += packet_size;
|
||||||
fu_flags->start_bit = 0;
|
fu_flags->start_bit = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//如果帧长度不超过mtu, 则按照Single NAL unit packet per H.264 方式打包
|
//如果帧长度不超过mtu, 则按照Single NAL unit packet per H.264 方式打包
|
||||||
makeH264Rtp(ptr, len, false, false, pts);
|
//为了兼容性 webrtc使用 STAP-A 打包
|
||||||
|
auto rtp = makeRtp(getTrackType(), nullptr,len+3,isMark,pts);
|
||||||
|
uint8_t *payload = rtp->getPayload();
|
||||||
|
payload[0] = (ptr[0] & (~0x1F)) | 24;
|
||||||
|
payload[1] = len >> 8;
|
||||||
|
payload[2] = len & 0xff;
|
||||||
|
memcpy(payload+3,(uint8_t *) ptr,len);
|
||||||
|
RtpCodec::inputRtp(rtp,false);
|
||||||
|
//makeH264Rtp(ptr, len, false, false, pts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_last_frame = frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
void H264RtpEncoder::makeH264Rtp(const void* data, size_t len, bool mark, bool gop_pos, uint32_t uiStamp) {
|
void H264RtpEncoder::makeH264Rtp(const void* data, size_t len, bool mark, bool gop_pos, uint32_t uiStamp) {
|
||||||
|
@ -83,6 +83,9 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void makeH264Rtp(const void *pData, size_t uiLen, bool bMark, bool gop_pos, uint32_t uiStamp);
|
void makeH264Rtp(const void *pData, size_t uiLen, bool bMark, bool gop_pos, uint32_t uiStamp);
|
||||||
|
string _sps;
|
||||||
|
string _pps;
|
||||||
|
Frame::Ptr _last_frame;
|
||||||
};
|
};
|
||||||
|
|
||||||
}//namespace mediakit{
|
}//namespace mediakit{
|
||||||
|
Loading…
Reference in New Issue
Block a user