mirror of
https://github.com/ossrs/srs.git
synced 2025-02-15 04:42:04 +00:00
For #307, refactor SPS/PPS only before IDR, not each FUA
This commit is contained in:
parent
a695afb368
commit
719c0ae85b
4 changed files with 32 additions and 19 deletions
|
@ -115,16 +115,23 @@ srs_error_t SrsRtpH264Muxer::frame_to_packet(SrsSharedPtrMessage* shared_frame,
|
||||||
|
|
||||||
vector<SrsRtpSharedPacket*> rtp_packets;
|
vector<SrsRtpSharedPacket*> rtp_packets;
|
||||||
|
|
||||||
for (int i = 0; i < format->video->nb_samples; ++i) {
|
// Well, for each IDR, we append a SPS/PPS before it, which is packaged in STAP-A.
|
||||||
SrsSample sample = format->video->samples[i];
|
if (format->video && format->video->has_idr) {
|
||||||
|
if ((err = packet_stap_a(sps, pps, shared_frame, rtp_packets)) != srs_success) {
|
||||||
|
return srs_error_wrap(err, "packet stap-a");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t header = sample.bytes[0];
|
for (int i = 0; i < format->video->nb_samples; ++i) {
|
||||||
|
SrsSample* sample = &format->video->samples[i];
|
||||||
|
|
||||||
|
uint8_t header = sample->bytes[0];
|
||||||
uint8_t nal_type = header & kNalTypeMask;
|
uint8_t nal_type = header & kNalTypeMask;
|
||||||
|
|
||||||
// Because RTC does not support B-frame, so we will drop them.
|
// Because RTC does not support B-frame, so we will drop them.
|
||||||
// TODO: Drop B-frame in better way, which not cause picture corruption.
|
// TODO: Drop B-frame in better way, which not cause picture corruption.
|
||||||
if (discard_bframe && (nal_type == SrsAvcNaluTypeNonIDR || nal_type == SrsAvcNaluTypeDataPartitionA || nal_type == SrsAvcNaluTypeIDR)) {
|
if (discard_bframe && (nal_type == SrsAvcNaluTypeNonIDR || nal_type == SrsAvcNaluTypeDataPartitionA || nal_type == SrsAvcNaluTypeIDR)) {
|
||||||
SrsBuffer* stream = new SrsBuffer(sample.bytes, sample.size);
|
SrsBuffer* stream = new SrsBuffer(sample->bytes, sample->size);
|
||||||
SrsAutoFree(SrsBuffer, stream);
|
SrsAutoFree(SrsBuffer, stream);
|
||||||
|
|
||||||
// Skip nalu header.
|
// Skip nalu header.
|
||||||
|
@ -147,12 +154,12 @@ srs_error_t SrsRtpH264Muxer::frame_to_packet(SrsSharedPtrMessage* shared_frame,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sample.size <= kRtpMaxPayloadSize) {
|
if (sample->size <= kRtpMaxPayloadSize) {
|
||||||
if ((err = packet_single_nalu(shared_frame, format, &sample, rtp_packets)) != srs_success) {
|
if ((err = packet_single_nalu(shared_frame, format, sample, rtp_packets)) != srs_success) {
|
||||||
return srs_error_wrap(err, "packet single nalu");
|
return srs_error_wrap(err, "packet single nalu");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ((err = packet_fu_a(shared_frame, format, &sample, rtp_packets)) != srs_success) {
|
if ((err = packet_fu_a(shared_frame, format, sample, rtp_packets)) != srs_success) {
|
||||||
return srs_error_wrap(err, "packet fu-a");
|
return srs_error_wrap(err, "packet fu-a");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -180,12 +187,6 @@ srs_error_t SrsRtpH264Muxer::packet_fu_a(SrsSharedPtrMessage* shared_frame, SrsF
|
||||||
uint8_t header = sample->bytes[0];
|
uint8_t header = sample->bytes[0];
|
||||||
uint8_t nal_type = header & kNalTypeMask;
|
uint8_t nal_type = header & kNalTypeMask;
|
||||||
|
|
||||||
if (nal_type == SrsAvcNaluTypeIDR) {
|
|
||||||
if ((err = packet_stap_a(sps, pps, shared_frame, rtp_packets)) != srs_success) {
|
|
||||||
return srs_error_wrap(err, "packet stap-a");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int num_of_packet = (sample->size - 1 + kRtpMaxPayloadSize) / kRtpMaxPayloadSize;
|
int num_of_packet = (sample->size - 1 + kRtpMaxPayloadSize) / kRtpMaxPayloadSize;
|
||||||
for (int i = 0; i < num_of_packet; ++i) {
|
for (int i = 0; i < num_of_packet; ++i) {
|
||||||
char buf[kRtpPacketSize];
|
char buf[kRtpPacketSize];
|
||||||
|
@ -223,6 +224,7 @@ srs_error_t SrsRtpH264Muxer::packet_fu_a(SrsSharedPtrMessage* shared_frame, SrsF
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Single NAL Unit Packet @see https://tools.ietf.org/html/rfc6184#section-5.6
|
||||||
srs_error_t SrsRtpH264Muxer::packet_single_nalu(SrsSharedPtrMessage* shared_frame, SrsFormat* format, SrsSample* sample, vector<SrsRtpSharedPacket*>& rtp_packets)
|
srs_error_t SrsRtpH264Muxer::packet_single_nalu(SrsSharedPtrMessage* shared_frame, SrsFormat* format, SrsSample* sample, vector<SrsRtpSharedPacket*>& rtp_packets)
|
||||||
{
|
{
|
||||||
srs_error_t err = srs_success;
|
srs_error_t err = srs_success;
|
||||||
|
@ -230,12 +232,6 @@ srs_error_t SrsRtpH264Muxer::packet_single_nalu(SrsSharedPtrMessage* shared_fram
|
||||||
uint8_t header = sample->bytes[0];
|
uint8_t header = sample->bytes[0];
|
||||||
uint8_t nal_type = header & kNalTypeMask;
|
uint8_t nal_type = header & kNalTypeMask;
|
||||||
|
|
||||||
if (nal_type == SrsAvcNaluTypeIDR) {
|
|
||||||
if ((err = packet_stap_a(sps, pps, shared_frame, rtp_packets)) != srs_success) {
|
|
||||||
return srs_error_wrap(err, "packet stap-a");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
srs_verbose("rtp single nalu, size=%u, seq=%u, timestamp=%lu", sample->size, sequence, (shared_frame->timestamp * 90));
|
srs_verbose("rtp single nalu, size=%u, seq=%u, timestamp=%lu", sample->size, sequence, (shared_frame->timestamp * 90));
|
||||||
|
|
||||||
SrsRtpSharedPacket* packet = new SrsRtpSharedPacket();
|
SrsRtpSharedPacket* packet = new SrsRtpSharedPacket();
|
||||||
|
|
|
@ -78,6 +78,14 @@ srs_error_t parse_h264_fmtp(const std::string& fmtp, H264SpecificParam& h264_par
|
||||||
if (kv[0] == "profile-level-id") {
|
if (kv[0] == "profile-level-id") {
|
||||||
h264_param.profile_level_id = kv[1];
|
h264_param.profile_level_id = kv[1];
|
||||||
} else if (kv[0] == "packetization-mode") {
|
} else if (kv[0] == "packetization-mode") {
|
||||||
|
// 6.3. Non-Interleaved Mode
|
||||||
|
// This mode is in use when the value of the OPTIONAL packetization-mode
|
||||||
|
// media type parameter is equal to 1. This mode SHOULD be supported.
|
||||||
|
// It is primarily intended for low-delay applications. Only single NAL
|
||||||
|
// unit packets, STAP-As, and FU-As MAY be used in this mode. STAP-Bs,
|
||||||
|
// MTAPs, and FU-Bs MUST NOT be used. The transmission order of NAL
|
||||||
|
// units MUST comply with the NAL unit decoding order.
|
||||||
|
// @see https://tools.ietf.org/html/rfc6184#section-6.3
|
||||||
h264_param.packetization_mode = kv[1];
|
h264_param.packetization_mode = kv[1];
|
||||||
} else if (kv[0] == "level-asymmetry-allowed") {
|
} else if (kv[0] == "level-asymmetry-allowed") {
|
||||||
h264_param.level_asymmerty_allow = kv[1];
|
h264_param.level_asymmerty_allow = kv[1];
|
||||||
|
|
|
@ -488,6 +488,13 @@ SrsVideoFrame::~SrsVideoFrame()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
srs_error_t SrsVideoFrame::initialize(SrsCodecConfig* c)
|
||||||
|
{
|
||||||
|
first_nalu_type = SrsAvcNaluTypeForbidden;
|
||||||
|
has_idr = has_sps_pps = has_aud = false;
|
||||||
|
return SrsFrame::initialize(c);
|
||||||
|
}
|
||||||
|
|
||||||
srs_error_t SrsVideoFrame::add_sample(char* bytes, int size)
|
srs_error_t SrsVideoFrame::add_sample(char* bytes, int size)
|
||||||
{
|
{
|
||||||
srs_error_t err = srs_success;
|
srs_error_t err = srs_success;
|
||||||
|
|
|
@ -703,6 +703,8 @@ public:
|
||||||
SrsVideoFrame();
|
SrsVideoFrame();
|
||||||
virtual ~SrsVideoFrame();
|
virtual ~SrsVideoFrame();
|
||||||
public:
|
public:
|
||||||
|
// Initialize the frame, to parse sampels.
|
||||||
|
virtual srs_error_t initialize(SrsCodecConfig* c);
|
||||||
// Add the sample without ANNEXB or IBMF header, or RAW AAC or MP3 data.
|
// Add the sample without ANNEXB or IBMF header, or RAW AAC or MP3 data.
|
||||||
virtual srs_error_t add_sample(char* bytes, int size);
|
virtual srs_error_t add_sample(char* bytes, int size);
|
||||||
public:
|
public:
|
||||||
|
|
Loading…
Reference in a new issue