mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
For #307, zero copy for RTP STAP packet
This commit is contained in:
parent
4b2404c203
commit
aa81b47c9a
8 changed files with 191 additions and 55 deletions
|
@ -29,6 +29,14 @@ using namespace std;
|
|||
#include <srs_kernel_error.hpp>
|
||||
#include <srs_kernel_utility.hpp>
|
||||
|
||||
ISrsEncoder::ISrsEncoder()
|
||||
{
|
||||
}
|
||||
|
||||
ISrsEncoder::~ISrsEncoder()
|
||||
{
|
||||
}
|
||||
|
||||
ISrsCodec::ISrsCodec()
|
||||
{
|
||||
}
|
||||
|
|
|
@ -31,6 +31,24 @@
|
|||
|
||||
class SrsBuffer;
|
||||
|
||||
// Encoder.
|
||||
class ISrsEncoder
|
||||
{
|
||||
public:
|
||||
ISrsEncoder();
|
||||
virtual ~ISrsEncoder();
|
||||
public:
|
||||
/**
|
||||
* get the number of bytes to code to.
|
||||
*/
|
||||
// TODO: FIXME: change to uint64_t.
|
||||
virtual int nb_bytes() = 0;
|
||||
/**
|
||||
* encode object to bytes in SrsBuffer.
|
||||
*/
|
||||
virtual srs_error_t encode(SrsBuffer* buf) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* the srs codec, to code and decode object with bytes:
|
||||
* code: to encode/serialize object to bytes in buffer,
|
||||
|
@ -56,21 +74,11 @@ class SrsBuffer;
|
|||
* @remark protocol or amf0 or json should implements this interface.
|
||||
*/
|
||||
// TODO: FIXME: protocol, amf0, json should implements it.
|
||||
class ISrsCodec
|
||||
class ISrsCodec : public ISrsEncoder
|
||||
{
|
||||
public:
|
||||
ISrsCodec();
|
||||
virtual ~ISrsCodec();
|
||||
public:
|
||||
/**
|
||||
* get the number of bytes to code to.
|
||||
*/
|
||||
// TODO: FIXME: change to uint64_t.
|
||||
virtual int nb_bytes() = 0;
|
||||
/**
|
||||
* encode object to bytes in SrsBuffer.
|
||||
*/
|
||||
virtual srs_error_t encode(SrsBuffer* buf) = 0;
|
||||
public:
|
||||
/**
|
||||
* decode object from bytes in SrsBuffer.
|
||||
|
|
|
@ -32,6 +32,7 @@ using namespace std;
|
|||
#include <srs_kernel_buffer.hpp>
|
||||
#include <srs_kernel_utility.hpp>
|
||||
#include <srs_core_autofree.hpp>
|
||||
#include <srs_kernel_rtp.hpp>
|
||||
|
||||
string srs_video_codec_id2str(SrsVideoCodecId codec)
|
||||
{
|
||||
|
@ -375,9 +376,6 @@ srs_error_t SrsSample::parse_bframe()
|
|||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
// H.264 nalu header type mask.
|
||||
static uint8_t kNalTypeMask = 0x1F;
|
||||
|
||||
uint8_t header = bytes[0];
|
||||
SrsAvcNaluType nal_type = (SrsAvcNaluType)(header & kNalTypeMask);
|
||||
|
||||
|
|
|
@ -32,6 +32,8 @@ using namespace std;
|
|||
#include <srs_kernel_buffer.hpp>
|
||||
#include <srs_kernel_utility.hpp>
|
||||
|
||||
// @see: https://tools.ietf.org/html/rfc6184#section-5.2
|
||||
const uint8_t kStapA = 24;
|
||||
|
||||
SrsRtpHeader::SrsRtpHeader()
|
||||
{
|
||||
|
@ -148,32 +150,106 @@ void SrsRtpHeader::set_ssrc(uint32_t ssrc)
|
|||
SrsRtpPacket2::SrsRtpPacket2()
|
||||
{
|
||||
payload = NULL;
|
||||
nn_payload = 0;
|
||||
}
|
||||
|
||||
SrsRtpPacket2::~SrsRtpPacket2()
|
||||
{
|
||||
srs_freep(payload);
|
||||
}
|
||||
|
||||
srs_error_t SrsRtpPacket2::encode(SrsBuffer* stream)
|
||||
srs_error_t SrsRtpPacket2::encode(SrsBuffer* buf)
|
||||
{
|
||||
srs_error_t err = srs_success;
|
||||
|
||||
if ((err = rtp_header.encode(stream)) != srs_success) {
|
||||
if ((err = rtp_header.encode(buf)) != srs_success) {
|
||||
return srs_error_wrap(err, "rtp header");
|
||||
}
|
||||
|
||||
if (nn_payload <= 0) {
|
||||
return 0;
|
||||
if (payload && (err = payload->encode(buf)) != srs_success) {
|
||||
return srs_error_wrap(err, "encode payload");
|
||||
}
|
||||
|
||||
if (!stream->require(nn_payload)) {
|
||||
return err;
|
||||
}
|
||||
|
||||
SrsRtpRawPayload::SrsRtpRawPayload()
|
||||
{
|
||||
payload = NULL;
|
||||
nn_payload = 0;
|
||||
}
|
||||
|
||||
SrsRtpRawPayload::~SrsRtpRawPayload()
|
||||
{
|
||||
}
|
||||
|
||||
int SrsRtpRawPayload::nb_bytes()
|
||||
{
|
||||
return nn_payload;
|
||||
}
|
||||
|
||||
srs_error_t SrsRtpRawPayload::encode(SrsBuffer* buf)
|
||||
{
|
||||
if (nn_payload <= 0) {
|
||||
return srs_success;
|
||||
}
|
||||
|
||||
if (!buf->require(nn_payload)) {
|
||||
return srs_error_new(ERROR_RTC_RTP_MUXER, "requires %d bytes", nn_payload);
|
||||
}
|
||||
|
||||
stream->write_bytes(payload, nn_payload);
|
||||
buf->write_bytes(payload, nn_payload);
|
||||
|
||||
return err;
|
||||
return srs_success;
|
||||
}
|
||||
|
||||
SrsRtpSTAPPayload::SrsRtpSTAPPayload()
|
||||
{
|
||||
nri = (SrsAvcNaluType)0;
|
||||
nalus = NULL;
|
||||
nn_nalus = 0;
|
||||
}
|
||||
|
||||
SrsRtpSTAPPayload::~SrsRtpSTAPPayload()
|
||||
{
|
||||
srs_freepa(nalus);
|
||||
}
|
||||
|
||||
int SrsRtpSTAPPayload::nb_bytes()
|
||||
{
|
||||
int size = 1;
|
||||
|
||||
for (int i = 0; i < nn_nalus; i++) {
|
||||
SrsSample* p = nalus + i;
|
||||
size += 2 + p->size;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
srs_error_t SrsRtpSTAPPayload::encode(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 = kStapA;
|
||||
v |= (nri & (~kNalTypeMask));
|
||||
buf->write_1bytes(v);
|
||||
|
||||
// NALUs.
|
||||
for (int i = 0; i < nn_nalus; i++) {
|
||||
SrsSample* p = nalus + i;
|
||||
if (!buf->require(2 + p->size)) {
|
||||
return srs_error_new(ERROR_RTC_RTP_MUXER, "requires %d bytes", 2 + p->size);
|
||||
}
|
||||
|
||||
buf->write_2bytes(p->size);
|
||||
buf->write_bytes(p->bytes, p->size);
|
||||
}
|
||||
|
||||
return srs_success;
|
||||
}
|
||||
|
||||
SrsRtpSharedPacket::SrsRtpSharedPacketPayload::SrsRtpSharedPacketPayload()
|
||||
|
|
|
@ -26,11 +26,17 @@
|
|||
|
||||
#include <srs_core.hpp>
|
||||
|
||||
#include <srs_kernel_buffer.hpp>
|
||||
#include <srs_kernel_codec.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
const int kRtpHeaderFixedSize = 12;
|
||||
const uint8_t kRtpMarker = 0x80;
|
||||
|
||||
// H.264 nalu header type mask.
|
||||
const uint8_t kNalTypeMask = 0x1F;
|
||||
|
||||
class SrsBuffer;
|
||||
|
||||
class SrsRtpHeader
|
||||
|
@ -74,14 +80,45 @@ class SrsRtpPacket2
|
|||
{
|
||||
public:
|
||||
SrsRtpHeader rtp_header;
|
||||
// @remark We only refer to the memory, user must free it.
|
||||
char* payload;
|
||||
int nn_payload;
|
||||
ISrsEncoder* payload;
|
||||
public:
|
||||
SrsRtpPacket2();
|
||||
virtual ~SrsRtpPacket2();
|
||||
public:
|
||||
virtual srs_error_t encode(SrsBuffer* stream);
|
||||
virtual srs_error_t encode(SrsBuffer* buf);
|
||||
};
|
||||
|
||||
class SrsRtpRawPayload : public ISrsEncoder
|
||||
{
|
||||
public:
|
||||
// @remark We only refer to the memory, user must free it.
|
||||
char* payload;
|
||||
int nn_payload;
|
||||
public:
|
||||
SrsRtpRawPayload();
|
||||
virtual ~SrsRtpRawPayload();
|
||||
// interface ISrsEncoder
|
||||
public:
|
||||
virtual int nb_bytes();
|
||||
virtual srs_error_t encode(SrsBuffer* buf);
|
||||
};
|
||||
|
||||
class SrsRtpSTAPPayload : public ISrsEncoder
|
||||
{
|
||||
public:
|
||||
// The NRI in NALU type.
|
||||
SrsAvcNaluType nri;
|
||||
// The NALU samples.
|
||||
// @remark We only refer to the memory, user must free its bytes.
|
||||
SrsSample* nalus;
|
||||
int nn_nalus;
|
||||
public:
|
||||
SrsRtpSTAPPayload();
|
||||
virtual ~SrsRtpSTAPPayload();
|
||||
// interface ISrsEncoder
|
||||
public:
|
||||
virtual int nb_bytes();
|
||||
virtual srs_error_t encode(SrsBuffer* buf);
|
||||
};
|
||||
|
||||
class SrsRtpSharedPacket
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue