AI: Improve coverage of app by utest (#4494)

Co-authored-by: OSSRS-AI <winlinam@gmail.com>
This commit is contained in:
Winlin 2025-09-17 17:07:37 -04:00 committed by winlin
parent b39aae1447
commit 04b88e889f
29 changed files with 16265 additions and 673 deletions

4
trunk/configure vendored
View File

@ -377,8 +377,8 @@ fi
if [[ $SRS_UTEST == YES ]]; then
MODULE_FILES=("srs_utest" "srs_utest_amf0" "srs_utest_kernel" "srs_utest_core"
"srs_utest_config" "srs_utest_rtmp" "srs_utest_http" "srs_utest_avc" "srs_utest_reload"
"srs_utest_mp4" "srs_utest_service" "srs_utest_app" "srs_utest_rtc" "srs_utest_config2"
"srs_utest_protocol" "srs_utest_protocol2" "srs_utest_kernel2" "srs_utest_protocol3"
"srs_utest_mp4" "srs_utest_service" "srs_utest_app" "srs_utest_app2" "srs_utest_rtc" "srs_utest_config2"
"srs_utest_config3" "srs_utest_config4" "srs_utest_protocol" "srs_utest_protocol2" "srs_utest_kernel2" "srs_utest_protocol3"
"srs_utest_st" "srs_utest_rtc2" "srs_utest_rtc3" "srs_utest_fmp4" "srs_utest_source_lock"
"srs_utest_stream_token" "srs_utest_rtc_recv_track" "srs_utest_st2" "srs_utest_hevc_structs"
"srs_utest_coworkers" "srs_utest_pithy_print" "srs_utest_kernel3" "srs_utest_protocol4")

View File

@ -277,7 +277,7 @@ bool srs_directive_equals(SrsConfDirective *a, SrsConfDirective *b, string excep
SrsConfDirective *b0 = b->at(i);
// donot compare the except child directive.
if (a0->name_ == except) {
if (a0->name_ == except && b0->name_ == except) {
continue;
}

View File

@ -564,7 +564,7 @@ srs_error_t SrsGbMediaTcpConn::do_cycle()
continue;
}
if ((err = bind_session(rtp.header.get_ssrc(), &session_)) != srs_success) {
if ((err = bind_session(rtp.header_.get_ssrc(), &session_)) != srs_success) {
return srs_error_wrap(err, "bind session");
}
}
@ -1432,11 +1432,11 @@ srs_error_t SrsRecoverablePsContext::decode_rtp(SrsBuffer *stream, int reserved,
}
SrsBuffer b((char *)rtp_raw->payload_, rtp_raw->nn_payload_);
// srs_trace("GB: Got RTP length=%d, payload=%d, seq=%u, ts=%d", length, rtp_raw->nn_payload, rtp.header.get_sequence(), rtp.header.get_timestamp());
// srs_trace("GB: Got RTP length=%d, payload=%d, seq=%u, ts=%d", length, rtp_raw->nn_payload, rtp.header_.get_sequence(), rtp.header_.get_timestamp());
ctx_.helper_.rtp_seq_ = rtp.header.get_sequence();
ctx_.helper_.rtp_ts_ = rtp.header.get_timestamp();
ctx_.helper_.rtp_pt_ = rtp.header.get_payload_type();
ctx_.helper_.rtp_seq_ = rtp.header_.get_sequence();
ctx_.helper_.rtp_ts_ = rtp.header_.get_timestamp();
ctx_.helper_.rtp_pt_ = rtp.header_.get_payload_type();
if ((err = decode(&b, handler)) != srs_success) {
return srs_error_wrap(err, "decode");
}

View File

@ -626,13 +626,13 @@ srs_error_t SrsRtcPlayStream::cycle()
SrsSharedPtr<SrsRtcSource> &source = source_;
srs_assert(source.get());
SrsRtcConsumer *consumer_raw = NULL;
ISrsRtcConsumer *consumer_raw = NULL;
if ((err = source->create_consumer(consumer_raw)) != srs_success) {
return srs_error_wrap(err, "create consumer, source=%s", req_->get_stream_url().c_str());
}
srs_assert(consumer_raw);
SrsUniquePtr<SrsRtcConsumer> consumer(consumer_raw);
SrsUniquePtr<SrsRtcConsumer> consumer(dynamic_cast<SrsRtcConsumer *>(consumer_raw));
consumer->set_handler(this);
@ -685,7 +685,7 @@ srs_error_t SrsRtcPlayStream::send_packet(SrsRtpPacket *&pkt)
{
srs_error_t err = srs_success;
uint32_t ssrc = pkt->header.get_ssrc();
uint32_t ssrc = pkt->header_.get_ssrc();
// Try to find track from cache.
SrsRtcSendTrack *track = NULL;
@ -733,7 +733,7 @@ srs_error_t SrsRtcPlayStream::send_packet(SrsRtpPacket *&pkt)
// Consume packet by track.
if ((err = track->on_rtp(pkt)) != srs_success) {
return srs_error_wrap(err, "audio track, SSRC=%u, SEQ=%u", ssrc, pkt->header.get_sequence());
return srs_error_wrap(err, "audio track, SSRC=%u, SEQ=%u", ssrc, pkt->header_.get_sequence());
}
// For NACK to handle packet.
@ -1433,14 +1433,14 @@ srs_error_t SrsRtcPublishStream::do_on_rtp_plaintext(SrsRtpPacket *&pkt, SrsBuff
pkt->set_decode_handler(this);
pkt->set_extension_types(&extension_types_);
pkt->header.ignore_padding(false);
pkt->header_.ignore_padding(false);
if ((err = pkt->decode(buf)) != srs_success) {
return srs_error_wrap(err, "decode rtp packet");
}
// For source to consume packet.
uint32_t ssrc = pkt->header.get_ssrc();
uint32_t ssrc = pkt->header_.get_ssrc();
SrsRtcAudioRecvTrack *audio_track = get_audio_track(ssrc);
SrsRtcVideoRecvTrack *video_track = get_video_track(ssrc);
if (audio_track) {
@ -1512,7 +1512,7 @@ void SrsRtcPublishStream::on_before_decode_payload(SrsRtpPacket *pkt, SrsBuffer
return;
}
uint32_t ssrc = pkt->header.get_ssrc();
uint32_t ssrc = pkt->header_.get_ssrc();
SrsRtcAudioRecvTrack *audio_track = get_audio_track(ssrc);
SrsRtcVideoRecvTrack *video_track = get_video_track(ssrc);
@ -2518,7 +2518,7 @@ srs_error_t SrsRtcConnection::do_send_packet(SrsRtpPacket *pkt)
// For NACK simulator, drop packet.
if (nn_simulate_player_nack_drop_) {
simulate_player_drop_packet(&pkt->header, (int)iov->iov_len);
simulate_player_drop_packet(&pkt->header_, (int)iov->iov_len);
iov->iov_len = 0;
return err;
}
@ -2532,8 +2532,8 @@ srs_error_t SrsRtcConnection::do_send_packet(SrsRtpPacket *pkt)
}
// Detail log, should disable it in release version.
srs_info("RTC: SEND PT=%u, SSRC=%#x, SEQ=%u, Time=%u, %u/%u bytes", pkt->header.get_payload_type(), pkt->header.get_ssrc(),
pkt->header.get_sequence(), pkt->header.get_timestamp(), pkt->nb_bytes(), iov->iov_len);
srs_info("RTC: SEND PT=%u, SSRC=%#x, SEQ=%u, Time=%u, %u/%u bytes", pkt->header_.get_payload_type(), pkt->header_.get_ssrc(),
pkt->header_.get_sequence(), pkt->header_.get_timestamp(), pkt->nb_bytes(), iov->iov_len);
return err;
}

View File

@ -150,7 +150,23 @@ ISrsRtcSourceChangeCallback::~ISrsRtcSourceChangeCallback()
{
}
SrsRtcConsumer::SrsRtcConsumer(SrsRtcSource *s)
ISrsRtcSourceForConsumer::ISrsRtcSourceForConsumer()
{
}
ISrsRtcSourceForConsumer::~ISrsRtcSourceForConsumer()
{
}
ISrsRtcConsumer::ISrsRtcConsumer()
{
}
ISrsRtcConsumer::~ISrsRtcConsumer()
{
}
SrsRtcConsumer::SrsRtcConsumer(ISrsRtcSourceForConsumer *s)
{
source_ = s;
should_update_source_id_ = false;
@ -548,9 +564,9 @@ srs_error_t SrsRtcSource::on_source_changed()
}
// Notify all consumers.
std::vector<SrsRtcConsumer *>::iterator it;
std::vector<ISrsRtcConsumer *>::iterator it;
for (it = consumers_.begin(); it != consumers_.end(); ++it) {
SrsRtcConsumer *consumer = *it;
ISrsRtcConsumer *consumer = *it;
// Notify if context id changed.
if (id_changed) {
@ -585,7 +601,7 @@ void SrsRtcSource::set_bridge(ISrsStreamBridge *bridge)
#endif
}
srs_error_t SrsRtcSource::create_consumer(SrsRtcConsumer *&consumer)
srs_error_t SrsRtcSource::create_consumer(ISrsRtcConsumer *&consumer)
{
srs_error_t err = srs_success;
@ -599,7 +615,7 @@ srs_error_t SrsRtcSource::create_consumer(SrsRtcConsumer *&consumer)
return err;
}
srs_error_t SrsRtcSource::consumer_dumps(SrsRtcConsumer *consumer, bool ds, bool dm, bool dg)
srs_error_t SrsRtcSource::consumer_dumps(ISrsRtcConsumer *consumer, bool ds, bool dm, bool dg)
{
srs_error_t err = srs_success;
@ -609,9 +625,9 @@ srs_error_t SrsRtcSource::consumer_dumps(SrsRtcConsumer *consumer, bool ds, bool
return err;
}
void SrsRtcSource::on_consumer_destroy(SrsRtcConsumer *consumer)
void SrsRtcSource::on_consumer_destroy(ISrsRtcConsumer *consumer)
{
std::vector<SrsRtcConsumer *>::iterator it;
std::vector<ISrsRtcConsumer *>::iterator it;
it = std::find(consumers_.begin(), consumers_.end(), consumer);
if (it != consumers_.end()) {
it = consumers_.erase(it);
@ -783,7 +799,7 @@ srs_error_t SrsRtcSource::on_rtp(SrsRtpPacket *pkt)
}
for (int i = 0; i < (int)consumers_.size(); i++) {
SrsRtcConsumer *consumer = consumers_.at(i);
ISrsRtcConsumer *consumer = consumers_.at(i);
if ((err = consumer->enqueue(pkt->copy())) != srs_success) {
return srs_error_wrap(err, "consume message");
}
@ -1153,12 +1169,12 @@ srs_error_t SrsRtcRtpBuilder::package_opus(SrsParsedAudioPacket *audio, SrsRtpPa
{
srs_error_t err = srs_success;
pkt->header.set_payload_type(audio_payload_type_);
pkt->header.set_ssrc(audio_ssrc_);
pkt->header_.set_payload_type(audio_payload_type_);
pkt->header_.set_ssrc(audio_ssrc_);
pkt->frame_type_ = SrsFrameTypeAudio;
pkt->header.set_marker(true);
pkt->header.set_sequence(audio_sequence_++);
pkt->header.set_timestamp(audio->dts_ * 48);
pkt->header_.set_marker(true);
pkt->header_.set_sequence(audio_sequence_++);
pkt->header_.set_timestamp(audio->dts_ * 48);
SrsRtpRawPayload *raw = new SrsRtpRawPayload();
pkt->set_payload(raw, SrsRtpPacketPayloadTypeRaw);
@ -1262,7 +1278,7 @@ srs_error_t SrsRtcRtpBuilder::on_video(SrsMediaPacket *msg)
}
if (!pkts.empty()) {
pkts.back()->header.set_marker(true);
pkts.back()->header_.set_marker(true);
}
return consume_packets(pkts);
@ -1405,15 +1421,15 @@ void SrsRtcFrameBuilderVideoPacketCache::store_packet(SrsRtpPacket *pkt)
return; // Ignore null packets
}
uint16_t index = cache_index(pkt->header.get_sequence());
uint16_t index = cache_index(pkt->header_.get_sequence());
RtcPacketCache &cache = cache_pkts_[index];
cache.in_use_ = true;
srs_freep(cache.pkt_);
cache.pkt_ = pkt;
cache.sn_ = pkt->header.get_sequence();
cache.sn_ = pkt->header_.get_sequence();
cache.ts_ = pkt->get_avsync_time();
cache.rtp_ts_ = pkt->header.get_timestamp();
cache.rtp_ts_ = pkt->header_.get_timestamp();
}
bool SrsRtcFrameBuilderVideoPacketCache::is_slot_in_use(uint16_t sequence_number)
@ -1485,7 +1501,7 @@ int32_t SrsRtcFrameBuilderVideoPacketCache::find_next_lost_sn(uint16_t current_s
}
SrsRtpPacket *pkt = get_packet(lost_sn);
if (pkt && pkt->header.get_marker()) {
if (pkt && pkt->header_.get_marker()) {
end_sn = lost_sn;
return -1;
}
@ -1546,19 +1562,19 @@ SrsRtcFrameBuilderVideoFrameDetector::~SrsRtcFrameBuilderVideoFrameDetector()
void SrsRtcFrameBuilderVideoFrameDetector::on_keyframe_start(SrsRtpPacket *pkt)
{
if (-1 == rtp_key_frame_ts_) {
rtp_key_frame_ts_ = pkt->header.get_timestamp();
header_sn_ = pkt->header.get_sequence();
rtp_key_frame_ts_ = pkt->header_.get_timestamp();
header_sn_ = pkt->header_.get_sequence();
lost_sn_ = header_sn_ + 1;
// Received key frame and clean cache of old p frame pkts
video_cache_->clear_all();
srs_trace("RTC2RTMP: keyframe set ts=%u, header=%hu, lost=%hu", (uint32_t)rtp_key_frame_ts_, header_sn_, lost_sn_);
} else if (rtp_key_frame_ts_ != pkt->header.get_timestamp()) {
} else if (rtp_key_frame_ts_ != pkt->header_.get_timestamp()) {
// new key frame, clean cache
int64_t old_ts = rtp_key_frame_ts_;
uint16_t old_header_sn = header_sn_;
uint16_t old_lost_sn = lost_sn_;
rtp_key_frame_ts_ = pkt->header.get_timestamp();
header_sn_ = pkt->header.get_sequence();
rtp_key_frame_ts_ = pkt->header_.get_timestamp();
header_sn_ = pkt->header_.get_sequence();
lost_sn_ = header_sn_ + 1;
video_cache_->clear_all();
srs_warn("RTC2RTMP: keyframe drop old ts=%u, header=%hu, lost=%hu, set new ts=%u, header=%hu, lost=%hu",
@ -1654,7 +1670,7 @@ srs_error_t SrsRtcFrameBuilderAudioPacketCache::process_packet(SrsRtpPacket *src
{
srs_error_t err = srs_success;
uint16_t seq = src->header.get_sequence();
uint16_t seq = src->header_.get_sequence();
srs_utime_t now = srs_time_now_realtime();
if (!initialized_) {
@ -1811,7 +1827,7 @@ srs_error_t SrsRtcFrameBuilder::on_rtp(SrsRtpPacket *pkt)
// Have no received any sender report, can't calculate avsync_time,
// discard it to avoid timestamp problem in live source
const SrsRtpHeader &h = pkt->header;
const SrsRtpHeader &h = pkt->header_;
if (pkt->get_avsync_time() <= 0) {
if (sync_state_ < 0) {
srs_trace("RTC: Discard no-sync %s, ssrc=%u, seq=%u, ts=%u, state=%d", pkt->is_audio() ? "Audio" : "Video",
@ -1944,7 +1960,7 @@ srs_error_t SrsRtcFrameBuilder::packet_video(SrsRtpPacket *pkt)
video_cache_->store_packet(pkt->copy());
// check whether to recovery lost packet and can construct a video frame
uint16_t current_sn = pkt->header.get_sequence();
uint16_t current_sn = pkt->header_.get_sequence();
if (frame_detector_->is_lost_sn(current_sn)) {
uint16_t start, end;
bool got_frame;
@ -1979,7 +1995,7 @@ srs_error_t SrsRtcFrameBuilder::packet_video_key_frame(SrsRtpPacket *pkt)
video_cache_->store_packet(pkt->copy());
uint16_t current_sn = pkt->header.get_sequence();
uint16_t current_sn = pkt->header_.get_sequence();
if (frame_detector_->is_lost_sn(current_sn)) {
uint16_t start, end;
bool got_frame;
@ -3171,7 +3187,7 @@ srs_error_t SrsRtcRecvTrack::on_nack(SrsRtpPacket **ppkt)
srs_error_t err = srs_success;
SrsRtpPacket *pkt = *ppkt;
uint16_t seq = pkt->header.get_sequence();
uint16_t seq = pkt->header_.get_sequence();
SrsRtpNackInfo *nack_info = nack_receiver_->find(seq);
if (nack_info) {
@ -3248,8 +3264,8 @@ srs_error_t SrsRtcAudioRecvTrack::on_rtp(SrsSharedPtr<SrsRtcSource> &source, Srs
{
srs_error_t err = srs_success;
pkt->set_avsync_time(cal_avsync_time(pkt->header.get_timestamp()));
srs_info("Audio async rate=%d, rtp=%u, corrected=%" PRId64, (int)rate_, pkt->header.get_timestamp(), pkt->get_avsync_time());
pkt->set_avsync_time(cal_avsync_time(pkt->header_.get_timestamp()));
srs_info("Audio async rate=%d, rtp=%u, corrected=%" PRId64, (int)rate_, pkt->header_.get_timestamp(), pkt->get_avsync_time());
if ((err = source->on_rtp(pkt)) != srs_success) {
return srs_error_wrap(err, "source on rtp");
@ -3327,8 +3343,8 @@ srs_error_t SrsRtcVideoRecvTrack::on_rtp(SrsSharedPtr<SrsRtcSource> &source, Srs
{
srs_error_t err = srs_success;
pkt->set_avsync_time(cal_avsync_time(pkt->header.get_timestamp()));
srs_info("Video async rate=%d, rtp=%u, corrected=%" PRId64, (int)rate_, pkt->header.get_timestamp(), pkt->get_avsync_time());
pkt->set_avsync_time(cal_avsync_time(pkt->header_.get_timestamp()));
srs_info("Video async rate=%d, rtp=%u, corrected=%" PRId64, (int)rate_, pkt->header_.get_timestamp(), pkt->get_avsync_time());
if ((err = source->on_rtp(pkt)) != srs_success) {
return srs_error_wrap(err, "source on rtp");
@ -3433,7 +3449,7 @@ SrsRtpPacket *SrsRtcSendTrack::fetch_rtp_packet(uint16_t seq)
// For NACK, it sequence must match exactly, or it cause SRTP fail.
// Return packet only when sequence is equal.
if (pkt->header.get_sequence() == seq) {
if (pkt->header_.get_sequence() == seq) {
++_srs_pps_rhnack->sugar_;
return pkt;
}
@ -3441,9 +3457,9 @@ SrsRtpPacket *SrsRtcSendTrack::fetch_rtp_packet(uint16_t seq)
// Ignore if sequence not match.
uint32_t nn = 0;
if (nack_epp->can_print(pkt->header.get_ssrc(), &nn)) {
srs_trace("RTC: NACK miss seq=%u, require_seq=%u, ssrc=%u, ts=%u, count=%u/%u, %d bytes", seq, pkt->header.get_sequence(),
pkt->header.get_ssrc(), pkt->header.get_timestamp(), nn, nack_epp->nn_count_, pkt->nb_bytes());
if (nack_epp->can_print(pkt->header_.get_ssrc(), &nn)) {
srs_trace("RTC: NACK miss seq=%u, require_seq=%u, ssrc=%u, ts=%u, count=%u/%u, %d bytes", seq, pkt->header_.get_sequence(),
pkt->header_.get_ssrc(), pkt->header_.get_timestamp(), nn, nack_epp->nn_count_, pkt->nb_bytes());
}
return NULL;
}
@ -3469,14 +3485,14 @@ std::string SrsRtcSendTrack::get_track_id()
void SrsRtcSendTrack::rebuild_packet(SrsRtpPacket *pkt)
{
// Rebuild the sequence number.
int16_t seq = pkt->header.get_sequence();
pkt->header.set_sequence(jitter_seq_->correct(seq));
int16_t seq = pkt->header_.get_sequence();
pkt->header_.set_sequence(jitter_seq_->correct(seq));
// Rebuild the timestamp.
uint32_t ts = pkt->header.get_timestamp();
pkt->header.set_timestamp(jitter_ts_->correct(ts));
uint32_t ts = pkt->header_.get_timestamp();
pkt->header_.set_timestamp(jitter_ts_->correct(ts));
srs_info("RTC: Correct %s seq=%u/%u, ts=%u/%u", track_desc_->type_.c_str(), seq, pkt->header.get_sequence(), ts, pkt->header.get_timestamp());
srs_info("RTC: Correct %s seq=%u/%u, ts=%u/%u", track_desc_->type_.c_str(), seq, pkt->header_.get_sequence(), ts, pkt->header_.get_timestamp());
}
srs_error_t SrsRtcSendTrack::on_nack(SrsRtpPacket **ppkt)
@ -3484,7 +3500,7 @@ srs_error_t SrsRtcSendTrack::on_nack(SrsRtpPacket **ppkt)
srs_error_t err = srs_success;
SrsRtpPacket *pkt = *ppkt;
uint16_t seq = pkt->header.get_sequence();
uint16_t seq = pkt->header_.get_sequence();
// insert into video_queue and audio_queue
// We directly use the pkt, never copy it, so we should set the pkt to NULL.
@ -3512,9 +3528,9 @@ srs_error_t SrsRtcSendTrack::on_recv_nack(const vector<uint16_t> &lost_seqs)
}
uint32_t nn = 0;
if (nack_epp->can_print(pkt->header.get_ssrc(), &nn)) {
srs_trace("RTC: NACK ARQ seq=%u, ssrc=%u, ts=%u, count=%u/%u, %d bytes", pkt->header.get_sequence(),
pkt->header.get_ssrc(), pkt->header.get_timestamp(), nn, nack_epp->nn_count_, pkt->nb_bytes());
if (nack_epp->can_print(pkt->header_.get_ssrc(), &nn)) {
srs_trace("RTC: NACK ARQ seq=%u, ssrc=%u, ts=%u, count=%u/%u, %d bytes", pkt->header_.get_sequence(),
pkt->header_.get_ssrc(), pkt->header_.get_timestamp(), nn, nack_epp->nn_count_, pkt->nb_bytes());
}
// By default, we send packets by sendmmsg.
@ -3543,15 +3559,15 @@ srs_error_t SrsRtcAudioSendTrack::on_rtp(SrsRtpPacket *pkt)
return err;
}
pkt->header.set_ssrc(track_desc_->ssrc_);
pkt->header_.set_ssrc(track_desc_->ssrc_);
// Should update PT, because subscriber may use different PT to publisher.
if (track_desc_->media_ && pkt->header.get_payload_type() == track_desc_->media_->pt_of_publisher_) {
if (track_desc_->media_ && pkt->header_.get_payload_type() == track_desc_->media_->pt_of_publisher_) {
// If PT is media from publisher, change to PT of media for subscriber.
pkt->header.set_payload_type(track_desc_->media_->pt_);
} else if (track_desc_->red_ && pkt->header.get_payload_type() == track_desc_->red_->pt_of_publisher_) {
pkt->header_.set_payload_type(track_desc_->media_->pt_);
} else if (track_desc_->red_ && pkt->header_.get_payload_type() == track_desc_->red_->pt_of_publisher_) {
// If PT is RED from publisher, change to PT of RED for subscriber.
pkt->header.set_payload_type(track_desc_->red_->pt_);
pkt->header_.set_payload_type(track_desc_->red_->pt_);
} else {
// TODO: FIXME: Should update PT for RTX.
}
@ -3563,8 +3579,8 @@ srs_error_t SrsRtcAudioSendTrack::on_rtp(SrsRtpPacket *pkt)
return srs_error_wrap(err, "raw send");
}
srs_info("RTC: Send audio ssrc=%d, seqno=%d, keyframe=%d, ts=%u", pkt->header.get_ssrc(),
pkt->header.get_sequence(), pkt->is_keyframe(), pkt->header.get_timestamp());
srs_info("RTC: Send audio ssrc=%d, seqno=%d, keyframe=%d, ts=%u", pkt->header_.get_ssrc(),
pkt->header_.get_sequence(), pkt->is_keyframe(), pkt->header_.get_timestamp());
return err;
}
@ -3593,15 +3609,15 @@ srs_error_t SrsRtcVideoSendTrack::on_rtp(SrsRtpPacket *pkt)
return err;
}
pkt->header.set_ssrc(track_desc_->ssrc_);
pkt->header_.set_ssrc(track_desc_->ssrc_);
// Should update PT, because subscriber may use different PT to publisher.
if (track_desc_->media_ && pkt->header.get_payload_type() == track_desc_->media_->pt_of_publisher_) {
if (track_desc_->media_ && pkt->header_.get_payload_type() == track_desc_->media_->pt_of_publisher_) {
// If PT is media from publisher, change to PT of media for subscriber.
pkt->header.set_payload_type(track_desc_->media_->pt_);
} else if (track_desc_->red_ && pkt->header.get_payload_type() == track_desc_->red_->pt_of_publisher_) {
pkt->header_.set_payload_type(track_desc_->media_->pt_);
} else if (track_desc_->red_ && pkt->header_.get_payload_type() == track_desc_->red_->pt_of_publisher_) {
// If PT is RED from publisher, change to PT of RED for subscriber.
pkt->header.set_payload_type(track_desc_->red_->pt_);
pkt->header_.set_payload_type(track_desc_->red_->pt_);
} else {
// TODO: FIXME: Should update PT for RTX.
}
@ -3613,8 +3629,8 @@ srs_error_t SrsRtcVideoSendTrack::on_rtp(SrsRtpPacket *pkt)
return srs_error_wrap(err, "raw send");
}
srs_info("RTC: Send video ssrc=%d, seqno=%d, keyframe=%d, ts=%u", pkt->header.get_ssrc(),
pkt->header.get_sequence(), pkt->is_keyframe(), pkt->header.get_timestamp());
srs_info("RTC: Send video ssrc=%d, seqno=%d, keyframe=%d, ts=%u", pkt->header_.get_ssrc(),
pkt->header_.get_sequence(), pkt->is_keyframe(), pkt->header_.get_timestamp());
return err;
}

View File

@ -43,6 +43,7 @@ class SrsErrorPithyPrint;
class SrsRtcFrameBuilder;
class SrsLiveSource;
class SrsRtpVideoBuilder;
class ISrsRtcConsumer;
// Firefox defaults as 109, Chrome is 111.
const int kAudioPayloadType = 111;
@ -89,12 +90,38 @@ public:
virtual void on_stream_change(SrsRtcSourceDescription *desc) = 0;
};
// The RTC source for consumer.
class ISrsRtcSourceForConsumer
{
public:
ISrsRtcSourceForConsumer();
virtual ~ISrsRtcSourceForConsumer();
public:
virtual void on_consumer_destroy(ISrsRtcConsumer *consumer) = 0;
virtual SrsContextId source_id() = 0;
virtual SrsContextId pre_source_id() = 0;
};
// The RTC consumer interface.
class ISrsRtcConsumer
{
public:
ISrsRtcConsumer();
virtual ~ISrsRtcConsumer();
public:
virtual void update_source_id() = 0;
virtual void on_stream_change(SrsRtcSourceDescription *desc) = 0;
virtual srs_error_t enqueue(SrsRtpPacket *pkt) = 0;
};
// The RTC stream consumer, consume packets from RTC stream source.
class SrsRtcConsumer
class SrsRtcConsumer : public ISrsRtcConsumer
{
private:
// Because source references to this object, so we should directly use the source ptr.
SrsRtcSource *source_;
ISrsRtcSourceForConsumer *source_;
private:
std::vector<SrsRtpPacket *> queue_;
@ -110,7 +137,7 @@ private:
ISrsRtcSourceChangeCallback *handler_;
public:
SrsRtcConsumer(SrsRtcSource *s);
SrsRtcConsumer(ISrsRtcSourceForConsumer *s);
virtual ~SrsRtcConsumer();
public:
@ -189,7 +216,7 @@ public:
};
// A Source is a stream, to publish and to play with, binding to SrsRtcPublishStream and SrsRtcPlayStream.
class SrsRtcSource : public ISrsFastTimer
class SrsRtcSource : public ISrsFastTimer, public ISrsRtcSourceForConsumer
{
private:
// For publish, it's the publish client id.
@ -214,7 +241,7 @@ private:
private:
// To delivery stream to clients.
std::vector<SrsRtcConsumer *> consumers_;
std::vector<ISrsRtcConsumer *> consumers_;
// Whether stream is created, that is, SDP is done.
bool is_created_;
// Whether stream is delivering data, that is, DTLS is done.
@ -264,13 +291,13 @@ public:
public:
// Create consumer
// @param consumer, output the create consumer.
virtual srs_error_t create_consumer(SrsRtcConsumer *&consumer);
virtual srs_error_t create_consumer(ISrsRtcConsumer *&consumer);
// Dumps packets in cache to consumer.
// @param ds, whether dumps the sequence header.
// @param dm, whether dumps the metadata.
// @param dg, whether dumps the gop cache.
virtual srs_error_t consumer_dumps(SrsRtcConsumer *consumer, bool ds = true, bool dm = true, bool dg = true);
virtual void on_consumer_destroy(SrsRtcConsumer *consumer);
virtual srs_error_t consumer_dumps(ISrsRtcConsumer *consumer, bool ds = true, bool dm = true, bool dg = true);
virtual void on_consumer_destroy(ISrsRtcConsumer *consumer);
// Whether we can publish stream to the source, return false if it exists.
// @remark Note that when SDP is done, we set the stream is not able to publish.
virtual bool can_publish();

View File

@ -264,7 +264,7 @@ srs_error_t SrsRtspPlayStream::send_packet(SrsRtpPacket *&pkt)
{
srs_error_t err = srs_success;
uint32_t ssrc = pkt->header.get_ssrc();
uint32_t ssrc = pkt->header_.get_ssrc();
// Try to find track from cache.
SrsRtspSendTrack *track = NULL;
@ -312,7 +312,7 @@ srs_error_t SrsRtspPlayStream::send_packet(SrsRtpPacket *&pkt)
// Consume packet by track.
if ((err = track->on_rtp(pkt)) != srs_success) {
return srs_error_wrap(err, "audio track, SSRC=%u, SEQ=%u", ssrc, pkt->header.get_sequence());
return srs_error_wrap(err, "audio track, SSRC=%u, SEQ=%u", ssrc, pkt->header_.get_sequence());
}
return err;
@ -416,7 +416,7 @@ srs_error_t SrsRtspConnection::do_send_packet(SrsRtpPacket *pkt)
{
srs_error_t err = srs_success;
uint32_t ssrc = pkt->header.get_ssrc();
uint32_t ssrc = pkt->header_.get_ssrc();
ISrsStreamWriter *network = networks_[ssrc];
if (!network) {
return srs_error_new(ERROR_RTSP_NO_TRACK, "network not found for ssrc: %u", ssrc);

View File

@ -765,12 +765,12 @@ srs_error_t SrsRtspRtpBuilder::package_aac(SrsParsedAudioPacket *audio, SrsRtpPa
dts *= (int64_t)audio_sample_rate_;
dts /= 1000;
pkt->header.set_payload_type(audio_payload_type_);
pkt->header.set_ssrc(audio_ssrc_);
pkt->header_.set_payload_type(audio_payload_type_);
pkt->header_.set_ssrc(audio_ssrc_);
pkt->frame_type_ = SrsFrameTypeAudio;
pkt->header.set_marker(true);
pkt->header.set_sequence(audio_sequence_++);
pkt->header.set_timestamp(dts);
pkt->header_.set_marker(true);
pkt->header_.set_sequence(audio_sequence_++);
pkt->header_.set_timestamp(dts);
SrsRtpRawPayload *raw = new SrsRtpRawPayload();
pkt->set_payload(raw, SrsRtpPacketPayloadTypeRaw);
@ -902,7 +902,7 @@ srs_error_t SrsRtspRtpBuilder::on_video(SrsMediaPacket *msg)
}
if (!pkts.empty()) {
pkts.back()->header.set_marker(true);
pkts.back()->header_.set_marker(true);
}
return consume_packets(pkts);
@ -1035,15 +1035,15 @@ srs_error_t SrsRtspAudioSendTrack::on_rtp(SrsRtpPacket *pkt)
return err;
}
pkt->header.set_ssrc(track_desc_->ssrc_);
pkt->header_.set_ssrc(track_desc_->ssrc_);
// Should update PT, because subscriber may use different PT to publisher.
if (track_desc_->media_ && pkt->header.get_payload_type() == track_desc_->media_->pt_of_publisher_) {
if (track_desc_->media_ && pkt->header_.get_payload_type() == track_desc_->media_->pt_of_publisher_) {
// If PT is media from publisher, change to PT of media for subscriber.
pkt->header.set_payload_type(track_desc_->media_->pt_);
} else if (track_desc_->red_ && pkt->header.get_payload_type() == track_desc_->red_->pt_of_publisher_) {
pkt->header_.set_payload_type(track_desc_->media_->pt_);
} else if (track_desc_->red_ && pkt->header_.get_payload_type() == track_desc_->red_->pt_of_publisher_) {
// If PT is RED from publisher, change to PT of RED for subscriber.
pkt->header.set_payload_type(track_desc_->red_->pt_);
pkt->header_.set_payload_type(track_desc_->red_->pt_);
} else {
// TODO: FIXME: Should update PT for RTX.
}
@ -1052,8 +1052,8 @@ srs_error_t SrsRtspAudioSendTrack::on_rtp(SrsRtpPacket *pkt)
return srs_error_wrap(err, "raw send");
}
srs_info("RTSP: Send audio ssrc=%d, seqno=%d, keyframe=%d, ts=%u", pkt->header.get_ssrc(),
pkt->header.get_sequence(), pkt->is_keyframe(), pkt->header.get_timestamp());
srs_info("RTSP: Send audio ssrc=%d, seqno=%d, keyframe=%d, ts=%u", pkt->header_.get_ssrc(),
pkt->header_.get_sequence(), pkt->is_keyframe(), pkt->header_.get_timestamp());
return err;
}
@ -1075,15 +1075,15 @@ srs_error_t SrsRtspVideoSendTrack::on_rtp(SrsRtpPacket *pkt)
return err;
}
pkt->header.set_ssrc(track_desc_->ssrc_);
pkt->header_.set_ssrc(track_desc_->ssrc_);
// Should update PT, because subscriber may use different PT to publisher.
if (track_desc_->media_ && pkt->header.get_payload_type() == track_desc_->media_->pt_of_publisher_) {
if (track_desc_->media_ && pkt->header_.get_payload_type() == track_desc_->media_->pt_of_publisher_) {
// If PT is media from publisher, change to PT of media for subscriber.
pkt->header.set_payload_type(track_desc_->media_->pt_);
} else if (track_desc_->red_ && pkt->header.get_payload_type() == track_desc_->red_->pt_of_publisher_) {
pkt->header_.set_payload_type(track_desc_->media_->pt_);
} else if (track_desc_->red_ && pkt->header_.get_payload_type() == track_desc_->red_->pt_of_publisher_) {
// If PT is RED from publisher, change to PT of RED for subscriber.
pkt->header.set_payload_type(track_desc_->red_->pt_);
pkt->header_.set_payload_type(track_desc_->red_->pt_);
} else {
// TODO: FIXME: Should update PT for RTX.
}
@ -1092,8 +1092,8 @@ srs_error_t SrsRtspVideoSendTrack::on_rtp(SrsRtpPacket *pkt)
return srs_error_wrap(err, "raw send");
}
srs_info("RTSP: Send video ssrc=%d, seqno=%d, keyframe=%d, ts=%u", pkt->header.get_ssrc(),
pkt->header.get_sequence(), pkt->is_keyframe(), pkt->header.get_timestamp());
srs_info("RTSP: Send video ssrc=%d, seqno=%d, keyframe=%d, ts=%u", pkt->header_.get_ssrc(),
pkt->header_.get_sequence(), pkt->is_keyframe(), pkt->header_.get_timestamp());
return err;
}

View File

@ -149,7 +149,7 @@ void SrsRtpRingBuffer::clear_histroy(uint16_t seq)
// TODO FIXME Did not consider loopback
for (uint16_t i = 0; i < capacity_; i++) {
SrsRtpPacket *p = queue_[i];
if (p && p->header.get_sequence() < seq) {
if (p && p->header_.get_sequence() < seq) {
srs_freep(p);
queue_[i] = NULL;
}

View File

@ -824,7 +824,7 @@ SrsRtpPacket *SrsRtpPacket::copy()
{
SrsRtpPacket *cp = new SrsRtpPacket();
cp->header = header;
cp->header_ = header_;
cp->payload_ = payload_ ? payload_->copy() : NULL;
cp->payload_type_ = payload_type_;
@ -844,15 +844,15 @@ SrsRtpPacket *SrsRtpPacket::copy()
void SrsRtpPacket::set_padding(int size)
{
header.set_padding(size);
header_.set_padding(size);
if (cached_payload_size_) {
cached_payload_size_ += size - header.get_padding();
cached_payload_size_ += size - header_.get_padding();
}
}
void SrsRtpPacket::add_padding(int size)
{
header.set_padding(header.get_padding() + size);
header_.set_padding(header_.get_padding() + size);
if (cached_payload_size_) {
cached_payload_size_ += size;
}
@ -870,14 +870,14 @@ bool SrsRtpPacket::is_audio()
void SrsRtpPacket::set_extension_types(SrsRtpExtensionTypes *v)
{
return header.set_extensions(v);
return header_.set_extensions(v);
}
uint64_t SrsRtpPacket::nb_bytes()
{
if (!cached_payload_size_) {
int nn_payload = (payload_ ? payload_->nb_bytes() : 0);
cached_payload_size_ = header.nb_bytes() + nn_payload + header.get_padding();
cached_payload_size_ = header_.nb_bytes() + nn_payload + header_.get_padding();
}
return cached_payload_size_;
}
@ -886,7 +886,7 @@ srs_error_t SrsRtpPacket::encode(SrsBuffer *buf)
{
srs_error_t err = srs_success;
if ((err = header.encode(buf)) != srs_success) {
if ((err = header_.encode(buf)) != srs_success) {
return srs_error_wrap(err, "rtp header");
}
@ -894,8 +894,8 @@ srs_error_t SrsRtpPacket::encode(SrsBuffer *buf)
return srs_error_wrap(err, "rtp payload");
}
if (header.get_padding() > 0) {
uint8_t padding = header.get_padding();
if (header_.get_padding() > 0) {
uint8_t padding = header_.get_padding();
if (!buf->require(padding)) {
return srs_error_new(ERROR_RTC_RTP_MUXER, "requires %d bytes", padding);
}
@ -910,12 +910,12 @@ srs_error_t SrsRtpPacket::decode(SrsBuffer *buf)
{
srs_error_t err = srs_success;
if ((err = header.decode(buf)) != srs_success) {
if ((err = header_.decode(buf)) != srs_success) {
return srs_error_wrap(err, "rtp header");
}
// We must skip the padding bytes before parsing payload.
uint8_t padding = header.get_padding();
uint8_t padding = header_.get_padding();
if (!buf->require(padding)) {
return srs_error_wrap(err, "requires padding %d bytes", padding);
}

View File

@ -324,7 +324,7 @@ class SrsRtpPacket
{
// RTP packet fields.
public:
SrsRtpHeader header;
SrsRtpHeader header_;
private:
ISrsRtpPayloader *payload_;
@ -369,7 +369,7 @@ public:
public:
// Parse the TWCC extension, ignore by default.
void enable_twcc_decode() { header.enable_twcc_decode(); } // SrsRtpPacket::enable_twcc_decode
void enable_twcc_decode() { header_.enable_twcc_decode(); } // SrsRtpPacket::enable_twcc_decode
// Get and set the payload of packet.
// @remark Note that return NULL if no payload.
void set_payload(ISrsRtpPayloader *p, SrsRtpPacketPayloadType pt)

View File

@ -45,12 +45,12 @@ srs_error_t SrsRtpVideoBuilder::package_stap_a(SrsMediaPacket *msg, SrsRtpPacket
return err;
}
pkt->header.set_payload_type(video_payload_type_);
pkt->header.set_ssrc(video_ssrc_);
pkt->header_.set_payload_type(video_payload_type_);
pkt->header_.set_ssrc(video_ssrc_);
pkt->frame_type_ = SrsFrameTypeVideo;
pkt->header.set_marker(false);
pkt->header.set_sequence(video_sequence_++);
pkt->header.set_timestamp(msg->timestamp_ * 90);
pkt->header_.set_marker(false);
pkt->header_.set_sequence(video_sequence_++);
pkt->header_.set_timestamp(msg->timestamp_ * 90);
ISrsRtpPayloader *stap = NULL;
vector<vector<char> *> params;
@ -141,12 +141,12 @@ srs_error_t SrsRtpVideoBuilder::package_nalus(SrsMediaPacket *msg, const vector<
SrsRtpPacket *pkt = new SrsRtpPacket();
pkts.push_back(pkt);
pkt->header.set_payload_type(video_payload_type_);
pkt->header.set_ssrc(video_ssrc_);
pkt->header_.set_payload_type(video_payload_type_);
pkt->header_.set_ssrc(video_ssrc_);
pkt->frame_type_ = SrsFrameTypeVideo;
pkt->nalu_type_ = first_nalu_type;
pkt->header.set_sequence(video_sequence_++);
pkt->header.set_timestamp(msg->timestamp_ * 90);
pkt->header_.set_sequence(video_sequence_++);
pkt->header_.set_timestamp(msg->timestamp_ * 90);
pkt->set_payload(raw_raw, SrsRtpPacketPayloadTypeNALU);
pkt->wrap(msg->payload_);
} else {
@ -171,12 +171,12 @@ srs_error_t SrsRtpVideoBuilder::package_nalus(SrsMediaPacket *msg, const vector<
SrsRtpPacket *pkt = new SrsRtpPacket();
pkts.push_back(pkt);
pkt->header.set_payload_type(video_payload_type_);
pkt->header.set_ssrc(video_ssrc_);
pkt->header_.set_payload_type(video_payload_type_);
pkt->header_.set_ssrc(video_ssrc_);
pkt->frame_type_ = SrsFrameTypeVideo;
pkt->nalu_type_ = kFuA;
pkt->header.set_sequence(video_sequence_++);
pkt->header.set_timestamp(msg->timestamp_ * 90);
pkt->header_.set_sequence(video_sequence_++);
pkt->header_.set_timestamp(msg->timestamp_ * 90);
if (is_hevc) {
SrsRtpFUAPayloadHevc *fua = new SrsRtpFUAPayloadHevc();
@ -219,11 +219,11 @@ srs_error_t SrsRtpVideoBuilder::package_single_nalu(SrsMediaPacket *msg, SrsNalu
SrsRtpPacket *pkt = new SrsRtpPacket();
pkts.push_back(pkt);
pkt->header.set_payload_type(video_payload_type_);
pkt->header.set_ssrc(video_ssrc_);
pkt->header_.set_payload_type(video_payload_type_);
pkt->header_.set_ssrc(video_ssrc_);
pkt->frame_type_ = SrsFrameTypeVideo;
pkt->header.set_sequence(video_sequence_++);
pkt->header.set_timestamp(msg->timestamp_ * 90);
pkt->header_.set_sequence(video_sequence_++);
pkt->header_.set_timestamp(msg->timestamp_ * 90);
SrsRtpRawPayload *raw = new SrsRtpRawPayload();
pkt->set_payload(raw, SrsRtpPacketPayloadTypeRaw);
@ -260,11 +260,11 @@ srs_error_t SrsRtpVideoBuilder::package_fu_a(SrsMediaPacket *msg, SrsNaluSample
SrsRtpPacket *pkt = new SrsRtpPacket();
pkts.push_back(pkt);
pkt->header.set_payload_type(video_payload_type_);
pkt->header.set_ssrc(video_ssrc_);
pkt->header_.set_payload_type(video_payload_type_);
pkt->header_.set_ssrc(video_ssrc_);
pkt->frame_type_ = SrsFrameTypeVideo;
pkt->header.set_sequence(video_sequence_++);
pkt->header.set_timestamp(msg->timestamp_ * 90);
pkt->header_.set_sequence(video_sequence_++);
pkt->header_.set_timestamp(msg->timestamp_ * 90);
pkt->nalu_type_ = is_hevc ? kFuHevc : kFuA;
if (is_hevc) {

View File

@ -0,0 +1,679 @@
//
// Copyright (c) 2013-2025 The SRS Authors
//
// SPDX-License-Identifier: MIT
//
#include <srs_utest_app2.hpp>
#include <srs_app_rtc_source.hpp>
#include <srs_core_autofree.hpp>
#include <srs_kernel_buffer.hpp>
#include <srs_kernel_codec.hpp>
#include <srs_kernel_rtc_rtp.hpp>
#include <srs_protocol_format.hpp>
#include <srs_utest.hpp>
// External function declaration from srs_app_rtc_source.cpp
extern srs_error_t aac_raw_append_adts_header(SrsMediaPacket *shared_audio, SrsFormat *format, char **pbuf, int *pnn_buf);
// Mock implementation of ISrsRtcSourceForConsumer for testing SrsRtcConsumer
class MockRtcSourceForConsumer : public ISrsRtcSourceForConsumer
{
public:
SrsContextId source_id_;
SrsContextId pre_source_id_;
int consumer_destroy_count_;
ISrsRtcConsumer *last_destroyed_consumer_;
MockRtcSourceForConsumer()
{
source_id_.set_value("test-source-id");
pre_source_id_.set_value("test-pre-source-id");
consumer_destroy_count_ = 0;
last_destroyed_consumer_ = NULL;
}
virtual ~MockRtcSourceForConsumer()
{
}
virtual void on_consumer_destroy(ISrsRtcConsumer *consumer)
{
consumer_destroy_count_++;
last_destroyed_consumer_ = consumer;
}
virtual SrsContextId source_id()
{
return source_id_;
}
virtual SrsContextId pre_source_id()
{
return pre_source_id_;
}
};
// Mock implementation of ISrsRtcSourceChangeCallback for testing
class MockRtcSourceChangeCallback : public ISrsRtcSourceChangeCallback
{
public:
int stream_change_count_;
SrsRtcSourceDescription *last_stream_desc_;
MockRtcSourceChangeCallback()
{
stream_change_count_ = 0;
last_stream_desc_ = NULL;
}
virtual ~MockRtcSourceChangeCallback()
{
}
virtual void on_stream_change(SrsRtcSourceDescription *desc)
{
stream_change_count_++;
last_stream_desc_ = desc;
}
};
VOID TEST(AppTest2, AacRawAppendAdtsHeaderSequenceHeader)
{
srs_error_t err;
// Create a mock AAC sequence header packet
SrsUniquePtr<SrsMediaPacket> audio_packet(new SrsMediaPacket());
audio_packet->message_type_ = SrsFrameTypeAudio;
// Create format with AAC sequence header
SrsUniquePtr<SrsFormat> format(new SrsFormat());
HELPER_EXPECT_SUCCESS(format->initialize());
// Set up AAC codec info to simulate sequence header
format->acodec_ = new SrsAudioCodecConfig();
format->acodec_->id_ = SrsAudioCodecIdAAC;
format->acodec_->aac_object_ = SrsAacObjectTypeAacLC;
format->acodec_->aac_sample_rate_ = 4; // 44100 Hz index
format->acodec_->aac_channels_ = 2;
// Create audio frame info to simulate sequence header
format->audio_ = new SrsParsedAudioPacket();
format->audio_->dts_ = 1000;
format->audio_->cts_ = 0;
format->audio_->nb_samples_ = 0; // Sequence header has 0 samples
char *buf = NULL;
int nn_buf = 0;
// Test: sequence header should return success without creating buffer
HELPER_EXPECT_SUCCESS(aac_raw_append_adts_header(audio_packet.get(), format.get(), &buf, &nn_buf));
EXPECT_TRUE(buf == NULL);
EXPECT_EQ(0, nn_buf);
}
VOID TEST(AppTest2, AacRawAppendAdtsHeaderNoSamples)
{
srs_error_t err;
// Create a mock AAC packet
SrsUniquePtr<SrsMediaPacket> audio_packet(new SrsMediaPacket());
audio_packet->message_type_ = SrsFrameTypeAudio;
// Create format with AAC but no samples
SrsUniquePtr<SrsFormat> format(new SrsFormat());
HELPER_EXPECT_SUCCESS(format->initialize());
// Set up AAC codec info
format->acodec_ = new SrsAudioCodecConfig();
format->acodec_->id_ = SrsAudioCodecIdAAC;
format->acodec_->aac_object_ = SrsAacObjectTypeAacLC;
format->acodec_->aac_sample_rate_ = 4; // 44100 Hz index
format->acodec_->aac_channels_ = 2;
// Create audio frame info with no samples
format->audio_ = new SrsParsedAudioPacket();
format->audio_->dts_ = 1000;
format->audio_->cts_ = 0;
format->audio_->nb_samples_ = 0; // No samples
char *buf = NULL;
int nn_buf = 0;
// Test: no samples should return success without creating buffer
HELPER_EXPECT_SUCCESS(aac_raw_append_adts_header(audio_packet.get(), format.get(), &buf, &nn_buf));
EXPECT_TRUE(buf == NULL);
EXPECT_EQ(0, nn_buf);
}
VOID TEST(AppTest2, AacRawAppendAdtsHeaderMultipleSamples)
{
srs_error_t err;
// Create a mock AAC packet
SrsUniquePtr<SrsMediaPacket> audio_packet(new SrsMediaPacket());
audio_packet->message_type_ = SrsFrameTypeAudio;
// Create format with AAC
SrsUniquePtr<SrsFormat> format(new SrsFormat());
HELPER_EXPECT_SUCCESS(format->initialize());
// Set up AAC codec info
format->acodec_ = new SrsAudioCodecConfig();
format->acodec_->id_ = SrsAudioCodecIdAAC;
format->acodec_->aac_object_ = SrsAacObjectTypeAacLC;
format->acodec_->aac_sample_rate_ = 4; // 44100 Hz index
format->acodec_->aac_channels_ = 2;
// Create audio frame info with multiple samples (should fail)
format->audio_ = new SrsParsedAudioPacket();
format->audio_->dts_ = 1000;
format->audio_->cts_ = 0;
format->audio_->nb_samples_ = 2; // Multiple samples should cause error
char *buf = NULL;
int nn_buf = 0;
// Test: multiple samples should return error
HELPER_EXPECT_FAILED(aac_raw_append_adts_header(audio_packet.get(), format.get(), &buf, &nn_buf));
}
VOID TEST(AppTest2, AacRawAppendAdtsHeaderValidSingleSample)
{
srs_error_t err;
// Create a mock AAC packet
SrsUniquePtr<SrsMediaPacket> audio_packet(new SrsMediaPacket());
audio_packet->message_type_ = SrsFrameTypeAudio;
// Create format with AAC
SrsUniquePtr<SrsFormat> format(new SrsFormat());
HELPER_EXPECT_SUCCESS(format->initialize());
// Set up AAC codec info
format->acodec_ = new SrsAudioCodecConfig();
format->acodec_->id_ = SrsAudioCodecIdAAC;
format->acodec_->aac_object_ = SrsAacObjectTypeAacLC; // Object type 2
format->acodec_->aac_sample_rate_ = 4; // 44100 Hz index
format->acodec_->aac_channels_ = 2; // Stereo
// Create audio frame info with single sample
format->audio_ = new SrsParsedAudioPacket();
format->audio_->dts_ = 1000;
format->audio_->cts_ = 0;
format->audio_->nb_samples_ = 1; // Single sample
// Create sample data
const char sample_data[] = {0x01, 0x02, 0x03, 0x04, 0x05}; // 5 bytes of sample data
format->audio_->samples_[0].bytes_ = (char *)sample_data;
format->audio_->samples_[0].size_ = sizeof(sample_data);
char *buf = NULL;
int nn_buf = 0;
// Test: valid single sample should create ADTS header + data
HELPER_EXPECT_SUCCESS(aac_raw_append_adts_header(audio_packet.get(), format.get(), &buf, &nn_buf));
// Verify buffer was created
EXPECT_TRUE(buf != NULL);
EXPECT_EQ(7 + sizeof(sample_data), nn_buf); // 7 bytes ADTS header + sample data
if (!buf) {
return;
}
SrsUniquePtr<char> buf_ptr(buf);
// Verify ADTS header structure
EXPECT_EQ((unsigned char)0xFF, (unsigned char)buf[0]); // Sync word high
EXPECT_EQ((unsigned char)0xF9, (unsigned char)buf[1]); // Sync word low + layer + protection
// Verify AAC object type, sample rate, and channels are encoded correctly
// Byte 2: (object-1)<<6 | (sample_rate&0x0F)<<2 | (channels&0x04)>>2
unsigned char expected_byte2 = ((SrsAacObjectTypeAacLC - 1) << 6) | ((4 & 0x0F) << 2) | ((2 & 0x04) >> 2);
EXPECT_EQ(expected_byte2, (unsigned char)buf[2]);
// Verify frame length is encoded correctly (total length = 7 + sample size)
int expected_frame_len = 7 + sizeof(sample_data);
// Frame length spans bytes 3-5
unsigned char expected_byte3 = ((2 & 0x03) << 6) | ((expected_frame_len >> 11) & 0x03);
unsigned char expected_byte4 = (expected_frame_len >> 3) & 0xFF;
unsigned char expected_byte5 = ((expected_frame_len & 0x07) << 5) | 0x1F;
EXPECT_EQ(expected_byte3, (unsigned char)buf[3]);
EXPECT_EQ(expected_byte4, (unsigned char)buf[4]);
EXPECT_EQ(expected_byte5, (unsigned char)buf[5]);
EXPECT_EQ((unsigned char)0xFC, (unsigned char)buf[6]); // Buffer fullness + frame count
// Verify sample data is copied correctly
for (int i = 0; i < sizeof(sample_data); i++) {
EXPECT_EQ(sample_data[i], buf[7 + i]);
}
}
VOID TEST(AppTest2, AacRawAppendAdtsHeaderDifferentCodecParams)
{
srs_error_t err;
// Create a mock AAC packet
SrsUniquePtr<SrsMediaPacket> audio_packet(new SrsMediaPacket());
audio_packet->message_type_ = SrsFrameTypeAudio;
// Create format with different AAC parameters
SrsUniquePtr<SrsFormat> format(new SrsFormat());
HELPER_EXPECT_SUCCESS(format->initialize());
// Set up AAC codec info with different parameters
format->acodec_ = new SrsAudioCodecConfig();
format->acodec_->id_ = SrsAudioCodecIdAAC;
format->acodec_->aac_object_ = SrsAacObjectTypeAacHE; // Object type 5
format->acodec_->aac_sample_rate_ = 3; // 48000 Hz index
format->acodec_->aac_channels_ = 1; // Mono
// Create audio frame info with single sample
format->audio_ = new SrsParsedAudioPacket();
format->audio_->dts_ = 2000;
format->audio_->cts_ = 0;
format->audio_->nb_samples_ = 1;
// Create sample data
const char sample_data[] = {(char)0xAA, (char)0xBB, (char)0xCC}; // 3 bytes of sample data
format->audio_->samples_[0].bytes_ = (char *)sample_data;
format->audio_->samples_[0].size_ = sizeof(sample_data);
char *buf = NULL;
int nn_buf = 0;
// Test: different codec parameters should work
HELPER_EXPECT_SUCCESS(aac_raw_append_adts_header(audio_packet.get(), format.get(), &buf, &nn_buf));
// Verify buffer was created with correct size
EXPECT_TRUE(buf != NULL);
EXPECT_EQ(7 + sizeof(sample_data), nn_buf);
if (!buf) {
return;
}
SrsUniquePtr<char> buf_ptr(buf);
// Verify ADTS header with different parameters
EXPECT_EQ((unsigned char)0xFF, (unsigned char)buf[0]);
EXPECT_EQ((unsigned char)0xF9, (unsigned char)buf[1]);
// Verify different AAC object type, sample rate, and channels
unsigned char expected_byte2 = (unsigned char)(((SrsAacObjectTypeAacHE - 1) << 6) | ((3 & 0x0F) << 2) | ((1 & 0x04) >> 2));
EXPECT_EQ(expected_byte2, (unsigned char)buf[2]);
}
VOID TEST(AppTest2, AacRawAppendAdtsHeaderLargeSample)
{
srs_error_t err;
// Create a mock AAC packet
SrsUniquePtr<SrsMediaPacket> audio_packet(new SrsMediaPacket());
audio_packet->message_type_ = SrsFrameTypeAudio;
// Create format with AAC
SrsUniquePtr<SrsFormat> format(new SrsFormat());
HELPER_EXPECT_SUCCESS(format->initialize());
// Set up AAC codec info
format->acodec_ = new SrsAudioCodecConfig();
format->acodec_->id_ = SrsAudioCodecIdAAC;
format->acodec_->aac_object_ = SrsAacObjectTypeAacLC;
format->acodec_->aac_sample_rate_ = 4; // 44100 Hz index
format->acodec_->aac_channels_ = 2;
// Create audio frame info with single large sample
format->audio_ = new SrsParsedAudioPacket();
format->audio_->dts_ = 1000;
format->audio_->cts_ = 0;
format->audio_->nb_samples_ = 1;
// Create large sample data (1KB)
const int large_size = 1024;
SrsUniquePtr<char> large_sample(new char[large_size]);
for (int i = 0; i < large_size; i++) {
large_sample.get()[i] = (char)(i % 256);
}
format->audio_->samples_[0].bytes_ = large_sample.get();
format->audio_->samples_[0].size_ = large_size;
char *buf = NULL;
int nn_buf = 0;
// Test: large sample should work correctly
HELPER_EXPECT_SUCCESS(aac_raw_append_adts_header(audio_packet.get(), format.get(), &buf, &nn_buf));
// Verify buffer was created with correct size
EXPECT_TRUE(buf != NULL);
EXPECT_EQ(7 + large_size, nn_buf);
if (!buf) {
return;
}
SrsUniquePtr<char> buf_ptr(buf);
// Verify ADTS header
EXPECT_EQ((unsigned char)0xFF, (unsigned char)buf[0]);
EXPECT_EQ((unsigned char)0xF9, (unsigned char)buf[1]);
// Verify frame length encoding for large frame
int expected_frame_len = 7 + large_size;
unsigned char byte4 = (expected_frame_len >> 3) & 0xFF;
EXPECT_EQ(byte4, (unsigned char)buf[4]);
// Verify sample data is copied correctly (check first and last bytes)
EXPECT_EQ(large_sample.get()[0], buf[7]);
EXPECT_EQ(large_sample.get()[large_size - 1], buf[7 + large_size - 1]);
}
VOID TEST(AppTest2, RtcConsumerUpdateSourceId)
{
MockRtcSourceForConsumer mock_source;
SrsRtcConsumer consumer(&mock_source);
// Initially should_update_source_id_ should be false
consumer.update_source_id();
// After calling update_source_id, the flag should be set
// We can verify this by calling dump_packet which checks and resets the flag
SrsRtpPacket *pkt = NULL;
srs_error_t err;
HELPER_EXPECT_SUCCESS(consumer.dump_packet(&pkt));
EXPECT_TRUE(pkt == NULL); // No packets in queue
}
VOID TEST(AppTest2, RtcConsumerEnqueueAndDumpSinglePacket)
{
srs_error_t err;
MockRtcSourceForConsumer mock_source;
SrsRtcConsumer consumer(&mock_source);
// Create a test RTP packet
SrsRtpPacket *test_pkt = new SrsRtpPacket();
test_pkt->header_.set_sequence(1234);
test_pkt->header_.set_timestamp(5678);
test_pkt->header_.set_ssrc(0x12345678);
// Enqueue the packet (consumer takes ownership)
HELPER_EXPECT_SUCCESS(consumer.enqueue(test_pkt));
// Dump the packet
SrsRtpPacket *dumped_pkt = NULL;
HELPER_EXPECT_SUCCESS(consumer.dump_packet(&dumped_pkt));
EXPECT_TRUE(dumped_pkt != NULL);
EXPECT_EQ(1234, dumped_pkt->header_.get_sequence());
EXPECT_EQ(5678, dumped_pkt->header_.get_timestamp());
EXPECT_EQ(0x12345678, dumped_pkt->header_.get_ssrc());
srs_freep(dumped_pkt);
}
VOID TEST(AppTest2, RtcConsumerEnqueueMultiplePackets)
{
srs_error_t err;
MockRtcSourceForConsumer mock_source;
SrsRtcConsumer consumer(&mock_source);
// Create and enqueue multiple test packets
for (int i = 0; i < 5; i++) {
SrsRtpPacket *test_pkt = new SrsRtpPacket();
test_pkt->header_.set_sequence(1000 + i);
test_pkt->header_.set_timestamp(2000 + i * 100);
test_pkt->header_.set_ssrc(0x12345678);
HELPER_EXPECT_SUCCESS(consumer.enqueue(test_pkt));
}
// Dump packets in FIFO order
for (int i = 0; i < 5; i++) {
SrsRtpPacket *dumped_pkt = NULL;
HELPER_EXPECT_SUCCESS(consumer.dump_packet(&dumped_pkt));
EXPECT_TRUE(dumped_pkt != NULL);
EXPECT_EQ(1000 + i, dumped_pkt->header_.get_sequence());
EXPECT_EQ(2000 + i * 100, dumped_pkt->header_.get_timestamp());
srs_freep(dumped_pkt);
}
// Queue should be empty now
SrsRtpPacket *empty_pkt = NULL;
HELPER_EXPECT_SUCCESS(consumer.dump_packet(&empty_pkt));
EXPECT_TRUE(empty_pkt == NULL);
}
VOID TEST(AppTest2, RtcConsumerDumpEmptyQueue)
{
srs_error_t err;
MockRtcSourceForConsumer mock_source;
SrsRtcConsumer consumer(&mock_source);
// Dump from empty queue should return NULL
SrsRtpPacket *pkt = NULL;
HELPER_EXPECT_SUCCESS(consumer.dump_packet(&pkt));
EXPECT_TRUE(pkt == NULL);
}
VOID TEST(AppTest2, RtcConsumerStreamChangeCallback)
{
MockRtcSourceForConsumer mock_source;
MockRtcSourceChangeCallback mock_callback;
SrsRtcConsumer consumer(&mock_source);
// Set the callback handler
consumer.set_handler(&mock_callback);
// Create a mock stream description
SrsUniquePtr<SrsRtcSourceDescription> stream_desc(new SrsRtcSourceDescription());
stream_desc->id_ = "test-stream";
// Trigger stream change
consumer.on_stream_change(stream_desc.get());
// Verify callback was called
EXPECT_EQ(1, mock_callback.stream_change_count_);
EXPECT_EQ(stream_desc.get(), mock_callback.last_stream_desc_);
}
VOID TEST(AppTest2, RtcConsumerStreamChangeCallbackNoHandler)
{
MockRtcSourceForConsumer mock_source;
SrsRtcConsumer consumer(&mock_source);
// No handler set - should not crash
SrsUniquePtr<SrsRtcSourceDescription> stream_desc(new SrsRtcSourceDescription());
stream_desc->id_ = "test-stream";
// This should not crash even without handler
consumer.on_stream_change(stream_desc.get());
}
VOID TEST(AppTest2, RtcConsumerQueueSizeCheck)
{
srs_error_t err;
MockRtcSourceForConsumer mock_source;
SrsRtcConsumer consumer(&mock_source);
// Enqueue packets and verify queue behavior
for (int i = 0; i < 5; i++) {
SrsRtpPacket *test_pkt = new SrsRtpPacket();
test_pkt->header_.set_sequence(1000 + i);
HELPER_EXPECT_SUCCESS(consumer.enqueue(test_pkt));
}
// Verify we can dump packets in correct order
SrsRtpPacket *pkt = NULL;
HELPER_EXPECT_SUCCESS(consumer.dump_packet(&pkt));
EXPECT_TRUE(pkt != NULL);
EXPECT_EQ(1000, pkt->header_.get_sequence());
srs_freep(pkt);
}
VOID TEST(AppTest2, RtcConsumerEnqueueBehavior)
{
srs_error_t err;
MockRtcSourceForConsumer mock_source;
SrsRtcConsumer consumer(&mock_source);
// Enqueue multiple packets to test queue behavior
SrsRtpPacket *test_pkt1 = new SrsRtpPacket();
test_pkt1->header_.set_sequence(1001);
HELPER_EXPECT_SUCCESS(consumer.enqueue(test_pkt1));
SrsRtpPacket *test_pkt2 = new SrsRtpPacket();
test_pkt2->header_.set_sequence(1002);
HELPER_EXPECT_SUCCESS(consumer.enqueue(test_pkt2));
SrsRtpPacket *test_pkt3 = new SrsRtpPacket();
test_pkt3->header_.set_sequence(1003);
HELPER_EXPECT_SUCCESS(consumer.enqueue(test_pkt3));
// Verify packets are in queue in FIFO order
SrsRtpPacket *pkt = NULL;
HELPER_EXPECT_SUCCESS(consumer.dump_packet(&pkt));
EXPECT_TRUE(pkt != NULL);
EXPECT_EQ(1001, pkt->header_.get_sequence());
srs_freep(pkt);
HELPER_EXPECT_SUCCESS(consumer.dump_packet(&pkt));
EXPECT_TRUE(pkt != NULL);
EXPECT_EQ(1002, pkt->header_.get_sequence());
srs_freep(pkt);
}
VOID TEST(AppTest2, RtcConsumerSourceIdUpdate)
{
MockRtcSourceForConsumer mock_source;
SrsRtcConsumer consumer(&mock_source);
// Set different source IDs
mock_source.source_id_.set_value("new-source-id");
mock_source.pre_source_id_.set_value("old-source-id");
// Trigger source ID update
consumer.update_source_id();
// Dump packet should log the source ID change
SrsRtpPacket *pkt = NULL;
srs_error_t err;
HELPER_EXPECT_SUCCESS(consumer.dump_packet(&pkt));
EXPECT_TRUE(pkt == NULL); // No packets in queue
// After dump_packet, the update flag should be reset
// Calling dump_packet again should not trigger another log
HELPER_EXPECT_SUCCESS(consumer.dump_packet(&pkt));
EXPECT_TRUE(pkt == NULL);
}
VOID TEST(AppTest2, RtcConsumerPacketMemoryManagement)
{
srs_error_t err;
MockRtcSourceForConsumer mock_source;
SrsRtcConsumer consumer(&mock_source);
// Create test packets and enqueue copies (simulating real usage)
std::vector<SrsRtpPacket *> original_packets;
for (int i = 0; i < 3; i++) {
SrsRtpPacket *original_pkt = new SrsRtpPacket();
original_pkt->header_.set_sequence(2000 + i);
original_pkt->header_.set_timestamp(3000 + i * 100);
original_packets.push_back(original_pkt);
// Enqueue a copy (this is how it's used in real code)
HELPER_EXPECT_SUCCESS(consumer.enqueue(original_pkt->copy()));
}
// Dump all packets and verify they have correct data
for (int i = 0; i < 3; i++) {
SrsRtpPacket *dumped_pkt = NULL;
HELPER_EXPECT_SUCCESS(consumer.dump_packet(&dumped_pkt));
EXPECT_TRUE(dumped_pkt != NULL);
EXPECT_TRUE(dumped_pkt != original_packets[i]); // Should be different instances
EXPECT_EQ(2000 + i, dumped_pkt->header_.get_sequence());
EXPECT_EQ(3000 + i * 100, dumped_pkt->header_.get_timestamp());
srs_freep(dumped_pkt);
}
// Clean up original packets
for (size_t i = 0; i < original_packets.size(); i++) {
srs_freep(original_packets[i]);
}
}
VOID TEST(AppTest2, RtcConsumerCallbackHandlerLifecycle)
{
MockRtcSourceForConsumer mock_source;
MockRtcSourceChangeCallback callback1;
MockRtcSourceChangeCallback callback2;
SrsRtcConsumer consumer(&mock_source);
// Initially no handler
SrsUniquePtr<SrsRtcSourceDescription> stream_desc(new SrsRtcSourceDescription());
stream_desc->id_ = "test-stream-1";
consumer.on_stream_change(stream_desc.get());
EXPECT_EQ(0, callback1.stream_change_count_);
EXPECT_EQ(0, callback2.stream_change_count_);
// Set first handler
consumer.set_handler(&callback1);
consumer.on_stream_change(stream_desc.get());
EXPECT_EQ(1, callback1.stream_change_count_);
EXPECT_EQ(0, callback2.stream_change_count_);
// Change handler
consumer.set_handler(&callback2);
stream_desc->id_ = "test-stream-2";
consumer.on_stream_change(stream_desc.get());
EXPECT_EQ(1, callback1.stream_change_count_); // Should not increase
EXPECT_EQ(1, callback2.stream_change_count_); // Should increase
// Remove handler
consumer.set_handler(NULL);
consumer.on_stream_change(stream_desc.get());
EXPECT_EQ(1, callback1.stream_change_count_); // Should not increase
EXPECT_EQ(1, callback2.stream_change_count_); // Should not increase
}
VOID TEST(AppTest2, RtcConsumerLargePacketQueue)
{
srs_error_t err;
MockRtcSourceForConsumer mock_source;
SrsRtcConsumer consumer(&mock_source);
const int large_count = 100;
// Enqueue many packets
for (int i = 0; i < large_count; i++) {
SrsRtpPacket *test_pkt = new SrsRtpPacket();
test_pkt->header_.set_sequence(4000 + i);
test_pkt->header_.set_timestamp(5000 + i * 10);
test_pkt->header_.set_ssrc(0xABCDEF00 + i);
HELPER_EXPECT_SUCCESS(consumer.enqueue(test_pkt));
}
// Dump all packets and verify order
for (int i = 0; i < large_count; i++) {
SrsRtpPacket *dumped_pkt = NULL;
HELPER_EXPECT_SUCCESS(consumer.dump_packet(&dumped_pkt));
EXPECT_TRUE(dumped_pkt != NULL);
EXPECT_EQ(4000 + i, dumped_pkt->header_.get_sequence());
EXPECT_EQ(5000 + i * 10, dumped_pkt->header_.get_timestamp());
EXPECT_EQ(0xABCDEF00 + i, dumped_pkt->header_.get_ssrc());
srs_freep(dumped_pkt);
}
// Queue should be empty
SrsRtpPacket *empty_pkt = NULL;
HELPER_EXPECT_SUCCESS(consumer.dump_packet(&empty_pkt));
EXPECT_TRUE(empty_pkt == NULL);
}

View File

@ -0,0 +1,15 @@
//
// Copyright (c) 2013-2025 The SRS Authors
//
// SPDX-License-Identifier: MIT
//
#ifndef SRS_UTEST_APP2_HPP
#define SRS_UTEST_APP2_HPP
/*
#include <srs_utest_app2.hpp>
*/
#include <srs_utest.hpp>
#endif

File diff suppressed because it is too large Load Diff

View File

@ -38,7 +38,7 @@ private:
std::map<std::string, std::string> included_files;
public:
virtual srs_error_t parse(std::string buf);
virtual srs_error_t mock_parse(std::string buf);
virtual srs_error_t mock_include(const std::string file_name, const std::string content);
protected:

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,15 @@
//
// Copyright (c) 2013-2025 The SRS Authors
//
// SPDX-License-Identifier: MIT
//
#ifndef SRS_UTEST_CONFIG3_HPP
#define SRS_UTEST_CONFIG3_HPP
/*
#include <srs_utest_config3.hpp>
*/
#include <srs_utest_config.hpp>
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,15 @@
//
// Copyright (c) 2013-2025 The SRS Authors
//
// SPDX-License-Identifier: MIT
//
#ifndef SRS_UTEST_CONFIG4_HPP
#define SRS_UTEST_CONFIG4_HPP
/*
#include <srs_utest_config4.hpp>
*/
#include <srs_utest.hpp>
#endif

View File

@ -2031,22 +2031,22 @@ VOID TEST(KernelRtcRtpTest, SrsRtpPacketBasics)
SrsRtpPacket packet;
// Test initial state
EXPECT_EQ(0, packet.header.get_sequence());
EXPECT_EQ(0, packet.header.get_timestamp());
EXPECT_EQ(0, packet.header.get_ssrc());
EXPECT_EQ(0, packet.header_.get_sequence());
EXPECT_EQ(0, packet.header_.get_timestamp());
EXPECT_EQ(0, packet.header_.get_ssrc());
EXPECT_EQ(NULL, packet.payload());
EXPECT_EQ(0, packet.nalu_type_);
EXPECT_EQ(SrsFrameTypeReserved, packet.frame_type_);
EXPECT_EQ(-1, packet.get_avsync_time());
// Test setting header values
packet.header.set_sequence(100);
packet.header.set_timestamp(200);
packet.header.set_ssrc(0xABCDEF00);
packet.header_.set_sequence(100);
packet.header_.set_timestamp(200);
packet.header_.set_ssrc(0xABCDEF00);
EXPECT_EQ(100, packet.header.get_sequence());
EXPECT_EQ(200, packet.header.get_timestamp());
EXPECT_EQ(0xABCDEF00, packet.header.get_ssrc());
EXPECT_EQ(100, packet.header_.get_sequence());
EXPECT_EQ(200, packet.header_.get_timestamp());
EXPECT_EQ(0xABCDEF00, packet.header_.get_ssrc());
// Test wrapping buffer
char test_data[64] = "test payload data";
@ -2418,11 +2418,11 @@ VOID TEST(KernelRtcRtpTest, SrsRtpPacketCopyAndEncodeDecode)
// Create original packet
SrsRtpPacket original;
original.header.set_sequence(1000);
original.header.set_timestamp(2000);
original.header.set_ssrc(0x12345678);
original.header.set_marker(true);
original.header.set_payload_type(96);
original.header_.set_sequence(1000);
original.header_.set_timestamp(2000);
original.header_.set_ssrc(0x12345678);
original.header_.set_marker(true);
original.header_.set_payload_type(96);
original.nalu_type_ = SrsAvcNaluTypeIDR;
original.frame_type_ = SrsFrameTypeVideo;
original.set_avsync_time(5000);
@ -2434,11 +2434,11 @@ VOID TEST(KernelRtcRtpTest, SrsRtpPacketCopyAndEncodeDecode)
// Test copy
SrsRtpPacket *copied = original.copy();
EXPECT_TRUE(copied != NULL);
EXPECT_EQ(1000, copied->header.get_sequence());
EXPECT_EQ(2000, copied->header.get_timestamp());
EXPECT_EQ(0x12345678, copied->header.get_ssrc());
EXPECT_TRUE(copied->header.get_marker());
EXPECT_EQ(96, copied->header.get_payload_type());
EXPECT_EQ(1000, copied->header_.get_sequence());
EXPECT_EQ(2000, copied->header_.get_timestamp());
EXPECT_EQ(0x12345678, copied->header_.get_ssrc());
EXPECT_TRUE(copied->header_.get_marker());
EXPECT_EQ(96, copied->header_.get_payload_type());
EXPECT_EQ(SrsAvcNaluTypeIDR, copied->nalu_type_);
EXPECT_EQ(SrsFrameTypeVideo, copied->frame_type_);
EXPECT_EQ(5000, copied->get_avsync_time());
@ -2455,11 +2455,11 @@ VOID TEST(KernelRtcRtpTest, SrsRtpPacketCopyAndEncodeDecode)
SrsRtpPacket decoded;
HELPER_EXPECT_SUCCESS(decoded.decode(&decode_buffer));
EXPECT_EQ(1000, decoded.header.get_sequence());
EXPECT_EQ(2000, decoded.header.get_timestamp());
EXPECT_EQ(0x12345678, decoded.header.get_ssrc());
EXPECT_TRUE(decoded.header.get_marker());
EXPECT_EQ(96, decoded.header.get_payload_type());
EXPECT_EQ(1000, decoded.header_.get_sequence());
EXPECT_EQ(2000, decoded.header_.get_timestamp());
EXPECT_EQ(0x12345678, decoded.header_.get_ssrc());
EXPECT_TRUE(decoded.header_.get_marker());
EXPECT_EQ(96, decoded.header_.get_payload_type());
}
VOID TEST(KernelKbpsTest, SrsPps_MockClockUpdate)

View File

@ -1550,11 +1550,11 @@ VOID TEST(ProtocolRtpTest, SrsRtpVideoBuilderPackageStapA)
HELPER_EXPECT_SUCCESS(builder.package_stap_a(msg, pkt));
// Verify RTP packet was properly configured
EXPECT_EQ(payload_type, pkt->header.get_payload_type());
EXPECT_EQ(ssrc, pkt->header.get_ssrc());
EXPECT_EQ(payload_type, pkt->header_.get_payload_type());
EXPECT_EQ(ssrc, pkt->header_.get_ssrc());
EXPECT_EQ(SrsFrameTypeVideo, pkt->frame_type_);
EXPECT_EQ(1000 * 90, pkt->header.get_timestamp()); // timestamp * 90
EXPECT_FALSE(pkt->header.get_marker()); // STAP-A should not have marker bit set
EXPECT_EQ(1000 * 90, pkt->header_.get_timestamp()); // timestamp * 90
EXPECT_FALSE(pkt->header_.get_marker()); // STAP-A should not have marker bit set
// Verify STAP-A payload was created
EXPECT_TRUE(pkt->payload() != NULL);
@ -1638,10 +1638,10 @@ VOID TEST(ProtocolRtpTest, SrsRtpVideoBuilderPackageNalusWithFormat)
// Verify first packet configuration
if (!pkts.empty()) {
SrsRtpPacket *pkt = pkts[0];
EXPECT_EQ(payload_type, pkt->header.get_payload_type());
EXPECT_EQ(ssrc, pkt->header.get_ssrc());
EXPECT_EQ(payload_type, pkt->header_.get_payload_type());
EXPECT_EQ(ssrc, pkt->header_.get_ssrc());
EXPECT_EQ(SrsFrameTypeVideo, pkt->frame_type_);
EXPECT_EQ(2000 * 90, pkt->header.get_timestamp()); // timestamp * 90
EXPECT_EQ(2000 * 90, pkt->header_.get_timestamp()); // timestamp * 90
}
// Clean up any created packets
@ -1694,10 +1694,10 @@ VOID TEST(ProtocolRtpTest, SrsRtpVideoBuilderPackageSingleNalu)
if (!pkts.empty()) {
SrsRtpPacket *pkt = pkts[0];
EXPECT_EQ(payload_type, pkt->header.get_payload_type());
EXPECT_EQ(ssrc, pkt->header.get_ssrc());
EXPECT_EQ(payload_type, pkt->header_.get_payload_type());
EXPECT_EQ(ssrc, pkt->header_.get_ssrc());
EXPECT_EQ(SrsFrameTypeVideo, pkt->frame_type_);
EXPECT_EQ(3000 * 90, pkt->header.get_timestamp()); // timestamp * 90
EXPECT_EQ(3000 * 90, pkt->header_.get_timestamp()); // timestamp * 90
}
// Clean up packets
@ -1769,10 +1769,10 @@ VOID TEST(ProtocolRtpTest, SrsRtpVideoBuilderPackageFuA)
// Verify first packet configuration
if (!pkts.empty()) {
SrsRtpPacket *pkt = pkts[0];
EXPECT_EQ(payload_type, pkt->header.get_payload_type());
EXPECT_EQ(ssrc, pkt->header.get_ssrc());
EXPECT_EQ(payload_type, pkt->header_.get_payload_type());
EXPECT_EQ(ssrc, pkt->header_.get_ssrc());
EXPECT_EQ(SrsFrameTypeVideo, pkt->frame_type_);
EXPECT_EQ(4000 * 90, pkt->header.get_timestamp()); // timestamp * 90
EXPECT_EQ(4000 * 90, pkt->header_.get_timestamp()); // timestamp * 90
// Verify it's a FU-A payload
SrsRtpFUAPayload2 *fua_payload = dynamic_cast<SrsRtpFUAPayload2 *>(pkt->payload());

View File

@ -1472,12 +1472,12 @@ VOID TEST(RTPVideoBuilderTest, PackageStapAHevc)
HELPER_ASSERT_SUCCESS(builder.package_stap_a(&msg, &pkt));
// Verify RTP header settings
EXPECT_EQ(96, pkt.header.get_payload_type());
EXPECT_EQ(0x12345678, pkt.header.get_ssrc());
EXPECT_EQ(96, pkt.header_.get_payload_type());
EXPECT_EQ(0x12345678, pkt.header_.get_ssrc());
EXPECT_EQ(SrsFrameTypeVideo, pkt.frame_type_);
EXPECT_FALSE(pkt.header.get_marker());
EXPECT_EQ(100, pkt.header.get_sequence());
EXPECT_EQ(90000, pkt.header.get_timestamp()); // 1000 * 90
EXPECT_FALSE(pkt.header_.get_marker());
EXPECT_EQ(100, pkt.header_.get_sequence());
EXPECT_EQ(90000, pkt.header_.get_timestamp()); // 1000 * 90
// Verify NALU type is set to HEVC STAP
EXPECT_EQ(kStapHevc, pkt.nalu_type_);
@ -1599,11 +1599,11 @@ VOID TEST(RTPVideoBuilderTest, PackageNalusWithEmptySamples)
SrsRtpPacket *pkt = pkts[0];
// Verify RTP header settings
EXPECT_EQ(96, pkt->header.get_payload_type());
EXPECT_EQ(0x12345678, pkt->header.get_ssrc());
EXPECT_EQ(96, pkt->header_.get_payload_type());
EXPECT_EQ(0x12345678, pkt->header_.get_ssrc());
EXPECT_EQ(SrsFrameTypeVideo, pkt->frame_type_);
EXPECT_EQ(200, pkt->header.get_sequence());
EXPECT_EQ(180000, pkt->header.get_timestamp()); // 2000 * 90
EXPECT_EQ(200, pkt->header_.get_sequence());
EXPECT_EQ(180000, pkt->header_.get_timestamp()); // 2000 * 90
// Verify NALU type is set to first valid NALU type (IDR)
EXPECT_EQ(SrsAvcNaluTypeIDR, pkt->nalu_type_);
@ -1751,11 +1751,11 @@ VOID TEST(RTPVideoBuilderTest, PackageNalusLargePayload)
SrsRtpPacket *pkt = pkts[i];
// Verify RTP header settings
EXPECT_EQ(96, pkt->header.get_payload_type());
EXPECT_EQ(0x87654321, pkt->header.get_ssrc());
EXPECT_EQ(96, pkt->header_.get_payload_type());
EXPECT_EQ(0x87654321, pkt->header_.get_ssrc());
EXPECT_EQ(SrsFrameTypeVideo, pkt->frame_type_);
EXPECT_EQ(400 + i, pkt->header.get_sequence()); // Sequence increments
EXPECT_EQ(360000, pkt->header.get_timestamp()); // 4000 * 90
EXPECT_EQ(400 + i, pkt->header_.get_sequence()); // Sequence increments
EXPECT_EQ(360000, pkt->header_.get_timestamp()); // 4000 * 90
// Verify NALU type is FU-A for fragmented packets
EXPECT_EQ(kFuA, pkt->nalu_type_);
@ -1864,11 +1864,11 @@ VOID TEST(RTPVideoBuilderTest, PackageNalusLargePayloadHevc)
SrsRtpPacket *pkt = pkts[i];
// Verify RTP header settings
EXPECT_EQ(96, pkt->header.get_payload_type());
EXPECT_EQ(0x11223344, pkt->header.get_ssrc());
EXPECT_EQ(96, pkt->header_.get_payload_type());
EXPECT_EQ(0x11223344, pkt->header_.get_ssrc());
EXPECT_EQ(SrsFrameTypeVideo, pkt->frame_type_);
EXPECT_EQ(500 + i, pkt->header.get_sequence()); // Sequence increments
EXPECT_EQ(450000, pkt->header.get_timestamp()); // 5000 * 90
EXPECT_EQ(500 + i, pkt->header_.get_sequence()); // Sequence increments
EXPECT_EQ(450000, pkt->header_.get_timestamp()); // 5000 * 90
// Verify NALU type is FU-A for fragmented packets
EXPECT_EQ(kFuA, pkt->nalu_type_);
@ -1994,11 +1994,11 @@ VOID TEST(RTPVideoBuilderTest, PackageNalusMultipleSamplesLargePayload)
SrsRtpPacket *pkt = pkts[i];
// Verify RTP header settings
EXPECT_EQ(96, pkt->header.get_payload_type());
EXPECT_EQ(0xAABBCCDD, pkt->header.get_ssrc());
EXPECT_EQ(96, pkt->header_.get_payload_type());
EXPECT_EQ(0xAABBCCDD, pkt->header_.get_ssrc());
EXPECT_EQ(SrsFrameTypeVideo, pkt->frame_type_);
EXPECT_EQ(600 + i, pkt->header.get_sequence()); // Sequence increments
EXPECT_EQ(540000, pkt->header.get_timestamp()); // 6000 * 90
EXPECT_EQ(600 + i, pkt->header_.get_sequence()); // Sequence increments
EXPECT_EQ(540000, pkt->header_.get_timestamp()); // 6000 * 90
// Verify NALU type is FU-A for fragmented packets
EXPECT_EQ(kFuA, pkt->nalu_type_);
@ -2130,11 +2130,11 @@ VOID TEST(RTPVideoBuilderTest, PackageNalusMultipleSamplesLargePayloadHevc)
SrsRtpPacket *pkt = pkts[i];
// Verify RTP header settings
EXPECT_EQ(96, pkt->header.get_payload_type());
EXPECT_EQ(0x12345678, pkt->header.get_ssrc());
EXPECT_EQ(96, pkt->header_.get_payload_type());
EXPECT_EQ(0x12345678, pkt->header_.get_ssrc());
EXPECT_EQ(SrsFrameTypeVideo, pkt->frame_type_);
EXPECT_EQ(700 + i, pkt->header.get_sequence()); // Sequence increments
EXPECT_EQ(630000, pkt->header.get_timestamp()); // 7000 * 90
EXPECT_EQ(700 + i, pkt->header_.get_sequence()); // Sequence increments
EXPECT_EQ(630000, pkt->header_.get_timestamp()); // 7000 * 90
// Verify NALU type is FU-A for fragmented packets
EXPECT_EQ(kFuA, pkt->nalu_type_);
@ -2238,11 +2238,11 @@ VOID TEST(RTPVideoBuilderTest, PackageFuAHevc)
SrsRtpPacket *pkt = pkts[i];
// Verify RTP header settings
EXPECT_EQ(96, pkt->header.get_payload_type());
EXPECT_EQ(0x11223344, pkt->header.get_ssrc());
EXPECT_EQ(96, pkt->header_.get_payload_type());
EXPECT_EQ(0x11223344, pkt->header_.get_ssrc());
EXPECT_EQ(SrsFrameTypeVideo, pkt->frame_type_);
EXPECT_EQ(800 + i, pkt->header.get_sequence()); // Sequence increments
EXPECT_EQ(720000, pkt->header.get_timestamp()); // 8000 * 90
EXPECT_EQ(800 + i, pkt->header_.get_sequence()); // Sequence increments
EXPECT_EQ(720000, pkt->header_.get_timestamp()); // 8000 * 90
// Verify NALU type is HEVC FU-A for fragmented packets
EXPECT_EQ(kFuHevc, pkt->nalu_type_);
@ -2351,11 +2351,11 @@ VOID TEST(RTPVideoBuilderTest, PackageFuAH264)
SrsRtpPacket *pkt = pkts[i];
// Verify RTP header settings
EXPECT_EQ(96, pkt->header.get_payload_type());
EXPECT_EQ(0x55667788, pkt->header.get_ssrc());
EXPECT_EQ(96, pkt->header_.get_payload_type());
EXPECT_EQ(0x55667788, pkt->header_.get_ssrc());
EXPECT_EQ(SrsFrameTypeVideo, pkt->frame_type_);
EXPECT_EQ(900 + i, pkt->header.get_sequence()); // Sequence increments
EXPECT_EQ(810000, pkt->header.get_timestamp()); // 9000 * 90
EXPECT_EQ(900 + i, pkt->header_.get_sequence()); // Sequence increments
EXPECT_EQ(810000, pkt->header_.get_timestamp()); // 9000 * 90
// Verify NALU type is H.264 FU-A for fragmented packets
EXPECT_EQ(kFuA, pkt->nalu_type_);

View File

@ -78,7 +78,7 @@ srs_error_t MockSrsReloadConfig::do_reload(string buf)
srs_error_t err = srs_success;
MockSrsReloadConfig conf;
if ((err = conf.parse(buf)) != srs_success) {
if ((err = conf.mock_parse(buf)) != srs_success) {
return srs_error_wrap(err, "parse");
}
@ -97,7 +97,7 @@ VOID TEST(ConfigReloadTest, ReloadEmpty)
MockSrsReloadConfig conf;
conf.subscribe(&handler);
HELPER_EXPECT_FAILED(conf.parse(""));
HELPER_EXPECT_FAILED(conf.mock_parse(""));
HELPER_EXPECT_FAILED(conf.do_reload(""));
EXPECT_TRUE(handler.all_false());
}
@ -110,7 +110,7 @@ VOID TEST(ConfigReloadTest, ReloadVhostChunkSize)
MockSrsReloadConfig conf;
conf.subscribe(&handler);
HELPER_EXPECT_SUCCESS(conf.parse(_MIN_OK_CONF "vhost ossrs.net { chunk_size 60000; }"));
HELPER_EXPECT_SUCCESS(conf.mock_parse(_MIN_OK_CONF "vhost ossrs.net { chunk_size 60000; }"));
HELPER_EXPECT_SUCCESS(conf.do_reload(_MIN_OK_CONF "vhost ossrs.net { chunk_size 60000; }"));
EXPECT_TRUE(handler.all_false());
handler.reset();

View File

@ -1338,8 +1338,8 @@ VOID TEST(KernelRTCTest, NACKFetchRTPPacket)
// The RTP queue will free the packet.
if (true) {
SrsRtpPacket *pkt = new SrsRtpPacket();
pkt->header.set_sequence(100);
track->rtp_queue_->set(pkt->header.get_sequence(), pkt);
pkt->header_.set_sequence(100);
track->rtp_queue_->set(pkt->header_.get_sequence(), pkt);
}
// If sequence not match, packet not found.
@ -1670,7 +1670,7 @@ VOID TEST(KernelRTCTest, SyncTimestampBySenderReportNormal)
uint32_t video_absolute_ts = srs_time_now_cached();
uint32_t video_rtp_ts = random();
video_rtp_pkt->header.set_timestamp(video_rtp_ts);
video_rtp_pkt->header_.set_timestamp(video_rtp_ts);
video->on_rtp(rtc_source, video_rtp_pkt);
// No received any sender report, can not calculate absolute time, expect equal to -1.
EXPECT_EQ(video_rtp_pkt->get_avsync_time(), -1);
@ -1688,7 +1688,7 @@ VOID TEST(KernelRTCTest, SyncTimestampBySenderReportNormal)
// Video timebase 90000, fps=25
video_rtp_ts += 3600;
video_absolute_ts += 40;
video_rtp_pkt->header.set_timestamp(video_rtp_ts);
video_rtp_pkt->header_.set_timestamp(video_rtp_ts);
video->on_rtp(rtc_source, video_rtp_pkt);
// Received one sender report, can not calculate absolute time, expect equal to -1.
@ -1703,7 +1703,7 @@ VOID TEST(KernelRTCTest, SyncTimestampBySenderReportNormal)
// Video timebase 90000, fps=25
video_rtp_ts += 3600;
video_absolute_ts += 40;
video_rtp_pkt->header.set_timestamp(video_rtp_ts);
video_rtp_pkt->header_.set_timestamp(video_rtp_ts);
video->on_rtp(rtc_source, video_rtp_pkt);
EXPECT_NEAR(video_rtp_pkt->get_avsync_time(), video_absolute_ts, 1);
}
@ -1736,7 +1736,7 @@ VOID TEST(KernelRTCTest, SyncTimestampBySenderReportOutOfOrder)
uint32_t video_absolute_ts = srs_time_now_cached();
uint32_t video_rtp_ts = random();
video_rtp_pkt->header.set_timestamp(video_rtp_ts);
video_rtp_pkt->header_.set_timestamp(video_rtp_ts);
video->on_rtp(rtc_source, video_rtp_pkt);
// No received any sender report, can not calculate absolute time, expect equal to -1.
EXPECT_EQ(video_rtp_pkt->get_avsync_time(), -1);
@ -1753,7 +1753,7 @@ VOID TEST(KernelRTCTest, SyncTimestampBySenderReportOutOfOrder)
// Video timebase 90000, fps=25
video_rtp_ts += 3600;
video_absolute_ts += 40;
video_rtp_pkt->header.set_timestamp(video_rtp_ts);
video_rtp_pkt->header_.set_timestamp(video_rtp_ts);
video->on_rtp(rtc_source, video_rtp_pkt);
// No received any sender report, can not calculate absolute time, expect equal to -1.
@ -1774,7 +1774,7 @@ VOID TEST(KernelRTCTest, SyncTimestampBySenderReportOutOfOrder)
// Video timebase 90000, fps=25
video_rtp_ts += 3600;
video_absolute_ts += 40;
video_rtp_pkt->header.set_timestamp(video_rtp_ts);
video_rtp_pkt->header_.set_timestamp(video_rtp_ts);
video->on_rtp(rtc_source, video_rtp_pkt);
EXPECT_NEAR(video_rtp_pkt->get_avsync_time(), video_absolute_ts, 1);
}
@ -1807,7 +1807,7 @@ VOID TEST(KernelRTCTest, SyncTimestampBySenderReportConsecutive)
uint32_t video_absolute_ts = srs_time_now_cached();
uint32_t video_rtp_ts = random();
video_rtp_pkt->header.set_timestamp(video_rtp_ts);
video_rtp_pkt->header_.set_timestamp(video_rtp_ts);
video->on_rtp(rtc_source, video_rtp_pkt);
// No received any sender report, can not calculate absolute time, expect equal to -1.
EXPECT_EQ(video_rtp_pkt->get_avsync_time(), -1);
@ -1825,7 +1825,7 @@ VOID TEST(KernelRTCTest, SyncTimestampBySenderReportConsecutive)
// Video timebase 90000, fps=25
video_rtp_ts += 3600;
video_absolute_ts += 40;
video_rtp_pkt->header.set_timestamp(video_rtp_ts);
video_rtp_pkt->header_.set_timestamp(video_rtp_ts);
video->on_rtp(rtc_source, video_rtp_pkt);
// Received one sender report, can not calculate absolute time, expect equal to -1.
@ -1840,7 +1840,7 @@ VOID TEST(KernelRTCTest, SyncTimestampBySenderReportConsecutive)
// Video timebase 90000, fps=25
video_rtp_ts += 3600;
video_absolute_ts += 40;
video_rtp_pkt->header.set_timestamp(video_rtp_ts);
video_rtp_pkt->header_.set_timestamp(video_rtp_ts);
video->on_rtp(rtc_source, video_rtp_pkt);
EXPECT_NEAR(video_rtp_pkt->get_avsync_time(), video_absolute_ts, 1);
@ -1911,7 +1911,7 @@ VOID TEST(KernelRTCTest, SyncTimestampBySenderReportDuplicated)
uint32_t video_absolute_ts = srs_time_now_cached();
uint32_t video_rtp_ts = random();
video_rtp_pkt->header.set_timestamp(video_rtp_ts);
video_rtp_pkt->header_.set_timestamp(video_rtp_ts);
video->on_rtp(rtc_source, video_rtp_pkt);
// No received any sender report, can not calculate absolute time, expect equal to -1.
EXPECT_EQ(video_rtp_pkt->get_avsync_time(), -1);
@ -1929,7 +1929,7 @@ VOID TEST(KernelRTCTest, SyncTimestampBySenderReportDuplicated)
// Video timebase 90000, fps=25
video_rtp_ts += 3600;
video_absolute_ts += 40;
video_rtp_pkt->header.set_timestamp(video_rtp_ts);
video_rtp_pkt->header_.set_timestamp(video_rtp_ts);
video->on_rtp(rtc_source, video_rtp_pkt);
// Received one sender report, can not calculate absolute time, expect equal to -1.
@ -1944,7 +1944,7 @@ VOID TEST(KernelRTCTest, SyncTimestampBySenderReportDuplicated)
// Video timebase 90000, fps=25
video_rtp_ts += 3600;
video_absolute_ts += 40;
video_rtp_pkt->header.set_timestamp(video_rtp_ts);
video_rtp_pkt->header_.set_timestamp(video_rtp_ts);
video->on_rtp(rtc_source, video_rtp_pkt);
EXPECT_NEAR(video_rtp_pkt->get_avsync_time(), video_absolute_ts, 1);
// Duplicate 3 sender report packets.

View File

@ -423,10 +423,10 @@ VOID TEST(KernelRTC2Test, SrsCodecPayloadCopyBehavior)
SrsRtpPacket *mock_create_test_rtp_packet(uint16_t sequence_number, uint32_t timestamp, bool marker = false)
{
SrsRtpPacket *pkt = new SrsRtpPacket();
pkt->header.set_sequence(sequence_number);
pkt->header.set_timestamp(timestamp);
pkt->header.set_marker(marker);
pkt->header.set_ssrc(12345);
pkt->header_.set_sequence(sequence_number);
pkt->header_.set_timestamp(timestamp);
pkt->header_.set_marker(marker);
pkt->header_.set_ssrc(12345);
return pkt;
}
@ -460,8 +460,8 @@ VOID TEST(KernelRTC2Test, SrsRtcFrameBuilderVideoPacketCacheBasicOperations)
SrsRtpPacket *retrieved = cache.get_packet(100);
EXPECT_TRUE(retrieved != NULL);
EXPECT_EQ(100, retrieved->header.get_sequence());
EXPECT_EQ(1000, retrieved->header.get_timestamp());
EXPECT_EQ(100, retrieved->header_.get_sequence());
EXPECT_EQ(1000, retrieved->header_.get_timestamp());
// Test getting non-existent packet
SrsRtpPacket *missing = cache.get_packet(200);
@ -501,8 +501,8 @@ VOID TEST(KernelRTC2Test, SrsRtcFrameBuilderVideoPacketCacheOverwrite)
// Should get the second packet
SrsRtpPacket *retrieved = cache.get_packet(100);
EXPECT_TRUE(retrieved != NULL);
EXPECT_EQ(100, retrieved->header.get_sequence());
EXPECT_EQ(2000, retrieved->header.get_timestamp());
EXPECT_EQ(100, retrieved->header_.get_sequence());
EXPECT_EQ(2000, retrieved->header_.get_timestamp());
}
}
@ -527,8 +527,8 @@ VOID TEST(KernelRTC2Test, SrsRtcFrameBuilderVideoPacketCacheModuloIndexing)
SrsRtpPacket *retrieved2 = cache.get_packet(100 + cache_size);
EXPECT_TRUE(retrieved2 != NULL);
EXPECT_EQ(100 + cache_size, retrieved2->header.get_sequence());
EXPECT_EQ(2000, retrieved2->header.get_timestamp());
EXPECT_EQ(100 + cache_size, retrieved2->header_.get_sequence());
EXPECT_EQ(2000, retrieved2->header_.get_timestamp());
}
}
@ -545,7 +545,7 @@ VOID TEST(KernelRTC2Test, SrsRtcFrameBuilderVideoPacketCacheTakePacket)
// Take the packet (should remove from cache)
SrsRtpPacket *taken = cache.take_packet(100);
EXPECT_TRUE(taken != NULL);
EXPECT_EQ(100, taken->header.get_sequence());
EXPECT_EQ(100, taken->header_.get_sequence());
// Clean up the taken packet
srs_freep(taken);
@ -957,11 +957,11 @@ VOID TEST(KernelRTC2Test, SrsRtcFrameBuilderVideoPacketCacheSequenceWrapAround)
// Should be able to retrieve both packets
SrsRtpPacket *retrieved1 = cache.get_packet(seq_near_max);
EXPECT_TRUE(retrieved1 != NULL);
EXPECT_EQ(seq_near_max, retrieved1->header.get_sequence());
EXPECT_EQ(seq_near_max, retrieved1->header_.get_sequence());
SrsRtpPacket *retrieved2 = cache.get_packet(seq_wrapped);
EXPECT_TRUE(retrieved2 != NULL);
EXPECT_EQ(seq_wrapped, retrieved2->header.get_sequence());
EXPECT_EQ(seq_wrapped, retrieved2->header_.get_sequence());
}
}
@ -982,7 +982,7 @@ VOID TEST(KernelRTC2Test, SrsRtcFrameBuilderVideoPacketCacheMemoryManagement)
// Verify the second packet is stored
SrsRtpPacket *retrieved = cache.get_packet(100);
EXPECT_TRUE(retrieved != NULL);
EXPECT_EQ(2000, retrieved->header.get_timestamp());
EXPECT_EQ(2000, retrieved->header_.get_timestamp());
// Clear all should free remaining packets
cache.clear_all();

View File

@ -18,12 +18,12 @@ SrsRtpPacket *mock_create_audio_rtp_packet(uint16_t sequence, uint32_t timestamp
SrsRtpPacket *pkt = new SrsRtpPacket();
// Set RTP header
pkt->header.set_padding(false);
pkt->header.set_marker(false);
pkt->header.set_payload_type(111); // Audio payload type
pkt->header.set_sequence(sequence);
pkt->header.set_timestamp(timestamp);
pkt->header.set_ssrc(0x12345678);
pkt->header_.set_padding(false);
pkt->header_.set_marker(false);
pkt->header_.set_payload_type(111); // Audio payload type
pkt->header_.set_sequence(sequence);
pkt->header_.set_timestamp(timestamp);
pkt->header_.set_ssrc(0x12345678);
// For audio cache testing, we don't need actual payload data or avsync time
// The cache is only concerned with sequence numbers and system time for jitter buffer logic
@ -59,7 +59,7 @@ VOID TEST(RTC3AudioCacheTest, BasicPacketProcessing)
// First packet should be processed immediately
EXPECT_EQ(1, (int)ready_packets.size());
EXPECT_EQ(100, ready_packets[0]->header.get_sequence());
EXPECT_EQ(100, ready_packets[0]->header_.get_sequence());
free_audio_packets(ready_packets);
@ -69,7 +69,7 @@ VOID TEST(RTC3AudioCacheTest, BasicPacketProcessing)
// Second packet should be processed immediately
EXPECT_EQ(1, (int)ready_packets.size());
EXPECT_EQ(101, ready_packets[0]->header.get_sequence());
EXPECT_EQ(101, ready_packets[0]->header_.get_sequence());
free_audio_packets(ready_packets);
}
@ -103,7 +103,7 @@ VOID TEST(RTC3AudioCacheTest, OutOfOrderPackets)
// Should process packet 101 now
EXPECT_EQ(1, (int)ready_packets.size());
EXPECT_EQ(101, ready_packets[0]->header.get_sequence());
EXPECT_EQ(101, ready_packets[0]->header_.get_sequence());
free_audio_packets(ready_packets);
// Process packet 102 (completes sequence)
@ -112,8 +112,8 @@ VOID TEST(RTC3AudioCacheTest, OutOfOrderPackets)
// Should process both 102 and 103
EXPECT_EQ(2, (int)ready_packets.size());
EXPECT_EQ(102, ready_packets[0]->header.get_sequence());
EXPECT_EQ(103, ready_packets[1]->header.get_sequence());
EXPECT_EQ(102, ready_packets[0]->header_.get_sequence());
EXPECT_EQ(103, ready_packets[1]->header_.get_sequence());
free_audio_packets(ready_packets);
}
@ -133,7 +133,7 @@ VOID TEST(RTC3AudioCacheTest, LatePacketHandling)
SrsUniquePtr<SrsRtpPacket> pkt(mock_create_audio_rtp_packet(seq, 1000 + (seq - 100) * 20));
HELPER_EXPECT_SUCCESS(cache.process_packet(pkt.get(), ready_packets));
EXPECT_EQ(1, (int)ready_packets.size());
EXPECT_EQ(seq, ready_packets[0]->header.get_sequence());
EXPECT_EQ(seq, ready_packets[0]->header_.get_sequence());
free_audio_packets(ready_packets);
}
@ -160,28 +160,28 @@ VOID TEST(RTC3AudioCacheTest, SequenceNumberWrapAround)
SrsUniquePtr<SrsRtpPacket> pkt1(mock_create_audio_rtp_packet(seq_near_max, 1000));
HELPER_EXPECT_SUCCESS(cache.process_packet(pkt1.get(), ready_packets));
EXPECT_EQ(1, (int)ready_packets.size());
EXPECT_EQ(seq_near_max, ready_packets[0]->header.get_sequence());
EXPECT_EQ(seq_near_max, ready_packets[0]->header_.get_sequence());
free_audio_packets(ready_packets);
// Process packet 65535
SrsUniquePtr<SrsRtpPacket> pkt2(mock_create_audio_rtp_packet(65535, 1020));
HELPER_EXPECT_SUCCESS(cache.process_packet(pkt2.get(), ready_packets));
EXPECT_EQ(1, (int)ready_packets.size());
EXPECT_EQ(65535, ready_packets[0]->header.get_sequence());
EXPECT_EQ(65535, ready_packets[0]->header_.get_sequence());
free_audio_packets(ready_packets);
// Process packet 0 (after wrap-around)
SrsUniquePtr<SrsRtpPacket> pkt3(mock_create_audio_rtp_packet(0, 1040));
HELPER_EXPECT_SUCCESS(cache.process_packet(pkt3.get(), ready_packets));
EXPECT_EQ(1, (int)ready_packets.size());
EXPECT_EQ(0, ready_packets[0]->header.get_sequence());
EXPECT_EQ(0, ready_packets[0]->header_.get_sequence());
free_audio_packets(ready_packets);
// Process packet 1
SrsUniquePtr<SrsRtpPacket> pkt4(mock_create_audio_rtp_packet(1, 1060));
HELPER_EXPECT_SUCCESS(cache.process_packet(pkt4.get(), ready_packets));
EXPECT_EQ(1, (int)ready_packets.size());
EXPECT_EQ(1, ready_packets[0]->header.get_sequence());
EXPECT_EQ(1, ready_packets[0]->header_.get_sequence());
free_audio_packets(ready_packets);
}
}
@ -221,7 +221,7 @@ VOID TEST(RTC3AudioCacheTest, PacketLossWithTimeout)
// Should process packet 103 despite missing 101, 102 due to timeout
bool found_103 = false;
for (size_t i = 0; i < ready_packets.size(); i++) {
if (ready_packets[i]->header.get_sequence() == 103) {
if (ready_packets[i]->header_.get_sequence() == 103) {
found_103 = true;
break;
}
@ -322,8 +322,8 @@ VOID TEST(RTC3AudioCacheTest, DuplicatePacketHandling)
// Should process 101 and one instance of 102 (duplicate should be handled)
EXPECT_GE((int)ready_packets.size(), 2);
EXPECT_EQ(101, ready_packets[0]->header.get_sequence());
EXPECT_EQ(102, ready_packets[1]->header.get_sequence());
EXPECT_EQ(101, ready_packets[0]->header_.get_sequence());
EXPECT_EQ(102, ready_packets[1]->header_.get_sequence());
free_audio_packets(ready_packets);
}
}

View File

@ -88,7 +88,7 @@ VOID TEST(RtcRecvTrackTest, OnNackBasicTest)
// Create a test RTP packet
SrsRtpPacket pkt;
pkt.header.set_sequence(100);
pkt.header_.set_sequence(100);
SrsRtpPacket *ppkt = &pkt;
@ -98,7 +98,7 @@ VOID TEST(RtcRecvTrackTest, OnNackBasicTest)
// Test case 2: NACK info exists (recovered packet)
recv_track.receiver_insert(101, 102);
SrsRtpPacket pkt2;
pkt2.header.set_sequence(101);
pkt2.header_.set_sequence(101);
ppkt = &pkt2;
HELPER_EXPECT_SUCCESS(recv_track.on_nack(&ppkt));
}
@ -116,7 +116,7 @@ VOID TEST(RtcRecvTrackTest, OnNackRecoveredPacketTest)
// Create recovered packet
SrsRtpPacket pkt;
pkt.header.set_sequence(200);
pkt.header_.set_sequence(200);
SrsRtpPacket *ppkt = &pkt;
// Process the recovered packet
@ -128,7 +128,7 @@ VOID TEST(RtcRecvTrackTest, OnNackRecoveredPacketTest)
// Verify the packet was added to RTP queue
SrsRtpPacket *queued_pkt = recv_track.get_packet_from_queue(200);
EXPECT_TRUE(queued_pkt != NULL);
EXPECT_TRUE(queued_pkt->header.get_sequence() == 200);
EXPECT_TRUE(queued_pkt->header_.get_sequence() == 200);
}
VOID TEST(RtcRecvTrackTest, OnNackSequentialPacketsTest)
@ -139,7 +139,7 @@ VOID TEST(RtcRecvTrackTest, OnNackSequentialPacketsTest)
// Process sequential packets
for (uint16_t seq = 300; seq < 305; seq++) {
SrsRtpPacket pkt;
pkt.header.set_sequence(seq);
pkt.header_.set_sequence(seq);
SrsRtpPacket *ppkt = &pkt;
HELPER_EXPECT_SUCCESS(recv_track.on_nack(&ppkt));
@ -147,7 +147,7 @@ VOID TEST(RtcRecvTrackTest, OnNackSequentialPacketsTest)
// Verify packet is in queue
SrsRtpPacket *queued_pkt = recv_track.get_packet_from_queue(seq);
EXPECT_TRUE(queued_pkt != NULL);
EXPECT_TRUE(queued_pkt->header.get_sequence() == seq);
EXPECT_TRUE(queued_pkt->header_.get_sequence() == seq);
}
}
@ -161,7 +161,7 @@ VOID TEST(RtcRecvTrackTest, OnNackOutOfOrderPacketsTest)
for (int i = 0; i < 3; i++) {
SrsRtpPacket pkt;
pkt.header.set_sequence(sequences[i]);
pkt.header_.set_sequence(sequences[i]);
SrsRtpPacket *ppkt = &pkt;
HELPER_EXPECT_SUCCESS(recv_track.on_nack(&ppkt));
@ -169,7 +169,7 @@ VOID TEST(RtcRecvTrackTest, OnNackOutOfOrderPacketsTest)
// Verify packet is in queue
SrsRtpPacket *queued_pkt = recv_track.get_packet_from_queue(sequences[i]);
EXPECT_TRUE(queued_pkt != NULL);
EXPECT_TRUE(queued_pkt->header.get_sequence() == sequences[i]);
EXPECT_TRUE(queued_pkt->header_.get_sequence() == sequences[i]);
}
}
@ -183,7 +183,7 @@ VOID TEST(RtcRecvTrackTest, OnNackNoCopyModeTest)
// Create a test RTP packet
SrsRtpPacket *pkt = new SrsRtpPacket();
pkt->header.set_sequence(500);
pkt->header_.set_sequence(500);
SrsRtpPacket *ppkt = pkt;
// Process packet in no-copy mode
@ -195,7 +195,7 @@ VOID TEST(RtcRecvTrackTest, OnNackNoCopyModeTest)
// Verify packet is in queue (original packet, not a copy)
SrsRtpPacket *queued_pkt = recv_track.get_packet_from_queue(500);
EXPECT_TRUE(queued_pkt != NULL);
EXPECT_TRUE(queued_pkt->header.get_sequence() == 500);
EXPECT_TRUE(queued_pkt->header_.get_sequence() == 500);
EXPECT_TRUE(queued_pkt == pkt); // Should be the same object
}
@ -209,7 +209,7 @@ VOID TEST(RtcRecvTrackTest, OnNackCopyModeTest)
// Create a test RTP packet
SrsRtpPacket pkt;
pkt.header.set_sequence(600);
pkt.header_.set_sequence(600);
SrsRtpPacket *ppkt = &pkt;
// Process packet in copy mode
@ -221,7 +221,7 @@ VOID TEST(RtcRecvTrackTest, OnNackCopyModeTest)
// Verify packet is in queue (should be a copy)
SrsRtpPacket *queued_pkt = recv_track.get_packet_from_queue(600);
EXPECT_TRUE(queued_pkt != NULL);
EXPECT_TRUE(queued_pkt->header.get_sequence() == 600);
EXPECT_TRUE(queued_pkt->header_.get_sequence() == 600);
EXPECT_TRUE(queued_pkt != &pkt); // Should be a different object (copy)
}
@ -235,7 +235,7 @@ VOID TEST(RtcRecvTrackTest, OnNackSequenceWrapAroundTest)
for (int i = 0; i < 5; i++) {
SrsRtpPacket pkt;
pkt.header.set_sequence(sequences[i]);
pkt.header_.set_sequence(sequences[i]);
SrsRtpPacket *ppkt = &pkt;
HELPER_EXPECT_SUCCESS(recv_track.on_nack(&ppkt));
@ -243,7 +243,7 @@ VOID TEST(RtcRecvTrackTest, OnNackSequenceWrapAroundTest)
// Verify packet is in queue
SrsRtpPacket *queued_pkt = recv_track.get_packet_from_queue(sequences[i]);
EXPECT_TRUE(queued_pkt != NULL);
EXPECT_TRUE(queued_pkt->header.get_sequence() == sequences[i]);
EXPECT_TRUE(queued_pkt->header_.get_sequence() == sequences[i]);
}
}
@ -265,7 +265,7 @@ VOID TEST(RtcRecvTrackTest, OnNackMixedRecoveredAndNewPacketsTest)
for (int i = 0; i < 4; i++) {
SrsRtpPacket pkt;
pkt.header.set_sequence(sequences[i]);
pkt.header_.set_sequence(sequences[i]);
SrsRtpPacket *ppkt = &pkt;
// Check if packet is in NACK receiver before processing
@ -282,7 +282,7 @@ VOID TEST(RtcRecvTrackTest, OnNackMixedRecoveredAndNewPacketsTest)
// Verify packet is in queue
SrsRtpPacket *queued_pkt = recv_track.get_packet_from_queue(sequences[i]);
EXPECT_TRUE(queued_pkt != NULL);
EXPECT_TRUE(queued_pkt->header.get_sequence() == sequences[i]);
EXPECT_TRUE(queued_pkt->header_.get_sequence() == sequences[i]);
}
}
@ -296,25 +296,25 @@ VOID TEST(RtcRecvTrackTest, OnNackDuplicatePacketTest)
// First time processing
SrsRtpPacket pkt1;
pkt1.header.set_sequence(seq);
pkt1.header_.set_sequence(seq);
SrsRtpPacket *ppkt1 = &pkt1;
HELPER_EXPECT_SUCCESS(recv_track.on_nack(&ppkt1));
// Verify packet is in queue
SrsRtpPacket *queued_pkt1 = recv_track.get_packet_from_queue(seq);
EXPECT_TRUE(queued_pkt1 != NULL);
EXPECT_TRUE(queued_pkt1->header.get_sequence() == seq);
EXPECT_TRUE(queued_pkt1->header_.get_sequence() == seq);
// Second time processing (duplicate)
SrsRtpPacket pkt2;
pkt2.header.set_sequence(seq);
pkt2.header_.set_sequence(seq);
SrsRtpPacket *ppkt2 = &pkt2;
HELPER_EXPECT_SUCCESS(recv_track.on_nack(&ppkt2));
// Verify the packet in queue is replaced (should be the new one)
SrsRtpPacket *queued_pkt2 = recv_track.get_packet_from_queue(seq);
EXPECT_TRUE(queued_pkt2 != NULL);
EXPECT_TRUE(queued_pkt2->header.get_sequence() == seq);
EXPECT_TRUE(queued_pkt2->header_.get_sequence() == seq);
// In copy mode, it should be a different object
EXPECT_TRUE(queued_pkt2 != queued_pkt1);
}
@ -330,24 +330,24 @@ VOID TEST(RtcRecvTrackTest, OnNackLargeGapTest)
// Process first packet
SrsRtpPacket pkt1;
pkt1.header.set_sequence(seq1);
pkt1.header_.set_sequence(seq1);
SrsRtpPacket *ppkt1 = &pkt1;
HELPER_EXPECT_SUCCESS(recv_track.on_nack(&ppkt1));
// Process second packet with large gap
SrsRtpPacket pkt2;
pkt2.header.set_sequence(seq2);
pkt2.header_.set_sequence(seq2);
SrsRtpPacket *ppkt2 = &pkt2;
HELPER_EXPECT_SUCCESS(recv_track.on_nack(&ppkt2));
// Verify both packets are in queue
SrsRtpPacket *queued_pkt1 = recv_track.get_packet_from_queue(seq1);
EXPECT_TRUE(queued_pkt1 != NULL);
EXPECT_TRUE(queued_pkt1->header.get_sequence() == seq1);
EXPECT_TRUE(queued_pkt1->header_.get_sequence() == seq1);
SrsRtpPacket *queued_pkt2 = recv_track.get_packet_from_queue(seq2);
EXPECT_TRUE(queued_pkt2 != NULL);
EXPECT_TRUE(queued_pkt2->header.get_sequence() == seq2);
EXPECT_TRUE(queued_pkt2->header_.get_sequence() == seq2);
}
VOID TEST(RtcRecvTrackTest, OnNackRecoveredPacketRemovedFromNackTest)
@ -367,7 +367,7 @@ VOID TEST(RtcRecvTrackTest, OnNackRecoveredPacketRemovedFromNackTest)
uint16_t recovered_seqs[] = {1001, 1003};
for (int i = 0; i < 2; i++) {
SrsRtpPacket pkt;
pkt.header.set_sequence(recovered_seqs[i]);
pkt.header_.set_sequence(recovered_seqs[i]);
SrsRtpPacket *ppkt = &pkt;
HELPER_EXPECT_SUCCESS(recv_track.on_nack(&ppkt));
@ -378,7 +378,7 @@ VOID TEST(RtcRecvTrackTest, OnNackRecoveredPacketRemovedFromNackTest)
// Verify packet is in queue
SrsRtpPacket *queued_pkt = recv_track.get_packet_from_queue(recovered_seqs[i]);
EXPECT_TRUE(queued_pkt != NULL);
EXPECT_TRUE(queued_pkt->header.get_sequence() == recovered_seqs[i]);
EXPECT_TRUE(queued_pkt->header_.get_sequence() == recovered_seqs[i]);
}
// Verify non-recovered packets are still in NACK receiver
@ -405,7 +405,7 @@ VOID TEST(RtcRecvTrackTest, OnNackBugFixVerificationTest)
// Step 2: Simulate packet recovery (retransmission arrives)
SrsRtpPacket recovered_pkt;
recovered_pkt.header.set_sequence(lost_seq);
recovered_pkt.header_.set_sequence(lost_seq);
SrsRtpPacket *ppkt = &recovered_pkt;
// Step 3: Process the recovered packet
@ -417,7 +417,7 @@ VOID TEST(RtcRecvTrackTest, OnNackBugFixVerificationTest)
// Step 5: Verify the fix - packet should be added to RTP queue (this was the bug)
SrsRtpPacket *queued_pkt = recv_track.get_packet_from_queue(lost_seq);
EXPECT_TRUE(queued_pkt != NULL);
EXPECT_TRUE(queued_pkt->header.get_sequence() == lost_seq);
EXPECT_TRUE(queued_pkt->header_.get_sequence() == lost_seq);
// This test ensures that recovered packets are properly processed and not discarded
}
@ -432,7 +432,7 @@ VOID TEST(RtcRecvTrackTest, OnNackControlFlowTest)
// Scenario 1: New packet (not in NACK receiver)
uint16_t new_seq = 1200;
SrsRtpPacket new_pkt;
new_pkt.header.set_sequence(new_seq);
new_pkt.header_.set_sequence(new_seq);
SrsRtpPacket *new_ppkt = &new_pkt;
// Should not be in NACK receiver initially
@ -443,7 +443,7 @@ VOID TEST(RtcRecvTrackTest, OnNackControlFlowTest)
// New packet should be added to queue
SrsRtpPacket *new_queued = recv_track.get_packet_from_queue(new_seq);
EXPECT_TRUE(new_queued != NULL);
EXPECT_TRUE(new_queued->header.get_sequence() == new_seq);
EXPECT_TRUE(new_queued->header_.get_sequence() == new_seq);
// Scenario 2: Recovered packet (in NACK receiver)
uint16_t recovered_seq = 1201;
@ -453,7 +453,7 @@ VOID TEST(RtcRecvTrackTest, OnNackControlFlowTest)
EXPECT_TRUE(recv_track.receiver_find(recovered_seq) != NULL);
SrsRtpPacket recovered_pkt;
recovered_pkt.header.set_sequence(recovered_seq);
recovered_pkt.header_.set_sequence(recovered_seq);
SrsRtpPacket *recovered_ppkt = &recovered_pkt;
HELPER_EXPECT_SUCCESS(recv_track.on_nack(&recovered_ppkt));
@ -464,7 +464,7 @@ VOID TEST(RtcRecvTrackTest, OnNackControlFlowTest)
// Recovered packet should also be added to queue (the fix)
SrsRtpPacket *recovered_queued = recv_track.get_packet_from_queue(recovered_seq);
EXPECT_TRUE(recovered_queued != NULL);
EXPECT_TRUE(recovered_queued->header.get_sequence() == recovered_seq);
EXPECT_TRUE(recovered_queued->header_.get_sequence() == recovered_seq);
}
VOID TEST(RtcRecvTrackTest, OnNackStressTest)
@ -492,7 +492,7 @@ VOID TEST(RtcRecvTrackTest, OnNackStressTest)
EXPECT_TRUE(is_in_nack == should_be_recovered);
SrsRtpPacket pkt;
pkt.header.set_sequence(seq);
pkt.header_.set_sequence(seq);
SrsRtpPacket *ppkt = &pkt;
HELPER_EXPECT_SUCCESS(recv_track.on_nack(&ppkt));
@ -503,6 +503,6 @@ VOID TEST(RtcRecvTrackTest, OnNackStressTest)
// Verify packet is in queue (the key fix)
SrsRtpPacket *queued_pkt = recv_track.get_packet_from_queue(seq);
EXPECT_TRUE(queued_pkt != NULL);
EXPECT_TRUE(queued_pkt->header.get_sequence() == seq);
EXPECT_TRUE(queued_pkt->header_.get_sequence() == seq);
}
}