From 5b8b5c0ed56caa7371cd7208b87607b783e557e1 Mon Sep 17 00:00:00 2001 From: xgj Date: Fri, 11 Jun 2021 11:04:43 +0800 Subject: [PATCH 1/6] for ssl static link add ld library link --- CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 54bfed8a..3329bdf4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -87,6 +87,10 @@ if (OPENSSL_FOUND AND ENABLE_OPENSSL) include_directories(${OPENSSL_INCLUDE_DIR}) add_definitions(-DENABLE_OPENSSL) list(APPEND LINK_LIB_LIST ${OPENSSL_LIBRARIES}) + if (CMAKE_SYSTEM_NAME MATCHES "Linux") + list(APPEND LINK_LIB_LIST dl) + endif() + else() message(WARNING "openssl未找到,rtmp将不支持flash播放器,https/wss/rtsps/rtmps也将失效") endif () From 98d9dcd0098afe8d67e46925a9c3bc88cb15c305 Mon Sep 17 00:00:00 2001 From: xgj Date: Fri, 11 Jun 2021 11:57:55 +0800 Subject: [PATCH 2/6] when link ssl with static library add ld link like this cmake .. -DCMAKE_BUILD_TYPE=Release -DOPENSSL_ROOT_DIR=/usr/local/ssl -DOPENSSL_USE_STATIC_LIBS=TRUE --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3329bdf4..b3a53a41 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -87,7 +87,7 @@ if (OPENSSL_FOUND AND ENABLE_OPENSSL) include_directories(${OPENSSL_INCLUDE_DIR}) add_definitions(-DENABLE_OPENSSL) list(APPEND LINK_LIB_LIST ${OPENSSL_LIBRARIES}) - if (CMAKE_SYSTEM_NAME MATCHES "Linux") + if (CMAKE_SYSTEM_NAME MATCHES "Linux" AND OPENSSL_USE_STATIC_LIBS) list(APPEND LINK_LIB_LIST dl) endif() From 1920802764d7eb50e2cb87c4cfea79b314c31635 Mon Sep 17 00:00:00 2001 From: xgj Date: Thu, 17 Jun 2021 18:08:35 +0800 Subject: [PATCH 3/6] for h264 multi slice on frame compatibility --- src/Extension/Frame.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Extension/Frame.cpp b/src/Extension/Frame.cpp index b43206db..61b6d613 100644 --- a/src/Extension/Frame.cpp +++ b/src/Extension/Frame.cpp @@ -191,9 +191,12 @@ bool FrameMerger::willFlush(const Frame::Ptr &frame) const{ } switch (frame->getCodecId()) { case CodecH264 : { - if (H264_TYPE(frame->data()[frame->prefixSize()]) == H264Frame::NAL_B_P) { - //如果是264的b/p帧,那么也刷新输出 + if (frame->data()[frame->prefixSize()+1]&0x80 !=0) { + //264 新一帧的开始,刷新输出 return true; + }else{ + // 不刷新输出 + return false; } break; } From 3429690d75cb0702eec6255bf0ec661d59f27bdd Mon Sep 17 00:00:00 2001 From: xgj Date: Thu, 17 Jun 2021 19:26:58 +0800 Subject: [PATCH 4/6] for h264 pps sps aud sei not check first_mb_in_slice --- src/Extension/Frame.cpp | 3 ++- src/Extension/H264Rtmp.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Extension/Frame.cpp b/src/Extension/Frame.cpp index 61b6d613..5864908b 100644 --- a/src/Extension/Frame.cpp +++ b/src/Extension/Frame.cpp @@ -191,7 +191,8 @@ bool FrameMerger::willFlush(const Frame::Ptr &frame) const{ } switch (frame->getCodecId()) { case CodecH264 : { - if (frame->data()[frame->prefixSize()+1]&0x80 !=0) { + auto type = H264_TYPE(frame->data()[frame->prefixSize()]); + if (frame->data()[frame->prefixSize()+1]&0x80 !=0 && type >=H264Frame::NAL_B_P && type<=H264Frame::NAL_IDR ) {// sei aud pps sps 不判断 //264 新一帧的开始,刷新输出 return true; }else{ diff --git a/src/Extension/H264Rtmp.cpp b/src/Extension/H264Rtmp.cpp index 19152a6f..47f5192e 100644 --- a/src/Extension/H264Rtmp.cpp +++ b/src/Extension/H264Rtmp.cpp @@ -183,7 +183,7 @@ void H264RtmpEncoder::inputFrame(const Frame::Ptr &frame) { } } - if(_lastPacket && (_lastPacket->time_stamp != frame->dts() || pcData[1]&0x80 != 0)) { + if(_lastPacket && (_lastPacket->time_stamp != frame->dts() || (pcData[1]&0x80 != 0 && type>=H264Frame::NAL_B_P && type<=H264Frame::NAL_IDR))) { RtmpCodec::inputRtmp(_lastPacket); _lastPacket = nullptr; } From a6e9652da843f111f0232ff9494a40f12b62e9b0 Mon Sep 17 00:00:00 2001 From: xgj Date: Fri, 18 Jun 2021 12:40:42 +0800 Subject: [PATCH 5/6] for h264/h265 judge a frame start more safe(h264 is first_mb_in_slice h265 is first_slice_segment_in_pic_flag) and for h265 only idr is key frame --- src/Extension/Frame.cpp | 9 ++++++--- src/Extension/H264Rtmp.cpp | 2 +- src/Extension/H265.cpp | 7 ++++--- src/Extension/H265Rtmp.cpp | 2 +- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/Extension/Frame.cpp b/src/Extension/Frame.cpp index 5864908b..f51f5945 100644 --- a/src/Extension/Frame.cpp +++ b/src/Extension/Frame.cpp @@ -192,7 +192,7 @@ bool FrameMerger::willFlush(const Frame::Ptr &frame) const{ switch (frame->getCodecId()) { case CodecH264 : { auto type = H264_TYPE(frame->data()[frame->prefixSize()]); - if (frame->data()[frame->prefixSize()+1]&0x80 !=0 && type >=H264Frame::NAL_B_P && type<=H264Frame::NAL_IDR ) {// sei aud pps sps 不判断 + if ((frame->data()[frame->prefixSize()+1]&0x80) !=0 && type >=H264Frame::NAL_B_P && type<=H264Frame::NAL_IDR ) {// sei aud pps sps 不判断 //264 新一帧的开始,刷新输出 return true; }else{ @@ -202,9 +202,12 @@ bool FrameMerger::willFlush(const Frame::Ptr &frame) const{ break; } case CodecH265 : { - if (H265_TYPE(frame->data()[frame->prefixSize()]) == H265Frame::NAL_TRAIL_R) { - //如果是265的TRAIL_R帧,那么也刷新输出 + auto type = H265_TYPE(frame->data()[frame->prefixSize()]); + if ((type>=H265Frame::NAL_TRAIL_R &&type<= H265Frame::NAL_RSV_IRAP_VCL23) && ( (frame->data()[frame->prefixSize()+2]>>7 & 0x01) != 0)) { + //first_slice_segment_in_pic_flag is frame start return true; + }else{ + return false; } break; } diff --git a/src/Extension/H264Rtmp.cpp b/src/Extension/H264Rtmp.cpp index 47f5192e..b3426fe8 100644 --- a/src/Extension/H264Rtmp.cpp +++ b/src/Extension/H264Rtmp.cpp @@ -183,7 +183,7 @@ void H264RtmpEncoder::inputFrame(const Frame::Ptr &frame) { } } - if(_lastPacket && (_lastPacket->time_stamp != frame->dts() || (pcData[1]&0x80 != 0 && type>=H264Frame::NAL_B_P && type<=H264Frame::NAL_IDR))) { + if(_lastPacket && (_lastPacket->time_stamp != frame->dts() || ((pcData[1]&0x80) != 0 && type>=H264Frame::NAL_B_P && type<=H264Frame::NAL_IDR))) { RtmpCodec::inputRtmp(_lastPacket); _lastPacket = nullptr; } diff --git a/src/Extension/H265.cpp b/src/Extension/H265.cpp index 76df36a7..a4b2dde6 100644 --- a/src/Extension/H265.cpp +++ b/src/Extension/H265.cpp @@ -64,10 +64,11 @@ bool H265Frame::configFrame() const { } bool H265Frame::isKeyFrame(int type, const char *ptr) { - if (!ptr || type != NAL_IDR_W_RADL) { - return type >= NAL_BLA_W_LP && type <= NAL_RSV_IRAP_VCL23; + if(ptr){ + return (((*((uint8_t *) ptr + 2)) >> 7) & 0x01) == 1 && (type == NAL_IDR_N_LP || type == NAL_IDR_W_RADL); } - return (((*((uint8_t *) ptr + 2)) >> 7) & 0x01) == 1; + return false; + } H265Frame::H265Frame(){ diff --git a/src/Extension/H265Rtmp.cpp b/src/Extension/H265Rtmp.cpp index 3a8c32ab..f863b502 100644 --- a/src/Extension/H265Rtmp.cpp +++ b/src/Extension/H265Rtmp.cpp @@ -169,7 +169,7 @@ void H265RtmpEncoder::inputFrame(const Frame::Ptr &frame) { return; } - if (_lastPacket && (_lastPacket->time_stamp != frame->dts() || type == H265Frame::NAL_TRAIL_R)) { + if (_lastPacket && (_lastPacket->time_stamp != frame->dts() || (type >=H264Frame::NAL_B_P && type<=H264Frame::NAL_IDR && (pcData[2]>>7 &0x01) !=0))) { RtmpCodec::inputRtmp(_lastPacket); _lastPacket = nullptr; } From 2335043cdf2e6d2db0b98e484568ed669469e565 Mon Sep 17 00:00:00 2001 From: xgj Date: Fri, 18 Jun 2021 15:19:21 +0800 Subject: [PATCH 6/6] drop SEI and AUD for h264 and h265 avoid sei as a frame --- src/Extension/Frame.cpp | 27 ++++++++++++++++++++++++++- src/Extension/Frame.h | 1 + src/Extension/H265Rtmp.cpp | 4 ++-- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/Extension/Frame.cpp b/src/Extension/Frame.cpp index f51f5945..62753f59 100644 --- a/src/Extension/Frame.cpp +++ b/src/Extension/Frame.cpp @@ -244,8 +244,33 @@ void FrameMerger::doMerge(BufferLikeString &merged, const Frame::Ptr &frame) con default: /*不可达*/ assert(0); break; } } - +bool FrameMerger::shouldDrop(const Frame::Ptr &frame) const{ + switch (frame->getCodecId()) { + case CodecH264:{ + auto type = H264_TYPE(frame->data()[frame->prefixSize()]); + if(type == H264Frame::NAL_SEI || type == H264Frame::NAL_AUD){ + // 防止吧AUD或者SEI当成一帧 + return true; + } + break; + } + case CodecH265: { + //如果是新的一帧,前面的缓存需要输出 + auto type = H265_TYPE(frame->data()[frame->prefixSize()]); + if(type == H265Frame::NAL_AUD || type == H265Frame::NAL_SEI_PREFIX || type == H265Frame::NAL_SEI_SUFFIX){ + // 防止吧AUD或者SEI当成一帧 + return true; + } + break; + } + default: break; + } + return false; +} void FrameMerger::inputFrame(const Frame::Ptr &frame, const onOutput &cb) { + if(shouldDrop(frame)){ + return; + } if (willFlush(frame)) { Frame::Ptr back = _frameCached.back(); Buffer::Ptr merged_frame = back; diff --git a/src/Extension/Frame.h b/src/Extension/Frame.h index ca8a2b39..95a5ec6d 100644 --- a/src/Extension/Frame.h +++ b/src/Extension/Frame.h @@ -475,6 +475,7 @@ public: private: bool willFlush(const Frame::Ptr &frame) const; void doMerge(BufferLikeString &buffer, const Frame::Ptr &frame) const; + bool shouldDrop(const Frame::Ptr &frame) const; private: int _type; diff --git a/src/Extension/H265Rtmp.cpp b/src/Extension/H265Rtmp.cpp index f863b502..84dddad6 100644 --- a/src/Extension/H265Rtmp.cpp +++ b/src/Extension/H265Rtmp.cpp @@ -165,8 +165,8 @@ void H265RtmpEncoder::inputFrame(const Frame::Ptr &frame) { } } - if(type == H265Frame::NAL_SEI_PREFIX || type == H265Frame::NAL_SEI_SUFFIX){ - return; + if(type == H265Frame::NAL_SEI_PREFIX || type == H265Frame::NAL_SEI_SUFFIX || type == H265Frame::NAL_AUD){ + return;// 防止sei aud 作为一帧 } if (_lastPacket && (_lastPacket->time_stamp != frame->dts() || (type >=H264Frame::NAL_B_P && type<=H264Frame::NAL_IDR && (pcData[2]>>7 &0x01) !=0))) {