From ca192a4286a37a153225a34454bf21a8c5568c16 Mon Sep 17 00:00:00 2001 From: baiyfcu Date: Wed, 9 Jun 2021 09:51:28 +0800 Subject: [PATCH] =?UTF-8?q?H265=20I=E5=B8=A7=E5=A4=9Aslice=E6=83=85?= =?UTF-8?q?=E5=86=B5=E4=B8=8B=E5=AF=BC=E8=87=B4=E8=8A=B1=E5=B1=8F=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit H265 I帧分片多包情况下,GPO缓冲只保存了I帧最后一个分片导致花屏 --- src/Extension/H265.cpp | 25 +++++++++++++++++++------ src/Extension/H265.h | 2 +- src/Extension/H265Rtp.cpp | 6 +++--- src/Rtmp/RtmpSession.cpp | 1 - 4 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/Extension/H265.cpp b/src/Extension/H265.cpp index 48132a1d..23177030 100644 --- a/src/Extension/H265.cpp +++ b/src/Extension/H265.cpp @@ -51,7 +51,7 @@ bool getHEVCInfo(const string &strVps, const string &strSps, int &iVideoWidth, i ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool H265Frame::keyFrame() const { - return isKeyFrame(H265_TYPE(_buffer[_prefix_size])); + return isKeyFrame(H265_TYPE(_buffer[_prefix_size]), _buffer.data(), _prefix_size); } bool H265Frame::configFrame() const { @@ -63,9 +63,22 @@ bool H265Frame::configFrame() const { } } -bool H265Frame::isKeyFrame(int type) { - return type >= NAL_BLA_W_LP && type <= NAL_RSV_IRAP_VCL23; -} +bool H265Frame::isKeyFrame(int type, const char* ptr, uint32_t prefix_size) { + if (nullptr != ptr) + { + if (type == NAL_IDR_W_RADL) + { + uint32_t r = 0; + r = ((*((uint8_t*)ptr + prefix_size + 2)) >> 7) & 0x01; + if (r == 1) + return true; + else + return false; + }else + return type >= NAL_BLA_W_LP && type <= NAL_RSV_IRAP_VCL23; + } + return type >= NAL_BLA_W_LP && type <= NAL_RSV_IRAP_VCL23; + } H265Frame::H265Frame(){ _codec_id = CodecH265; @@ -83,7 +96,7 @@ H265FrameNoCacheAble::H265FrameNoCacheAble(char *ptr, size_t size, uint32_t dts, } bool H265FrameNoCacheAble::keyFrame() const { - return H265Frame::isKeyFrame(H265_TYPE(((uint8_t *) _ptr)[_prefix_size])); + return H265Frame::isKeyFrame(H265_TYPE(((uint8_t *) _ptr)[_prefix_size]), _ptr, _prefix_size); } bool H265FrameNoCacheAble::configFrame() const { @@ -152,7 +165,7 @@ void H265Track::inputFrame(const Frame::Ptr &frame) { void H265Track::inputFrame_l(const Frame::Ptr &frame) { int type = H265_TYPE(((uint8_t *) frame->data() + frame->prefixSize())[0]); - if (H265Frame::isKeyFrame(type)) { + if (H265Frame::isKeyFrame(type, frame->data(), frame->prefixSize())) { insertConfigFrame(frame); VideoTrack::inputFrame(frame); _is_idr = true; diff --git a/src/Extension/H265.h b/src/Extension/H265.h index c9dc671a..2d1fad49 100644 --- a/src/Extension/H265.h +++ b/src/Extension/H265.h @@ -61,7 +61,7 @@ public: bool keyFrame() const override; bool configFrame() const override; - static bool isKeyFrame(int type); + static bool isKeyFrame(int type, const char* ptr, uint32_t prefix_size); protected: friend class FrameImp; diff --git a/src/Extension/H265Rtp.cpp b/src/Extension/H265Rtp.cpp index 262ba347..0a947a98 100644 --- a/src/Extension/H265Rtp.cpp +++ b/src/Extension/H265Rtp.cpp @@ -263,13 +263,13 @@ void H265RtpEncoder::inputFrame(const Frame::Ptr &frame) { //FU 第1个字节,表明为FU payload[0] = 49 << 1; //FU 第2个字节貌似固定为1 - payload[1] = 1; + payload[1] = ptr[1];// 1; //FU 第3个字节 payload[2] = s_e_flags; //H265 数据 memcpy(payload + 3, ptr + offset, max_size); //输入到rtp环形缓存 - RtpCodec::inputRtp(rtp, fu_start && H265Frame::isKeyFrame(nal_type)); + RtpCodec::inputRtp(rtp, fu_start && H265Frame::isKeyFrame(nal_type, frame->data(), frame->prefixSize())); } offset += max_size; @@ -281,7 +281,7 @@ void H265RtpEncoder::inputFrame(const Frame::Ptr &frame) { } void H265RtpEncoder::makeH265Rtp(int nal_type,const void* data, size_t len, bool mark, bool first_packet, uint32_t uiStamp) { - RtpCodec::inputRtp(makeRtp(getTrackType(),data,len,mark,uiStamp),first_packet && H265Frame::isKeyFrame(nal_type)); + RtpCodec::inputRtp(makeRtp(getTrackType(),data,len,mark,uiStamp),first_packet && H265Frame::isKeyFrame(nal_type, (const char*)data, prefixSize((const char*)data, len))); } }//namespace mediakit diff --git a/src/Rtmp/RtmpSession.cpp b/src/Rtmp/RtmpSession.cpp index 7775c553..7591ff63 100644 --- a/src/Rtmp/RtmpSession.cpp +++ b/src/Rtmp/RtmpSession.cpp @@ -499,7 +499,6 @@ void RtmpSession::onRtmpChunk(RtmpPacket::Ptr packet) { void RtmpSession::onCmd_seek(AMFDecoder &dec) { dec.load();/* NULL */ AMFValue status(AMF_OBJECT); - AMFEncoder invoke; status.set("level", "status"); status.set("code", "NetStream.Seek.Notify"); status.set("description", "Seeking.");