From e13ae419ae5ed5957169a8ce9ea5e8f88419efa8 Mon Sep 17 00:00:00 2001 From: xiongziliang <771730766@qq.com> Date: Thu, 1 Aug 2019 14:39:09 +0800 Subject: [PATCH] =?UTF-8?q?=E7=B2=BE=E7=AE=80H264Frame=E5=AF=B9=E8=B1=A1?= =?UTF-8?q?=EF=BC=8C=E5=88=A0=E9=99=A4=E5=A4=9A=E4=BD=99=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 3rdpart/media-server | 2 +- src/Extension/H264.h | 6 +---- src/Extension/H264Rtmp.cpp | 1 - src/Extension/H264Rtp.cpp | 46 ++++++++++++++++++-------------------- src/Extension/H264Rtp.h | 1 + 5 files changed, 25 insertions(+), 31 deletions(-) diff --git a/3rdpart/media-server b/3rdpart/media-server index e399b938..a32fe104 160000 --- a/3rdpart/media-server +++ b/3rdpart/media-server @@ -1 +1 @@ -Subproject commit e399b93802610dcf574ff64bcb7677572cd028c1 +Subproject commit a32fe104c0290bc01a7ee73d50b568e8d9ded931 diff --git a/src/Extension/H264.h b/src/Extension/H264.h index 400f5474..54e28e07 100644 --- a/src/Extension/H264.h +++ b/src/Extension/H264.h @@ -80,13 +80,11 @@ public: } bool keyFrame() const override { - return type == NAL_IDR; + return H264_TYPE(buffer[iPrefixSize]) == H264Frame::NAL_IDR; } public: - uint16_t sequence; uint32_t timeStamp; uint32_t ptsStamp = 0; - unsigned char type; string buffer; uint32_t iPrefixSize = 4; }; @@ -326,7 +324,6 @@ private: if(!_sps.empty()){ auto spsFrame = std::make_shared(); - spsFrame->type = H264Frame::NAL_SPS; spsFrame->iPrefixSize = 4; spsFrame->buffer.assign("\x0\x0\x0\x1",4); spsFrame->buffer.append(_sps); @@ -336,7 +333,6 @@ private: if(!_pps.empty()){ auto ppsFrame = std::make_shared(); - ppsFrame->type = H264Frame::NAL_PPS; ppsFrame->iPrefixSize = 4; ppsFrame->buffer.assign("\x0\x0\x0\x1",4); ppsFrame->buffer.append(_pps); diff --git a/src/Extension/H264Rtmp.cpp b/src/Extension/H264Rtmp.cpp index 9ff10e27..2f56b9e6 100644 --- a/src/Extension/H264Rtmp.cpp +++ b/src/Extension/H264Rtmp.cpp @@ -80,7 +80,6 @@ bool H264RtmpDecoder::decodeRtmp(const RtmpPacket::Ptr &pkt) { inline void H264RtmpDecoder::onGetH264(const char* pcData, int iLen, uint32_t dts,uint32_t pts) { #if 1 - _h264frame->type = H264_TYPE(pcData[0]); _h264frame->timeStamp = dts; _h264frame->ptsStamp = pts; _h264frame->buffer.assign("\x0\x0\x0\x1", 4); //添加264头 diff --git a/src/Extension/H264Rtp.cpp b/src/Extension/H264Rtp.cpp index 7dd58c47..51581c6c 100644 --- a/src/Extension/H264Rtp.cpp +++ b/src/Extension/H264Rtp.cpp @@ -100,12 +100,10 @@ bool H264RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) { //a full frame _h264frame->buffer.assign("\x0\x0\x0\x1", 4); _h264frame->buffer.append((char *)frame, length); - _h264frame->type = nal.type; _h264frame->timeStamp = rtppack->timeStamp; - _h264frame->sequence = rtppack->sequence; - auto isIDR = _h264frame->type == H264Frame::NAL_IDR; + auto key = _h264frame->keyFrame(); onGetH264(_h264frame); - return (isIDR); //i frame + return (key); //i frame } switch (nal.type){ @@ -131,9 +129,7 @@ bool H264RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) { MakeNalu(ptr[0], nal); _h264frame->buffer.assign("\x0\x0\x0\x1", 4); _h264frame->buffer.append((char *)ptr, len); - _h264frame->type = nal.type; _h264frame->timeStamp = rtppack->timeStamp; - _h264frame->sequence = rtppack->sequence; if(nal.type == H264Frame::NAL_IDR){ haveIDR = true; } @@ -148,35 +144,39 @@ bool H264RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) { //FU-A FU fu; MakeFU(frame[1], fu); - if (fu.S == 1) { - //FU-A start + if (fu.S) { + //该帧的第一个rtp包 char tmp = (nal.forbidden_zero_bit << 7 | nal.nal_ref_idc << 5 | fu.type); _h264frame->buffer.assign("\x0\x0\x0\x1", 4); _h264frame->buffer.push_back(tmp); _h264frame->buffer.append((char *)frame + 2, length - 2); - _h264frame->type = fu.type; _h264frame->timeStamp = rtppack->timeStamp; - _h264frame->sequence = rtppack->sequence; - return (_h264frame->type == H264Frame::NAL_IDR); //i frame + //该函数return时,保存下当前sequence,以便下次对比seq是否连续 + _lastSeq = rtppack->sequence; + return _h264frame->keyFrame(); } - if (rtppack->sequence != (uint16_t)(_h264frame->sequence + 1)) { + if (rtppack->sequence != _lastSeq + 1 && rtppack->sequence != 0) { + //中间的或末尾的rtp包,其seq必须连续(如果回环了则判定为连续),否则说明rtp丢包,那么该帧不完整,必须得丢弃 _h264frame->buffer.clear(); - WarnL << "丢包,帧废弃:" << rtppack->sequence << "," << _h264frame->sequence; + WarnL << "rtp sequence不连续: " << rtppack->sequence << " != " << _lastSeq << " + 1,该帧被废弃"; return false; } - _h264frame->sequence = rtppack->sequence; - if (fu.E == 1) { - //FU-A end + + if (!fu.E) { + //该帧的中间rtp包 _h264frame->buffer.append((char *)frame + 2, length - 2); - _h264frame->timeStamp = rtppack->timeStamp; - auto isIDR = _h264frame->type == H264Frame::NAL_IDR; - onGetH264(_h264frame); - return isIDR; + //该函数return时,保存下当前sequence,以便下次对比seq是否连续 + _lastSeq = rtppack->sequence; + return false; } - //FU-A mid + + //该帧最后一个rtp包 _h264frame->buffer.append((char *)frame + 2, length - 2); - return false; + _h264frame->timeStamp = rtppack->timeStamp; + auto key = _h264frame->keyFrame(); + onGetH264(_h264frame); + return key; } default:{ @@ -195,10 +195,8 @@ bool H264RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtppack) { void H264RtpDecoder::onGetH264(const H264Frame::Ptr &frame) { //写入环形缓存 - auto lastSeq = _h264frame->sequence; RtpCodec::inputFrame(frame); _h264frame = obtainFrame(); - _h264frame->sequence = lastSeq; } diff --git a/src/Extension/H264Rtp.h b/src/Extension/H264Rtp.h index 4719fe3a..09f2346d 100644 --- a/src/Extension/H264Rtp.h +++ b/src/Extension/H264Rtp.h @@ -64,6 +64,7 @@ private: H264Frame::Ptr obtainFrame(); private: H264Frame::Ptr _h264frame; + int _lastSeq = 0; }; /**