Skip to content

Commit

Permalink
Perf: Refine object cache, avoid dynamic cast
Browse files Browse the repository at this point in the history
  • Loading branch information
winlinvip committed Feb 27, 2021
1 parent 427e3e0 commit 471cf61
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 44 deletions.
6 changes: 3 additions & 3 deletions trunk/src/app/srs_app_rtc_conn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1268,7 +1268,7 @@ srs_error_t SrsRtcPublishStream::check_send_nacks()
return err;
}

void SrsRtcPublishStream::on_before_decode_payload(SrsRtpPacket2* pkt, SrsBuffer* buf, ISrsRtpPayloader** ppayload)
void SrsRtcPublishStream::on_before_decode_payload(SrsRtpPacket2* pkt, SrsBuffer* buf, ISrsRtpPayloader** ppayload, SrsRtpPacketPayloadType* ppt)
{
// No payload, ignore.
if (buf->empty()) {
Expand All @@ -1280,9 +1280,9 @@ void SrsRtcPublishStream::on_before_decode_payload(SrsRtpPacket2* pkt, SrsBuffer
SrsRtcVideoRecvTrack* video_track = get_video_track(ssrc);

if (audio_track) {
audio_track->on_before_decode_payload(pkt, buf, ppayload);
audio_track->on_before_decode_payload(pkt, buf, ppayload, ppt);
} else if (video_track) {
video_track->on_before_decode_payload(pkt, buf, ppayload);
video_track->on_before_decode_payload(pkt, buf, ppayload, ppt);
}
}

Expand Down
2 changes: 1 addition & 1 deletion trunk/src/app/srs_app_rtc_conn.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ class SrsRtcPublishStream : virtual public ISrsHourGlass, virtual public ISrsRtp
public:
srs_error_t check_send_nacks();
public:
virtual void on_before_decode_payload(SrsRtpPacket2* pkt, SrsBuffer* buf, ISrsRtpPayloader** ppayload);
virtual void on_before_decode_payload(SrsRtpPacket2* pkt, SrsBuffer* buf, ISrsRtpPayloader** ppayload, SrsRtpPacketPayloadType* ppt);
private:
srs_error_t send_periodic_twcc();
public:
Expand Down
20 changes: 12 additions & 8 deletions trunk/src/app/srs_app_rtc_source.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -826,7 +826,7 @@ srs_error_t SrsRtcFromRtmpBridger::package_opus(char* data, int size, SrsRtpPack
audio_timestamp += 960;

SrsRtpRawPayload* raw = _srs_rtp_raw_cache->allocate();
pkt->payload = raw;
pkt->set_payload(raw, SrsRtpPacketPayloadTypeRaw);

raw->payload = pkt->wrap(data, size);
raw->nn_payload = size;
Expand Down Expand Up @@ -961,7 +961,7 @@ srs_error_t SrsRtcFromRtmpBridger::package_stap_a(SrsRtcStream* source, SrsShare
pkt->header.set_timestamp(msg->timestamp * 90);

SrsRtpSTAPPayload* stap = new SrsRtpSTAPPayload();
pkt->payload = stap;
pkt->set_payload(stap, SrsRtpPacketPayloadTypeSTAP);

uint8_t header = sps[0];
stap->nri = (SrsAvcNaluType)header;
Expand Down Expand Up @@ -1041,7 +1041,7 @@ srs_error_t SrsRtcFromRtmpBridger::package_nalus(SrsSharedPtrMessage* msg, const
pkt->nalu_type = (SrsAvcNaluType)first_nalu_type;
pkt->header.set_sequence(video_sequence++);
pkt->header.set_timestamp(msg->timestamp * 90);
pkt->payload = raw;
pkt->set_payload(raw, SrsRtpPacketPayloadTypeNALU);
pkt->wrap(msg);
} else {
// We must free it, should never use RTP packets to free it,
Expand Down Expand Up @@ -1082,7 +1082,7 @@ srs_error_t SrsRtcFromRtmpBridger::package_nalus(SrsSharedPtrMessage* msg, const
fua->start = bool(i == 0);
fua->end = bool(i == num_of_packet - 1);

pkt->payload = fua;
pkt->set_payload(fua, SrsRtpPacketPayloadTypeFUA);
pkt->wrap(msg);

nb_left -= packet_size;
Expand All @@ -1108,7 +1108,7 @@ srs_error_t SrsRtcFromRtmpBridger::package_single_nalu(SrsSharedPtrMessage* msg,
pkt->header.set_timestamp(msg->timestamp * 90);

SrsRtpRawPayload* raw = _srs_rtp_raw_cache->allocate();
pkt->payload = raw;
pkt->set_payload(raw, SrsRtpPacketPayloadTypeRaw);

raw->payload = sample->bytes;
raw->nn_payload = sample->size;
Expand Down Expand Up @@ -1142,7 +1142,7 @@ srs_error_t SrsRtcFromRtmpBridger::package_fu_a(SrsSharedPtrMessage* msg, SrsSam
pkt->header.set_timestamp(msg->timestamp * 90);

SrsRtpFUAPayload2* fua = _srs_rtp_fua_cache->allocate();
pkt->payload = fua;
pkt->set_payload(fua, SrsRtpPacketPayloadTypeFUA2);

fua->nri = (SrsAvcNaluType)header;
fua->nalu_type = (SrsAvcNaluType)nal_type;
Expand Down Expand Up @@ -1854,14 +1854,15 @@ SrsRtcAudioRecvTrack::~SrsRtcAudioRecvTrack()
{
}

void SrsRtcAudioRecvTrack::on_before_decode_payload(SrsRtpPacket2* pkt, SrsBuffer* buf, ISrsRtpPayloader** ppayload)
void SrsRtcAudioRecvTrack::on_before_decode_payload(SrsRtpPacket2* pkt, SrsBuffer* buf, ISrsRtpPayloader** ppayload, SrsRtpPacketPayloadType* ppt)
{
// No payload, ignore.
if (buf->empty()) {
return;
}

*ppayload = _srs_rtp_raw_cache->allocate();
*ppt = SrsRtpPacketPayloadTypeRaw;
}

srs_error_t SrsRtcAudioRecvTrack::on_rtp(SrsRtcStream* source, SrsRtpPacket2* pkt, bool nack_enabled)
Expand Down Expand Up @@ -1910,7 +1911,7 @@ SrsRtcVideoRecvTrack::~SrsRtcVideoRecvTrack()
{
}

void SrsRtcVideoRecvTrack::on_before_decode_payload(SrsRtpPacket2* pkt, SrsBuffer* buf, ISrsRtpPayloader** ppayload)
void SrsRtcVideoRecvTrack::on_before_decode_payload(SrsRtpPacket2* pkt, SrsBuffer* buf, ISrsRtpPayloader** ppayload, SrsRtpPacketPayloadType* ppt)
{
// No payload, ignore.
if (buf->empty()) {
Expand All @@ -1920,10 +1921,13 @@ void SrsRtcVideoRecvTrack::on_before_decode_payload(SrsRtpPacket2* pkt, SrsBuffe
uint8_t v = (uint8_t)pkt->nalu_type;
if (v == kStapA) {
*ppayload = new SrsRtpSTAPPayload();
*ppt = SrsRtpPacketPayloadTypeUnknown;
} else if (v == kFuA) {
*ppayload = _srs_rtp_fua_cache->allocate();
*ppt = SrsRtpPacketPayloadTypeFUA2;
} else {
*ppayload = _srs_rtp_raw_cache->allocate();
*ppt = SrsRtpPacketPayloadTypeRaw;
}
}

Expand Down
4 changes: 2 additions & 2 deletions trunk/src/app/srs_app_rtc_source.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,7 @@ class SrsRtcAudioRecvTrack : virtual public SrsRtcRecvTrack, virtual public ISrs
SrsRtcAudioRecvTrack(SrsRtcConnection* session, SrsRtcTrackDescription* track_desc);
virtual ~SrsRtcAudioRecvTrack();
public:
virtual void on_before_decode_payload(SrsRtpPacket2* pkt, SrsBuffer* buf, ISrsRtpPayloader** ppayload);
virtual void on_before_decode_payload(SrsRtpPacket2* pkt, SrsBuffer* buf, ISrsRtpPayloader** ppayload, SrsRtpPacketPayloadType* ppt);
public:
virtual srs_error_t on_rtp(SrsRtcStream* source, SrsRtpPacket2* pkt, bool nack_enabled);
virtual srs_error_t check_send_nacks();
Expand All @@ -561,7 +561,7 @@ class SrsRtcVideoRecvTrack : virtual public SrsRtcRecvTrack, virtual public ISrs
SrsRtcVideoRecvTrack(SrsRtcConnection* session, SrsRtcTrackDescription* stream_descs);
virtual ~SrsRtcVideoRecvTrack();
public:
virtual void on_before_decode_payload(SrsRtpPacket2* pkt, SrsBuffer* buf, ISrsRtpPayloader** ppayload);
virtual void on_before_decode_payload(SrsRtpPacket2* pkt, SrsBuffer* buf, ISrsRtpPayloader** ppayload, SrsRtpPacketPayloadType* ppt);
public:
virtual srs_error_t on_rtp(SrsRtcStream* source, SrsRtpPacket2* pkt, bool nack_enabled);
virtual srs_error_t check_send_nacks();
Expand Down
60 changes: 33 additions & 27 deletions trunk/src/kernel/srs_kernel_rtc_rtp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -811,7 +811,7 @@ ISrsRtpPacketDecodeHandler::~ISrsRtpPacketDecodeHandler()

SrsRtpPacket2::SrsRtpPacket2()
{
payload = NULL;
payload_ = NULL; payload_type_ = SrsRtpPacketPayloadTypeUnknown;
shared_msg = NULL;

reset();
Expand All @@ -821,31 +821,31 @@ SrsRtpPacket2::SrsRtpPacket2()

SrsRtpPacket2::~SrsRtpPacket2()
{
reuse();
reuse_payload();
reuse_shared_msg();
}

void SrsRtpPacket2::reuse()
void SrsRtpPacket2::reuse_payload()
{
if (!payload_) {
return;
}

if (_srs_rtp_raw_cache->enabled() || _srs_rtp_fua_cache->enabled()) {
// Only recycle some common payloads.
SrsRtpRawPayload* raw_payload;
SrsRtpFUAPayload2* fua_payload;

if ((raw_payload = dynamic_cast<SrsRtpRawPayload*>(payload)) != NULL) {
_srs_rtp_raw_cache->recycle(raw_payload);
payload = NULL;
} else if ((fua_payload = dynamic_cast<SrsRtpFUAPayload2*>(payload)) != NULL) {
_srs_rtp_fua_cache->recycle(fua_payload);
payload = NULL;
if (payload_type_ == SrsRtpPacketPayloadTypeRaw) {
_srs_rtp_raw_cache->recycle((SrsRtpRawPayload*)payload_);
} else if (payload_type_ == SrsRtpPacketPayloadTypeFUA2) {
_srs_rtp_fua_cache->recycle((SrsRtpFUAPayload2*)payload_);
} else {
srs_freep(payload);
srs_freep(payload_);
}
} else {
srs_freep(payload);
srs_freep(payload_);
}

// Recycle the real owner of message, clear the reference.
reuse_shared_msg();
// Reset the payload and its type.
payload_ = NULL; payload_type_ = SrsRtpPacketPayloadTypeUnknown;
}

void SrsRtpPacket2::reuse_shared_msg()
Expand All @@ -854,6 +854,7 @@ void SrsRtpPacket2::reuse_shared_msg()
return;
}

// Recycle the real owner of message, clear the reference.
if (_srs_rtp_msg_cache_buffers->enabled() || _srs_rtp_msg_cache_objs->enabled()) {
// We only recycle the RTC UDP packet messages.
if (shared_msg->payload && shared_msg->size == kRtpPacketSize && shared_msg->count() == 0) {
Expand All @@ -877,9 +878,8 @@ bool SrsRtpPacket2::reset()
decode_handler = NULL;

header.reset();

// Reset and reuse the payload and shared message.
reuse();
reuse_payload();
reuse_shared_msg();

return true;
}
Expand Down Expand Up @@ -967,11 +967,16 @@ SrsRtpPacket2* SrsRtpPacket2::copy()
{
SrsRtpPacket2* cp = _srs_rtp_cache->allocate();

// We got packet from cache, so we must recycle it.
cp->reuse_payload();
cp->reuse_shared_msg();

cp->header = header;
cp->payload = payload? payload->copy():NULL;
cp->payload_ = payload_? payload_->copy():NULL;
cp->payload_type_ = payload_type_;

cp->nalu_type = nalu_type;
cp->wrap(shared_msg); // Wrap the shared message and buffer.
cp->shared_msg = shared_msg->copy();
cp->frame_type = frame_type;

cp->cached_payload_size = cached_payload_size;
Expand All @@ -988,7 +993,7 @@ void SrsRtpPacket2::set_extension_types(const SrsRtpExtensionTypes* v)
uint64_t SrsRtpPacket2::nb_bytes()
{
if (!cached_payload_size) {
int nn_payload = (payload? payload->nb_bytes():0);
int nn_payload = (payload_? payload_->nb_bytes():0);
cached_payload_size = header.nb_bytes() + nn_payload + header.get_padding();
}
return cached_payload_size;
Expand All @@ -1002,7 +1007,7 @@ srs_error_t SrsRtpPacket2::encode(SrsBuffer* buf)
return srs_error_wrap(err, "rtp header");
}

if (payload && (err = payload->encode(buf)) != srs_success) {
if (payload_ && (err = payload_->encode(buf)) != srs_success) {
return srs_error_wrap(err, "rtp payload");
}

Expand Down Expand Up @@ -1040,15 +1045,16 @@ srs_error_t SrsRtpPacket2::decode(SrsBuffer* buf)

// If user set the decode handler, call it to set the payload.
if (decode_handler) {
decode_handler->on_before_decode_payload(this, buf, &payload);
decode_handler->on_before_decode_payload(this, buf, &payload_, &payload_type_);
}

// By default, we always use the RAW payload.
if (!payload) {
payload = _srs_rtp_raw_cache->allocate();
if (!payload_) {
payload_ = _srs_rtp_raw_cache->allocate();
payload_type_ = SrsRtpPacketPayloadTypeRaw;
}

if ((err = payload->decode(buf)) != srs_success) {
if ((err = payload_->decode(buf)) != srs_success) {
return srs_error_wrap(err, "rtp payload");
}

Expand Down
23 changes: 20 additions & 3 deletions trunk/src/kernel/srs_kernel_rtc_rtp.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ class SrsRtpHeader// : public ISrsCodec
srs_error_t set_twcc_sequence_number(uint8_t id, uint16_t sn);
};

// The common payload interface for RTP packet.
class ISrsRtpPayloader : public ISrsCodec
{
public:
Expand All @@ -267,14 +268,25 @@ class ISrsRtpPayloader : public ISrsCodec
virtual ISrsRtpPayloader* copy() = 0;
};

// The payload type, for performance to avoid dynamic cast.
enum SrsRtpPacketPayloadType
{
SrsRtpPacketPayloadTypeRaw,
SrsRtpPacketPayloadTypeFUA2,
SrsRtpPacketPayloadTypeFUA,
SrsRtpPacketPayloadTypeNALU,
SrsRtpPacketPayloadTypeSTAP,
SrsRtpPacketPayloadTypeUnknown,
};

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, ISrsRtpPayloader** ppayload) = 0;
virtual void on_before_decode_payload(SrsRtpPacket2* pkt, SrsBuffer* buf, ISrsRtpPayloader** ppayload, SrsRtpPacketPayloadType* ppt) = 0;
};

// The RTP packet with cached shared message.
Expand All @@ -283,7 +295,9 @@ class SrsRtpPacket2
// RTP packet fields.
public:
SrsRtpHeader header;
ISrsRtpPayloader* payload;
private:
ISrsRtpPayloader* payload_;
SrsRtpPacketPayloadType payload_type_;
private:
// The original shared message, all RTP packets can refer to its data.
SrsSharedPtrMessage* shared_msg;
Expand All @@ -303,7 +317,7 @@ class SrsRtpPacket2
SrsRtpPacket2();
virtual ~SrsRtpPacket2();
private:
void reuse();
void reuse_payload();
void reuse_shared_msg();
public:
// Reset the object to reuse it.
Expand All @@ -314,6 +328,9 @@ class SrsRtpPacket2
// Wrap the shared message, we copy it.
char* wrap(SrsSharedPtrMessage* msg);
public:
// Get and set the payload of packet.
void set_payload(ISrsRtpPayloader* p, SrsRtpPacketPayloadType pt) { payload_ = p; payload_type_ = pt; }
ISrsRtpPayloader* payload() { return payload_; }
// Set the padding of RTP packet.
void set_padding(int size);
// Increase the padding of RTP packet.
Expand Down

0 comments on commit 471cf61

Please sign in to comment.