Also for augment AI to review it.
This commit is contained in:
parent
40df358e50
commit
07163df9a4
|
|
@ -1680,50 +1680,9 @@ srs_error_t SrsRtcFrameBuilder::packet_video_key_frame(SrsRtpPacket* pkt)
|
|||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
// For OBS WHIP, it uses RTP Raw packet with SPS/PPS/IDR frame. Note that not all
|
||||
// raw payload is SPS/PPS.
|
||||
bool has_sps_pps_in_raw_payload = false;
|
||||
SrsRtpRawPayload* raw_payload = dynamic_cast<SrsRtpRawPayload*>(pkt->payload());
|
||||
if (raw_payload) {
|
||||
if (pkt->nalu_type == SrsAvcNaluTypeSPS) {
|
||||
has_sps_pps_in_raw_payload = true;
|
||||
srs_freep(obs_whip_sps_);
|
||||
obs_whip_sps_ = pkt->copy();
|
||||
} else if (pkt->nalu_type == SrsAvcNaluTypePPS) {
|
||||
has_sps_pps_in_raw_payload = true;
|
||||
srs_freep(obs_whip_pps_);
|
||||
obs_whip_pps_ = pkt->copy();
|
||||
}
|
||||
// Ignore if one of OBS WHIP SPS/PPS is not ready.
|
||||
if (has_sps_pps_in_raw_payload && (!obs_whip_sps_ || !obs_whip_pps_)) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
// Generally, there will be SPS+PPS+IDR in a STAP-A packet.
|
||||
SrsRtpSTAPPayload* stap_payload = dynamic_cast<SrsRtpSTAPPayload*>(pkt->payload());
|
||||
|
||||
// Handle SPS/PPS in cache or STAP-A packet.
|
||||
if (stap_payload || has_sps_pps_in_raw_payload) {
|
||||
// Get the SPS/PPS from cache or STAP-A packet.
|
||||
SrsSample* sps = stap_payload ? stap_payload->get_sps() : NULL;
|
||||
if (!sps && obs_whip_sps_) sps = dynamic_cast<SrsRtpRawPayload*>(obs_whip_sps_->payload())->sample_;
|
||||
SrsSample* pps = stap_payload ? stap_payload->get_pps() : NULL;
|
||||
if (!pps && obs_whip_pps_) pps = dynamic_cast<SrsRtpRawPayload*>(obs_whip_pps_->payload())->sample_;
|
||||
if (!sps || !pps) {
|
||||
return srs_error_new(ERROR_RTC_RTP_MUXER, "no sps or pps in stap-a rtp. sps: %p, pps:%p", sps, pps);
|
||||
}
|
||||
|
||||
// Packet SPS/PPS to RTMP keyframe.
|
||||
err = packet_sps_pps(pkt, sps, pps);
|
||||
|
||||
// Always reset the SPS/PPS cache after used it.
|
||||
srs_freep(obs_whip_sps_);
|
||||
srs_freep(obs_whip_pps_);
|
||||
|
||||
if (err != srs_success) {
|
||||
return srs_error_wrap(err, "packet sps/pps");
|
||||
}
|
||||
err = packet_sequence_header_avc(pkt);
|
||||
if (err != srs_success) {
|
||||
return srs_error_wrap(err, "packet video key frame");
|
||||
}
|
||||
|
||||
if (-1 == rtp_key_frame_ts_) {
|
||||
|
|
@ -1779,7 +1738,60 @@ srs_error_t SrsRtcFrameBuilder::packet_video_key_frame(SrsRtpPacket* pkt)
|
|||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsRtcFrameBuilder::packet_sps_pps(SrsRtpPacket* pkt, SrsSample* sps, SrsSample* pps)
|
||||
srs_error_t SrsRtcFrameBuilder::packet_sequence_header_avc(SrsRtpPacket* pkt)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
// For OBS WHIP, it uses RTP Raw packet with SPS/PPS/IDR frame. Note that not all
|
||||
// raw payload is SPS/PPS.
|
||||
bool has_sps_pps_in_raw_payload = false;
|
||||
SrsRtpRawPayload* raw_payload = dynamic_cast<SrsRtpRawPayload*>(pkt->payload());
|
||||
if (raw_payload) {
|
||||
if (pkt->nalu_type == SrsAvcNaluTypeSPS) {
|
||||
has_sps_pps_in_raw_payload = true;
|
||||
srs_freep(obs_whip_sps_);
|
||||
obs_whip_sps_ = pkt->copy();
|
||||
} else if (pkt->nalu_type == SrsAvcNaluTypePPS) {
|
||||
has_sps_pps_in_raw_payload = true;
|
||||
srs_freep(obs_whip_pps_);
|
||||
obs_whip_pps_ = pkt->copy();
|
||||
}
|
||||
// Ignore if one of OBS WHIP SPS/PPS is not ready.
|
||||
if (has_sps_pps_in_raw_payload && (!obs_whip_sps_ || !obs_whip_pps_)) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
// Generally, there will be SPS+PPS+IDR in a STAP-A packet.
|
||||
SrsRtpSTAPPayload* stap_payload = dynamic_cast<SrsRtpSTAPPayload*>(pkt->payload());
|
||||
|
||||
// Handle SPS/PPS in cache or STAP-A packet.
|
||||
if (stap_payload || has_sps_pps_in_raw_payload) {
|
||||
// Get the SPS/PPS from cache or STAP-A packet.
|
||||
SrsSample* sps = stap_payload ? stap_payload->get_sps() : NULL;
|
||||
if (!sps && obs_whip_sps_) sps = dynamic_cast<SrsRtpRawPayload*>(obs_whip_sps_->payload())->sample_;
|
||||
SrsSample* pps = stap_payload ? stap_payload->get_pps() : NULL;
|
||||
if (!pps && obs_whip_pps_) pps = dynamic_cast<SrsRtpRawPayload*>(obs_whip_pps_->payload())->sample_;
|
||||
if (!sps || !pps) {
|
||||
return srs_error_new(ERROR_RTC_RTP_MUXER, "no sps or pps in stap-a rtp. sps: %p, pps:%p", sps, pps);
|
||||
}
|
||||
|
||||
// Packet SPS/PPS to RTMP keyframe.
|
||||
err = do_packet_sequence_header_avc(pkt, sps, pps);
|
||||
|
||||
// Always reset the SPS/PPS cache after used it.
|
||||
srs_freep(obs_whip_sps_);
|
||||
srs_freep(obs_whip_pps_);
|
||||
|
||||
if (err != srs_success) {
|
||||
return srs_error_wrap(err, "packet sps/pps");
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
srs_error_t SrsRtcFrameBuilder::do_packet_sequence_header_avc(SrsRtpPacket* pkt, SrsSample* sps, SrsSample* pps)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
|
|
|
|||
|
|
@ -356,7 +356,8 @@ private:
|
|||
private:
|
||||
srs_error_t packet_video(SrsRtpPacket* pkt);
|
||||
srs_error_t packet_video_key_frame(SrsRtpPacket* pkt);
|
||||
srs_error_t packet_sps_pps(SrsRtpPacket* pkt, SrsSample* sps, SrsSample* pps);
|
||||
srs_error_t packet_sequence_header_avc(SrsRtpPacket* pkt);
|
||||
srs_error_t do_packet_sequence_header_avc(SrsRtpPacket* pkt, SrsSample* sps, SrsSample* pps);
|
||||
private:
|
||||
inline uint16_t cache_index(uint16_t current_sn) {
|
||||
return current_sn % s_cache_size;
|
||||
|
|
|
|||
|
|
@ -946,21 +946,16 @@ srs_error_t SrsRtpPacket::decode(SrsBuffer* buf)
|
|||
return err;
|
||||
}
|
||||
|
||||
bool SrsRtpPacket::is_keyframe()
|
||||
// Helper function to check if H.264 RTP packet is a keyframe
|
||||
bool srs_rtp_packet_h264_is_keyframe(uint8_t nalu_type, ISrsRtpPayloader* payload)
|
||||
{
|
||||
// False if audio packet
|
||||
if(SrsFrameTypeAudio == frame_type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// It's normal H264 video rtp packet
|
||||
if (nalu_type == kStapA) {
|
||||
SrsRtpSTAPPayload* stap_payload = dynamic_cast<SrsRtpSTAPPayload*>(payload_);
|
||||
SrsRtpSTAPPayload* stap_payload = dynamic_cast<SrsRtpSTAPPayload*>(payload);
|
||||
if(NULL != stap_payload->get_sps() || NULL != stap_payload->get_pps()) {
|
||||
return true;
|
||||
}
|
||||
} else if (nalu_type == kFuA) {
|
||||
SrsRtpFUAPayload2* fua_payload = dynamic_cast<SrsRtpFUAPayload2*>(payload_);
|
||||
SrsRtpFUAPayload2* fua_payload = dynamic_cast<SrsRtpFUAPayload2*>(payload);
|
||||
if(SrsAvcNaluTypeIDR == fua_payload->nalu_type) {
|
||||
return true;
|
||||
}
|
||||
|
|
@ -968,28 +963,56 @@ bool SrsRtpPacket::is_keyframe()
|
|||
if((SrsAvcNaluTypeIDR == nalu_type) || (SrsAvcNaluTypeSPS == nalu_type) || (SrsAvcNaluTypePPS == nalu_type)) {
|
||||
return true;
|
||||
}
|
||||
#ifdef SRS_H265
|
||||
if(nalu_type == kStapHevc) {
|
||||
SrsRtpSTAPPayloadHevc* stap_payload = dynamic_cast<SrsRtpSTAPPayloadHevc*>(payload_);
|
||||
if(NULL != stap_payload->get_vps() || NULL != stap_payload->get_sps() || NULL != stap_payload->get_pps()) {
|
||||
return true;
|
||||
}
|
||||
} else if(nalu_type == kFuHevc) {
|
||||
SrsRtpFUAPayloadHevc2* fua_payload = dynamic_cast<SrsRtpFUAPayloadHevc2*>(payload_);
|
||||
if(fua_payload->nalu_type >= SrsHevcNaluType_CODED_SLICE_BLA && fua_payload->nalu_type <= SrsHevcNaluType_RESERVED_23) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if((SrsHevcNaluType_VPS == nalu_type) || (SrsHevcNaluType_SPS == nalu_type) || (SrsHevcNaluType_PPS == nalu_type)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef SRS_H265
|
||||
// Helper function to check if H.265 RTP packet is a keyframe
|
||||
bool srs_rtp_packet_h265_is_keyframe(uint8_t nalu_type, ISrsRtpPayloader* payload)
|
||||
{
|
||||
if(nalu_type == kStapHevc) {
|
||||
SrsRtpSTAPPayloadHevc* stap_payload = dynamic_cast<SrsRtpSTAPPayloadHevc*>(payload);
|
||||
if(NULL != stap_payload->get_vps() || NULL != stap_payload->get_sps() || NULL != stap_payload->get_pps()) {
|
||||
return true;
|
||||
}
|
||||
} else if(nalu_type == kFuHevc) {
|
||||
SrsRtpFUAPayloadHevc2* fua_payload = dynamic_cast<SrsRtpFUAPayloadHevc2*>(payload);
|
||||
if(fua_payload->nalu_type >= SrsHevcNaluType_CODED_SLICE_BLA && fua_payload->nalu_type <= SrsHevcNaluType_RESERVED_23) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if((SrsHevcNaluType_VPS == nalu_type) || (SrsHevcNaluType_SPS == nalu_type) || (SrsHevcNaluType_PPS == nalu_type)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool SrsRtpPacket::is_keyframe()
|
||||
{
|
||||
// False if audio packet
|
||||
if(SrsFrameTypeAudio == frame_type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check H.264 keyframe types
|
||||
if (nalu_type == kStapA || nalu_type == kFuA ||
|
||||
nalu_type == SrsAvcNaluTypeIDR || nalu_type == SrsAvcNaluTypeSPS || nalu_type == SrsAvcNaluTypePPS) {
|
||||
return srs_rtp_packet_h264_is_keyframe(nalu_type, payload_);
|
||||
}
|
||||
|
||||
#ifdef SRS_H265
|
||||
// Check H.265 keyframe types
|
||||
return srs_rtp_packet_h265_is_keyframe(nalu_type, payload_);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
SrsRtpRawPayload::SrsRtpRawPayload()
|
||||
{
|
||||
payload = NULL;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user