!10 对h264 一帧多slice (多nal)fmp4播放卡顿(vlc)

Merge pull request !10 from xiongguangjie/dev
This commit is contained in:
夏楚 2021-06-18 07:27:52 +00:00 committed by Gitee
commit 05c9a842a9
6 changed files with 50 additions and 12 deletions

View File

@ -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" AND OPENSSL_USE_STATIC_LIBS)
list(APPEND LINK_LIB_LIST dl)
endif()
else()
message(WARNING "openssl未找到rtmp将不支持flash播放器https/wss/rtsps/rtmps也将失效")
endif ()

View File

@ -191,16 +191,23 @@ 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帧那么也刷新输出
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{
// 不刷新输出
return false;
}
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;
}
@ -237,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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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(){

View File

@ -165,11 +165,11 @@ 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 == 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;
}