mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2024-11-22 19:00:01 +08:00
RTC: 修复gop没有sps/pps导致的秒开失败问题 (#2959)
rtc场景下,如果directProxy设置为1,sdp没有传递sps/pps,因此gop的开始需要是rtp sps/pps配置帧而不是idr关键帧,这样才能保证秒开。
This commit is contained in:
parent
c95ccbd544
commit
433ecb1c5c
@ -44,13 +44,15 @@ H264Frame::Ptr H264RtpDecoder::obtainFrame() {
|
|||||||
|
|
||||||
bool H264RtpDecoder::inputRtp(const RtpPacket::Ptr &rtp, bool key_pos) {
|
bool H264RtpDecoder::inputRtp(const RtpPacket::Ptr &rtp, bool key_pos) {
|
||||||
auto seq = rtp->getSeq();
|
auto seq = rtp->getSeq();
|
||||||
auto ret = decodeRtp(rtp);
|
auto last_is_gop = _is_gop;
|
||||||
if (!_gop_dropped && seq != (uint16_t) (_last_seq + 1) && _last_seq) {
|
_is_gop = decodeRtp(rtp);
|
||||||
|
if (!_gop_dropped && seq != (uint16_t)(_last_seq + 1) && _last_seq) {
|
||||||
_gop_dropped = true;
|
_gop_dropped = true;
|
||||||
WarnL << "start drop h264 gop, last seq:" << _last_seq << ", rtp:\r\n" << rtp->dumpString();
|
WarnL << "start drop h264 gop, last seq:" << _last_seq << ", rtp:\r\n" << rtp->dumpString();
|
||||||
}
|
}
|
||||||
_last_seq = seq;
|
_last_seq = seq;
|
||||||
return ret;
|
// 确保有sps rtp的时候,gop从sps开始;否则从关键帧开始
|
||||||
|
return _is_gop && !last_is_gop;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -74,7 +76,7 @@ bool H264RtpDecoder::singleFrame(const RtpPacket::Ptr &rtp, const uint8_t *ptr,
|
|||||||
_frame->_buffer.assign("\x00\x00\x00\x01", 4);
|
_frame->_buffer.assign("\x00\x00\x00\x01", 4);
|
||||||
_frame->_buffer.append((char *) ptr, size);
|
_frame->_buffer.append((char *) ptr, size);
|
||||||
_frame->_pts = stamp;
|
_frame->_pts = stamp;
|
||||||
auto key = _frame->keyFrame();
|
auto key = _frame->keyFrame() || _frame->configFrame();
|
||||||
outputFrame(rtp, _frame);
|
outputFrame(rtp, _frame);
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
@ -127,7 +129,7 @@ bool H264RtpDecoder::mergeFu(const RtpPacket::Ptr &rtp, const uint8_t *ptr, ssiz
|
|||||||
|
|
||||||
if (!fu->end_bit) {
|
if (!fu->end_bit) {
|
||||||
//非末尾包
|
//非末尾包
|
||||||
return fu->start_bit ? _frame->keyFrame() : false;
|
return fu->start_bit ? (_frame->keyFrame() || _frame->configFrame()) : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//确保下一次fu必须收到第一个包
|
//确保下一次fu必须收到第一个包
|
||||||
|
@ -51,6 +51,7 @@ private:
|
|||||||
void outputFrame(const RtpPacket::Ptr &rtp, const H264Frame::Ptr &frame);
|
void outputFrame(const RtpPacket::Ptr &rtp, const H264Frame::Ptr &frame);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool _is_gop = false;
|
||||||
bool _gop_dropped = false;
|
bool _gop_dropped = false;
|
||||||
bool _fu_dropped = true;
|
bool _fu_dropped = true;
|
||||||
uint16_t _last_seq = 0;
|
uint16_t _last_seq = 0;
|
||||||
|
@ -163,7 +163,7 @@ bool H265RtpDecoder::mergeFu(const RtpPacket::Ptr &rtp, const uint8_t *ptr, ssiz
|
|||||||
|
|
||||||
if (!e_bit) {
|
if (!e_bit) {
|
||||||
//非末尾包
|
//非末尾包
|
||||||
return s_bit ? _frame->keyFrame() : false;
|
return s_bit ? (_frame->keyFrame() || _frame->configFrame()) : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//确保下一次fu必须收到第一个包
|
//确保下一次fu必须收到第一个包
|
||||||
@ -175,13 +175,15 @@ bool H265RtpDecoder::mergeFu(const RtpPacket::Ptr &rtp, const uint8_t *ptr, ssiz
|
|||||||
|
|
||||||
bool H265RtpDecoder::inputRtp(const RtpPacket::Ptr &rtp, bool) {
|
bool H265RtpDecoder::inputRtp(const RtpPacket::Ptr &rtp, bool) {
|
||||||
auto seq = rtp->getSeq();
|
auto seq = rtp->getSeq();
|
||||||
auto ret = decodeRtp(rtp);
|
auto last_is_gop = _is_gop;
|
||||||
|
_is_gop = decodeRtp(rtp);
|
||||||
if (!_gop_dropped && seq != (uint16_t) (_last_seq + 1) && _last_seq) {
|
if (!_gop_dropped && seq != (uint16_t) (_last_seq + 1) && _last_seq) {
|
||||||
_gop_dropped = true;
|
_gop_dropped = true;
|
||||||
WarnL << "start drop h265 gop, last seq:" << _last_seq << ", rtp:\r\n" << rtp->dumpString();
|
WarnL << "start drop h265 gop, last seq:" << _last_seq << ", rtp:\r\n" << rtp->dumpString();
|
||||||
}
|
}
|
||||||
_last_seq = seq;
|
_last_seq = seq;
|
||||||
return ret;
|
// 确保有sps rtp的时候,gop从sps开始;否则从关键帧开始
|
||||||
|
return _is_gop && !last_is_gop;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool H265RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtp) {
|
bool H265RtpDecoder::decodeRtp(const RtpPacket::Ptr &rtp) {
|
||||||
@ -220,7 +222,7 @@ bool H265RtpDecoder::singleFrame(const RtpPacket::Ptr &rtp, const uint8_t *ptr,
|
|||||||
_frame->_buffer.assign("\x00\x00\x00\x01", 4);
|
_frame->_buffer.assign("\x00\x00\x00\x01", 4);
|
||||||
_frame->_buffer.append((char *) ptr, size);
|
_frame->_buffer.append((char *) ptr, size);
|
||||||
_frame->_pts = stamp;
|
_frame->_pts = stamp;
|
||||||
auto key = _frame->keyFrame();
|
auto key = _frame->keyFrame() || _frame->configFrame();
|
||||||
outputFrame(rtp, _frame);
|
outputFrame(rtp, _frame);
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
@ -51,6 +51,7 @@ private:
|
|||||||
void outputFrame(const RtpPacket::Ptr &rtp, const H265Frame::Ptr &frame);
|
void outputFrame(const RtpPacket::Ptr &rtp, const H265Frame::Ptr &frame);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool _is_gop = false;
|
||||||
bool _using_donl_field = false;
|
bool _using_donl_field = false;
|
||||||
bool _gop_dropped = false;
|
bool _gop_dropped = false;
|
||||||
bool _fu_dropped = true;
|
bool _fu_dropped = true;
|
||||||
|
Loading…
Reference in New Issue
Block a user