1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-03-09 15:49:59 +00:00

Refactor code to keep sample function order

This commit is contained in:
winlin 2020-05-02 09:15:49 +08:00
parent 7b5fa0e391
commit 6f2b78f16a
10 changed files with 987 additions and 593 deletions

View file

@ -58,11 +58,26 @@ SrsBuffer::~SrsBuffer()
{
}
char* SrsBuffer::data()
{
return bytes;
}
char* SrsBuffer::head()
{
return p;
}
int SrsBuffer::size()
{
return nb_bytes;
}
void SrsBuffer::set_size(int v)
{
nb_bytes = v;
}
int SrsBuffer::pos()
{
return (int)(p - bytes);

View file

@ -105,62 +105,62 @@ public:
// Create buffer with data b and size nn.
// @remark User must free the data b.
SrsBuffer(char* b, int nn);
virtual ~SrsBuffer();
~SrsBuffer();
public:
// Get the data and head of buffer.
// current-bytes = head() = data() + pos()
inline char* data() { return bytes; }
inline char* head() { return p; }
char* data();
char* head();
// Get the total size of buffer.
// left-bytes = size() - pos()
virtual int size();
void set_size(int v) { nb_bytes = v; }
int size();
void set_size(int v);
// Get the current buffer position.
virtual int pos();
int pos();
// Left bytes in buffer, total size() minus the current pos().
virtual int left();
int left();
// Whether buffer is empty.
virtual bool empty();
bool empty();
// Whether buffer is able to supply required size of bytes.
// @remark User should check buffer by require then do read/write.
// @remark Assert the required_size is not negative.
virtual bool require(int required_size);
bool require(int required_size);
public:
// Skip some size.
// @param size can be any value. positive to forward; nagetive to backward.
// @remark to skip(pos()) to reset buffer.
// @remark assert initialized, the data() not NULL.
virtual void skip(int size);
void skip(int size);
public:
// Read 1bytes char from buffer.
virtual int8_t read_1bytes();
int8_t read_1bytes();
// Read 2bytes int from buffer.
virtual int16_t read_2bytes();
int16_t read_2bytes();
// Read 3bytes int from buffer.
virtual int32_t read_3bytes();
int32_t read_3bytes();
// Read 4bytes int from buffer.
virtual int32_t read_4bytes();
int32_t read_4bytes();
// Read 8bytes int from buffer.
virtual int64_t read_8bytes();
int64_t read_8bytes();
// Read string from buffer, length specifies by param len.
virtual std::string read_string(int len);
std::string read_string(int len);
// Read bytes from buffer, length specifies by param len.
virtual void read_bytes(char* data, int size);
void read_bytes(char* data, int size);
public:
// Write 1bytes char to buffer.
virtual void write_1bytes(int8_t value);
void write_1bytes(int8_t value);
// Write 2bytes int to buffer.
virtual void write_2bytes(int16_t value);
void write_2bytes(int16_t value);
// Write 4bytes int to buffer.
virtual void write_4bytes(int32_t value);
void write_4bytes(int32_t value);
// Write 3bytes int to buffer.
virtual void write_3bytes(int32_t value);
void write_3bytes(int32_t value);
// Write 8bytes int to buffer.
virtual void write_8bytes(int64_t value);
void write_8bytes(int64_t value);
// Write string to buffer
virtual void write_string(std::string value);
void write_string(std::string value);
// Write bytes to buffer
virtual void write_bytes(char* data, int size);
void write_bytes(char* data, int size);
};
/**
@ -175,10 +175,10 @@ private:
SrsBuffer* stream;
public:
SrsBitBuffer(SrsBuffer* b);
virtual ~SrsBitBuffer();
~SrsBitBuffer();
public:
virtual bool empty();
virtual int8_t read_bit();
bool empty();
int8_t read_bit();
};
#endif

View file

@ -388,6 +388,36 @@ void SrsSharedPtrMessage::set_extra_payloads(SrsSample* payloads, int nn_payload
memcpy((void*)ptr->extra_payloads, payloads, nn_payloads * sizeof(SrsSample));
}
int SrsSharedPtrMessage::nn_extra_payloads()
{
return ptr->nn_extra_payloads;
}
SrsSample* SrsSharedPtrMessage::extra_payloads()
{
return ptr->extra_payloads;
}
void SrsSharedPtrMessage::set_max_extra_payload(int v)
{
ptr->nn_max_extra_payloads = v;
}
int SrsSharedPtrMessage::nn_max_extra_payloads()
{
return ptr->nn_max_extra_payloads;
}
bool SrsSharedPtrMessage::has_idr()
{
return ptr->has_idr;
}
void SrsSharedPtrMessage::set_has_idr(bool v)
{
ptr->has_idr = v;
}
void SrsSharedPtrMessage::set_samples(SrsSample* samples, int nn_samples)
{
srs_assert(nn_samples);
@ -398,6 +428,16 @@ void SrsSharedPtrMessage::set_samples(SrsSample* samples, int nn_samples)
ptr->samples = new SrsSample[nn_samples];
memcpy((void*)ptr->samples, samples, nn_samples * sizeof(SrsSample));
}
int SrsSharedPtrMessage::nn_samples()
{
return ptr->nn_samples;
}
SrsSample* SrsSharedPtrMessage::samples()
{
return ptr->samples;
}
#endif
SrsFlvTransmuxer::SrsFlvTransmuxer()

View file

@ -367,18 +367,18 @@ public:
// Set extra samples, for example, when we transcode an AAC audio packet to OPUS,
// we may get more than one OPUS packets, we set these OPUS packets in extra payloads.
void set_extra_payloads(SrsSample* payloads, int nn_payloads);
int nn_extra_payloads() { return ptr->nn_extra_payloads; }
SrsSample* extra_payloads() { return ptr->extra_payloads; }
int nn_extra_payloads();
SrsSample* extra_payloads();
// The max extra payload size.
void set_max_extra_payload(int v) { ptr->nn_max_extra_payloads = v; }
int nn_max_extra_payloads() { return ptr->nn_max_extra_payloads; }
void set_max_extra_payload(int v);
int nn_max_extra_payloads();
// Whether samples has idr.
bool has_idr() { return ptr->has_idr; }
void set_has_idr(bool v) { ptr->has_idr = v; }
bool has_idr();
void set_has_idr(bool v);
// Set samples, each sample points to the address of payload.
void set_samples(SrsSample* samples, int nn_samples);
int nn_samples() { return ptr->nn_samples; }
SrsSample* samples() { return ptr->samples; }
int nn_samples();
SrsSample* samples();
#endif
};

View file

@ -61,11 +61,11 @@ SrsRtpHeader::~SrsRtpHeader()
{
}
srs_error_t SrsRtpHeader::decode(SrsBuffer* stream)
srs_error_t SrsRtpHeader::decode(SrsBuffer* buf)
{
srs_error_t err = srs_success;
if (stream->size() < kRtpHeaderFixedSize) {
if (buf->size() < kRtpHeaderFixedSize) {
return srs_error_new(ERROR_RTC_RTP_MUXER, "rtp payload incorrect");
}
@ -84,60 +84,58 @@ srs_error_t SrsRtpHeader::decode(SrsBuffer* stream)
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
uint8_t first = stream->read_1bytes();
uint8_t first = buf->read_1bytes();
padding = (first & 0x20);
extension = (first & 0x10);
cc = (first & 0x0F);
uint8_t second = stream->read_1bytes();
uint8_t second = buf->read_1bytes();
marker = (second & 0x80);
payload_type = (second & 0x7F);
sequence = stream->read_2bytes();
timestamp = stream->read_4bytes();
ssrc = stream->read_4bytes();
sequence = buf->read_2bytes();
timestamp = buf->read_4bytes();
ssrc = buf->read_4bytes();
if ((size_t)stream->size() < header_size()) {
return srs_error_new(ERROR_RTC_RTP_MUXER, "rtp payload incorrect");
if (!buf->require(nb_bytes())) {
return srs_error_new(ERROR_RTC_RTP_MUXER, "requires %d+ bytes", nb_bytes());
}
for (uint8_t i = 0; i < cc; ++i) {
csrc[i] = stream->read_4bytes();
csrc[i] = buf->read_4bytes();
}
if (extension) {
// TODO:
uint16_t profile_id = stream->read_2bytes();
extension_length = stream->read_2bytes();
// @see: https://tools.ietf.org/html/rfc3550#section-5.3.1
stream->skip(extension_length * 4);
uint16_t profile_id = buf->read_2bytes();
extension_length = buf->read_2bytes();
srs_verbose("extension, profile_id=%u, length=%u", profile_id, extension_length);
// TODO: FIXME: Read extensions.
// @see: https://tools.ietf.org/html/rfc3550#section-5.3.1
buf->skip(extension_length * 4);
// @see: https://tools.ietf.org/html/rfc5285#section-4.2
if (profile_id == 0xBEDE) {
// TODO: FIXME: Implements it.
}
}
if (padding) {
padding_length = *(reinterpret_cast<uint8_t*>(stream->data() + stream->size() - 1));
if (padding_length > (stream->size() - stream->pos())) {
return srs_error_new(ERROR_RTC_RTP_MUXER, "rtp payload incorrect");
padding_length = *(reinterpret_cast<uint8_t*>(buf->data() + buf->size() - 1));
if (!buf->require(padding_length)) {
return srs_error_new(ERROR_RTC_RTP_MUXER, "padding requires %d bytes", padding_length);
}
srs_verbose("offset=%d, padding_length=%u", stream->size(), padding_length);
}
return err;
}
srs_error_t SrsRtpHeader::encode(SrsBuffer* stream)
srs_error_t SrsRtpHeader::encode(SrsBuffer* buf)
{
srs_error_t err = srs_success;
// Encode the RTP fix header, 12bytes.
// @see https://tools.ietf.org/html/rfc1889#section-5.1
char* op = stream->head();
char* op = buf->head();
char* p = op;
// The version, padding, extension and cc, total 1 byte.
@ -190,24 +188,42 @@ srs_error_t SrsRtpHeader::encode(SrsBuffer* stream)
}
// Consume the data.
stream->skip(p - op);
buf->skip(p - op);
return err;
}
size_t SrsRtpHeader::header_size()
int SrsRtpHeader::nb_bytes()
{
return kRtpHeaderFixedSize + cc * 4 + (extension ? (extension_length + 1) * 4 : 0);
}
ISrsRtpPacketDecodeHandler::ISrsRtpPacketDecodeHandler()
{
}
ISrsRtpPacketDecodeHandler::~ISrsRtpPacketDecodeHandler()
{
}
SrsRtpPacket2::SrsRtpPacket2()
{
payload = NULL;
padding = 0;
payload = NULL;
decode_handler = NULL;
is_first_packet_of_frame = false;
is_last_packet_of_frame = false;
is_key_frame = false;
nalu_type = SrsAvcNaluTypeReserved;
cache_raw = new SrsRtpRawPayload();
cache_fua = new SrsRtpFUAPayload2();
cache_payload = 0;
original_bytes = NULL;
nn_original_bytes = 0;
nn_original_payload = 0;
}
SrsRtpPacket2::~SrsRtpPacket2()
@ -220,6 +236,8 @@ SrsRtpPacket2::~SrsRtpPacket2()
srs_freep(payload);
srs_freep(cache_raw);
srs_freep(cache_fua);
srs_freepa(original_bytes);
}
void SrsRtpPacket2::set_padding(int size)
@ -270,7 +288,7 @@ SrsRtpFUAPayload2* SrsRtpPacket2::reuse_fua()
int SrsRtpPacket2::nb_bytes()
{
if (!cache_payload) {
cache_payload = rtp_header.header_size() + (payload? payload->nb_bytes():0) + padding;
cache_payload = rtp_header.nb_bytes() + (payload? payload->nb_bytes():0) + padding;
}
return cache_payload;
}
@ -284,7 +302,7 @@ srs_error_t SrsRtpPacket2::encode(SrsBuffer* buf)
}
if (payload && (err = payload->encode(buf)) != srs_success) {
return srs_error_wrap(err, "encode payload");
return srs_error_wrap(err, "rtp payload");
}
if (padding > 0) {
@ -298,6 +316,44 @@ srs_error_t SrsRtpPacket2::encode(SrsBuffer* buf)
return err;
}
srs_error_t SrsRtpPacket2::decode(SrsBuffer* buf)
{
srs_error_t err = srs_success;
if ((err = rtp_header.decode(buf)) != srs_success) {
return srs_error_wrap(err, "rtp header");
}
// We must skip the padding bytes before parsing payload.
padding = rtp_header.get_padding_length();
if (!buf->require(padding)) {
return srs_error_wrap(err, "requires padding %d bytes", padding);
}
buf->set_size(buf->size() - padding);
// Try to parse the NALU type for video decoder.
if (!buf->empty()) {
nalu_type = SrsAvcNaluType((uint8_t)(buf->head()[0] & 0x3f));
}
// If user set the decode handler, call it to set the payload.
if (decode_handler) {
decode_handler->on_before_decode_payload(this, buf, &payload);
nn_original_payload = buf->left();
}
// By default, we always use the RAW payload.
if (!payload) {
payload = reuse_raw();
}
if ((err = payload->decode(buf)) != srs_success) {
return srs_error_wrap(err, "rtp payload");
}
return err;
}
SrsRtpRawPayload::SrsRtpRawPayload()
{
payload = NULL;
@ -328,6 +384,18 @@ srs_error_t SrsRtpRawPayload::encode(SrsBuffer* buf)
return srs_success;
}
srs_error_t SrsRtpRawPayload::decode(SrsBuffer* buf)
{
if (buf->empty()) {
return srs_success;
}
payload = buf->head();
nn_payload = buf->left();
return srs_success;
}
SrsRtpRawNALUs::SrsRtpRawNALUs()
{
cursor = 0;
@ -336,12 +404,10 @@ SrsRtpRawNALUs::SrsRtpRawNALUs()
SrsRtpRawNALUs::~SrsRtpRawNALUs()
{
if (true) {
int nn_nalus = (int)nalus.size();
for (int i = 0; i < nn_nalus; i++) {
SrsSample* p = nalus[i];
srs_freep(p);
}
int nn_nalus = (int)nalus.size();
for (int i = 0; i < nn_nalus; i++) {
SrsSample* p = nalus[i];
srs_freep(p);
}
}
@ -436,6 +502,22 @@ srs_error_t SrsRtpRawNALUs::encode(SrsBuffer* buf)
return srs_success;
}
srs_error_t SrsRtpRawNALUs::decode(SrsBuffer* buf)
{
if (buf->empty()) {
return srs_success;
}
SrsSample* sample = new SrsSample();
sample->bytes = buf->head();
sample->size = buf->left();
buf->skip(sample->size);
nalus.push_back(sample);
return srs_success;
}
SrsRtpSTAPPayload::SrsRtpSTAPPayload()
{
nri = (SrsAvcNaluType)0;
@ -491,6 +573,39 @@ srs_error_t SrsRtpSTAPPayload::encode(SrsBuffer* buf)
return srs_success;
}
srs_error_t SrsRtpSTAPPayload::decode(SrsBuffer* buf)
{
if (!buf->require(1)) {
return srs_error_new(ERROR_RTC_RTP_MUXER, "requires %d bytes", 1);
}
// STAP header, RTP payload format for aggregation packets
// @see https://tools.ietf.org/html/rfc6184#section-5.7
uint8_t v = buf->read_1bytes();
nri = SrsAvcNaluType(v & kNalTypeMask);
// NALUs.
while (!buf->empty()) {
if (!buf->require(2)) {
return srs_error_new(ERROR_RTC_RTP_MUXER, "requires %d bytes", 2);
}
int size = buf->read_2bytes();
if (!buf->require(size)) {
return srs_error_new(ERROR_RTC_RTP_MUXER, "requires %d bytes", size);
}
SrsSample* sample = new SrsSample();
sample->bytes = buf->head();
sample->size = size;
buf->skip(size);
nalus.push_back(sample);
}
return srs_success;
}
SrsRtpFUAPayload::SrsRtpFUAPayload()
{
start = end = false;
@ -555,6 +670,36 @@ srs_error_t SrsRtpFUAPayload::encode(SrsBuffer* buf)
return srs_success;
}
srs_error_t SrsRtpFUAPayload::decode(SrsBuffer* buf)
{
if (!buf->require(2)) {
return srs_error_new(ERROR_RTC_RTP_MUXER, "requires %d bytes", 2);
}
// FU indicator, @see https://tools.ietf.org/html/rfc6184#section-5.8
uint8_t v = buf->read_1bytes();
nri = SrsAvcNaluType(v & kNalTypeMask);
// FU header, @see https://tools.ietf.org/html/rfc6184#section-5.8
v = buf->read_1bytes();
start = v & kStart;
end = v & kEnd;
nalu_type = SrsAvcNaluType(v & 0x3f);
if (!buf->require(1)) {
return srs_error_new(ERROR_RTC_RTP_MUXER, "requires %d bytes", 1);
}
SrsSample* sample = new SrsSample();
sample->bytes = buf->head();
sample->size = buf->left();
buf->skip(sample->size);
nalus.push_back(sample);
return srs_success;
}
SrsRtpFUAPayload2::SrsRtpFUAPayload2()
{
start = end = false;
@ -606,6 +751,33 @@ srs_error_t SrsRtpFUAPayload2::encode(SrsBuffer* buf)
return srs_success;
}
srs_error_t SrsRtpFUAPayload2::decode(SrsBuffer* buf)
{
if (!buf->require(2)) {
return srs_error_new(ERROR_RTC_RTP_MUXER, "requires %d bytes", 2);
}
// FU indicator, @see https://tools.ietf.org/html/rfc6184#section-5.8
uint8_t v = buf->read_1bytes();
nri = SrsAvcNaluType(v & (~kNalTypeMask));
// FU header, @see https://tools.ietf.org/html/rfc6184#section-5.8
v = buf->read_1bytes();
start = v & kStart;
end = v & kEnd;
nalu_type = SrsAvcNaluType(v & 0x3f);
if (!buf->require(1)) {
return srs_error_new(ERROR_RTC_RTP_MUXER, "requires %d bytes", 1);
}
payload = buf->head();
size = buf->left();
buf->skip(size);
return srs_success;
}
SrsRtpPayloadHeader::SrsRtpPayloadHeader()
{
is_first_packet_of_frame = false;
@ -721,7 +893,7 @@ srs_error_t SrsRtpSharedPacket::create(SrsRtpHeader* rtp_h, SrsRtpPayloadHeader*
this->rtp_payload_header = rtp_ph;
// TODO: rtp header padding.
size_t buffer_size = rtp_header.header_size() + s;
int buffer_size = rtp_header.nb_bytes() + s;
char* buffer = new char[buffer_size];
SrsBuffer stream(buffer, buffer_size);

View file

@ -31,6 +31,8 @@
#include <string>
class SrsRtpPacket2;
const int kRtpHeaderFixedSize = 12;
const uint8_t kRtpMarker = 0x80;
@ -72,10 +74,9 @@ public:
virtual ~SrsRtpHeader();
void reset();
public:
srs_error_t decode(SrsBuffer* stream);
srs_error_t encode(SrsBuffer* stream);
public:
size_t header_size();
virtual srs_error_t decode(SrsBuffer* buf);
virtual srs_error_t encode(SrsBuffer* buf);
virtual int nb_bytes();
public:
inline void set_marker(bool v) { marker = v; }
bool get_marker() const { return marker; }
@ -92,16 +93,48 @@ public:
uint8_t get_padding_length() const { return padding_length; }
};
class SrsRtpPacket2
class ISrsRtpPacketDecodeHandler
{
public:
ISrsRtpPacketDecodeHandler();
virtual ~ISrsRtpPacketDecodeHandler();
public:
// We don't know the actual payload, so we depends on external handler.
virtual void on_before_decode_payload(SrsRtpPacket2* pkt, SrsBuffer* buf, ISrsCodec** ppayload) = 0;
};
class SrsRtpPacket2
{
// RTP packet fields.
public:
// TODO: FIXME: Rename to header.
SrsRtpHeader rtp_header;
ISrsEncoder* payload;
ISrsCodec* payload;
// TODO: FIXME: Merge into rtp_header.
int padding;
// Decoder helper.
public:
// Helper information for decoder.
bool is_first_packet_of_frame;
bool is_last_packet_of_frame;
bool is_key_frame;
// The first byte as nalu type, for video decoder only.
SrsAvcNaluType nalu_type;
// The original payload bytes length.
int nn_original_payload;
// Decoder helper.
private:
// The original bytes for decoder only, we will free it.
char* original_bytes;
int nn_original_bytes;
// Fast cache for performance.
private:
// Cache frequently used payload for performance.
SrsRtpRawPayload* cache_raw;
SrsRtpFUAPayload2* cache_fua;
int cache_payload;
// The helper handler for decoder, use RAW payload if NULL.
ISrsRtpPacketDecodeHandler* decode_handler;
public:
SrsRtpPacket2();
virtual ~SrsRtpPacket2();
@ -116,14 +149,19 @@ public:
SrsRtpRawPayload* reuse_raw();
// Reuse the cached fua message as payload.
SrsRtpFUAPayload2* reuse_fua();
// Set the decode handler.
void set_decode_handler(ISrsRtpPacketDecodeHandler* h) { decode_handler = h; }
// Set the original bytes.
void set_original_bytes(char* buf, int nn_buf) { original_bytes = buf; nn_original_bytes = nn_buf; }
// interface ISrsEncoder
public:
virtual int nb_bytes();
virtual srs_error_t encode(SrsBuffer* buf);
virtual srs_error_t decode(SrsBuffer* buf);
};
// Single payload data.
class SrsRtpRawPayload : public ISrsEncoder
class SrsRtpRawPayload : public ISrsCodec
{
public:
// The RAW payload, directly point to the shared memory.
@ -137,10 +175,11 @@ public:
public:
virtual int nb_bytes();
virtual srs_error_t encode(SrsBuffer* buf);
virtual srs_error_t decode(SrsBuffer* buf);
};
// Multiple NALUs, automatically insert 001 between NALUs.
class SrsRtpRawNALUs : public ISrsEncoder
class SrsRtpRawNALUs : public ISrsCodec
{
private:
// We will manage the samples, but the sample itself point to the shared memory.
@ -160,10 +199,11 @@ public:
public:
virtual int nb_bytes();
virtual srs_error_t encode(SrsBuffer* buf);
virtual srs_error_t decode(SrsBuffer* buf);
};
// STAP-A, for multiple NALUs.
class SrsRtpSTAPPayload : public ISrsEncoder
class SrsRtpSTAPPayload : public ISrsCodec
{
public:
// The NRI in NALU type.
@ -178,11 +218,12 @@ public:
public:
virtual int nb_bytes();
virtual srs_error_t encode(SrsBuffer* buf);
virtual srs_error_t decode(SrsBuffer* buf);
};
// FU-A, for one NALU with multiple fragments.
// With more than one payload.
class SrsRtpFUAPayload : public ISrsEncoder
class SrsRtpFUAPayload : public ISrsCodec
{
public:
// The NRI in NALU type.
@ -201,11 +242,12 @@ public:
public:
virtual int nb_bytes();
virtual srs_error_t encode(SrsBuffer* buf);
virtual srs_error_t decode(SrsBuffer* buf);
};
// FU-A, for one NALU with multiple fragments.
// With only one payload.
class SrsRtpFUAPayload2 : public ISrsEncoder
class SrsRtpFUAPayload2 : public ISrsCodec
{
public:
// The NRI in NALU type.
@ -224,6 +266,7 @@ public:
public:
virtual int nb_bytes();
virtual srs_error_t encode(SrsBuffer* buf);
virtual srs_error_t decode(SrsBuffer* buf);
};
class SrsRtpPayloadHeader
@ -290,8 +333,8 @@ public:
srs_error_t decode(char* buf, int nb_buf);
SrsRtpSharedPacket* copy();
public:
char* rtp_payload() { return payload + rtp_header.header_size(); }
int rtp_payload_size() { return size - rtp_header.header_size() - rtp_header.get_padding_length(); }
char* rtp_payload() { return payload + rtp_header.nb_bytes(); }
int rtp_payload_size() { return size - rtp_header.nb_bytes() - rtp_header.get_padding_length(); }
// Interface to modify rtp header
public:
srs_error_t modify_rtp_header_marker(bool marker);