1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-02-24 15:04:20 +00:00
srs/trunk/src/kernel/srs_kernel_rtc_rtp.hpp

348 lines
10 KiB
C++
Raw Normal View History

2020-03-13 12:35:07 +00:00
/**
* The MIT License (MIT)
*
* Copyright (c) 2013-2020 Winlin
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
2020-05-11 04:07:55 +00:00
#ifndef SRS_KERNEL_RTC_RTP_HPP
#define SRS_KERNEL_RTC_RTP_HPP
2020-03-13 12:35:07 +00:00
#include <srs_core.hpp>
#include <srs_kernel_buffer.hpp>
#include <srs_kernel_codec.hpp>
2020-03-13 12:35:07 +00:00
#include <string>
class SrsRtpPacket2;
2020-05-13 07:27:31 +00:00
// The RTP packet max size, should never exceed this size.
const int kRtpPacketSize = 1500;
const int kRtpHeaderFixedSize = 12;
const uint8_t kRtpMarker = 0x80;
2020-04-08 06:45:26 +00:00
// H.264 nalu header type mask.
const uint8_t kNalTypeMask = 0x1F;
2020-04-23 09:08:21 +00:00
// @see: https://tools.ietf.org/html/rfc6184#section-5.2
const uint8_t kStapA = 24;
// @see: https://tools.ietf.org/html/rfc6184#section-5.2
const uint8_t kFuA = 28;
// @see: https://tools.ietf.org/html/rfc6184#section-5.8
const uint8_t kStart = 0x80; // Fu-header start bit
const uint8_t kEnd = 0x40; // Fu-header end bit
2020-04-08 06:45:26 +00:00
class SrsBuffer;
class SrsRtpRawPayload;
2020-04-18 12:37:08 +00:00
class SrsRtpFUAPayload2;
class SrsSharedPtrMessage;
2020-04-08 06:45:26 +00:00
// The "distance" between two uint16 number, for example:
// distance(prev_value=3, value=5) === (int16_t)(uint16_t)((uint16_t)3-(uint16_t)5) === -2
// distance(prev_value=3, value=65534) === (int16_t)(uint16_t)((uint16_t)3-(uint16_t)65534) === 5
// distance(prev_value=65532, value=65534) === (int16_t)(uint16_t)((uint16_t)65532-(uint16_t)65534) === -2
// For RTP sequence, it's only uint16 and may flip back, so 3 maybe 3+0xffff.
// @remark Note that srs_rtp_seq_distance(0, 32768)>0 is TRUE by https://mp.weixin.qq.com/s/JZTInmlB9FUWXBQw_7NYqg
// but for WebRTC jitter buffer it's FALSE and we follow it.
// @remark For srs_rtp_seq_distance(32768, 0)>0, it's FALSE definitely.
inline int16_t srs_rtp_seq_distance(const uint16_t& prev_value, const uint16_t& value)
{
return (int16_t)(value - prev_value);
}
2020-05-19 09:49:34 +00:00
// For map to compare the sequence of RTP.
struct SrsSeqCompareLess {
bool operator()(const uint16_t& pre_value, const uint16_t& value) const {
return srs_rtp_seq_distance(pre_value, value) > 0;
}
};
bool srs_seq_is_newer(uint16_t value, uint16_t pre_value);
2020-05-19 10:06:12 +00:00
bool srs_seq_is_rollback(uint16_t value, uint16_t pre_value);
int32_t srs_seq_distance(uint16_t value, uint16_t pre_value);
2020-05-09 02:51:57 +00:00
2020-05-19 12:47:01 +00:00
enum SrsRtpExtensionType
{
kRtpExtensionNone,
kRtpExtensionTransportSequenceNumber,
kRtpExtensionNumberOfExtensions // Must be the last entity in the enum.
};
2020-05-19 12:47:01 +00:00
struct SrsExtensionInfo
{
SrsRtpExtensionType type;
std::string uri;
};
2020-05-19 12:47:01 +00:00
const SrsExtensionInfo kExtensions[] = {
{kRtpExtensionTransportSequenceNumber, std::string("http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01")}
};
2020-05-19 12:47:01 +00:00
class SrsRtpHeaderExtensionMap
{
public:
static const SrsRtpExtensionType kInvalidType = kRtpExtensionNone;
static const int kInvalidId = 0;
public:
bool register_by_uri(int id, std::string uri);
SrsRtpExtensionType get_type(int id) const;
public:
SrsRtpHeaderExtensionMap();
virtual ~SrsRtpHeaderExtensionMap();
private:
bool register_id(int id, SrsRtpExtensionType type, std::string uri);
private:
uint8_t ids_[kRtpExtensionNumberOfExtensions];
};
2020-05-19 12:47:01 +00:00
class SrsRtpHeaderExtension
{
public:
bool has_transport_sequence_number;
uint16_t transport_sequence_number;
uint8_t transport_cc_ext_id;
public:
SrsRtpHeaderExtension();
virtual ~SrsRtpHeaderExtension();
};
2020-05-19 12:47:01 +00:00
2020-04-08 06:45:26 +00:00
class SrsRtpHeader
{
private:
2020-04-23 09:08:21 +00:00
uint8_t padding_length;
2020-04-08 06:45:26 +00:00
bool extension;
uint8_t cc;
bool marker;
uint8_t payload_type;
uint16_t sequence;
2020-05-04 06:47:58 +00:00
uint32_t timestamp;
2020-04-08 06:45:26 +00:00
uint32_t ssrc;
uint32_t csrc[15];
uint16_t extension_length;
SrsRtpHeaderExtension header_extension;
2020-04-08 06:45:26 +00:00
public:
SrsRtpHeader();
virtual ~SrsRtpHeader();
private:
srs_error_t parse_extension(SrsBuffer* buf, const SrsRtpHeaderExtensionMap* extension_map);
2020-04-08 06:45:26 +00:00
public:
virtual srs_error_t decode(SrsBuffer* buf, const SrsRtpHeaderExtensionMap* extmap = NULL);
virtual srs_error_t encode(SrsBuffer* buf);
virtual int nb_bytes();
2020-04-08 06:45:26 +00:00
public:
void set_marker(bool v);
bool get_marker() const;
void set_payload_type(uint8_t v);
uint8_t get_payload_type() const;
void set_sequence(uint16_t v);
uint16_t get_sequence() const;
2020-05-04 06:47:58 +00:00
void set_timestamp(uint32_t v);
uint32_t get_timestamp() const;
void set_ssrc(uint32_t v);
uint32_t get_ssrc() const;
2020-05-14 07:01:12 +00:00
void set_padding(uint8_t v);
uint8_t get_padding() const;
srs_error_t get_twcc_sequence_number(uint16_t& twcc_sn);
2020-04-08 06:45:26 +00:00
};
2020-03-18 00:45:20 +00:00
2020-05-14 06:26:19 +00:00
class ISrsRtpPayloader : public ISrsCodec
{
public:
ISrsRtpPayloader();
virtual ~ISrsRtpPayloader();
public:
virtual ISrsRtpPayloader* copy() = 0;
};
class ISrsRtpPacketDecodeHandler
{
public:
ISrsRtpPacketDecodeHandler();
virtual ~ISrsRtpPacketDecodeHandler();
public:
// We don't know the actual payload, so we depends on external handler.
2020-05-14 06:26:19 +00:00
virtual void on_before_decode_payload(SrsRtpPacket2* pkt, SrsBuffer* buf, ISrsRtpPayloader** ppayload) = 0;
};
class SrsRtpPacket2
{
// RTP packet fields.
public:
SrsRtpHeader header;
2020-05-14 06:26:19 +00:00
ISrsRtpPayloader* payload;
2020-05-13 12:13:25 +00:00
// Helper fields.
public:
// The first byte as nalu type, for video decoder only.
SrsAvcNaluType nalu_type;
// The original shared message, all RTP packets can refer to its data.
SrsSharedPtrMessage* shared_msg;
2020-05-13 12:13:25 +00:00
// The frame type, for RTMP bridger or SFU source.
SrsFrameType frame_type;
// Fast cache for performance.
private:
2020-05-14 06:44:24 +00:00
// The cached payload size for packet.
int cached_payload_size;
// The helper handler for decoder, use RAW payload if NULL.
ISrsRtpPacketDecodeHandler* decode_handler;
public:
SrsRtpPacket2();
virtual ~SrsRtpPacket2();
public:
2020-04-17 10:04:52 +00:00
// Set the padding of RTP packet.
2020-04-15 14:46:06 +00:00
void set_padding(int size);
2020-04-17 10:04:52 +00:00
// Increase the padding of RTP packet.
void add_padding(int size);
// Set the decode handler.
void set_decode_handler(ISrsRtpPacketDecodeHandler* h);
2020-05-13 12:13:25 +00:00
// Whether the packet is Audio packet.
bool is_audio();
2020-05-14 06:26:19 +00:00
// Copy the RTP packet.
SrsRtpPacket2* copy();
2020-04-13 05:44:55 +00:00
// interface ISrsEncoder
public:
virtual int nb_bytes();
virtual srs_error_t encode(SrsBuffer* buf);
2020-05-24 13:18:46 +00:00
// TODO: FIXME: Should follow interface ISrsEncoder.
virtual srs_error_t decode(SrsBuffer* buf, const SrsRtpHeaderExtensionMap* extmap = NULL);
};
// Single payload data.
2020-05-14 06:26:19 +00:00
class SrsRtpRawPayload : public ISrsRtpPayloader
{
public:
2020-04-18 12:37:08 +00:00
// The RAW payload, directly point to the shared memory.
// @remark We only refer to the memory, user must free its bytes.
char* payload;
int nn_payload;
public:
SrsRtpRawPayload();
virtual ~SrsRtpRawPayload();
2020-05-14 06:26:19 +00:00
// interface ISrsRtpPayloader
public:
virtual int nb_bytes();
virtual srs_error_t encode(SrsBuffer* buf);
virtual srs_error_t decode(SrsBuffer* buf);
2020-05-14 06:26:19 +00:00
virtual ISrsRtpPayloader* copy();
};
// Multiple NALUs, automatically insert 001 between NALUs.
2020-05-14 06:26:19 +00:00
class SrsRtpRawNALUs : public ISrsRtpPayloader
{
private:
2020-04-18 12:37:08 +00:00
// We will manage the samples, but the sample itself point to the shared memory.
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();
2020-04-18 12:37:08 +00:00
// We will manage the returned samples, if user want to manage it, please copy it.
srs_error_t read_samples(std::vector<SrsSample*>& samples, int packet_size);
2020-05-14 06:26:19 +00:00
// interface ISrsRtpPayloader
public:
virtual int nb_bytes();
virtual srs_error_t encode(SrsBuffer* buf);
virtual srs_error_t decode(SrsBuffer* buf);
2020-05-14 06:26:19 +00:00
virtual ISrsRtpPayloader* copy();
};
// STAP-A, for multiple NALUs.
2020-05-14 06:26:19 +00:00
class SrsRtpSTAPPayload : public ISrsRtpPayloader
{
public:
// The NRI in NALU type.
SrsAvcNaluType nri;
2020-04-19 01:32:09 +00:00
// The NALU samples, we will manage the samples.
// @remark We only refer to the memory, user must free its bytes.
2020-04-11 17:05:11 +00:00
std::vector<SrsSample*> nalus;
public:
SrsRtpSTAPPayload();
virtual ~SrsRtpSTAPPayload();
2020-05-02 12:57:36 +00:00
public:
SrsSample* get_sps();
SrsSample* get_pps();
2020-05-14 06:26:19 +00:00
// interface ISrsRtpPayloader
2020-04-11 17:01:39 +00:00
public:
virtual int nb_bytes();
virtual srs_error_t encode(SrsBuffer* buf);
virtual srs_error_t decode(SrsBuffer* buf);
2020-05-14 06:26:19 +00:00
virtual ISrsRtpPayloader* copy();
2020-04-11 17:01:39 +00:00
};
// FU-A, for one NALU with multiple fragments.
2020-04-18 12:37:08 +00:00
// With more than one payload.
2020-05-14 06:26:19 +00:00
class SrsRtpFUAPayload : public ISrsRtpPayloader
2020-04-11 17:01:39 +00:00
{
public:
// The NRI in NALU type.
SrsAvcNaluType nri;
// The FUA header.
bool start;
bool end;
SrsAvcNaluType nalu_type;
2020-04-19 01:32:09 +00:00
// The NALU samples, we manage the samples.
2020-04-11 17:01:39 +00:00
// @remark We only refer to the memory, user must free its bytes.
std::vector<SrsSample*> nalus;
public:
SrsRtpFUAPayload();
virtual ~SrsRtpFUAPayload();
2020-05-14 06:26:19 +00:00
// interface ISrsRtpPayloader
public:
2020-04-18 12:37:08 +00:00
virtual int nb_bytes();
virtual srs_error_t encode(SrsBuffer* buf);
virtual srs_error_t decode(SrsBuffer* buf);
2020-05-14 06:26:19 +00:00
virtual ISrsRtpPayloader* copy();
2020-04-18 12:37:08 +00:00
};
// FU-A, for one NALU with multiple fragments.
// With only one payload.
2020-05-14 06:26:19 +00:00
class SrsRtpFUAPayload2 : public ISrsRtpPayloader
2020-04-18 12:37:08 +00:00
{
public:
// The NRI in NALU type.
SrsAvcNaluType nri;
// The FUA header.
bool start;
bool end;
SrsAvcNaluType nalu_type;
// The payload and size,
char* payload;
int size;
public:
SrsRtpFUAPayload2();
virtual ~SrsRtpFUAPayload2();
2020-05-14 06:26:19 +00:00
// interface ISrsRtpPayloader
public:
virtual int nb_bytes();
virtual srs_error_t encode(SrsBuffer* buf);
virtual srs_error_t decode(SrsBuffer* buf);
2020-05-14 06:26:19 +00:00
virtual ISrsRtpPayloader* copy();
};
2020-03-13 12:35:07 +00:00
#endif