mirror of
				https://github.com/ossrs/srs.git
				synced 2025-03-09 15:49:59 +00:00 
			
		
		
		
	For #307, support merge multiple slices/NALUs to one NALU/RTP/FUA
This commit is contained in:
		
							parent
							
								
									5d23bb6a8a
								
							
						
					
					
						commit
						96059e0d42
					
				
					 7 changed files with 230 additions and 13 deletions
				
			
		| 
						 | 
					@ -437,8 +437,8 @@ rtc_server {
 | 
				
			||||||
    reuseport       4;
 | 
					    reuseport       4;
 | 
				
			||||||
    # Whether merge multiple NALUs into one.
 | 
					    # Whether merge multiple NALUs into one.
 | 
				
			||||||
    # @see https://github.com/ossrs/srs/issues/307#issuecomment-612806318
 | 
					    # @see https://github.com/ossrs/srs/issues/307#issuecomment-612806318
 | 
				
			||||||
    # default: off
 | 
					    # default: on
 | 
				
			||||||
    merge_nalus     off;
 | 
					    merge_nalus     on;
 | 
				
			||||||
    # Whether enable GSO to send out RTP packets.
 | 
					    # Whether enable GSO to send out RTP packets.
 | 
				
			||||||
    # default: off
 | 
					    # default: off
 | 
				
			||||||
    gso             off;
 | 
					    gso             off;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4774,7 +4774,7 @@ int SrsConfig::get_rtc_server_reuseport()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool SrsConfig::get_rtc_server_merge_nalus()
 | 
					bool SrsConfig::get_rtc_server_merge_nalus()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    static int DEFAULT = false;
 | 
					    static int DEFAULT = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    SrsConfDirective* conf = root->get("rtc_server");
 | 
					    SrsConfDirective* conf = root->get("rtc_server");
 | 
				
			||||||
    if (!conf) {
 | 
					    if (!conf) {
 | 
				
			||||||
| 
						 | 
					@ -4786,7 +4786,7 @@ bool SrsConfig::get_rtc_server_merge_nalus()
 | 
				
			||||||
        return DEFAULT;
 | 
					        return DEFAULT;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return SRS_CONF_PERFER_FALSE(conf->arg0());
 | 
					    return SRS_CONF_PERFER_TRUE(conf->arg0());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool SrsConfig::get_rtc_server_gso()
 | 
					bool SrsConfig::get_rtc_server_gso()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -727,7 +727,7 @@ srs_error_t SrsRtcSenderThread::messages_to_packets(
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // By default, we package each NALU(sample) to a RTP or FUA packet.
 | 
					        // By default, we package each NALU(sample) to a RTP or FUA packet.
 | 
				
			||||||
        for (int i = 0; i < msg->nn_samples(); i++) {
 | 
					        for (int i = 0; i < nn_samples; i++) {
 | 
				
			||||||
            SrsSample* sample = msg->samples() + i;
 | 
					            SrsSample* sample = msg->samples() + i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            // We always ignore bframe here, if config to discard bframe,
 | 
					            // We always ignore bframe here, if config to discard bframe,
 | 
				
			||||||
| 
						 | 
					@ -810,6 +810,81 @@ srs_error_t SrsRtcSenderThread::send_packets(SrsUdpMuxSocket* skt, SrsRtcPackets
 | 
				
			||||||
srs_error_t SrsRtcSenderThread::packet_nalus(SrsSharedPtrMessage* msg, SrsRtcPackets& packets)
 | 
					srs_error_t SrsRtcSenderThread::packet_nalus(SrsSharedPtrMessage* msg, SrsRtcPackets& packets)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    srs_error_t err = srs_success;
 | 
					    srs_error_t err = srs_success;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    SrsRtpRawNALUs* raw = new SrsRtpRawNALUs();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (int i = 0; i < msg->nn_samples(); i++) {
 | 
				
			||||||
 | 
					        SrsSample* sample = msg->samples() + i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // We always ignore bframe here, if config to discard bframe,
 | 
				
			||||||
 | 
					        // the bframe flag will not be set.
 | 
				
			||||||
 | 
					        if (sample->bframe) {
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        raw->push_back(sample->copy());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Ignore empty.
 | 
				
			||||||
 | 
					    int nn_bytes = raw->nb_bytes();
 | 
				
			||||||
 | 
					    if (nn_bytes <= 0) {
 | 
				
			||||||
 | 
					        srs_freep(raw);
 | 
				
			||||||
 | 
					        return err;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const int kRtpMaxPayloadSize = 1200;
 | 
				
			||||||
 | 
					    if (nn_bytes < kRtpMaxPayloadSize) {
 | 
				
			||||||
 | 
					        // Package NALUs in a single RTP packet.
 | 
				
			||||||
 | 
					        SrsRtpPacket2* packet = new SrsRtpPacket2();
 | 
				
			||||||
 | 
					        packet->rtp_header.set_timestamp(msg->timestamp * 90);
 | 
				
			||||||
 | 
					        packet->rtp_header.set_sequence(video_sequence++);
 | 
				
			||||||
 | 
					        packet->rtp_header.set_ssrc(video_ssrc);
 | 
				
			||||||
 | 
					        packet->rtp_header.set_payload_type(video_payload_type);
 | 
				
			||||||
 | 
					        packet->payload = raw;
 | 
				
			||||||
 | 
					        packets.packets.push_back(packet);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        SrsAutoFree(SrsRtpRawNALUs, raw);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Package NALUs in FU-A RTP packets.
 | 
				
			||||||
 | 
					        int fu_payload_size = kRtpMaxPayloadSize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // The first byte is store in FU-A header.
 | 
				
			||||||
 | 
					        uint8_t header = raw->skip_first_byte();
 | 
				
			||||||
 | 
					        uint8_t nal_type = header & kNalTypeMask;
 | 
				
			||||||
 | 
					        int nb_left = nn_bytes - 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        int num_of_packet = 1 + (nn_bytes - 1) / fu_payload_size;
 | 
				
			||||||
 | 
					        for (int i = 0; i < num_of_packet; ++i) {
 | 
				
			||||||
 | 
					            int packet_size = srs_min(nb_left, fu_payload_size);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            SrsRtpPacket2* packet = new SrsRtpPacket2();
 | 
				
			||||||
 | 
					            packets.packets.push_back(packet);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            packet->rtp_header.set_timestamp(msg->timestamp * 90);
 | 
				
			||||||
 | 
					            packet->rtp_header.set_sequence(video_sequence++);
 | 
				
			||||||
 | 
					            packet->rtp_header.set_ssrc(video_ssrc);
 | 
				
			||||||
 | 
					            packet->rtp_header.set_payload_type(video_payload_type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            SrsRtpFUAPayload* fua = new SrsRtpFUAPayload();
 | 
				
			||||||
 | 
					            packet->payload = fua;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            fua->nri = (SrsAvcNaluType)header;
 | 
				
			||||||
 | 
					            fua->nalu_type = (SrsAvcNaluType)nal_type;
 | 
				
			||||||
 | 
					            fua->start = bool(i == 0);
 | 
				
			||||||
 | 
					            fua->end = bool(i == num_of_packet - 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if ((err = raw->read_samples(fua->nalus, packet_size)) != srs_success) {
 | 
				
			||||||
 | 
					                return srs_error_wrap(err, "read samples %d bytes, left %d, total %d", packet_size, nb_left, nn_bytes);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            nb_left -= packet_size;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!packets.packets.empty()) {
 | 
				
			||||||
 | 
					        packets.packets.back()->rtp_header.set_marker(true);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return err;
 | 
					    return err;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -866,10 +941,10 @@ srs_error_t SrsRtcSenderThread::packet_fu_a(SrsSharedPtrMessage* msg, SrsSample*
 | 
				
			||||||
        fua->start = bool(i == 0);
 | 
					        fua->start = bool(i == 0);
 | 
				
			||||||
        fua->end = bool(i == num_of_packet - 1);
 | 
					        fua->end = bool(i == num_of_packet - 1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        SrsSample* sample = new SrsSample();
 | 
					        SrsSample* fragment_sample = new SrsSample();
 | 
				
			||||||
        sample->bytes = p;
 | 
					        fragment_sample->bytes = p;
 | 
				
			||||||
        sample->size = packet_size;
 | 
					        fragment_sample->size = packet_size;
 | 
				
			||||||
        fua->nalus.push_back(sample);
 | 
					        fua->nalus.push_back(fragment_sample);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        p += packet_size;
 | 
					        p += packet_size;
 | 
				
			||||||
        nb_left -= packet_size;
 | 
					        nb_left -= packet_size;
 | 
				
			||||||
| 
						 | 
					@ -889,11 +964,13 @@ srs_error_t SrsRtcSenderThread::packet_single_nalu(SrsSharedPtrMessage* msg, Srs
 | 
				
			||||||
    packet->rtp_header.set_ssrc(video_ssrc);
 | 
					    packet->rtp_header.set_ssrc(video_ssrc);
 | 
				
			||||||
    packet->rtp_header.set_payload_type(video_payload_type);
 | 
					    packet->rtp_header.set_payload_type(video_payload_type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    SrsRtpRawPayload* raw = new SrsRtpRawPayload();
 | 
					    SrsRtpRawNALUs* raw = new SrsRtpRawNALUs();
 | 
				
			||||||
    packet->payload = raw;
 | 
					    packet->payload = raw;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    raw->payload = sample->bytes;
 | 
					    SrsSample* p = new SrsSample();
 | 
				
			||||||
    raw->nn_payload = sample->size;
 | 
					    p->bytes = sample->bytes;
 | 
				
			||||||
 | 
					    p->size = sample->size;
 | 
				
			||||||
 | 
					    raw->push_back(p);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    *ppacket = packet;
 | 
					    *ppacket = packet;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -409,6 +409,14 @@ srs_error_t SrsSample::parse_bframe()
 | 
				
			||||||
    return err;
 | 
					    return err;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SrsSample* SrsSample::copy()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    SrsSample* p = new SrsSample();
 | 
				
			||||||
 | 
					    p->bytes = bytes;
 | 
				
			||||||
 | 
					    p->size = size;
 | 
				
			||||||
 | 
					    return p;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SrsCodecConfig::SrsCodecConfig()
 | 
					SrsCodecConfig::SrsCodecConfig()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -542,6 +542,8 @@ public:
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
    // If we need to know whether sample is bframe, we have to parse the NALU payload.
 | 
					    // If we need to know whether sample is bframe, we have to parse the NALU payload.
 | 
				
			||||||
    srs_error_t parse_bframe();
 | 
					    srs_error_t parse_bframe();
 | 
				
			||||||
 | 
					    // Copy sample, share the bytes pointer.
 | 
				
			||||||
 | 
					    SrsSample* copy();
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -229,6 +229,112 @@ srs_error_t SrsRtpRawPayload::encode(SrsBuffer* buf)
 | 
				
			||||||
    return srs_success;
 | 
					    return srs_success;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SrsRtpRawNALUs::SrsRtpRawNALUs()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    cursor = 0;
 | 
				
			||||||
 | 
					    nn_bytes = 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SrsRtpRawNALUs::~SrsRtpRawNALUs()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    vector<SrsSample*>::iterator it;
 | 
				
			||||||
 | 
					    for (it = nalus.begin(); it != nalus.end(); ++it) {
 | 
				
			||||||
 | 
					        SrsSample* p = *it;
 | 
				
			||||||
 | 
					        srs_freep(p);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    nalus.clear();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void SrsRtpRawNALUs::push_back(SrsSample* sample)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (sample->size <= 0) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (!nalus.empty()) {
 | 
				
			||||||
 | 
					        SrsSample* p = new SrsSample();
 | 
				
			||||||
 | 
					        p->bytes = (char*)"\0\0\1";
 | 
				
			||||||
 | 
					        p->size = 3;
 | 
				
			||||||
 | 
					        nn_bytes += 3;
 | 
				
			||||||
 | 
					        nalus.push_back(p);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    nn_bytes += sample->size;
 | 
				
			||||||
 | 
					    nalus.push_back(sample);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint8_t SrsRtpRawNALUs::skip_first_byte()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    srs_assert (cursor >= 0 && nn_bytes > 0 && cursor < nn_bytes);
 | 
				
			||||||
 | 
					    cursor++;
 | 
				
			||||||
 | 
					    return uint8_t(nalus[0]->bytes[0]);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					srs_error_t SrsRtpRawNALUs::read_samples(vector<SrsSample*>& samples, int size)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (cursor + size < 0 || cursor + size > nn_bytes) {
 | 
				
			||||||
 | 
					        return srs_error_new(ERROR_RTC_RTP_MUXER, "cursor=%d, max=%d, size=%d", cursor, nn_bytes, size);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    int pos = cursor;
 | 
				
			||||||
 | 
					    cursor += size;
 | 
				
			||||||
 | 
					    int left = size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    vector<SrsSample*>::iterator it;
 | 
				
			||||||
 | 
					    for (it = nalus.begin(); it != nalus.end() && left > 0; ++it) {
 | 
				
			||||||
 | 
					        SrsSample* p = *it;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Ignore previous consumed samples.
 | 
				
			||||||
 | 
					        if (pos && pos - p->size >= 0) {
 | 
				
			||||||
 | 
					            pos -= p->size;
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Now, we are working at the sample.
 | 
				
			||||||
 | 
					        int nn = srs_min(left, p->size - pos);
 | 
				
			||||||
 | 
					        srs_assert(nn > 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        SrsSample* sample = new SrsSample();
 | 
				
			||||||
 | 
					        sample->bytes = p->bytes + pos;
 | 
				
			||||||
 | 
					        sample->size = nn;
 | 
				
			||||||
 | 
					        samples.push_back(sample);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        left -= nn;
 | 
				
			||||||
 | 
					        pos = 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return srs_success;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int SrsRtpRawNALUs::nb_bytes()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    int size = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    vector<SrsSample*>::iterator it;
 | 
				
			||||||
 | 
					    for (it = nalus.begin(); it != nalus.end(); ++it) {
 | 
				
			||||||
 | 
					        SrsSample* p = *it;
 | 
				
			||||||
 | 
					        size += p->size;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return size;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					srs_error_t SrsRtpRawNALUs::encode(SrsBuffer* buf)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    vector<SrsSample*>::iterator it;
 | 
				
			||||||
 | 
					    for (it = nalus.begin(); it != nalus.end(); ++it) {
 | 
				
			||||||
 | 
					        SrsSample* p = *it;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!buf->require(p->size)) {
 | 
				
			||||||
 | 
					            return srs_error_new(ERROR_RTC_RTP_MUXER, "requires %d bytes", p->size);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        buf->write_bytes(p->bytes, p->size);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return srs_success;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SrsRtpSTAPPayload::SrsRtpSTAPPayload()
 | 
					SrsRtpSTAPPayload::SrsRtpSTAPPayload()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    nri = (SrsAvcNaluType)0;
 | 
					    nri = (SrsAvcNaluType)0;
 | 
				
			||||||
| 
						 | 
					@ -339,7 +445,7 @@ srs_error_t SrsRtpFUAPayload::encode(SrsBuffer* buf)
 | 
				
			||||||
    for (it = nalus.begin(); it != nalus.end(); ++it) {
 | 
					    for (it = nalus.begin(); it != nalus.end(); ++it) {
 | 
				
			||||||
        SrsSample* p = *it;
 | 
					        SrsSample* p = *it;
 | 
				
			||||||
        if (!buf->require(p->size)) {
 | 
					        if (!buf->require(p->size)) {
 | 
				
			||||||
            return srs_error_new(ERROR_RTC_RTP_MUXER, "requires %d bytes", 2 + p->size);
 | 
					            return srs_error_new(ERROR_RTC_RTP_MUXER, "requires %d bytes", p->size);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        buf->write_bytes(p->bytes, p->size);
 | 
					        buf->write_bytes(p->bytes, p->size);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -95,6 +95,7 @@ public:
 | 
				
			||||||
    virtual srs_error_t encode(SrsBuffer* buf);
 | 
					    virtual srs_error_t encode(SrsBuffer* buf);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Single payload data.
 | 
				
			||||||
class SrsRtpRawPayload : public ISrsEncoder
 | 
					class SrsRtpRawPayload : public ISrsEncoder
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
| 
						 | 
					@ -110,6 +111,28 @@ public:
 | 
				
			||||||
    virtual srs_error_t encode(SrsBuffer* buf);
 | 
					    virtual srs_error_t encode(SrsBuffer* buf);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Multiple NALUs, automatically insert 001 between NALUs.
 | 
				
			||||||
 | 
					class SrsRtpRawNALUs : public ISrsEncoder
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    std::vector<SrsSample*> nalus;
 | 
				
			||||||
 | 
					    int nn_bytes;
 | 
				
			||||||
 | 
					    int cursor;
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    SrsRtpRawNALUs();
 | 
				
			||||||
 | 
					    virtual ~SrsRtpRawNALUs();
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    void push_back(SrsSample* sample);
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    uint8_t skip_first_byte();
 | 
				
			||||||
 | 
					    srs_error_t read_samples(std::vector<SrsSample*>& samples, int size);
 | 
				
			||||||
 | 
					// interface ISrsEncoder
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    virtual int nb_bytes();
 | 
				
			||||||
 | 
					    virtual srs_error_t encode(SrsBuffer* buf);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// STAP-A, for multiple NALUs.
 | 
				
			||||||
class SrsRtpSTAPPayload : public ISrsEncoder
 | 
					class SrsRtpSTAPPayload : public ISrsEncoder
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
| 
						 | 
					@ -127,6 +150,7 @@ public:
 | 
				
			||||||
    virtual srs_error_t encode(SrsBuffer* buf);
 | 
					    virtual srs_error_t encode(SrsBuffer* buf);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// FU-A, for one NALU with multiple fragments.
 | 
				
			||||||
class SrsRtpFUAPayload : public ISrsEncoder
 | 
					class SrsRtpFUAPayload : public ISrsEncoder
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue