AI: Add utest to cover the rtc network module.

This commit is contained in:
OSSRS-AI 2025-10-08 22:57:07 -04:00 committed by winlin
parent 3919e86cc0
commit 646b833757
19 changed files with 2533 additions and 131 deletions

View File

@ -12,6 +12,7 @@
using namespace std;
#include <srs_app_config.hpp>
#include <srs_app_factory.hpp>
#include <srs_app_fragment.hpp>
#include <srs_app_http_hooks.hpp>
#include <srs_app_utility.hpp>
@ -25,7 +26,6 @@ using namespace std;
#include <srs_protocol_amf0.hpp>
#include <srs_protocol_json.hpp>
#include <srs_protocol_rtmp_stack.hpp>
#include <srs_app_factory.hpp>
#define SRS_FWRITE_CACHE_SIZE 65536

View File

@ -8,21 +8,20 @@
#include <srs_app_caster_flv.hpp>
#include <srs_app_config.hpp>
#include <srs_app_dvr.hpp>
#include <srs_app_gb28181.hpp>
#include <srs_app_rtmp_conn.hpp>
#include <srs_app_rtmp_source.hpp>
#include <srs_app_rtsp_source.hpp>
#include <srs_app_st.hpp>
#include <srs_kernel_file.hpp>
#include <srs_kernel_flv.hpp>
#include <srs_kernel_hourglass.hpp>
#include <srs_kernel_mp4.hpp>
#include <srs_kernel_ts.hpp>
#include <srs_kernel_utility.hpp>
#include <srs_protocol_http_client.hpp>
#include <srs_protocol_st.hpp>
#include <srs_app_rtsp_source.hpp>
#include <srs_kernel_flv.hpp>
#include <srs_kernel_mp4.hpp>
#include <srs_app_dvr.hpp>
#include <srs_app_gb28181.hpp>
ISrsAppFactory::ISrsAppFactory()
{
@ -129,6 +128,7 @@ ISrsDvrSegmenter *SrsAppFactory::create_dvr_mp4_segmenter()
return new SrsDvrMp4Segmenter();
}
#ifdef SRS_GB28181
ISrsGbMediaTcpConn *SrsAppFactory::create_gb_media_tcp_conn()
{
return new SrsGbMediaTcpConn();
@ -138,6 +138,7 @@ ISrsGbSession *SrsAppFactory::create_gb_session()
{
return new SrsGbSession();
}
#endif
SrsFinalFactory::SrsFinalFactory()
{

View File

@ -59,8 +59,10 @@ public:
virtual ISrsMp4Encoder *create_mp4_encoder() = 0;
virtual ISrsDvrSegmenter *create_dvr_flv_segmenter() = 0;
virtual ISrsDvrSegmenter *create_dvr_mp4_segmenter() = 0;
#ifdef SRS_GB28181
virtual ISrsGbMediaTcpConn *create_gb_media_tcp_conn() = 0;
virtual ISrsGbSession *create_gb_session() = 0;
#endif
};
// The factory to create app objects.
@ -90,8 +92,10 @@ public:
virtual ISrsMp4Encoder *create_mp4_encoder();
virtual ISrsDvrSegmenter *create_dvr_flv_segmenter();
virtual ISrsDvrSegmenter *create_dvr_mp4_segmenter();
#ifdef SRS_GB28181
virtual ISrsGbMediaTcpConn *create_gb_media_tcp_conn();
virtual ISrsGbSession *create_gb_session();
#endif
};
extern ISrsAppFactory *_srs_app_factory;

View File

@ -7,6 +7,7 @@
#include <srs_app_gb28181.hpp>
#include <srs_app_config.hpp>
#include <srs_app_factory.hpp>
#include <srs_app_http_api.hpp>
#include <srs_app_listener.hpp>
#include <srs_app_rtmp_conn.hpp>
@ -25,7 +26,6 @@
#include <srs_protocol_raw_avc.hpp>
#include <srs_protocol_sdp.hpp>
#include <srs_protocol_utility.hpp>
#include <srs_app_factory.hpp>
#include <sstream>
using namespace std;

View File

@ -128,6 +128,7 @@ public:
virtual void setup_owner(SrsSharedResource<ISrsGbSession> *wrapper, ISrsInterruptable *owner_coroutine, ISrsContextIdSetter *owner_cid) = 0;
// Notice session to use current media connection.
virtual void on_media_transport(SrsSharedResource<ISrsGbMediaTcpConn> media) = 0;
public:
virtual void on_ps_pack(ISrsPackContext *ctx, SrsPsPacket *ps, const std::vector<SrsTsMessage *> &msgs) = 0;
};
@ -140,7 +141,7 @@ class SrsGbSession : public ISrsGbSession
{
private:
ISrsAppConfig *config_;
private:
SrsContextId cid_;
@ -298,7 +299,7 @@ public:
// A GB28181 TCP media connection, for PS stream.
class SrsGbMediaTcpConn : public ISrsGbMediaTcpConn, // It's a resource, coroutine handler, and executor handler.
public ISrsPsPackHandler
public ISrsPsPackHandler
{
private:
ISrsResourceManager *gb_manager_;

View File

@ -430,6 +430,14 @@ srs_error_t SrsMultipleTcpListeners::on_tcp_client(ISrsListener *listener, srs_n
return handler_->on_tcp_client(this, stfd);
}
ISrsUdpMuxSocket::ISrsUdpMuxSocket()
{
}
ISrsUdpMuxSocket::~ISrsUdpMuxSocket()
{
}
SrsUdpMuxSocket::SrsUdpMuxSocket(srs_netfd_t fd)
{
nn_msgs_for_yield_ = 0;
@ -612,7 +620,7 @@ SrsBuffer *SrsUdpMuxSocket::buffer()
return cache_buffer_;
}
SrsUdpMuxSocket *SrsUdpMuxSocket::copy_sendonly()
ISrsUdpMuxSocket *SrsUdpMuxSocket::copy_sendonly()
{
SrsUdpMuxSocket *sendonly = new SrsUdpMuxSocket(lfd_);

View File

@ -189,8 +189,24 @@ public:
virtual srs_error_t on_tcp_client(ISrsListener *listener, srs_netfd_t stfd);
};
// The UDP socket interface.
class ISrsUdpMuxSocket
{
public:
ISrsUdpMuxSocket();
virtual ~ISrsUdpMuxSocket();
public:
virtual srs_error_t sendto(void *data, int size, srs_utime_t timeout) = 0;
virtual std::string get_peer_ip() const = 0;
virtual int get_peer_port() const = 0;
virtual std::string peer_id() = 0;
virtual uint64_t fast_id() = 0;
virtual ISrsUdpMuxSocket *copy_sendonly() = 0;
};
// TODO: FIXME: Rename it. Refine it for performance issue.
class SrsUdpMuxSocket
class SrsUdpMuxSocket : public ISrsUdpMuxSocket
{
private:
// For sender yield only.
@ -235,7 +251,7 @@ public:
std::string peer_id();
uint64_t fast_id();
SrsBuffer *buffer();
SrsUdpMuxSocket *copy_sendonly();
ISrsUdpMuxSocket *copy_sendonly();
};
class SrsUdpMuxListener : public ISrsCoroutineHandler

View File

@ -554,11 +554,11 @@ public:
// The interface for RTC connection.
class ISrsRtcConnection : public ISrsResource, // It's a resource.
public ISrsDisposingHandler,
public ISrsExpire,
public ISrsRtcPacketSender,
public ISrsRtcPacketReceiver,
public ISrsRtcConnectionNackTimerHandler
public ISrsDisposingHandler,
public ISrsExpire,
public ISrsRtcPacketSender,
public ISrsRtcPacketReceiver,
public ISrsRtcConnectionNackTimerHandler
{
public:
ISrsRtcConnection();

View File

@ -203,9 +203,9 @@ SrsRtcUdpNetwork::~SrsRtcUdpNetwork()
// Note that we should never delete the sendonly_skt,
// it's just point to the object in peer_addresses_.
map<string, SrsUdpMuxSocket *>::iterator it;
map<string, ISrsUdpMuxSocket *>::iterator it;
for (it = peer_addresses_.begin(); it != peer_addresses_.end(); ++it) {
SrsUdpMuxSocket *addr = it->second;
ISrsUdpMuxSocket *addr = it->second;
srs_freep(addr);
}
@ -368,7 +368,7 @@ int SrsRtcUdpNetwork::get_peer_port()
return sendonly_skt_->get_peer_port();
}
void SrsRtcUdpNetwork::update_sendonly_socket(SrsUdpMuxSocket *skt)
void SrsRtcUdpNetwork::update_sendonly_socket(ISrsUdpMuxSocket *skt)
{
// TODO: FIXME: Refine performance.
string prev_peer_id, peer_id = skt->peer_id();
@ -382,9 +382,9 @@ void SrsRtcUdpNetwork::update_sendonly_socket(SrsUdpMuxSocket *skt)
}
// Find object from cache.
SrsUdpMuxSocket *addr_cache = NULL;
ISrsUdpMuxSocket *addr_cache = NULL;
if (true) {
map<string, SrsUdpMuxSocket *>::iterator it = peer_addresses_.find(peer_id);
map<string, ISrsUdpMuxSocket *>::iterator it = peer_addresses_.find(peer_id);
if (it != peer_addresses_.end()) {
addr_cache = it->second;
}

View File

@ -25,6 +25,7 @@ class SrsTcpConnection;
class ISrsTcpConnection;
class ISrsKbpsDelta;
class SrsUdpMuxSocket;
class ISrsUdpMuxSocket;
class SrsErrorPithyPrint;
class ISrsRtcTransport;
class SrsEphemeralDelta;
@ -183,9 +184,9 @@ private:
// Pithy print for address change, use port as error code.
SrsErrorPithyPrint *pp_address_change_;
// The peer address, client maybe use more than one address, it's the current selected one.
SrsUdpMuxSocket *sendonly_skt_;
ISrsUdpMuxSocket *sendonly_skt_;
// The address list, client may use multiple addresses.
std::map<std::string, SrsUdpMuxSocket *> peer_addresses_;
std::map<std::string, ISrsUdpMuxSocket *> peer_addresses_;
// The DTLS transport over this network.
ISrsRtcTransport *transport_;
@ -195,7 +196,7 @@ public:
public:
// Update the UDP connection.
void update_sendonly_socket(SrsUdpMuxSocket *skt);
void update_sendonly_socket(ISrsUdpMuxSocket *skt);
// When got STUN ping message. The peer address may change, we can identify that by STUN messages.
srs_error_t on_stun(SrsStunPacket *r, char *data, int nb_data);
@ -320,7 +321,7 @@ private:
std::string ip_;
int port_;
// The delta for statistic.
SrsNetworkDelta *delta_;
ISrsNetworkDelta *delta_;
ISrsProtocolReadWriter *skt_;
// Packet cache.
char *pkt_;

View File

@ -850,7 +850,7 @@ SrsOriginHub::SrsOriginHub()
hls_ = new SrsHls();
dash_ = new SrsDash();
dvr_ = new SrsDvr();
dvr_->assemble();

View File

@ -13,6 +13,7 @@ using namespace std;
#include <sstream>
#include <srs_app_config.hpp>
#include <srs_app_factory.hpp>
#include <srs_app_http_hooks.hpp>
#include <srs_app_rtsp_source.hpp>
#include <srs_app_security.hpp>
@ -29,7 +30,6 @@ using namespace std;
#include <srs_protocol_rtsp_stack.hpp>
#include <srs_protocol_st.hpp>
#include <srs_protocol_utility.hpp>
#include <srs_app_factory.hpp>
extern SrsPps *_srs_pps_snack;
extern SrsPps *_srs_pps_snack2;
@ -656,8 +656,8 @@ srs_error_t SrsRtspConnection::on_rtsp_request(SrsRtspRequest *req_raw)
return srs_error_wrap(err, "response setup");
}
srs_trace("RTSP: SETUP cseq=%ld, session=%s, transport=%s/%s/%s, ssrc=%u, client_port=%d-%d",
req->seq_, session_id_.c_str(), req->transport_->transport_.c_str(), req->transport_->profile_.c_str(),
req->transport_->lower_transport_.c_str(), ssrc, req->transport_->client_port_min_, req->transport_->client_port_max_);
req->seq_, session_id_.c_str(), req->transport_->transport_.c_str(), req->transport_->profile_.c_str(),
req->transport_->lower_transport_.c_str(), ssrc, req->transport_->client_port_min_, req->transport_->client_port_max_);
} else if (req->is_play()) {
SrsUniquePtr<SrsRtspResponse> res(new SrsRtspResponse((int)req->seq_));
res->session_ = session_id_;

View File

@ -197,7 +197,11 @@ public:
// return err;
// }
class SrsExecutorCoroutine : public ISrsResource, // It's a resource.
public ISrsStartable, public ISrsInterruptable, public ISrsContextIdSetter, public ISrsContextIdGetter, public ISrsCoroutineHandler
public ISrsStartable,
public ISrsInterruptable,
public ISrsContextIdSetter,
public ISrsContextIdGetter,
public ISrsCoroutineHandler
{
private:
ISrsResourceManager *manager_;

View File

@ -89,7 +89,7 @@ SrsTsMessage *SrsPsContext::reap()
return msg;
}
SrsPsDecodeHelper* SrsPsContext::helper()
SrsPsDecodeHelper *SrsPsContext::helper()
{
return &helper_;
}

View File

@ -65,7 +65,7 @@ public:
virtual ~ISrsPsContext();
public:
virtual SrsPsDecodeHelper* helper() = 0;
virtual SrsPsDecodeHelper *helper() = 0;
virtual void set_detect_ps_integrity(bool v) = 0;
virtual srs_error_t decode(SrsBuffer *stream, ISrsPsMessageHandler *handler) = 0;
virtual SrsTsMessage *last() = 0;
@ -102,7 +102,7 @@ public:
SrsTsMessage *last();
// Reap the last message and create a fresh one.
SrsTsMessage *reap();
virtual SrsPsDecodeHelper* helper();
virtual SrsPsDecodeHelper *helper();
public:
// Feed with ts packets, decode as ts message, callback handler if got one ts message.

View File

@ -2063,19 +2063,19 @@ VOID TEST(RtspPlayStreamTest, OnStreamChange)
// Create new audio track description with different SSRC and PT
new_desc->audio_track_desc_ = new SrsRtcTrackDescription();
new_desc->audio_track_desc_->type_ = "audio";
new_desc->audio_track_desc_->ssrc_ = 1002; // Changed SSRC
new_desc->audio_track_desc_->media_ = new SrsAudioPayload(112, "opus", 48000, 2); // Changed PT
new_desc->audio_track_desc_->ssrc_ = 1002; // Changed SSRC
new_desc->audio_track_desc_->media_ = new SrsAudioPayload(112, "opus", 48000, 2); // Changed PT
new_desc->audio_track_desc_->media_->pt_ = 112;
new_desc->audio_track_desc_->red_ = new SrsRedPayload(64, "red", 48000, 2); // Changed PT
new_desc->audio_track_desc_->red_ = new SrsRedPayload(64, "red", 48000, 2); // Changed PT
new_desc->audio_track_desc_->red_->pt_ = 64;
// Create new video track description with different SSRC and PT
SrsRtcTrackDescription *new_video_desc = new SrsRtcTrackDescription();
new_video_desc->type_ = "video";
new_video_desc->ssrc_ = 2002; // Changed SSRC
new_video_desc->media_ = new SrsVideoPayload(103, "H264", 90000); // Changed PT
new_video_desc->ssrc_ = 2002; // Changed SSRC
new_video_desc->media_ = new SrsVideoPayload(103, "H264", 90000); // Changed PT
new_video_desc->media_->pt_ = 103;
new_video_desc->red_ = new SrsCodecPayload(101, "rtx", 90000); // Changed PT
new_video_desc->red_ = new SrsCodecPayload(101, "rtx", 90000); // Changed PT
new_video_desc->red_->pt_ = 101;
new_desc->video_track_descs_.push_back(new_video_desc);
@ -2084,13 +2084,13 @@ VOID TEST(RtspPlayStreamTest, OnStreamChange)
// Verify that audio track map was updated with new SSRC
EXPECT_EQ(1, (int)play_stream->audio_tracks_.size());
EXPECT_TRUE(play_stream->audio_tracks_.find(1001) == play_stream->audio_tracks_.end()); // Old SSRC removed
EXPECT_TRUE(play_stream->audio_tracks_.find(1002) != play_stream->audio_tracks_.end()); // New SSRC added
EXPECT_TRUE(play_stream->audio_tracks_.find(1001) == play_stream->audio_tracks_.end()); // Old SSRC removed
EXPECT_TRUE(play_stream->audio_tracks_.find(1002) != play_stream->audio_tracks_.end()); // New SSRC added
// Verify that video track map was updated with new SSRC
EXPECT_EQ(1, (int)play_stream->video_tracks_.size());
EXPECT_TRUE(play_stream->video_tracks_.find(2001) == play_stream->video_tracks_.end()); // Old SSRC removed
EXPECT_TRUE(play_stream->video_tracks_.find(2002) != play_stream->video_tracks_.end()); // New SSRC added
EXPECT_TRUE(play_stream->video_tracks_.find(2001) == play_stream->video_tracks_.end()); // Old SSRC removed
EXPECT_TRUE(play_stream->video_tracks_.find(2002) != play_stream->video_tracks_.end()); // New SSRC added
// Verify that the track objects are the same (not recreated)
EXPECT_EQ(audio_track, play_stream->audio_tracks_[1002]);
@ -2470,7 +2470,7 @@ VOID TEST(RtspConnectionTest, SessionLifecycleAndDisposal)
// Test 1: Context management
{
// Get the context ID
const SrsContextId& cid = conn->context_id();
const SrsContextId &cid = conn->context_id();
EXPECT_FALSE(cid.empty());
// Switch to context should set the global context
@ -2566,7 +2566,7 @@ VOID TEST(RtspConnectionTest, DoDescribeWithAudioAndVideo)
audio_desc->type_ = "audio";
audio_desc->ssrc_ = 1001;
SrsAudioPayload *audio_payload = new SrsAudioPayload(97, "MPEG4-GENERIC", 48000, 2);
audio_payload->aac_config_hex_ = "1190"; // AAC config hex
audio_payload->aac_config_hex_ = "1190"; // AAC config hex
audio_desc->media_ = audio_payload;
mock_source->audio_desc_ = audio_desc;
@ -2729,7 +2729,7 @@ VOID TEST(RtspConnectionTest, DoSetupWithTcpTransport)
// Create a track description with known stream_id and ssrc
SrsRtcTrackDescription *video_desc = new SrsRtcTrackDescription();
video_desc->type_ = "video";
video_desc->id_ = "0"; // stream_id will be 0
video_desc->id_ = "0"; // stream_id will be 0
video_desc->ssrc_ = 12345;
// Add track to connection's tracks map
@ -2738,7 +2738,7 @@ VOID TEST(RtspConnectionTest, DoSetupWithTcpTransport)
// Create RTSP SETUP request with TCP transport
SrsUniquePtr<SrsRtspRequest> req(new SrsRtspRequest());
req->method_ = "SETUP";
req->stream_id_ = 0; // Matches track id_ = "0"
req->stream_id_ = 0; // Matches track id_ = "0"
// Configure TCP transport (interleaved mode)
req->transport_ = new SrsRtspTransport();
@ -2837,12 +2837,12 @@ VOID TEST(RtspConnectionTest, GetSsrcByStreamIdSuccess)
// Create multiple track descriptions with different stream IDs
SrsRtcTrackDescription *audio_desc = new SrsRtcTrackDescription();
audio_desc->type_ = "audio";
audio_desc->id_ = "0"; // stream_id 0
audio_desc->id_ = "0"; // stream_id 0
audio_desc->ssrc_ = 1001;
SrsRtcTrackDescription *video_desc = new SrsRtcTrackDescription();
video_desc->type_ = "video";
video_desc->id_ = "1"; // stream_id 1
video_desc->id_ = "1"; // stream_id 1
video_desc->ssrc_ = 2001;
// Add tracks to connection's tracks map (key is SSRC)
@ -3459,13 +3459,13 @@ VOID TEST(DvrSegmenterTest, OnUpdateDurationTypicalScenario)
// Create media packets with different timestamps to test duration tracking
SrsUniquePtr<SrsMediaPacket> msg1(new SrsMediaPacket());
msg1->timestamp_ = 1000; // 1000ms
msg1->timestamp_ = 1000; // 1000ms
SrsUniquePtr<SrsMediaPacket> msg2(new SrsMediaPacket());
msg2->timestamp_ = 2000; // 2000ms
msg2->timestamp_ = 2000; // 2000ms
SrsUniquePtr<SrsMediaPacket> msg3(new SrsMediaPacket());
msg3->timestamp_ = 3500; // 3500ms
msg3->timestamp_ = 3500; // 3500ms
// Verify initial fragment duration is 0
EXPECT_EQ(0, srsu2msi(segmenter->fragment_->duration()));
@ -3521,8 +3521,8 @@ VOID TEST(DvrFlvSegmenterTest, RefreshMetadataTypicalScenario)
HELPER_EXPECT_SUCCESS(mock_fs->write(dummy_data, sizeof(dummy_data), NULL));
// Set the duration and filesize offsets (simulate where metadata fields are in the file)
segmenter->duration_offset_ = 20; // Duration field at offset 20
segmenter->filesize_offset_ = 40; // Filesize field at offset 40
segmenter->duration_offset_ = 20; // Duration field at offset 20
segmenter->filesize_offset_ = 40; // Filesize field at offset 40
// Set up the fragment with a duration (5.5 seconds = 5500ms = 5500000us)
SrsUniquePtr<SrsMediaPacket> msg1(new SrsMediaPacket());
@ -3530,7 +3530,7 @@ VOID TEST(DvrFlvSegmenterTest, RefreshMetadataTypicalScenario)
HELPER_EXPECT_SUCCESS(segmenter->on_update_duration(msg1.get()));
SrsUniquePtr<SrsMediaPacket> msg2(new SrsMediaPacket());
msg2->timestamp_ = 6500; // 5500ms duration
msg2->timestamp_ = 6500; // 5500ms duration
HELPER_EXPECT_SUCCESS(segmenter->on_update_duration(msg2.get()));
// Verify fragment duration is 5500ms
@ -3538,7 +3538,7 @@ VOID TEST(DvrFlvSegmenterTest, RefreshMetadataTypicalScenario)
// Get current file position before refresh
int64_t pos_before = mock_fs->tellg();
EXPECT_EQ(100, pos_before); // Should be at end of dummy data
EXPECT_EQ(100, pos_before); // Should be at end of dummy data
// Call refresh_metadata() - this is the method under test
HELPER_EXPECT_SUCCESS(segmenter->refresh_metadata());
@ -3550,7 +3550,7 @@ VOID TEST(DvrFlvSegmenterTest, RefreshMetadataTypicalScenario)
// Verify the filesize was written correctly at filesize_offset_
mock_fs->seek2(segmenter->filesize_offset_);
int amf0_number_size = SrsAmf0Size::number();
char filesize_buf[9]; // AMF0 number is always 9 bytes (1 byte marker + 8 bytes double)
char filesize_buf[9]; // AMF0 number is always 9 bytes (1 byte marker + 8 bytes double)
ssize_t nread = 0;
HELPER_EXPECT_SUCCESS(mock_fs->uf->read(filesize_buf, amf0_number_size, &nread));
EXPECT_EQ(amf0_number_size, nread);
@ -3560,11 +3560,11 @@ VOID TEST(DvrFlvSegmenterTest, RefreshMetadataTypicalScenario)
SrsUniquePtr<SrsAmf0Any> filesize_value(SrsAmf0Any::number());
HELPER_EXPECT_SUCCESS(filesize_value->read(&filesize_stream));
EXPECT_TRUE(filesize_value->is_number());
EXPECT_EQ(100.0, filesize_value->to_number()); // Should match file size
EXPECT_EQ(100.0, filesize_value->to_number()); // Should match file size
// Verify the duration was written correctly at duration_offset_
mock_fs->seek2(segmenter->duration_offset_);
char duration_buf[9]; // AMF0 number is always 9 bytes (1 byte marker + 8 bytes double)
char duration_buf[9]; // AMF0 number is always 9 bytes (1 byte marker + 8 bytes double)
nread = 0;
HELPER_EXPECT_SUCCESS(mock_fs->uf->read(duration_buf, amf0_number_size, &nread));
EXPECT_EQ(amf0_number_size, nread);
@ -3574,7 +3574,7 @@ VOID TEST(DvrFlvSegmenterTest, RefreshMetadataTypicalScenario)
SrsUniquePtr<SrsAmf0Any> duration_value(SrsAmf0Any::number());
HELPER_EXPECT_SUCCESS(duration_value->read(&duration_stream));
EXPECT_TRUE(duration_value->is_number());
EXPECT_EQ(5.5, duration_value->to_number()); // Should be 5.5 seconds
EXPECT_EQ(5.5, duration_value->to_number()); // Should be 5.5 seconds
// Clean up - set to NULL to avoid double-free
segmenter->fs_ = NULL;
@ -3625,8 +3625,8 @@ VOID TEST(DvrFlvSegmenterTest, EncodeMetadataTypicalScenario)
SrsUniquePtr<SrsAmf0Object> metadata_obj(SrsAmf0Any::object());
metadata_obj->set("width", SrsAmf0Any::number(1920));
metadata_obj->set("height", SrsAmf0Any::number(1080));
metadata_obj->set("duration", SrsAmf0Any::number(120)); // Should be removed and replaced
metadata_obj->set("filesize", SrsAmf0Any::number(1000000)); // Should be removed and replaced
metadata_obj->set("duration", SrsAmf0Any::number(120)); // Should be removed and replaced
metadata_obj->set("filesize", SrsAmf0Any::number(1000000)); // Should be removed and replaced
// Serialize metadata to bytes
int metadata_size = name->total_size() + metadata_obj->total_size();
@ -3649,13 +3649,13 @@ VOID TEST(DvrFlvSegmenterTest, EncodeMetadataTypicalScenario)
// Verify the mock encoder's write_metadata was called
EXPECT_TRUE(mock_enc->write_metadata_called_);
EXPECT_EQ(18, (int)mock_enc->metadata_type_); // Type should be 18 (script data)
EXPECT_TRUE(mock_enc->metadata_size_ > 0); // Should have written some data
EXPECT_EQ(18, (int)mock_enc->metadata_type_); // Type should be 18 (script data)
EXPECT_TRUE(mock_enc->metadata_size_ > 0); // Should have written some data
// Verify duration_offset_ and filesize_offset_ were calculated
EXPECT_TRUE(segmenter->duration_offset_ > 0);
EXPECT_TRUE(segmenter->filesize_offset_ > 0);
EXPECT_TRUE(segmenter->filesize_offset_ < segmenter->duration_offset_); // filesize comes before duration
EXPECT_TRUE(segmenter->filesize_offset_ < segmenter->duration_offset_); // filesize comes before duration
// Verify calling encode_metadata again is ignored (metadata already written)
int64_t saved_duration_offset = segmenter->duration_offset_;
@ -3734,7 +3734,7 @@ VOID TEST(DvrMp4SegmenterTest, EncodeAudioVideoTypicalScenario)
audio_format->audio_->aac_packet_type_ = SrsAudioAacFrameTraitSequenceHeader;
// Create audio sample data
char audio_data[10] = {0x12, 0x10}; // AAC sequence header
char audio_data[10] = {0x12, 0x10}; // AAC sequence header
audio_format->raw_ = audio_data;
audio_format->nb_raw_ = 2;
@ -3758,7 +3758,7 @@ VOID TEST(DvrMp4SegmenterTest, EncodeAudioVideoTypicalScenario)
EXPECT_EQ(0x00, (int)mock_enc->last_frame_type_);
EXPECT_EQ(SrsAudioAacFrameTraitSequenceHeader, (int)mock_enc->last_codec_type_);
EXPECT_EQ(1000, (int)mock_enc->last_dts_);
EXPECT_EQ(1000, (int)mock_enc->last_pts_); // For audio, PTS = DTS
EXPECT_EQ(1000, (int)mock_enc->last_pts_); // For audio, PTS = DTS
EXPECT_EQ(2, (int)mock_enc->last_sample_size_);
// Reset mock encoder for video test
@ -3795,7 +3795,7 @@ VOID TEST(DvrMp4SegmenterTest, EncodeAudioVideoTypicalScenario)
EXPECT_EQ(SrsVideoAvcFrameTypeKeyFrame, (int)mock_enc->last_frame_type_);
EXPECT_EQ(SrsVideoAvcFrameTraitSequenceHeader, (int)mock_enc->last_codec_type_);
EXPECT_EQ(2000, (int)mock_enc->last_dts_);
EXPECT_EQ(2000, (int)mock_enc->last_pts_); // PTS = DTS + CTS (2000 + 0)
EXPECT_EQ(2000, (int)mock_enc->last_pts_); // PTS = DTS + CTS (2000 + 0)
EXPECT_EQ(4, (int)mock_enc->last_sample_size_);
// Reset mock encoder for regular video frame test
@ -3803,7 +3803,7 @@ VOID TEST(DvrMp4SegmenterTest, EncodeAudioVideoTypicalScenario)
// Test encode_video with regular video frame (with CTS)
video_format->video_->avc_packet_type_ = SrsVideoAvcFrameTraitNALU;
video_format->video_->cts_ = 40; // 40ms CTS
video_format->video_->cts_ = 40; // 40ms CTS
video_packet->timestamp_ = 3000;
// Call encode_video() again
@ -3814,7 +3814,7 @@ VOID TEST(DvrMp4SegmenterTest, EncodeAudioVideoTypicalScenario)
EXPECT_EQ(SrsMp4HandlerTypeVIDE, mock_enc->last_handler_type_);
EXPECT_EQ(SrsVideoAvcFrameTraitNALU, (int)mock_enc->last_codec_type_);
EXPECT_EQ(3000, (int)mock_enc->last_dts_);
EXPECT_EQ(3040, (int)mock_enc->last_pts_); // PTS = DTS + CTS (3000 + 40)
EXPECT_EQ(3040, (int)mock_enc->last_pts_); // PTS = DTS + CTS (3000 + 40)
// Clean up - set to NULL to avoid double-free
segmenter->fs_ = NULL;
@ -3917,7 +3917,7 @@ srs_error_t MockHttpHooksForDvrAsyncCall::on_dvr(SrsContextId cid, std::string u
}
srs_error_t MockHttpHooksForDvrAsyncCall::on_hls(SrsContextId cid, std::string url, ISrsRequest *req, std::string file, std::string ts_url,
std::string m3u8, std::string m3u8_url, int sn, srs_utime_t duration)
std::string m3u8, std::string m3u8_url, int sn, srs_utime_t duration)
{
return srs_success;
}
@ -4141,7 +4141,7 @@ VOID TEST(DvrPlanTest, CreatePlanTypicalScenario)
ISrsDvrPlan *segment_plan = NULL;
HELPER_EXPECT_SUCCESS(SrsDvrPlan::create_plan(segment_config.get(), "test.vhost", &segment_plan));
EXPECT_TRUE(segment_plan != NULL);
EXPECT_TRUE(dynamic_cast<SrsDvrSegmentPlan*>(segment_plan) != NULL);
EXPECT_TRUE(dynamic_cast<SrsDvrSegmentPlan *>(segment_plan) != NULL);
srs_freep(segment_plan);
// Test session plan
@ -4151,7 +4151,7 @@ VOID TEST(DvrPlanTest, CreatePlanTypicalScenario)
ISrsDvrPlan *session_plan = NULL;
HELPER_EXPECT_SUCCESS(SrsDvrPlan::create_plan(session_config.get(), "test.vhost", &session_plan));
EXPECT_TRUE(session_plan != NULL);
EXPECT_TRUE(dynamic_cast<SrsDvrSessionPlan*>(session_plan) != NULL);
EXPECT_TRUE(dynamic_cast<SrsDvrSessionPlan *>(session_plan) != NULL);
srs_freep(session_plan);
// Test illegal plan
@ -4456,16 +4456,16 @@ VOID TEST(DvrSegmentPlanTest, OnVideoReapSegmentWhenDurationExceeds)
// Simulate fragment duration exceeding the configured limit
// Append frames to build up duration to 31 seconds (exceeds 30 second limit)
fragment->append(0); // Start at 0ms
fragment->append(31000); // End at 31000ms (31 seconds)
fragment->append(0); // Start at 0ms
fragment->append(31000); // End at 31000ms (31 seconds)
// Create H.264 keyframe video packet (not sequence header)
// H.264 keyframe format: 0x17 = (1 << 4) | 7 = keyframe + H.264
// AVC packet type: 0x01 = NALU (not sequence header which is 0x00)
SrsUniquePtr<SrsMediaPacket> video_keyframe(new SrsMediaPacket());
char *keyframe_data = new char[10];
keyframe_data[0] = 0x17; // Keyframe + H.264 codec
keyframe_data[1] = 0x01; // AVC NALU (not sequence header)
keyframe_data[0] = 0x17; // Keyframe + H.264 codec
keyframe_data[1] = 0x01; // AVC NALU (not sequence header)
memset(keyframe_data + 2, 0, 8);
video_keyframe->wrap(keyframe_data, 10);
video_keyframe->message_type_ = SrsFrameTypeVideo;
@ -4718,16 +4718,16 @@ VOID TEST(DvrSegmentPlanTest, OnAudioTypicalScenario)
// AAC packet type: 0x01 = AAC raw (not sequence header which is 0x00)
SrsUniquePtr<SrsMediaPacket> audio(new SrsMediaPacket());
char *audio_data = new char[10];
audio_data[0] = 0xAF; // AAC codec
audio_data[1] = 0x01; // AAC raw (not sequence header)
audio_data[0] = 0xAF; // AAC codec
audio_data[1] = 0x01; // AAC raw (not sequence header)
memset(audio_data + 2, 0, 8);
audio->wrap(audio_data, 10);
audio->message_type_ = SrsFrameTypeAudio;
audio->timestamp_ = 1000; // 1 second
audio->timestamp_ = 1000; // 1 second
// Append timestamp to fragment to simulate duration tracking
fragment->append(0); // Start at 0ms
fragment->append(1000); // Current at 1000ms (1 second, well below 30 second limit)
fragment->append(0); // Start at 0ms
fragment->append(1000); // Current at 1000ms (1 second, well below 30 second limit)
// Call on_audio() - should succeed without triggering segment reaping
HELPER_EXPECT_SUCCESS(plan->on_audio(audio.get(), format.get()));

View File

@ -30,8 +30,8 @@
#include <srs_protocol_rtmp_conn.hpp>
#include <srs_protocol_rtmp_stack.hpp>
#include <srs_protocol_rtsp_stack.hpp>
#include <srs_utest_app6.hpp>
#include <srs_utest_app12.hpp>
#include <srs_utest_app6.hpp>
// Mock request class for testing edge upstream
class MockEdgeRequest : public ISrsRequest
@ -451,7 +451,7 @@ public:
bool send_message_called_;
int last_response_seq_;
std::string last_response_session_;
std::string last_response_type_; // "OPTIONS", "DESCRIBE", "SETUP", "PLAY", "TEARDOWN"
std::string last_response_type_; // "OPTIONS", "DESCRIBE", "SETUP", "PLAY", "TEARDOWN"
srs_error_t send_message_error_;
public:

File diff suppressed because it is too large Load Diff

View File

@ -12,17 +12,17 @@
*/
#include <srs_utest.hpp>
#include <srs_app_gb28181.hpp>
#include <srs_app_config.hpp>
#include <srs_app_server.hpp>
#include <srs_app_factory.hpp>
#include <srs_app_dvr.hpp>
#include <srs_protocol_http_stack.hpp>
#include <srs_protocol_rtmp_conn.hpp>
#include <srs_protocol_raw_avc.hpp>
#include <srs_app_factory.hpp>
#include <srs_app_gb28181.hpp>
#include <srs_app_server.hpp>
#include <srs_protocol_http_client.hpp>
#include <srs_utest_app6.hpp>
#include <srs_protocol_http_stack.hpp>
#include <srs_protocol_raw_avc.hpp>
#include <srs_protocol_rtmp_conn.hpp>
#include <srs_utest_app11.hpp>
#include <srs_utest_app6.hpp>
#ifdef SRS_RTSP
#include <srs_app_rtsp_conn.hpp>
@ -99,6 +99,88 @@ public:
void reset();
};
// Mock ISrsRtcConnection for testing SrsRtcUdpNetwork
class MockRtcConnectionForUdpNetwork : public ISrsRtcConnection
{
public:
srs_error_t on_dtls_alert_error_;
std::string last_alert_type_;
std::string last_alert_desc_;
bool on_rtp_cipher_called_;
bool on_rtp_plaintext_called_;
bool on_rtcp_called_;
public:
MockRtcConnectionForUdpNetwork();
virtual ~MockRtcConnectionForUdpNetwork();
public:
// ISrsResource interface
virtual const SrsContextId &get_id();
virtual std::string desc();
virtual void on_disposing(ISrsResource *c);
public:
// ISrsDisposingHandler interface
virtual void on_before_dispose(ISrsResource *c);
public:
// ISrsExpire interface
virtual void expire();
public:
// ISrsRtcPacketSender interface
virtual srs_error_t send_rtcp(char *data, int nb_data);
virtual srs_error_t do_send_packet(SrsRtpPacket *pkt);
virtual srs_error_t send_rtcp_rr(uint32_t ssrc, SrsRtpRingBuffer *rtp_queue, const uint64_t &last_send_systime, const SrsNtp &last_send_ntp);
virtual srs_error_t send_rtcp_xr_rrtr(uint32_t ssrc);
virtual void check_send_nacks(SrsRtpNackForReceiver *nack, uint32_t ssrc, uint32_t &sent_nacks, uint32_t &timeout_nacks);
virtual srs_error_t send_rtcp_fb_pli(uint32_t ssrc, const SrsContextId &cid_of_subscriber);
public:
// ISrsRtcPacketReceiver interface
virtual srs_error_t on_rtp(SrsRtpPacket *pkt);
virtual srs_error_t on_rtcp(SrsRtcpCommon *rtcp);
public:
// ISrsRtcConnectionNackTimerHandler interface
virtual srs_error_t do_check_send_nacks();
public:
// ISrsRtcConnection interface
virtual srs_error_t on_dtls_handshake_done();
virtual srs_error_t on_dtls_alert(std::string type, std::string desc);
virtual srs_error_t on_rtp_cipher(char *data, int nb_data);
virtual srs_error_t on_rtp_plaintext(char *data, int nb_data);
virtual srs_error_t on_rtcp(char *data, int nb_data);
virtual srs_error_t on_binding_request(SrsStunPacket *r, std::string &ice_pwd);
virtual ISrsRtcNetwork *udp();
virtual ISrsRtcNetwork *tcp();
virtual void alive();
virtual void switch_to_context();
public:
void set_on_dtls_alert_error(srs_error_t err);
void reset();
};
// Mock ISrsEphemeralDelta for testing SrsRtcUdpNetwork
class MockEphemeralDelta : public ISrsEphemeralDelta
{
public:
int64_t in_bytes_;
int64_t out_bytes_;
public:
MockEphemeralDelta();
virtual ~MockEphemeralDelta();
public:
virtual void add_delta(int64_t in, int64_t out);
virtual void remark(int64_t *in, int64_t *out);
void reset();
};
// Mock ISrsIpListener for testing SrsGbListener::initialize
class MockIpListener : public ISrsIpListener
{
@ -330,6 +412,73 @@ public:
virtual void on_executor_done(ISrsInterruptable *executor);
};
// Mock ISrsInterruptable for testing SrsRtcTcpConn
class MockInterruptableForRtcTcpConn : public ISrsInterruptable
{
public:
bool interrupt_called_;
srs_error_t pull_error_;
public:
MockInterruptableForRtcTcpConn();
virtual ~MockInterruptableForRtcTcpConn();
public:
virtual void interrupt();
virtual srs_error_t pull();
void reset();
};
// Mock ISrsContextIdSetter for testing SrsRtcTcpConn
class MockContextIdSetterForRtcTcpConn : public ISrsContextIdSetter
{
public:
bool set_cid_called_;
SrsContextId received_cid_;
public:
MockContextIdSetterForRtcTcpConn();
virtual ~MockContextIdSetterForRtcTcpConn();
public:
virtual void set_cid(const SrsContextId &cid);
void reset();
};
// Mock ISrsRtcConnection for testing SrsRtcTcpConn
class MockRtcConnectionForTcpConn : public ISrsRtcConnection
{
public:
MockRtcConnectionForTcpConn();
virtual ~MockRtcConnectionForTcpConn();
public:
virtual const SrsContextId &get_id();
virtual std::string desc();
virtual void on_disposing(ISrsResource *c);
virtual void on_before_dispose(ISrsResource *c);
virtual void expire();
virtual srs_error_t send_rtcp(char *data, int nb_data);
virtual srs_error_t send_rtcp_rr(uint32_t ssrc, SrsRtpRingBuffer *rtp_queue, const uint64_t &last_send_systime, const SrsNtp &last_send_ntp);
virtual srs_error_t send_rtcp_xr_rrtr(uint32_t ssrc);
virtual void check_send_nacks(SrsRtpNackForReceiver *nack, uint32_t ssrc, uint32_t &sent_nacks, uint32_t &timeout_nacks);
virtual srs_error_t send_rtcp_fb_pli(uint32_t ssrc, const SrsContextId &cid_of_subscriber);
virtual srs_error_t do_send_packet(SrsRtpPacket *pkt);
virtual srs_error_t do_check_send_nacks();
virtual void on_connection_established();
virtual srs_error_t on_dtls_alert(std::string type, std::string desc);
virtual srs_error_t on_dtls_handshake_done();
virtual srs_error_t on_dtls_application_data(const char *data, const int len);
virtual srs_error_t on_rtp_cipher(char *data, int nb_data);
virtual srs_error_t on_rtp_plaintext(char *buf, int nb_buf);
virtual srs_error_t on_rtcp(char *buf, int nb_buf);
virtual srs_error_t on_binding_request(SrsStunPacket *r, std::string &ice_pwd);
virtual ISrsRtcNetwork *udp();
virtual ISrsRtcNetwork *tcp();
virtual void alive();
virtual void switch_to_context();
};
// Mock ISrsPsPackHandler for testing SrsPackContext
class MockPsPackHandler : public ISrsPsPackHandler
{
@ -368,8 +517,8 @@ public:
class MockResourceManagerForGbPublish : public ISrsResourceManager
{
public:
std::map<std::string, ISrsResource*> id_map_;
std::map<uint64_t, ISrsResource*> fast_id_map_;
std::map<std::string, ISrsResource *> id_map_;
std::map<uint64_t, ISrsResource *> fast_id_map_;
public:
MockResourceManagerForGbPublish();
@ -454,5 +603,236 @@ public:
void reset();
};
#endif
// Mock ISrsRtcNetwork for testing SrsRtcNetworks
class MockRtcNetworkForNetworks : public ISrsRtcNetwork
{
public:
srs_error_t initialize_error_;
bool initialize_called_;
SrsSessionConfig *last_cfg_;
bool last_dtls_;
bool last_srtp_;
SrsRtcNetworkState state_;
bool is_established_;
public:
MockRtcNetworkForNetworks();
virtual ~MockRtcNetworkForNetworks();
public:
virtual srs_error_t initialize(SrsSessionConfig *cfg, bool dtls, bool srtp);
virtual void set_state(SrsRtcNetworkState state);
virtual srs_error_t on_dtls_handshake_done();
virtual srs_error_t on_dtls_alert(std::string type, std::string desc);
virtual srs_error_t on_dtls(char *data, int nb_data);
virtual srs_error_t protect_rtp(void *packet, int *nb_cipher);
virtual srs_error_t protect_rtcp(void *packet, int *nb_cipher);
virtual srs_error_t on_stun(SrsStunPacket *r, char *data, int nb_data);
virtual srs_error_t on_rtp(char *data, int nb_data);
virtual srs_error_t on_rtcp(char *data, int nb_data);
virtual bool is_establelished();
virtual srs_error_t write(void *buf, size_t size, ssize_t *nwrite);
public:
void reset();
void set_initialize_error(srs_error_t err);
};
// Mock ISrsRtcTransport for testing SrsRtcUdpNetwork RTP/RTCP handling
class MockRtcTransportForUdpNetwork : public ISrsRtcTransport
{
public:
srs_error_t unprotect_rtp_error_;
srs_error_t unprotect_rtcp_error_;
bool unprotect_rtp_called_;
bool unprotect_rtcp_called_;
int unprotected_rtp_size_;
int unprotected_rtcp_size_;
public:
MockRtcTransportForUdpNetwork();
virtual ~MockRtcTransportForUdpNetwork();
public:
virtual srs_error_t initialize(SrsSessionConfig *cfg);
virtual srs_error_t start_active_handshake();
virtual srs_error_t on_dtls(char *data, int nb_data);
virtual srs_error_t on_dtls_alert(std::string type, std::string desc);
virtual srs_error_t protect_rtp(void *packet, int *nb_cipher);
virtual srs_error_t protect_rtcp(void *packet, int *nb_cipher);
virtual srs_error_t unprotect_rtp(void *packet, int *nb_plaintext);
virtual srs_error_t unprotect_rtcp(void *packet, int *nb_plaintext);
// ISrsDtlsCallback interface
virtual srs_error_t on_dtls_handshake_done();
virtual srs_error_t on_dtls_application_data(const char *data, const int len);
virtual srs_error_t write_dtls_data(void *data, int size);
public:
void reset();
void set_unprotect_rtp_error(srs_error_t err);
void set_unprotect_rtcp_error(srs_error_t err);
};
// Mock ISrsResourceManager for testing SrsRtcUdpNetwork::update_sendonly_socket
class MockResourceManagerForUdpNetwork : public ISrsResourceManager
{
public:
std::map<std::string, ISrsResource *> id_map_;
std::map<uint64_t, ISrsResource *> fast_id_map_;
public:
MockResourceManagerForUdpNetwork();
virtual ~MockResourceManagerForUdpNetwork();
public:
virtual srs_error_t start();
virtual bool empty();
virtual size_t size();
virtual void add(ISrsResource *conn, bool *exists = NULL);
virtual void add_with_id(const std::string &id, ISrsResource *conn);
virtual void add_with_fast_id(uint64_t id, ISrsResource *conn);
virtual ISrsResource *at(int index);
virtual ISrsResource *find_by_id(std::string id);
virtual ISrsResource *find_by_fast_id(uint64_t id);
virtual ISrsResource *find_by_name(std::string name);
virtual void remove(ISrsResource *c);
virtual void subscribe(ISrsDisposingHandler *h);
virtual void unsubscribe(ISrsDisposingHandler *h);
void reset();
};
// Mock ISrsUdpMuxSocket for testing SrsRtcUdpNetwork STUN handling
class MockUdpMuxSocket : public ISrsUdpMuxSocket
{
public:
srs_error_t sendto_error_;
int sendto_called_count_;
int last_sendto_size_;
std::string peer_ip_;
int peer_port_;
std::string peer_id_;
uint64_t fast_id_;
public:
MockUdpMuxSocket();
virtual ~MockUdpMuxSocket();
public:
virtual srs_error_t sendto(void *data, int size, srs_utime_t timeout);
virtual std::string get_peer_ip() const;
virtual int get_peer_port() const;
virtual std::string peer_id();
virtual uint64_t fast_id();
virtual SrsUdpMuxSocket *copy_sendonly();
public:
void reset();
void set_sendto_error(srs_error_t err);
};
// Mock ISrsProtocolReadWriter for testing SrsRtcTcpNetwork write operations
class MockProtocolReadWriterForTcpNetwork : public ISrsProtocolReadWriter
{
public:
std::vector<std::string> written_data_;
srs_error_t write_error_;
int64_t send_bytes_;
int64_t recv_bytes_;
srs_utime_t send_timeout_;
srs_utime_t recv_timeout_;
std::string read_data_;
size_t read_pos_;
public:
MockProtocolReadWriterForTcpNetwork();
virtual ~MockProtocolReadWriterForTcpNetwork();
public:
virtual srs_error_t read_fully(void *buf, size_t size, ssize_t *nread);
virtual srs_error_t write(void *buf, size_t size, ssize_t *nwrite);
virtual void set_recv_timeout(srs_utime_t tm);
virtual srs_utime_t get_recv_timeout();
virtual int64_t get_recv_bytes();
virtual void set_send_timeout(srs_utime_t tm);
virtual srs_utime_t get_send_timeout();
virtual int64_t get_send_bytes();
virtual srs_error_t writev(const iovec *iov, int iov_size, ssize_t *nwrite);
virtual srs_error_t read(void *buf, size_t size, ssize_t *nread);
public:
void reset();
void set_write_error(srs_error_t err);
void set_read_data(const std::string &data);
};
// Mock ISrsResourceManager for testing SrsRtcTcpConn::handshake
class MockResourceManagerForTcpConnHandshake : public ISrsResourceManager
{
public:
ISrsResource *session_to_return_;
public:
MockResourceManagerForTcpConnHandshake();
virtual ~MockResourceManagerForTcpConnHandshake();
public:
virtual srs_error_t start();
virtual bool empty();
virtual size_t size();
virtual void add(ISrsResource *conn, bool *exists = NULL);
virtual void add_with_id(const std::string &id, ISrsResource *conn);
virtual void add_with_fast_id(uint64_t id, ISrsResource *conn);
virtual ISrsResource *at(int index);
virtual ISrsResource *find_by_id(std::string id);
virtual ISrsResource *find_by_fast_id(uint64_t id);
virtual ISrsResource *find_by_name(std::string name);
virtual void remove(ISrsResource *c);
virtual void subscribe(ISrsDisposingHandler *h);
virtual void unsubscribe(ISrsDisposingHandler *h);
void reset();
};
// Mock ISrsRtcConnection for testing SrsRtcTcpConn::handshake
class MockRtcConnectionForTcpConnHandshake : public ISrsRtcConnection
{
public:
ISrsRtcNetwork *tcp_network_;
std::string ice_pwd_;
bool switch_to_context_called_;
bool on_binding_request_called_;
public:
MockRtcConnectionForTcpConnHandshake();
virtual ~MockRtcConnectionForTcpConnHandshake();
public:
virtual const SrsContextId &get_id();
virtual std::string desc();
virtual void on_disposing(ISrsResource *c);
virtual void on_before_dispose(ISrsResource *c);
virtual void expire();
virtual srs_error_t send_rtcp(char *data, int nb_data);
virtual srs_error_t send_rtcp_rr(uint32_t ssrc, SrsRtpRingBuffer *rtp_queue, const uint64_t &last_send_systime, const SrsNtp &last_send_ntp);
virtual srs_error_t send_rtcp_xr_rrtr(uint32_t ssrc);
virtual void check_send_nacks(SrsRtpNackForReceiver *nack, uint32_t ssrc, uint32_t &sent_nacks, uint32_t &timeout_nacks);
virtual srs_error_t send_rtcp_fb_pli(uint32_t ssrc, const SrsContextId &cid_of_subscriber);
virtual srs_error_t do_send_packet(SrsRtpPacket *pkt);
virtual srs_error_t do_check_send_nacks();
virtual void on_connection_established();
virtual srs_error_t on_dtls_alert(std::string type, std::string desc);
virtual srs_error_t on_dtls_handshake_done();
virtual srs_error_t on_dtls_application_data(const char *data, const int len);
virtual srs_error_t on_rtp_cipher(char *data, int nb_data);
virtual srs_error_t on_rtp_plaintext(char *buf, int nb_buf);
virtual srs_error_t on_rtcp(char *buf, int nb_buf);
virtual srs_error_t on_binding_request(SrsStunPacket *r, std::string &ice_pwd);
virtual ISrsRtcNetwork *udp();
virtual ISrsRtcNetwork *tcp();
virtual void alive();
virtual void switch_to_context();
public:
void reset();
};
#endif