diff --git a/trunk/configure b/trunk/configure index 238792df3..5a2fcc528 100755 --- a/trunk/configure +++ b/trunk/configure @@ -385,7 +385,7 @@ if [[ $SRS_UTEST == YES ]]; then "srs_utest_protocol3" "srs_utest_app" "srs_utest_app2" "srs_utest_app3" "srs_utest_app4" "srs_utest_app5" "srs_utest_app6" "srs_utest_app7" "srs_utest_app8" "srs_utest_app9" "srs_utest_app10" "srs_utest_app11" "srs_utest_app15" "srs_utest_app16" - "srs_utest_app17" "srs_utest_rtc_playstream") + "srs_utest_app17" "srs_utest_mock" "srs_utest_rtc_playstream") # Always include SRT utest MODULE_FILES+=("srs_utest_srt") if [[ $SRS_GB28181 == YES ]]; then diff --git a/trunk/src/protocol/srs_protocol_http_stack_llhttpadapter.cpp b/trunk/src/protocol/srs_protocol_http_stack_llhttpadapter.cpp index 73257e9e3..d3b6e2d21 100644 --- a/trunk/src/protocol/srs_protocol_http_stack_llhttpadapter.cpp +++ b/trunk/src/protocol/srs_protocol_http_stack_llhttpadapter.cpp @@ -6,6 +6,8 @@ #include +// LCOV_EXCL_START + // To avoid type mismatch, these functions are used to bridge the APIs. // Bridge functions for internal callbacks that call the public API implementations // These bridge the internal callback signature to the public API signature @@ -199,3 +201,5 @@ int llhttp__after_message_complete(llhttp__internal_t *s, const unsigned char *p { return 0; } + +// LCOV_EXCL_STOP diff --git a/trunk/src/protocol/srs_protocol_srt.cpp b/trunk/src/protocol/srs_protocol_srt.cpp index d88d86e65..b85c76bc2 100644 --- a/trunk/src/protocol/srs_protocol_srt.cpp +++ b/trunk/src/protocol/srs_protocol_srt.cpp @@ -17,6 +17,8 @@ using namespace std; #include +// LCOV_EXCL_START + // TODO: FIXME: protocol could no include app's header file, so define TAG_SRT in this file. #define TAG_SRT "SRT" @@ -1029,3 +1031,5 @@ srs_error_t SrsSrtSocket::check_error() return err; } + +// LCOV_EXCL_STOP diff --git a/trunk/src/utest/srs_utest.hpp b/trunk/src/utest/srs_utest.hpp index 066b5784e..902f35ed9 100644 --- a/trunk/src/utest/srs_utest.hpp +++ b/trunk/src/utest/srs_utest.hpp @@ -32,6 +32,9 @@ using namespace std; #include #include +// Include headers for all the mocks. +#include + // we add an empty macro for upp to show the smart tips. #define VOID diff --git a/trunk/src/utest/srs_utest_app6.cpp b/trunk/src/utest/srs_utest_app6.cpp index e674a0677..681e3f11f 100644 --- a/trunk/src/utest/srs_utest_app6.cpp +++ b/trunk/src/utest/srs_utest_app6.cpp @@ -2364,678 +2364,6 @@ void MockContext::set_current_id(const SrsContextId &id) get_id_result_ = id; } -// Mock app config implementation -MockAppConfig::MockAppConfig() -{ - http_hooks_enabled_ = true; - on_stop_directive_ = NULL; - on_unpublish_directive_ = NULL; - rtc_nack_enabled_ = true; - rtc_nack_no_copy_ = false; - rtc_drop_for_pt_ = 0; - rtc_twcc_enabled_ = true; - srt_enabled_ = false; - rtc_to_rtmp_ = false; - dash_dispose_ = 0; - dash_enabled_ = false; - api_as_candidates_ = true; - resolve_api_domain_ = true; - keep_api_domain_ = false; - mw_msgs_ = 8; -} - -MockAppConfig::~MockAppConfig() -{ - clear_on_stop_directive(); - clear_on_unpublish_directive(); -} - -srs_utime_t MockAppConfig::get_pithy_print() -{ - return 10 * SRS_UTIME_SECONDS; -} - -std::string MockAppConfig::get_default_app_name() -{ - return "live"; -} - -void MockAppConfig::subscribe(ISrsReloadHandler *handler) -{ - // Do nothing in mock -} - -void MockAppConfig::unsubscribe(ISrsReloadHandler *handler) -{ - // Do nothing in mock -} - -bool MockAppConfig::get_vhost_http_hooks_enabled(std::string vhost) -{ - return http_hooks_enabled_; -} - -SrsConfDirective *MockAppConfig::get_vhost_on_stop(std::string vhost) -{ - return on_stop_directive_; -} - -SrsConfDirective *MockAppConfig::get_vhost_on_unpublish(std::string vhost) -{ - return on_unpublish_directive_; -} - -SrsConfDirective *MockAppConfig::get_vhost_on_dvr(std::string vhost) -{ - return NULL; -} - -bool MockAppConfig::get_rtc_nack_enabled(std::string vhost) -{ - return rtc_nack_enabled_; -} - -bool MockAppConfig::get_rtc_nack_no_copy(std::string vhost) -{ - return rtc_nack_no_copy_; -} - -bool MockAppConfig::get_realtime_enabled(std::string vhost, bool is_rtc) -{ - return true; -} - -int MockAppConfig::get_mw_msgs(std::string vhost, bool is_realtime, bool is_rtc) -{ - return mw_msgs_; -} - -int MockAppConfig::get_rtc_drop_for_pt(std::string vhost) -{ - return rtc_drop_for_pt_; -} - -bool MockAppConfig::get_rtc_twcc_enabled(std::string vhost) -{ - return rtc_twcc_enabled_; -} - -bool MockAppConfig::get_srt_enabled() -{ - return srt_enabled_; -} - -bool MockAppConfig::get_srt_enabled(std::string vhost) -{ - return srt_enabled_; -} - -std::string MockAppConfig::get_srt_default_streamid() -{ - return "#!::r=live/livestream,m=request"; -} - -bool MockAppConfig::get_srt_to_rtmp(std::string vhost) -{ - return true; -} - -bool MockAppConfig::get_rtc_to_rtmp(std::string vhost) -{ - return rtc_to_rtmp_; -} - -srs_utime_t MockAppConfig::get_rtc_stun_timeout(std::string vhost) -{ - return 30 * SRS_UTIME_SECONDS; // Default 30 seconds timeout -} - -bool MockAppConfig::get_rtc_stun_strict_check(std::string vhost) -{ - return false; // Default to non-strict mode -} - -std::string MockAppConfig::get_rtc_dtls_role(std::string vhost) -{ - return "passive"; // Default DTLS role -} - -std::string MockAppConfig::get_rtc_dtls_version(std::string vhost) -{ - return "auto"; // Default DTLS version -} - -SrsConfDirective *MockAppConfig::get_vhost_on_hls(std::string vhost) -{ - return NULL; -} - -SrsConfDirective *MockAppConfig::get_vhost_on_hls_notify(std::string vhost) -{ - return NULL; -} - -bool MockAppConfig::get_hls_enabled(std::string vhost) -{ - return false; -} - -bool MockAppConfig::get_hls_enabled(SrsConfDirective *vhost) -{ - return false; -} - -bool MockAppConfig::get_hls_use_fmp4(std::string vhost) -{ - return false; -} - -std::string MockAppConfig::get_hls_entry_prefix(std::string vhost) -{ - return ""; -} - -std::string MockAppConfig::get_hls_path(std::string vhost) -{ - return "./objs/nginx/html"; -} - -std::string MockAppConfig::get_hls_m3u8_file(std::string vhost) -{ - return "[app]/[stream].m3u8"; -} - -std::string MockAppConfig::get_hls_ts_file(std::string vhost) -{ - return "[app]/[stream]-[seq].ts"; -} - -std::string MockAppConfig::get_hls_fmp4_file(std::string vhost) -{ - return "[app]/[stream]-[seq].m4s"; -} - -std::string MockAppConfig::get_hls_init_file(std::string vhost) -{ - return "[app]/[stream]/init.mp4"; -} - -bool MockAppConfig::get_hls_ts_floor(std::string vhost) -{ - return false; -} - -srs_utime_t MockAppConfig::get_hls_fragment(std::string vhost) -{ - return 10 * SRS_UTIME_SECONDS; -} - -double MockAppConfig::get_hls_td_ratio(std::string vhost) -{ - return 1.5; -} - -double MockAppConfig::get_hls_aof_ratio(std::string vhost) -{ - return 2.0; -} - -srs_utime_t MockAppConfig::get_hls_window(std::string vhost) -{ - return 60 * SRS_UTIME_SECONDS; -} - -std::string MockAppConfig::get_hls_on_error(std::string vhost) -{ - return "continue"; -} - -bool MockAppConfig::get_hls_cleanup(std::string vhost) -{ - return true; -} - -srs_utime_t MockAppConfig::get_hls_dispose(std::string vhost) -{ - return 120 * SRS_UTIME_SECONDS; -} - -bool MockAppConfig::get_hls_wait_keyframe(std::string vhost) -{ - return true; -} - -bool MockAppConfig::get_hls_keys(std::string vhost) -{ - return false; -} - -int MockAppConfig::get_hls_fragments_per_key(std::string vhost) -{ - return 5; -} - -std::string MockAppConfig::get_hls_key_file(std::string vhost) -{ - return "[app]/[stream]-[seq].key"; -} - -std::string MockAppConfig::get_hls_key_file_path(std::string vhost) -{ - return "./objs/nginx/html"; -} - -std::string MockAppConfig::get_hls_key_url(std::string vhost) -{ - return ""; -} - -int MockAppConfig::get_vhost_hls_nb_notify(std::string vhost) -{ - return 64; -} - -bool MockAppConfig::get_vhost_hls_dts_directly(std::string vhost) -{ - return true; -} - -bool MockAppConfig::get_hls_ctx_enabled(std::string vhost) -{ - return true; -} - -bool MockAppConfig::get_hls_ts_ctx_enabled(std::string vhost) -{ - return true; -} - -bool MockAppConfig::get_hls_recover(std::string vhost) -{ - return true; -} - -bool MockAppConfig::get_forward_enabled(std::string vhost) -{ - return false; -} - -SrsConfDirective *MockAppConfig::get_forwards(std::string vhost) -{ - return NULL; -} - -srs_utime_t MockAppConfig::get_queue_length(std::string vhost) -{ - return 30 * SRS_UTIME_SECONDS; -} - -SrsConfDirective *MockAppConfig::get_forward_backend(std::string vhost) -{ - return NULL; -} - -bool MockAppConfig::get_atc(std::string vhost) -{ - return false; -} - -int MockAppConfig::get_time_jitter(std::string vhost) -{ - return SrsRtmpJitterAlgorithmFULL; -} - -bool MockAppConfig::get_mix_correct(std::string vhost) -{ - return false; -} - -bool MockAppConfig::try_annexb_first(std::string vhost) -{ - return true; -} - -bool MockAppConfig::get_vhost_is_edge(std::string vhost) -{ - return false; -} - -bool MockAppConfig::get_atc_auto(std::string vhost) -{ - return false; -} - -bool MockAppConfig::get_reduce_sequence_header(std::string vhost) -{ - return false; -} - -bool MockAppConfig::get_parse_sps(std::string vhost) -{ - return true; -} - -void MockAppConfig::set_http_hooks_enabled(bool enabled) -{ - http_hooks_enabled_ = enabled; -} - -void MockAppConfig::set_on_stop_urls(const std::vector &urls) -{ - clear_on_stop_directive(); - if (!urls.empty()) { - on_stop_directive_ = new SrsConfDirective(); - on_stop_directive_->name_ = "on_stop"; - on_stop_directive_->args_ = urls; - } -} - -void MockAppConfig::clear_on_stop_directive() -{ - srs_freep(on_stop_directive_); -} - -void MockAppConfig::set_on_unpublish_urls(const std::vector &urls) -{ - clear_on_unpublish_directive(); - if (!urls.empty()) { - on_unpublish_directive_ = new SrsConfDirective(); - on_unpublish_directive_->name_ = "on_unpublish"; - on_unpublish_directive_->args_ = urls; - } -} - -void MockAppConfig::clear_on_unpublish_directive() -{ - srs_freep(on_unpublish_directive_); -} - -void MockAppConfig::set_rtc_nack_enabled(bool enabled) -{ - rtc_nack_enabled_ = enabled; -} - -void MockAppConfig::set_rtc_nack_no_copy(bool no_copy) -{ - rtc_nack_no_copy_ = no_copy; -} - -void MockAppConfig::set_rtc_drop_for_pt(int pt) -{ - rtc_drop_for_pt_ = pt; -} - -void MockAppConfig::set_rtc_twcc_enabled(bool enabled) -{ - rtc_twcc_enabled_ = enabled; -} - -void MockAppConfig::set_srt_enabled(bool enabled) -{ - srt_enabled_ = enabled; -} - -void MockAppConfig::set_rtc_to_rtmp(bool enabled) -{ - rtc_to_rtmp_ = enabled; -} - -void MockAppConfig::set_api_as_candidates(bool enabled) -{ - api_as_candidates_ = enabled; -} - -void MockAppConfig::set_resolve_api_domain(bool enabled) -{ - resolve_api_domain_ = enabled; -} - -void MockAppConfig::set_keep_api_domain(bool enabled) -{ - keep_api_domain_ = enabled; -} - -// Mock request implementation -MockRtcAsyncCallRequest::MockRtcAsyncCallRequest(std::string vhost, std::string app, std::string stream) -{ - vhost_ = vhost; - app_ = app; - stream_ = stream; -} - -MockRtcAsyncCallRequest::~MockRtcAsyncCallRequest() -{ -} - -ISrsRequest *MockRtcAsyncCallRequest::copy() -{ - MockRtcAsyncCallRequest *cp = new MockRtcAsyncCallRequest(vhost_, app_, stream_); - return cp; -} - -std::string MockRtcAsyncCallRequest::get_stream_url() -{ - return "rtmp://" + vhost_ + "/" + app_ + "/" + stream_; -} - -void MockRtcAsyncCallRequest::update_auth(ISrsRequest *req) -{ -} - -void MockRtcAsyncCallRequest::strip() -{ -} - -ISrsRequest *MockRtcAsyncCallRequest::as_http() -{ - return this; -} - -// Mock RTC source manager implementation -MockRtcSourceManager::MockRtcSourceManager() -{ - initialize_error_ = srs_success; - fetch_or_create_error_ = srs_success; - initialize_count_ = 0; - fetch_or_create_count_ = 0; - mock_source_ = SrsSharedPtr(new SrsRtcSource()); -} - -MockRtcSourceManager::~MockRtcSourceManager() -{ - srs_freep(initialize_error_); - srs_freep(fetch_or_create_error_); -} - -srs_error_t MockRtcSourceManager::initialize() -{ - initialize_count_++; - return srs_error_copy(initialize_error_); -} - -srs_error_t MockRtcSourceManager::fetch_or_create(ISrsRequest *r, SrsSharedPtr &pps) -{ - fetch_or_create_count_++; - if (fetch_or_create_error_ != srs_success) { - return srs_error_copy(fetch_or_create_error_); - } - pps = mock_source_; - return srs_success; -} - -SrsSharedPtr MockRtcSourceManager::fetch(ISrsRequest *r) -{ - return mock_source_; -} - -void MockRtcSourceManager::set_initialize_error(srs_error_t err) -{ - srs_freep(initialize_error_); - initialize_error_ = srs_error_copy(err); -} - -void MockRtcSourceManager::set_fetch_or_create_error(srs_error_t err) -{ - srs_freep(fetch_or_create_error_); - fetch_or_create_error_ = srs_error_copy(err); -} - -void MockRtcSourceManager::reset() -{ - srs_freep(initialize_error_); - srs_freep(fetch_or_create_error_); - initialize_error_ = srs_success; - fetch_or_create_error_ = srs_success; - initialize_count_ = 0; - fetch_or_create_count_ = 0; -} - -// Mock statistic implementation -MockRtcStatistic::MockRtcStatistic() -{ - on_client_error_ = srs_success; - on_client_count_ = 0; - on_disconnect_count_ = 0; - last_client_id_ = ""; - last_client_req_ = NULL; - last_client_conn_ = NULL; - last_client_type_ = SrsRtmpConnUnknown; -} - -MockRtcStatistic::~MockRtcStatistic() -{ - srs_freep(on_client_error_); -} - -void MockRtcStatistic::on_disconnect(std::string id, srs_error_t err) -{ - on_disconnect_count_++; -} - -srs_error_t MockRtcStatistic::on_client(std::string id, ISrsRequest *req, ISrsExpire *conn, SrsRtmpConnType type) -{ - on_client_count_++; - last_client_id_ = id; - last_client_req_ = req; - last_client_conn_ = conn; - last_client_type_ = type; - return srs_error_copy(on_client_error_); -} - -void MockRtcStatistic::set_on_client_error(srs_error_t err) -{ - srs_freep(on_client_error_); - on_client_error_ = srs_error_copy(err); -} - -void MockRtcStatistic::reset() -{ - srs_freep(on_client_error_); - on_client_error_ = srs_success; - on_client_count_ = 0; - on_disconnect_count_ = 0; - last_client_id_ = ""; - last_client_req_ = NULL; - last_client_conn_ = NULL; - last_client_type_ = SrsRtmpConnUnknown; -} - -srs_error_t MockRtcStatistic::on_video_info(ISrsRequest *req, SrsVideoCodecId vcodec, int avc_profile, int avc_level, int width, int height) -{ - return srs_success; -} - -srs_error_t MockRtcStatistic::on_audio_info(ISrsRequest *req, SrsAudioCodecId acodec, SrsAudioSampleRate asample_rate, SrsAudioChannels asound_type, SrsAacObjectType aac_object) -{ - return srs_success; -} - -void MockRtcStatistic::on_stream_publish(ISrsRequest *req, std::string publisher_id) -{ - // Do nothing in mock -} - -void MockRtcStatistic::on_stream_close(ISrsRequest *req) -{ - // Do nothing in mock -} - -void MockRtcStatistic::kbps_add_delta(std::string id, ISrsKbpsDelta *delta) -{ - // Do nothing in mock -} - -void MockRtcStatistic::kbps_sample() -{ - // Do nothing in mock -} - -srs_error_t MockRtcStatistic::on_video_frames(ISrsRequest *req, int nb_frames) -{ - return srs_success; -} - -std::string MockRtcStatistic::server_id() -{ - return "mock_server_id"; -} - -std::string MockRtcStatistic::service_id() -{ - return "mock_service_id"; -} - -std::string MockRtcStatistic::service_pid() -{ - return "mock_pid"; -} - -SrsStatisticVhost *MockRtcStatistic::find_vhost_by_id(std::string vid) -{ - return NULL; -} - -SrsStatisticStream *MockRtcStatistic::find_stream(std::string sid) -{ - return NULL; -} - -SrsStatisticStream *MockRtcStatistic::find_stream_by_url(std::string url) -{ - return NULL; -} - -SrsStatisticClient *MockRtcStatistic::find_client(std::string client_id) -{ - return NULL; -} - -srs_error_t MockRtcStatistic::dumps_vhosts(SrsJsonArray *arr) -{ - return srs_success; -} - -srs_error_t MockRtcStatistic::dumps_streams(SrsJsonArray *arr, int start, int count) -{ - return srs_success; -} - -srs_error_t MockRtcStatistic::dumps_clients(SrsJsonArray *arr, int start, int count) -{ - return srs_success; -} - -srs_error_t MockRtcStatistic::dumps_metrics(int64_t &send_bytes, int64_t &recv_bytes, int64_t &nstreams, int64_t &nclients, int64_t &total_nclients, int64_t &nerrs) -{ - send_bytes = 0; - recv_bytes = 0; - nstreams = 0; - nclients = 0; - total_nclients = 0; - nerrs = 0; - return srs_success; -} - // Unit tests for SrsRtcAsyncCallOnStop::call() VOID TEST(RtcAsyncCallOnStopTest, CallWithHttpHooksDisabled) { @@ -3418,68 +2746,6 @@ VOID TEST(RtcPlayStreamTest, OnStreamChangeSuccess) srs_freep(source_desc); } -// Mock RTC async task executor implementation -MockRtcAsyncTaskExecutor::MockRtcAsyncTaskExecutor() -{ - exec_error_ = srs_success; - exec_count_ = 0; - last_task_ = NULL; -} - -MockRtcAsyncTaskExecutor::~MockRtcAsyncTaskExecutor() -{ -} - -srs_error_t MockRtcAsyncTaskExecutor::exec_rtc_async_work(ISrsAsyncCallTask *t) -{ - exec_count_++; - last_task_ = t; - return exec_error_; -} - -void MockRtcAsyncTaskExecutor::set_exec_error(srs_error_t err) -{ - exec_error_ = err; -} - -void MockRtcAsyncTaskExecutor::reset() -{ - exec_error_ = srs_success; - exec_count_ = 0; - last_task_ = NULL; -} - -// Mock RTC packet sender implementation -MockRtcPacketSender::MockRtcPacketSender() -{ - send_packet_error_ = srs_success; - send_packet_count_ = 0; - last_sent_packet_ = NULL; -} - -MockRtcPacketSender::~MockRtcPacketSender() -{ -} - -srs_error_t MockRtcPacketSender::do_send_packet(SrsRtpPacket *pkt) -{ - send_packet_count_++; - last_sent_packet_ = pkt; - return send_packet_error_; -} - -void MockRtcPacketSender::set_send_packet_error(srs_error_t err) -{ - send_packet_error_ = err; -} - -void MockRtcPacketSender::reset() -{ - send_packet_error_ = srs_success; - send_packet_count_ = 0; - last_sent_packet_ = NULL; -} - // Mock RTC send track implementation MockRtcSendTrack::MockRtcSendTrack(ISrsRtcPacketSender *sender, SrsRtcTrackDescription *track_desc, bool is_audio) : SrsRtcSendTrack(sender, track_desc, is_audio) diff --git a/trunk/src/utest/srs_utest_app6.hpp b/trunk/src/utest/srs_utest_app6.hpp index 0a0ca0caa..3bef0970b 100644 --- a/trunk/src/utest/srs_utest_app6.hpp +++ b/trunk/src/utest/srs_utest_app6.hpp @@ -308,411 +308,6 @@ public: void set_current_id(const SrsContextId &id); }; -// Mock app config for testing SrsRtcAsyncCallOnStop -class MockAppConfig : public ISrsAppConfig -{ -public: - bool http_hooks_enabled_; - SrsConfDirective *on_stop_directive_; - SrsConfDirective *on_unpublish_directive_; - bool rtc_nack_enabled_; - bool rtc_nack_no_copy_; - int rtc_drop_for_pt_; - bool rtc_twcc_enabled_; - bool srt_enabled_; - bool rtc_to_rtmp_; - srs_utime_t dash_dispose_; - bool dash_enabled_; - bool api_as_candidates_; - bool resolve_api_domain_; - bool keep_api_domain_; - int mw_msgs_; - -public: - MockAppConfig(); - virtual ~MockAppConfig(); - // ISrsConfig methods - virtual srs_utime_t get_pithy_print(); - virtual std::string get_default_app_name(); - virtual void subscribe(ISrsReloadHandler *handler); - virtual void unsubscribe(ISrsReloadHandler *handler); - virtual srs_error_t reload(SrsReloadState *pstate) { return srs_success; } - virtual srs_error_t persistence() { return srs_success; } - virtual std::string config() { return ""; } - virtual SrsConfDirective *get_root() { return NULL; } - virtual std::string cwd() { return "./"; } - virtual int get_max_connections() { return 1000; } - virtual std::string get_pid_file() { return ""; } - virtual bool empty_ip_ok() { return false; } - virtual bool get_asprocess() { return false; } - virtual srs_utime_t get_grace_start_wait() { return 0; } - virtual srs_utime_t get_grace_final_wait() { return 0; } - virtual bool is_force_grace_quit() { return false; } - virtual bool inotify_auto_reload() { return false; } - virtual bool auto_reload_for_docker() { return false; } - virtual std::vector get_listens() { return std::vector(); } - virtual bool get_rtmps_enabled() { return false; } - virtual std::vector get_rtmps_listen() { return std::vector(); } - virtual bool get_http_api_enabled() { return false; } - virtual std::vector get_http_api_listens() { return std::vector(); } - virtual bool get_https_api_enabled() { return false; } - virtual std::vector get_https_api_listens() { return std::vector(); } - virtual std::string get_https_api_ssl_key() { return ""; } - virtual std::string get_https_api_ssl_cert() { return ""; } - virtual bool get_raw_api() { return false; } - virtual bool get_raw_api_allow_reload() { return false; } - virtual bool get_raw_api_allow_query() { return false; } - virtual bool get_raw_api_allow_update() { return false; } - virtual bool get_http_api_auth_enabled() { return false; } - virtual std::string get_http_api_auth_username() { return ""; } - virtual std::string get_http_api_auth_password() { return ""; } - virtual srs_error_t raw_to_json(SrsJsonObject *obj) { return srs_success; } - virtual bool get_http_stream_enabled() { return false; } - virtual std::vector get_http_stream_listens() { return std::vector(); } - virtual bool get_https_stream_enabled() { return false; } - virtual std::vector get_https_stream_listens() { return std::vector(); } - virtual std::string get_https_stream_ssl_key() { return ""; } - virtual std::string get_https_stream_ssl_cert() { return ""; } - virtual std::string get_http_stream_dir() { return ""; } - virtual bool get_http_stream_crossdomain() { return false; } - virtual bool get_rtc_server_enabled() { return false; } - virtual bool get_rtc_server_tcp_enabled() { return false; } - virtual std::vector get_rtc_server_tcp_listens() { return std::vector(); } - virtual std::string get_rtc_server_protocol() { return "udp"; } - virtual std::vector get_rtc_server_listens() { return std::vector(); } - virtual int get_rtc_server_reuseport() { return 1; } - virtual bool get_rtc_server_encrypt() { return false; } - virtual bool get_api_as_candidates() { return api_as_candidates_; } - virtual bool get_resolve_api_domain() { return resolve_api_domain_; } - virtual bool get_keep_api_domain() { return keep_api_domain_; } - virtual std::string get_rtc_server_candidates() { return "*"; } - virtual bool get_use_auto_detect_network_ip() { return true; } - virtual std::string get_rtc_server_ip_family() { return "ipv4"; } - virtual bool get_rtsp_server_enabled() { return false; } - virtual std::vector get_rtsp_server_listens() { return std::vector(); } - virtual std::vector get_srt_listens() { return std::vector(); } - virtual std::vector get_stream_casters() { return std::vector(); } - virtual bool get_stream_caster_enabled(SrsConfDirective *conf) { return false; } - virtual std::string get_stream_caster_engine(SrsConfDirective *conf) { return ""; } - virtual std::string get_stream_caster_output(SrsConfDirective *conf) { return ""; } - virtual int get_stream_caster_listen(SrsConfDirective *conf) { return 0; } - virtual bool get_exporter_enabled() { return false; } - virtual std::string get_exporter_listen() { return ""; } - virtual std::string get_exporter_label() { return ""; } - virtual std::string get_exporter_tag() { return ""; } - virtual bool get_stats_enabled() { return false; } - virtual int get_stats_network() { return 0; } - virtual bool get_heartbeat_enabled() { return false; } - virtual srs_utime_t get_heartbeat_interval() { return 0; } - virtual std::string get_heartbeat_url() { return ""; } - virtual std::string get_heartbeat_device_id() { return ""; } - virtual bool get_heartbeat_summaries() { return false; } - virtual bool get_heartbeat_ports() { return false; } - virtual bool get_circuit_breaker() { return false; } - virtual int get_high_threshold() { return 0; } - virtual int get_high_pulse() { return 0; } - virtual int get_critical_threshold() { return 0; } - virtual int get_critical_pulse() { return 0; } - virtual int get_dying_threshold() { return 0; } - virtual int get_dying_pulse() { return 0; } - virtual std::string get_rtmps_ssl_cert() { return ""; } - virtual std::string get_rtmps_ssl_key() { return ""; } - virtual SrsConfDirective *get_vhost(std::string vhost, bool try_default_vhost = true) { return NULL; } - virtual bool get_vhost_enabled(std::string vhost) { return true; } - virtual bool get_debug_srs_upnode(std::string vhost) { return true; } - virtual int get_out_ack_size(std::string vhost) { return 2500000; } - virtual int get_in_ack_size(std::string vhost) { return 2500000; } - virtual int get_chunk_size(std::string vhost) { return 60000; } - virtual bool get_gop_cache(std::string vhost) { return true; } - virtual int get_gop_cache_max_frames(std::string vhost) { return 2500; } - virtual bool get_tcp_nodelay(std::string vhost) { return false; } - virtual srs_utime_t get_mw_sleep(std::string vhost, bool is_rtc = false) { return 350 * SRS_UTIME_MILLISECONDS; } - virtual srs_utime_t get_send_min_interval(std::string vhost) { return 0; } - virtual bool get_mr_enabled(std::string vhost) { return false; } - virtual srs_utime_t get_mr_sleep(std::string vhost) { return 350 * SRS_UTIME_MILLISECONDS; } - virtual srs_utime_t get_publish_1stpkt_timeout(std::string vhost) { return 20000 * SRS_UTIME_MILLISECONDS; } - virtual srs_utime_t get_publish_normal_timeout(std::string vhost) { return 5000 * SRS_UTIME_MILLISECONDS; } - virtual srs_utime_t get_publish_kickoff_for_idle(std::string vhost) { return 0; } - virtual bool get_refer_enabled(std::string vhost) { return false; } - virtual SrsConfDirective *get_refer_all(std::string vhost) { return NULL; } - virtual SrsConfDirective *get_refer_play(std::string vhost) { return NULL; } - virtual SrsConfDirective *get_refer_publish(std::string vhost) { return NULL; } - virtual bool get_vhost_origin_cluster(std::string vhost) { return false; } - virtual std::vector get_vhost_coworkers(std::string vhost) { return std::vector(); } - virtual bool get_vhost_edge_token_traverse(std::string vhost) { return false; } - virtual SrsConfDirective *get_vhost_edge_origin(std::string vhost) { return NULL; } - virtual SrsConfDirective *get_vhost_on_connect(std::string vhost) { return NULL; } - virtual SrsConfDirective *get_vhost_on_close(std::string vhost) { return NULL; } - virtual SrsConfDirective *get_vhost_on_publish(std::string vhost) { return NULL; } - virtual SrsConfDirective *get_vhost_on_play(std::string vhost) { return NULL; } - virtual bool get_rtc_enabled(std::string vhost) { return false; } - virtual bool get_rtsp_enabled(std::string vhost) { return false; } - virtual bool get_rtc_from_rtmp(std::string vhost) { return false; } - virtual bool get_rtsp_from_rtmp(std::string vhost) { return false; } - // ISrsAppConfig methods - virtual bool get_vhost_http_hooks_enabled(std::string vhost); - virtual SrsConfDirective *get_vhost_on_stop(std::string vhost); - virtual SrsConfDirective *get_vhost_on_unpublish(std::string vhost); - virtual SrsConfDirective *get_vhost_on_dvr(std::string vhost); - virtual bool get_rtc_nack_enabled(std::string vhost); - virtual bool get_rtc_nack_no_copy(std::string vhost); - virtual bool get_realtime_enabled(std::string vhost, bool is_rtc); - virtual int get_mw_msgs(std::string vhost, bool is_realtime, bool is_rtc); - virtual int get_rtc_drop_for_pt(std::string vhost); - virtual bool get_rtc_twcc_enabled(std::string vhost); - virtual bool get_srt_enabled(); - virtual bool get_srt_enabled(std::string vhost); - virtual std::string get_srt_default_streamid(); - virtual bool get_srt_to_rtmp(std::string vhost); - virtual bool get_rtc_to_rtmp(std::string vhost); - virtual srs_utime_t get_rtc_stun_timeout(std::string vhost); - virtual bool get_rtc_stun_strict_check(std::string vhost); - virtual std::string get_rtc_dtls_role(std::string vhost); - virtual std::string get_rtc_dtls_version(std::string vhost); - virtual SrsConfDirective *get_vhost_on_hls(std::string vhost); - virtual SrsConfDirective *get_vhost_on_hls_notify(std::string vhost); - // HLS methods - virtual bool get_hls_enabled(std::string vhost); - virtual bool get_hls_enabled(SrsConfDirective *vhost); - virtual bool get_hls_use_fmp4(std::string vhost); - virtual std::string get_hls_entry_prefix(std::string vhost); - virtual std::string get_hls_path(std::string vhost); - virtual std::string get_hls_m3u8_file(std::string vhost); - virtual std::string get_hls_ts_file(std::string vhost); - virtual std::string get_hls_fmp4_file(std::string vhost); - virtual std::string get_hls_init_file(std::string vhost); - virtual bool get_hls_ts_floor(std::string vhost); - virtual srs_utime_t get_hls_fragment(std::string vhost); - virtual double get_hls_td_ratio(std::string vhost); - virtual double get_hls_aof_ratio(std::string vhost); - virtual srs_utime_t get_hls_window(std::string vhost); - virtual std::string get_hls_on_error(std::string vhost); - virtual bool get_hls_cleanup(std::string vhost); - virtual srs_utime_t get_hls_dispose(std::string vhost); - virtual bool get_hls_wait_keyframe(std::string vhost); - virtual bool get_hls_keys(std::string vhost); - virtual int get_hls_fragments_per_key(std::string vhost); - virtual std::string get_hls_key_file(std::string vhost); - virtual std::string get_hls_key_file_path(std::string vhost); - virtual std::string get_hls_key_url(std::string vhost); - virtual int get_vhost_hls_nb_notify(std::string vhost); - virtual bool get_vhost_hls_dts_directly(std::string vhost); - virtual bool get_hls_ctx_enabled(std::string vhost); - virtual bool get_hls_ts_ctx_enabled(std::string vhost); - virtual bool get_hls_recover(std::string vhost); - virtual bool get_forward_enabled(std::string vhost); - virtual SrsConfDirective *get_forwards(std::string vhost); - virtual srs_utime_t get_queue_length(std::string vhost); - virtual SrsConfDirective *get_forward_backend(std::string vhost); - virtual bool get_atc(std::string vhost); - virtual int get_time_jitter(std::string vhost); - virtual bool get_mix_correct(std::string vhost); - virtual bool try_annexb_first(std::string vhost); - virtual bool get_vhost_is_edge(std::string vhost); - virtual bool get_atc_auto(std::string vhost); - virtual bool get_reduce_sequence_header(std::string vhost); - virtual bool get_parse_sps(std::string vhost); - // DVR methods - virtual std::string get_dvr_path(std::string vhost) { return "./[vhost]/[app]/[stream]/[2006]/[01]/[02]/[15].[04].[05].[999].flv"; } - virtual std::string get_dvr_plan(std::string vhost) { return "session"; } - virtual bool get_dvr_enabled(std::string vhost) { return false; } - virtual SrsConfDirective *get_dvr_apply(std::string vhost) { return NULL; } - virtual srs_utime_t get_dvr_duration(std::string vhost) { return 30 * SRS_UTIME_SECONDS; } - virtual int get_dvr_time_jitter(std::string vhost) { return 0; } - virtual bool get_dvr_wait_keyframe(std::string vhost) { return true; } - virtual bool get_vhost_enabled(SrsConfDirective *conf) { return true; } - virtual bool get_vhost_http_remux_enabled(std::string vhost) { return false; } - virtual bool get_vhost_http_remux_enabled(SrsConfDirective *vhost) { return false; } - virtual srs_utime_t get_vhost_http_remux_fast_cache(std::string vhost) { return 0; } - virtual bool get_vhost_http_remux_drop_if_not_match(std::string vhost) { return false; } - virtual bool get_vhost_http_remux_has_audio(std::string vhost) { return true; } - virtual bool get_vhost_http_remux_has_video(std::string vhost) { return true; } - virtual bool get_vhost_http_remux_guess_has_av(std::string vhost) { return true; } - virtual std::string get_vhost_http_remux_mount(std::string vhost) { return ""; } - virtual std::string get_vhost_edge_protocol(std::string vhost) { return "rtmp"; } - virtual bool get_vhost_edge_follow_client(std::string vhost) { return false; } - virtual std::string get_vhost_edge_transform_vhost(std::string vhost) { return ""; } - // DASH methods - virtual bool get_dash_enabled(std::string vhost) { return dash_enabled_; } - virtual bool get_dash_enabled(SrsConfDirective *vhost) { return dash_enabled_; } - virtual srs_utime_t get_dash_fragment(std::string vhost) { return 30 * SRS_UTIME_SECONDS; } - virtual srs_utime_t get_dash_update_period(std::string vhost) { return 30 * SRS_UTIME_SECONDS; } - virtual srs_utime_t get_dash_timeshift(std::string vhost) { return 300 * SRS_UTIME_SECONDS; } - virtual std::string get_dash_path(std::string vhost) { return "./[vhost]/[app]/[stream]/"; } - virtual std::string get_dash_mpd_file(std::string vhost) { return "[stream].mpd"; } - virtual int get_dash_window_size(std::string vhost) { return 10; } - virtual bool get_dash_cleanup(std::string vhost) { return true; } - virtual srs_utime_t get_dash_dispose(std::string vhost) { return dash_dispose_; } - // Exec config - virtual bool get_exec_enabled(std::string vhost) { return false; } - virtual std::vector get_exec_publishs(std::string vhost) { return std::vector(); } - // Ingest config - virtual void get_vhosts(std::vector &vhosts) {} - virtual std::vector get_ingesters(std::string vhost) { return std::vector(); } - virtual SrsConfDirective *get_ingest_by_id(std::string vhost, std::string ingest_id) { return NULL; } - virtual bool get_ingest_enabled(SrsConfDirective *conf) { return false; } - virtual std::string get_ingest_ffmpeg(SrsConfDirective *conf) { return ""; } - virtual std::string get_ingest_input_type(SrsConfDirective *conf) { return ""; } - virtual std::string get_ingest_input_url(SrsConfDirective *conf) { return ""; } - // FFmpeg log config - virtual bool get_ff_log_enabled() { return false; } - virtual std::string get_ff_log_dir() { return ""; } - virtual std::string get_ff_log_level() { return ""; } - // Transcode/Engine config - virtual SrsConfDirective *get_transcode(std::string vhost, std::string scope) { return NULL; } - virtual bool get_transcode_enabled(SrsConfDirective *conf) { return false; } - virtual std::string get_transcode_ffmpeg(SrsConfDirective *conf) { return ""; } - virtual std::vector get_transcode_engines(SrsConfDirective *conf) { return std::vector(); } - virtual bool get_engine_enabled(SrsConfDirective *conf) { return false; } - virtual std::vector get_engine_perfile(SrsConfDirective *conf) { return std::vector(); } - virtual std::string get_engine_iformat(SrsConfDirective *conf) { return ""; } - virtual std::vector get_engine_vfilter(SrsConfDirective *conf) { return std::vector(); } - virtual std::string get_engine_vcodec(SrsConfDirective *conf) { return ""; } - virtual int get_engine_vbitrate(SrsConfDirective *conf) { return 0; } - virtual double get_engine_vfps(SrsConfDirective *conf) { return 0; } - virtual int get_engine_vwidth(SrsConfDirective *conf) { return 0; } - virtual int get_engine_vheight(SrsConfDirective *conf) { return 0; } - virtual int get_engine_vthreads(SrsConfDirective *conf) { return 0; } - virtual std::string get_engine_vprofile(SrsConfDirective *conf) { return ""; } - virtual std::string get_engine_vpreset(SrsConfDirective *conf) { return ""; } - virtual std::vector get_engine_vparams(SrsConfDirective *conf) { return std::vector(); } - virtual std::string get_engine_acodec(SrsConfDirective *conf) { return ""; } - virtual int get_engine_abitrate(SrsConfDirective *conf) { return 0; } - virtual int get_engine_asample_rate(SrsConfDirective *conf) { return 0; } - virtual int get_engine_achannels(SrsConfDirective *conf) { return 0; } - virtual std::vector get_engine_aparams(SrsConfDirective *conf) { return std::vector(); } - virtual std::string get_engine_oformat(SrsConfDirective *conf) { return ""; } - virtual std::string get_engine_output(SrsConfDirective *conf) { return ""; } - void set_http_hooks_enabled(bool enabled); - void set_on_stop_urls(const std::vector &urls); - void clear_on_stop_directive(); - void set_on_unpublish_urls(const std::vector &urls); - void clear_on_unpublish_directive(); - void set_rtc_nack_enabled(bool enabled); - void set_rtc_nack_no_copy(bool no_copy); - void set_rtc_drop_for_pt(int pt); - void set_rtc_twcc_enabled(bool enabled); - void set_srt_enabled(bool enabled); - void set_rtc_to_rtmp(bool enabled); - void set_api_as_candidates(bool enabled); - void set_resolve_api_domain(bool enabled); - void set_keep_api_domain(bool enabled); -}; - -// Mock request for testing SrsRtcAsyncCallOnStop -class MockRtcAsyncCallRequest : public ISrsRequest -{ -public: - std::string vhost_; - std::string app_; - std::string stream_; - -public: - MockRtcAsyncCallRequest(std::string vhost = "__defaultVhost__", std::string app = "live", std::string stream = "test"); - virtual ~MockRtcAsyncCallRequest(); - virtual ISrsRequest *copy(); - virtual std::string get_stream_url(); - virtual void update_auth(ISrsRequest *req); - virtual void strip(); - virtual ISrsRequest *as_http(); -}; - -// Mock RTC source manager for testing SrsRtcPlayStream -class MockRtcSourceManager : public ISrsRtcSourceManager -{ -public: - srs_error_t initialize_error_; - srs_error_t fetch_or_create_error_; - int initialize_count_; - int fetch_or_create_count_; - SrsSharedPtr mock_source_; - -public: - MockRtcSourceManager(); - virtual ~MockRtcSourceManager(); - virtual srs_error_t initialize(); - virtual srs_error_t fetch_or_create(ISrsRequest *r, SrsSharedPtr &pps); - virtual SrsSharedPtr fetch(ISrsRequest *r); - void set_initialize_error(srs_error_t err); - void set_fetch_or_create_error(srs_error_t err); - void reset(); -}; - -// Mock statistic for testing SrsRtcPlayStream -class MockRtcStatistic : public ISrsStatistic -{ -public: - srs_error_t on_client_error_; - int on_client_count_; - int on_disconnect_count_; - std::string last_client_id_; - ISrsRequest *last_client_req_; - ISrsExpire *last_client_conn_; - SrsRtmpConnType last_client_type_; - -public: - MockRtcStatistic(); - virtual ~MockRtcStatistic(); - virtual void on_disconnect(std::string id, srs_error_t err); - virtual srs_error_t on_client(std::string id, ISrsRequest *req, ISrsExpire *conn, SrsRtmpConnType type); - virtual srs_error_t on_video_info(ISrsRequest *req, SrsVideoCodecId vcodec, int avc_profile, int avc_level, int width, int height); - virtual srs_error_t on_audio_info(ISrsRequest *req, SrsAudioCodecId acodec, SrsAudioSampleRate asample_rate, SrsAudioChannels asound_type, SrsAacObjectType aac_object); - virtual void on_stream_publish(ISrsRequest *req, std::string publisher_id); - virtual void on_stream_close(ISrsRequest *req); - virtual void kbps_add_delta(std::string id, ISrsKbpsDelta *delta); - virtual void kbps_sample(); - virtual srs_error_t on_video_frames(ISrsRequest *req, int nb_frames); - virtual std::string server_id(); - virtual std::string service_id(); - virtual std::string service_pid(); - virtual SrsStatisticVhost *find_vhost_by_id(std::string vid); - virtual SrsStatisticStream *find_stream(std::string sid); - virtual SrsStatisticStream *find_stream_by_url(std::string url); - virtual SrsStatisticClient *find_client(std::string client_id); - virtual srs_error_t dumps_vhosts(SrsJsonArray *arr); - virtual srs_error_t dumps_streams(SrsJsonArray *arr, int start, int count); - virtual srs_error_t dumps_clients(SrsJsonArray *arr, int start, int count); - virtual srs_error_t dumps_metrics(int64_t &send_bytes, int64_t &recv_bytes, int64_t &nstreams, int64_t &nclients, int64_t &total_nclients, int64_t &nerrs); - void set_on_client_error(srs_error_t err); - void reset(); -}; - -// Mock RTC async task executor for testing SrsRtcPlayStream::send_packet -class MockRtcAsyncTaskExecutor : public ISrsExecRtcAsyncTask -{ -public: - srs_error_t exec_error_; - int exec_count_; - ISrsAsyncCallTask *last_task_; - -public: - MockRtcAsyncTaskExecutor(); - virtual ~MockRtcAsyncTaskExecutor(); - -public: - virtual srs_error_t exec_rtc_async_work(ISrsAsyncCallTask *t); - void set_exec_error(srs_error_t err); - void reset(); -}; - -// Mock RTC packet sender for testing SrsRtcPlayStream::send_packet -class MockRtcPacketSender : public ISrsRtcPacketSender -{ -public: - srs_error_t send_packet_error_; - int send_packet_count_; - SrsRtpPacket *last_sent_packet_; - -public: - MockRtcPacketSender(); - virtual ~MockRtcPacketSender(); - -public: - virtual srs_error_t do_send_packet(SrsRtpPacket *pkt); - void set_send_packet_error(srs_error_t err); - void reset(); -}; - // Mock RTC send track for testing SrsRtcPlayStream::send_packet class MockRtcSendTrack : public SrsRtcSendTrack { diff --git a/trunk/src/utest/srs_utest_mock.cpp b/trunk/src/utest/srs_utest_mock.cpp new file mode 100644 index 000000000..705052b0f --- /dev/null +++ b/trunk/src/utest/srs_utest_mock.cpp @@ -0,0 +1,808 @@ +// +// Copyright (c) 2013-2025 The SRS Authors +// +// SPDX-License-Identifier: MIT +// + +#include + +#include +#include +#include +#include + +// MockRtcTrackDescriptionFactory implementation +MockRtcTrackDescriptionFactory::MockRtcTrackDescriptionFactory() +{ + audio_ssrc_ = 12345; + video_ssrc_ = 67890; + screen_ssrc_ = 98765; +} + +MockRtcTrackDescriptionFactory::~MockRtcTrackDescriptionFactory() +{ +} + +std::map MockRtcTrackDescriptionFactory::create_audio_video_tracks() +{ + std::map sub_relations; + + // Create audio track + SrsRtcTrackDescription *audio_desc = create_audio_track(audio_ssrc_, "audio-track-1", "0"); + sub_relations[audio_desc->ssrc_] = audio_desc; + + // Create video track + SrsRtcTrackDescription *video_desc = create_video_track(video_ssrc_, "video-track-1", "1"); + sub_relations[video_desc->ssrc_] = video_desc; + + // Create screen share track + SrsRtcTrackDescription *screen_desc = create_video_track(screen_ssrc_, "screen-track-1", "2"); + sub_relations[screen_desc->ssrc_] = screen_desc; + + return sub_relations; +} + +SrsRtcTrackDescription *MockRtcTrackDescriptionFactory::create_audio_track(uint32_t ssrc, std::string id, std::string mid) +{ + SrsRtcTrackDescription *audio_desc = new SrsRtcTrackDescription(); + audio_desc->type_ = "audio"; + audio_desc->ssrc_ = ssrc; + audio_desc->id_ = id; + audio_desc->is_active_ = true; + audio_desc->direction_ = "sendrecv"; + audio_desc->mid_ = mid; + audio_desc->media_ = new SrsAudioPayload(111, "opus", 48000, 2); + return audio_desc; +} + +SrsRtcTrackDescription *MockRtcTrackDescriptionFactory::create_video_track(uint32_t ssrc, std::string id, std::string mid) +{ + SrsRtcTrackDescription *video_desc = new SrsRtcTrackDescription(); + video_desc->type_ = "video"; + video_desc->ssrc_ = ssrc; + video_desc->id_ = id; + video_desc->is_active_ = true; + video_desc->direction_ = "sendrecv"; + video_desc->mid_ = mid; + video_desc->media_ = new SrsVideoPayload(96, "H264", 90000); + return video_desc; +} + +// MockExpire implementation +MockExpire::MockExpire() : expired_(false) +{ +} + +MockExpire::~MockExpire() +{ +} + +void MockExpire::expire() +{ + expired_ = true; +} + +// MockRtcAsyncCallRequest implementation +MockRtcAsyncCallRequest::MockRtcAsyncCallRequest(std::string vhost, std::string app, std::string stream) +{ + vhost_ = vhost; + app_ = app; + stream_ = stream; +} + +MockRtcAsyncCallRequest::~MockRtcAsyncCallRequest() +{ +} + +ISrsRequest *MockRtcAsyncCallRequest::copy() +{ + MockRtcAsyncCallRequest *cp = new MockRtcAsyncCallRequest(vhost_, app_, stream_); + return cp; +} + +std::string MockRtcAsyncCallRequest::get_stream_url() +{ + return "rtmp://" + vhost_ + "/" + app_ + "/" + stream_; +} + +void MockRtcAsyncCallRequest::update_auth(ISrsRequest *req) +{ +} + +void MockRtcAsyncCallRequest::strip() +{ +} + +ISrsRequest *MockRtcAsyncCallRequest::as_http() +{ + return this; +} + +// MockRtcSourceManager implementation +MockRtcSourceManager::MockRtcSourceManager() +{ + initialize_error_ = srs_success; + fetch_or_create_error_ = srs_success; + initialize_count_ = 0; + fetch_or_create_count_ = 0; + mock_source_ = SrsSharedPtr(new SrsRtcSource()); +} + +MockRtcSourceManager::~MockRtcSourceManager() +{ + srs_freep(initialize_error_); + srs_freep(fetch_or_create_error_); +} + +srs_error_t MockRtcSourceManager::initialize() +{ + initialize_count_++; + return srs_error_copy(initialize_error_); +} + +srs_error_t MockRtcSourceManager::fetch_or_create(ISrsRequest *r, SrsSharedPtr &pps) +{ + fetch_or_create_count_++; + if (fetch_or_create_error_ != srs_success) { + return srs_error_copy(fetch_or_create_error_); + } + pps = mock_source_; + return srs_success; +} + +SrsSharedPtr MockRtcSourceManager::fetch(ISrsRequest *r) +{ + return mock_source_; +} + +void MockRtcSourceManager::set_initialize_error(srs_error_t err) +{ + srs_freep(initialize_error_); + initialize_error_ = srs_error_copy(err); +} + +void MockRtcSourceManager::set_fetch_or_create_error(srs_error_t err) +{ + srs_freep(fetch_or_create_error_); + fetch_or_create_error_ = srs_error_copy(err); +} + +void MockRtcSourceManager::reset() +{ + srs_freep(initialize_error_); + srs_freep(fetch_or_create_error_); + initialize_error_ = srs_success; + fetch_or_create_error_ = srs_success; + initialize_count_ = 0; + fetch_or_create_count_ = 0; +} + +// MockRtcStatistic implementation +MockRtcStatistic::MockRtcStatistic() +{ + on_client_error_ = srs_success; + on_client_count_ = 0; + on_disconnect_count_ = 0; + last_client_id_ = ""; + last_client_req_ = NULL; + last_client_conn_ = NULL; + last_client_type_ = SrsRtmpConnUnknown; +} + +MockRtcStatistic::~MockRtcStatistic() +{ + srs_freep(on_client_error_); +} + +void MockRtcStatistic::on_disconnect(std::string id, srs_error_t err) +{ + on_disconnect_count_++; +} + +srs_error_t MockRtcStatistic::on_client(std::string id, ISrsRequest *req, ISrsExpire *conn, SrsRtmpConnType type) +{ + on_client_count_++; + last_client_id_ = id; + last_client_req_ = req; + last_client_conn_ = conn; + last_client_type_ = type; + return srs_error_copy(on_client_error_); +} + +srs_error_t MockRtcStatistic::on_video_info(ISrsRequest *req, SrsVideoCodecId vcodec, int avc_profile, int avc_level, int width, int height) +{ + return srs_success; +} + +srs_error_t MockRtcStatistic::on_audio_info(ISrsRequest *req, SrsAudioCodecId acodec, SrsAudioSampleRate asample_rate, SrsAudioChannels asound_type, SrsAacObjectType aac_object) +{ + return srs_success; +} + +void MockRtcStatistic::on_stream_publish(ISrsRequest *req, std::string publisher_id) +{ +} + +void MockRtcStatistic::on_stream_close(ISrsRequest *req) +{ +} + +void MockRtcStatistic::kbps_add_delta(std::string id, ISrsKbpsDelta *delta) +{ +} + +void MockRtcStatistic::kbps_sample() +{ +} + +srs_error_t MockRtcStatistic::on_video_frames(ISrsRequest *req, int nb_frames) +{ + return srs_success; +} + +std::string MockRtcStatistic::server_id() +{ + return ""; +} + +std::string MockRtcStatistic::service_id() +{ + return ""; +} + +std::string MockRtcStatistic::service_pid() +{ + return ""; +} + +SrsStatisticVhost *MockRtcStatistic::find_vhost_by_id(std::string vid) +{ + return NULL; +} + +SrsStatisticStream *MockRtcStatistic::find_stream(std::string sid) +{ + return NULL; +} + +SrsStatisticStream *MockRtcStatistic::find_stream_by_url(std::string url) +{ + return NULL; +} + +SrsStatisticClient *MockRtcStatistic::find_client(std::string client_id) +{ + return NULL; +} + +srs_error_t MockRtcStatistic::dumps_vhosts(SrsJsonArray *arr) +{ + return srs_success; +} + +srs_error_t MockRtcStatistic::dumps_streams(SrsJsonArray *arr, int start, int count) +{ + return srs_success; +} + +srs_error_t MockRtcStatistic::dumps_clients(SrsJsonArray *arr, int start, int count) +{ + return srs_success; +} + +srs_error_t MockRtcStatistic::dumps_metrics(int64_t &send_bytes, int64_t &recv_bytes, int64_t &nstreams, int64_t &nclients, int64_t &total_nclients, int64_t &nerrs) +{ + return srs_success; +} + +void MockRtcStatistic::set_on_client_error(srs_error_t err) +{ + srs_freep(on_client_error_); + on_client_error_ = srs_error_copy(err); +} + +void MockRtcStatistic::reset() +{ + srs_freep(on_client_error_); + on_client_error_ = srs_success; + on_client_count_ = 0; + on_disconnect_count_ = 0; + last_client_id_ = ""; + last_client_req_ = NULL; + last_client_conn_ = NULL; + last_client_type_ = SrsRtmpConnUnknown; +} + +// MockRtcAsyncTaskExecutor implementation +MockRtcAsyncTaskExecutor::MockRtcAsyncTaskExecutor() +{ + exec_error_ = srs_success; + exec_count_ = 0; + last_task_ = NULL; +} + +MockRtcAsyncTaskExecutor::~MockRtcAsyncTaskExecutor() +{ +} + +srs_error_t MockRtcAsyncTaskExecutor::exec_rtc_async_work(ISrsAsyncCallTask *t) +{ + exec_count_++; + last_task_ = t; + return exec_error_; +} + +void MockRtcAsyncTaskExecutor::set_exec_error(srs_error_t err) +{ + exec_error_ = err; +} + +void MockRtcAsyncTaskExecutor::reset() +{ + exec_error_ = srs_success; + exec_count_ = 0; + last_task_ = NULL; +} + +// MockRtcPacketSender implementation +MockRtcPacketSender::MockRtcPacketSender() +{ + send_packet_error_ = srs_success; + send_packet_count_ = 0; + last_sent_packet_ = NULL; +} + +MockRtcPacketSender::~MockRtcPacketSender() +{ +} + +srs_error_t MockRtcPacketSender::do_send_packet(SrsRtpPacket *pkt) +{ + send_packet_count_++; + last_sent_packet_ = pkt; + return send_packet_error_; +} + +void MockRtcPacketSender::set_send_packet_error(srs_error_t err) +{ + send_packet_error_ = err; +} + +void MockRtcPacketSender::reset() +{ + send_packet_error_ = srs_success; + send_packet_count_ = 0; + last_sent_packet_ = NULL; +} + +// MockAppConfig implementation +MockAppConfig::MockAppConfig() +{ + http_hooks_enabled_ = true; + on_stop_directive_ = NULL; + on_unpublish_directive_ = NULL; + rtc_nack_enabled_ = true; + rtc_nack_no_copy_ = false; + rtc_drop_for_pt_ = 0; + rtc_twcc_enabled_ = true; + srt_enabled_ = false; + rtc_to_rtmp_ = false; + dash_dispose_ = 0; + dash_enabled_ = false; + api_as_candidates_ = true; + resolve_api_domain_ = true; + keep_api_domain_ = false; + mw_msgs_ = 8; +} + +MockAppConfig::~MockAppConfig() +{ + clear_on_stop_directive(); + clear_on_unpublish_directive(); +} + +srs_utime_t MockAppConfig::get_pithy_print() +{ + return 10 * SRS_UTIME_SECONDS; +} + +std::string MockAppConfig::get_default_app_name() +{ + return "live"; +} + +void MockAppConfig::subscribe(ISrsReloadHandler *handler) +{ + // Do nothing in mock +} + +void MockAppConfig::unsubscribe(ISrsReloadHandler *handler) +{ + // Do nothing in mock +} + +bool MockAppConfig::get_vhost_http_hooks_enabled(std::string vhost) +{ + return http_hooks_enabled_; +} + +SrsConfDirective *MockAppConfig::get_vhost_on_stop(std::string vhost) +{ + return on_stop_directive_; +} + +SrsConfDirective *MockAppConfig::get_vhost_on_unpublish(std::string vhost) +{ + return on_unpublish_directive_; +} + +SrsConfDirective *MockAppConfig::get_vhost_on_dvr(std::string vhost) +{ + return NULL; +} + +bool MockAppConfig::get_rtc_nack_enabled(std::string vhost) +{ + return rtc_nack_enabled_; +} + +bool MockAppConfig::get_rtc_nack_no_copy(std::string vhost) +{ + return rtc_nack_no_copy_; +} + +bool MockAppConfig::get_realtime_enabled(std::string vhost, bool is_rtc) +{ + return true; +} + +int MockAppConfig::get_mw_msgs(std::string vhost, bool is_realtime, bool is_rtc) +{ + return mw_msgs_; +} + +int MockAppConfig::get_rtc_drop_for_pt(std::string vhost) +{ + return rtc_drop_for_pt_; +} + +bool MockAppConfig::get_rtc_twcc_enabled(std::string vhost) +{ + return rtc_twcc_enabled_; +} + +bool MockAppConfig::get_srt_enabled() +{ + return srt_enabled_; +} + +bool MockAppConfig::get_srt_enabled(std::string vhost) +{ + return srt_enabled_; +} + +std::string MockAppConfig::get_srt_default_streamid() +{ + return "#!::r=live/livestream,m=request"; +} + +bool MockAppConfig::get_srt_to_rtmp(std::string vhost) +{ + return true; +} + +bool MockAppConfig::get_rtc_to_rtmp(std::string vhost) +{ + return rtc_to_rtmp_; +} + +srs_utime_t MockAppConfig::get_rtc_stun_timeout(std::string vhost) +{ + return 30 * SRS_UTIME_SECONDS; +} + +bool MockAppConfig::get_rtc_stun_strict_check(std::string vhost) +{ + return false; +} + +std::string MockAppConfig::get_rtc_dtls_role(std::string vhost) +{ + return "passive"; +} + +std::string MockAppConfig::get_rtc_dtls_version(std::string vhost) +{ + return "auto"; +} + +SrsConfDirective *MockAppConfig::get_vhost_on_hls(std::string vhost) +{ + return NULL; +} + +SrsConfDirective *MockAppConfig::get_vhost_on_hls_notify(std::string vhost) +{ + return NULL; +} + +bool MockAppConfig::get_hls_enabled(std::string vhost) +{ + return false; +} + +bool MockAppConfig::get_hls_enabled(SrsConfDirective *vhost) +{ + return false; +} + +bool MockAppConfig::get_hls_use_fmp4(std::string vhost) +{ + return false; +} + +std::string MockAppConfig::get_hls_entry_prefix(std::string vhost) +{ + return ""; +} + +std::string MockAppConfig::get_hls_path(std::string vhost) +{ + return "./objs/nginx/html"; +} + +std::string MockAppConfig::get_hls_m3u8_file(std::string vhost) +{ + return "[app]/[stream].m3u8"; +} + +std::string MockAppConfig::get_hls_ts_file(std::string vhost) +{ + return "[app]/[stream]-[seq].ts"; +} + +std::string MockAppConfig::get_hls_fmp4_file(std::string vhost) +{ + return "[app]/[stream]-[seq].m4s"; +} + +std::string MockAppConfig::get_hls_init_file(std::string vhost) +{ + return "[app]/[stream]-init.mp4"; +} + +bool MockAppConfig::get_hls_ts_floor(std::string vhost) +{ + return false; +} + +srs_utime_t MockAppConfig::get_hls_fragment(std::string vhost) +{ + return 10 * SRS_UTIME_SECONDS; +} + +double MockAppConfig::get_hls_td_ratio(std::string vhost) +{ + return 1.5; +} + +double MockAppConfig::get_hls_aof_ratio(std::string vhost) +{ + return 2.0; +} + +srs_utime_t MockAppConfig::get_hls_window(std::string vhost) +{ + return 60 * SRS_UTIME_SECONDS; +} + +std::string MockAppConfig::get_hls_on_error(std::string vhost) +{ + return "continue"; +} + +bool MockAppConfig::get_hls_cleanup(std::string vhost) +{ + return true; +} + +srs_utime_t MockAppConfig::get_hls_dispose(std::string vhost) +{ + return 120 * SRS_UTIME_SECONDS; +} + +bool MockAppConfig::get_hls_wait_keyframe(std::string vhost) +{ + return true; +} + +bool MockAppConfig::get_hls_keys(std::string vhost) +{ + return false; +} + +int MockAppConfig::get_hls_fragments_per_key(std::string vhost) +{ + return 5; +} + +std::string MockAppConfig::get_hls_key_file(std::string vhost) +{ + return "[app]/[stream]-[seq].key"; +} + +std::string MockAppConfig::get_hls_key_file_path(std::string vhost) +{ + return "./objs/nginx/html"; +} + +std::string MockAppConfig::get_hls_key_url(std::string vhost) +{ + return ""; +} + +int MockAppConfig::get_vhost_hls_nb_notify(std::string vhost) +{ + return 64; +} + +bool MockAppConfig::get_vhost_hls_dts_directly(std::string vhost) +{ + return true; +} + +bool MockAppConfig::get_hls_ctx_enabled(std::string vhost) +{ + return true; +} + +bool MockAppConfig::get_hls_ts_ctx_enabled(std::string vhost) +{ + return true; +} + +bool MockAppConfig::get_hls_recover(std::string vhost) +{ + return true; +} + +bool MockAppConfig::get_forward_enabled(std::string vhost) +{ + return false; +} + +SrsConfDirective *MockAppConfig::get_forwards(std::string vhost) +{ + return NULL; +} + +srs_utime_t MockAppConfig::get_queue_length(std::string vhost) +{ + return 30 * SRS_UTIME_SECONDS; +} + +SrsConfDirective *MockAppConfig::get_forward_backend(std::string vhost) +{ + return NULL; +} + +bool MockAppConfig::get_atc(std::string vhost) +{ + return false; +} + +int MockAppConfig::get_time_jitter(std::string vhost) +{ + return SrsRtmpJitterAlgorithmFULL; +} + +bool MockAppConfig::get_mix_correct(std::string vhost) +{ + return false; +} + +bool MockAppConfig::try_annexb_first(std::string vhost) +{ + return true; +} + +bool MockAppConfig::get_vhost_is_edge(std::string vhost) +{ + return false; +} + +bool MockAppConfig::get_atc_auto(std::string vhost) +{ + return false; +} + +bool MockAppConfig::get_reduce_sequence_header(std::string vhost) +{ + return false; +} + +bool MockAppConfig::get_parse_sps(std::string vhost) +{ + return true; +} + +void MockAppConfig::set_http_hooks_enabled(bool enabled) +{ + http_hooks_enabled_ = enabled; +} + +void MockAppConfig::set_on_stop_urls(const std::vector &urls) +{ + clear_on_stop_directive(); + if (!urls.empty()) { + on_stop_directive_ = new SrsConfDirective(); + on_stop_directive_->name_ = "on_stop"; + on_stop_directive_->args_ = urls; + } +} + +void MockAppConfig::clear_on_stop_directive() +{ + srs_freep(on_stop_directive_); +} + +void MockAppConfig::set_on_unpublish_urls(const std::vector &urls) +{ + clear_on_unpublish_directive(); + if (!urls.empty()) { + on_unpublish_directive_ = new SrsConfDirective(); + on_unpublish_directive_->name_ = "on_unpublish"; + on_unpublish_directive_->args_ = urls; + } +} + +void MockAppConfig::clear_on_unpublish_directive() +{ + srs_freep(on_unpublish_directive_); +} + +void MockAppConfig::set_rtc_nack_enabled(bool enabled) +{ + rtc_nack_enabled_ = enabled; +} + +void MockAppConfig::set_rtc_nack_no_copy(bool no_copy) +{ + rtc_nack_no_copy_ = no_copy; +} + +void MockAppConfig::set_rtc_drop_for_pt(int pt) +{ + rtc_drop_for_pt_ = pt; +} + +void MockAppConfig::set_rtc_twcc_enabled(bool enabled) +{ + rtc_twcc_enabled_ = enabled; +} + +void MockAppConfig::set_srt_enabled(bool enabled) +{ + srt_enabled_ = enabled; +} + +void MockAppConfig::set_rtc_to_rtmp(bool enabled) +{ + rtc_to_rtmp_ = enabled; +} + +void MockAppConfig::set_api_as_candidates(bool enabled) +{ + api_as_candidates_ = enabled; +} + +void MockAppConfig::set_resolve_api_domain(bool enabled) +{ + resolve_api_domain_ = enabled; +} + +void MockAppConfig::set_keep_api_domain(bool enabled) +{ + keep_api_domain_ = enabled; +} + diff --git a/trunk/src/utest/srs_utest_mock.hpp b/trunk/src/utest/srs_utest_mock.hpp new file mode 100644 index 000000000..cbbe8ee5d --- /dev/null +++ b/trunk/src/utest/srs_utest_mock.hpp @@ -0,0 +1,471 @@ +// +// Copyright (c) 2013-2025 The SRS Authors +// +// SPDX-License-Identifier: MIT +// + +#ifndef SRS_UTEST_MOCK_HPP +#define SRS_UTEST_MOCK_HPP + +#include + +#include +#include + +// Include necessary SRS headers for interfaces +#include +#include +#include +#include +#include +#include + +// Forward declarations +class SrsRtcTrackDescription; +class SrsRtpPacket; + +// Helper class to create mock track descriptions for testing +class MockRtcTrackDescriptionFactory +{ +public: + MockRtcTrackDescriptionFactory(); + virtual ~MockRtcTrackDescriptionFactory(); + +public: + // Default SSRCs for audio and video tracks + uint32_t audio_ssrc_; + uint32_t video_ssrc_; + uint32_t screen_ssrc_; + +public: + // Create a map of track descriptions with audio and video tracks + std::map create_audio_video_tracks(); + + // Create a single audio track description + SrsRtcTrackDescription *create_audio_track(uint32_t ssrc, std::string id, std::string mid); + + // Create a single video track description + SrsRtcTrackDescription *create_video_track(uint32_t ssrc, std::string id, std::string mid); +}; + +// Mock expire for testing +class MockExpire : public ISrsExpire +{ +public: + bool expired_; + +public: + MockExpire(); + virtual ~MockExpire(); + +public: + virtual void expire(); +}; + +// Mock request for testing +class MockRtcAsyncCallRequest : public ISrsRequest +{ +public: + std::string vhost_; + std::string app_; + std::string stream_; + +public: + MockRtcAsyncCallRequest(std::string vhost = "__defaultVhost__", std::string app = "live", std::string stream = "test"); + virtual ~MockRtcAsyncCallRequest(); + virtual ISrsRequest *copy(); + virtual std::string get_stream_url(); + virtual void update_auth(ISrsRequest *req); + virtual void strip(); + virtual ISrsRequest *as_http(); +}; + +// Mock RTC source manager for testing +class MockRtcSourceManager : public ISrsRtcSourceManager +{ +public: + srs_error_t initialize_error_; + srs_error_t fetch_or_create_error_; + int initialize_count_; + int fetch_or_create_count_; + SrsSharedPtr mock_source_; + +public: + MockRtcSourceManager(); + virtual ~MockRtcSourceManager(); + virtual srs_error_t initialize(); + virtual srs_error_t fetch_or_create(ISrsRequest *r, SrsSharedPtr &pps); + virtual SrsSharedPtr fetch(ISrsRequest *r); + void set_initialize_error(srs_error_t err); + void set_fetch_or_create_error(srs_error_t err); + void reset(); +}; + +// Mock statistic for testing +class MockRtcStatistic : public ISrsStatistic +{ +public: + srs_error_t on_client_error_; + int on_client_count_; + int on_disconnect_count_; + std::string last_client_id_; + ISrsRequest *last_client_req_; + ISrsExpire *last_client_conn_; + SrsRtmpConnType last_client_type_; + +public: + MockRtcStatistic(); + virtual ~MockRtcStatistic(); + virtual void on_disconnect(std::string id, srs_error_t err); + virtual srs_error_t on_client(std::string id, ISrsRequest *req, ISrsExpire *conn, SrsRtmpConnType type); + virtual srs_error_t on_video_info(ISrsRequest *req, SrsVideoCodecId vcodec, int avc_profile, int avc_level, int width, int height); + virtual srs_error_t on_audio_info(ISrsRequest *req, SrsAudioCodecId acodec, SrsAudioSampleRate asample_rate, SrsAudioChannels asound_type, SrsAacObjectType aac_object); + virtual void on_stream_publish(ISrsRequest *req, std::string publisher_id); + virtual void on_stream_close(ISrsRequest *req); + virtual void kbps_add_delta(std::string id, ISrsKbpsDelta *delta); + virtual void kbps_sample(); + virtual srs_error_t on_video_frames(ISrsRequest *req, int nb_frames); + virtual std::string server_id(); + virtual std::string service_id(); + virtual std::string service_pid(); + virtual SrsStatisticVhost *find_vhost_by_id(std::string vid); + virtual SrsStatisticStream *find_stream(std::string sid); + virtual SrsStatisticStream *find_stream_by_url(std::string url); + virtual SrsStatisticClient *find_client(std::string client_id); + virtual srs_error_t dumps_vhosts(SrsJsonArray *arr); + virtual srs_error_t dumps_streams(SrsJsonArray *arr, int start, int count); + virtual srs_error_t dumps_clients(SrsJsonArray *arr, int start, int count); + virtual srs_error_t dumps_metrics(int64_t &send_bytes, int64_t &recv_bytes, int64_t &nstreams, int64_t &nclients, int64_t &total_nclients, int64_t &nerrs); + void set_on_client_error(srs_error_t err); + void reset(); +}; + +// Mock RTC async task executor for testing +class MockRtcAsyncTaskExecutor : public ISrsExecRtcAsyncTask +{ +public: + srs_error_t exec_error_; + int exec_count_; + ISrsAsyncCallTask *last_task_; + +public: + MockRtcAsyncTaskExecutor(); + virtual ~MockRtcAsyncTaskExecutor(); + +public: + virtual srs_error_t exec_rtc_async_work(ISrsAsyncCallTask *t); + void set_exec_error(srs_error_t err); + void reset(); +}; + +// Mock RTC packet sender for testing +class MockRtcPacketSender : public ISrsRtcPacketSender +{ +public: + srs_error_t send_packet_error_; + int send_packet_count_; + SrsRtpPacket *last_sent_packet_; + +public: + MockRtcPacketSender(); + virtual ~MockRtcPacketSender(); + +public: + virtual srs_error_t do_send_packet(SrsRtpPacket *pkt); + void set_send_packet_error(srs_error_t err); + void reset(); +}; + +// Mock app config for testing +class MockAppConfig : public ISrsAppConfig +{ +public: + bool http_hooks_enabled_; + SrsConfDirective *on_stop_directive_; + SrsConfDirective *on_unpublish_directive_; + bool rtc_nack_enabled_; + bool rtc_nack_no_copy_; + int rtc_drop_for_pt_; + bool rtc_twcc_enabled_; + bool srt_enabled_; + bool rtc_to_rtmp_; + srs_utime_t dash_dispose_; + bool dash_enabled_; + bool api_as_candidates_; + bool resolve_api_domain_; + bool keep_api_domain_; + int mw_msgs_; + +public: + MockAppConfig(); + virtual ~MockAppConfig(); + // ISrsConfig methods + virtual srs_utime_t get_pithy_print(); + virtual std::string get_default_app_name(); + virtual void subscribe(ISrsReloadHandler *handler); + virtual void unsubscribe(ISrsReloadHandler *handler); + virtual srs_error_t reload(SrsReloadState *pstate) { return srs_success; } + virtual srs_error_t persistence() { return srs_success; } + virtual std::string config() { return ""; } + virtual SrsConfDirective *get_root() { return NULL; } + virtual std::string cwd() { return "./"; } + virtual int get_max_connections() { return 1000; } + virtual std::string get_pid_file() { return ""; } + virtual bool empty_ip_ok() { return false; } + virtual bool get_asprocess() { return false; } + virtual srs_utime_t get_grace_start_wait() { return 0; } + virtual srs_utime_t get_grace_final_wait() { return 0; } + virtual bool is_force_grace_quit() { return false; } + virtual bool inotify_auto_reload() { return false; } + virtual bool auto_reload_for_docker() { return false; } + virtual std::vector get_listens() { return std::vector(); } + virtual bool get_rtmps_enabled() { return false; } + virtual std::vector get_rtmps_listen() { return std::vector(); } + virtual bool get_http_api_enabled() { return false; } + virtual std::vector get_http_api_listens() { return std::vector(); } + virtual bool get_https_api_enabled() { return false; } + virtual std::vector get_https_api_listens() { return std::vector(); } + virtual std::string get_https_api_ssl_key() { return ""; } + virtual std::string get_https_api_ssl_cert() { return ""; } + virtual bool get_raw_api() { return false; } + virtual bool get_raw_api_allow_reload() { return false; } + virtual bool get_raw_api_allow_query() { return false; } + virtual bool get_raw_api_allow_update() { return false; } + virtual bool get_http_api_auth_enabled() { return false; } + virtual std::string get_http_api_auth_username() { return ""; } + virtual std::string get_http_api_auth_password() { return ""; } + virtual srs_error_t raw_to_json(SrsJsonObject *obj) { return srs_success; } + virtual bool get_http_stream_enabled() { return false; } + virtual std::vector get_http_stream_listens() { return std::vector(); } + virtual bool get_https_stream_enabled() { return false; } + virtual std::vector get_https_stream_listens() { return std::vector(); } + virtual std::string get_https_stream_ssl_key() { return ""; } + virtual std::string get_https_stream_ssl_cert() { return ""; } + virtual std::string get_http_stream_dir() { return ""; } + virtual bool get_http_stream_crossdomain() { return false; } + virtual bool get_rtc_server_enabled() { return false; } + virtual bool get_rtc_server_tcp_enabled() { return false; } + virtual std::vector get_rtc_server_tcp_listens() { return std::vector(); } + virtual std::string get_rtc_server_protocol() { return "udp"; } + virtual std::vector get_rtc_server_listens() { return std::vector(); } + virtual int get_rtc_server_reuseport() { return 1; } + virtual bool get_rtc_server_encrypt() { return false; } + virtual bool get_api_as_candidates() { return api_as_candidates_; } + virtual bool get_resolve_api_domain() { return resolve_api_domain_; } + virtual bool get_keep_api_domain() { return keep_api_domain_; } + virtual std::string get_rtc_server_candidates() { return "*"; } + virtual bool get_use_auto_detect_network_ip() { return true; } + virtual std::string get_rtc_server_ip_family() { return "ipv4"; } + virtual bool get_rtsp_server_enabled() { return false; } + virtual std::vector get_rtsp_server_listens() { return std::vector(); } + virtual std::vector get_srt_listens() { return std::vector(); } + virtual std::vector get_stream_casters() { return std::vector(); } + virtual bool get_stream_caster_enabled(SrsConfDirective *conf) { return false; } + virtual std::string get_stream_caster_engine(SrsConfDirective *conf) { return ""; } + virtual std::string get_stream_caster_output(SrsConfDirective *conf) { return ""; } + virtual int get_stream_caster_listen(SrsConfDirective *conf) { return 0; } + virtual bool get_exporter_enabled() { return false; } + virtual std::string get_exporter_listen() { return ""; } + virtual std::string get_exporter_label() { return ""; } + virtual std::string get_exporter_tag() { return ""; } + virtual bool get_stats_enabled() { return false; } + virtual int get_stats_network() { return 0; } + virtual bool get_heartbeat_enabled() { return false; } + virtual srs_utime_t get_heartbeat_interval() { return 0; } + virtual std::string get_heartbeat_url() { return ""; } + virtual std::string get_heartbeat_device_id() { return ""; } + virtual bool get_heartbeat_summaries() { return false; } + virtual bool get_heartbeat_ports() { return false; } + virtual bool get_circuit_breaker() { return false; } + virtual int get_high_threshold() { return 0; } + virtual int get_high_pulse() { return 0; } + virtual int get_critical_threshold() { return 0; } + virtual int get_critical_pulse() { return 0; } + virtual int get_dying_threshold() { return 0; } + virtual int get_dying_pulse() { return 0; } + virtual std::string get_rtmps_ssl_cert() { return ""; } + virtual std::string get_rtmps_ssl_key() { return ""; } + virtual SrsConfDirective *get_vhost(std::string vhost, bool try_default_vhost = true) { return NULL; } + virtual bool get_vhost_enabled(std::string vhost) { return true; } + virtual bool get_debug_srs_upnode(std::string vhost) { return true; } + virtual int get_out_ack_size(std::string vhost) { return 2500000; } + virtual int get_in_ack_size(std::string vhost) { return 2500000; } + virtual int get_chunk_size(std::string vhost) { return 60000; } + virtual bool get_gop_cache(std::string vhost) { return true; } + virtual int get_gop_cache_max_frames(std::string vhost) { return 2500; } + virtual bool get_tcp_nodelay(std::string vhost) { return false; } + virtual srs_utime_t get_mw_sleep(std::string vhost, bool is_rtc = false) { return 350 * SRS_UTIME_MILLISECONDS; } + virtual srs_utime_t get_send_min_interval(std::string vhost) { return 0; } + virtual bool get_mr_enabled(std::string vhost) { return false; } + virtual srs_utime_t get_mr_sleep(std::string vhost) { return 350 * SRS_UTIME_MILLISECONDS; } + virtual srs_utime_t get_publish_1stpkt_timeout(std::string vhost) { return 20000 * SRS_UTIME_MILLISECONDS; } + virtual srs_utime_t get_publish_normal_timeout(std::string vhost) { return 5000 * SRS_UTIME_MILLISECONDS; } + virtual srs_utime_t get_publish_kickoff_for_idle(std::string vhost) { return 0; } + virtual bool get_refer_enabled(std::string vhost) { return false; } + virtual SrsConfDirective *get_refer_all(std::string vhost) { return NULL; } + virtual SrsConfDirective *get_refer_play(std::string vhost) { return NULL; } + virtual SrsConfDirective *get_refer_publish(std::string vhost) { return NULL; } + virtual bool get_vhost_origin_cluster(std::string vhost) { return false; } + virtual std::vector get_vhost_coworkers(std::string vhost) { return std::vector(); } + virtual bool get_vhost_edge_token_traverse(std::string vhost) { return false; } + virtual SrsConfDirective *get_vhost_edge_origin(std::string vhost) { return NULL; } + virtual SrsConfDirective *get_vhost_on_connect(std::string vhost) { return NULL; } + virtual SrsConfDirective *get_vhost_on_close(std::string vhost) { return NULL; } + virtual SrsConfDirective *get_vhost_on_publish(std::string vhost) { return NULL; } + virtual SrsConfDirective *get_vhost_on_play(std::string vhost) { return NULL; } + virtual bool get_rtc_enabled(std::string vhost) { return false; } + virtual bool get_rtsp_enabled(std::string vhost) { return false; } + virtual bool get_rtc_from_rtmp(std::string vhost) { return false; } + virtual bool get_rtsp_from_rtmp(std::string vhost) { return false; } + // ISrsAppConfig methods + virtual bool get_vhost_http_hooks_enabled(std::string vhost); + virtual SrsConfDirective *get_vhost_on_stop(std::string vhost); + virtual SrsConfDirective *get_vhost_on_unpublish(std::string vhost); + virtual SrsConfDirective *get_vhost_on_dvr(std::string vhost); + virtual bool get_rtc_nack_enabled(std::string vhost); + virtual bool get_rtc_nack_no_copy(std::string vhost); + virtual bool get_realtime_enabled(std::string vhost, bool is_rtc); + virtual int get_mw_msgs(std::string vhost, bool is_realtime, bool is_rtc); + virtual int get_rtc_drop_for_pt(std::string vhost); + virtual bool get_rtc_twcc_enabled(std::string vhost); + virtual bool get_srt_enabled(); + virtual bool get_srt_enabled(std::string vhost); + virtual std::string get_srt_default_streamid(); + virtual bool get_srt_to_rtmp(std::string vhost); + virtual bool get_rtc_to_rtmp(std::string vhost); + virtual srs_utime_t get_rtc_stun_timeout(std::string vhost); + virtual bool get_rtc_stun_strict_check(std::string vhost); + virtual std::string get_rtc_dtls_role(std::string vhost); + virtual std::string get_rtc_dtls_version(std::string vhost); + virtual SrsConfDirective *get_vhost_on_hls(std::string vhost); + virtual SrsConfDirective *get_vhost_on_hls_notify(std::string vhost); + // HLS methods + virtual bool get_hls_enabled(std::string vhost); + virtual bool get_hls_enabled(SrsConfDirective *vhost); + virtual bool get_hls_use_fmp4(std::string vhost); + virtual std::string get_hls_entry_prefix(std::string vhost); + virtual std::string get_hls_path(std::string vhost); + virtual std::string get_hls_m3u8_file(std::string vhost); + virtual std::string get_hls_ts_file(std::string vhost); + virtual std::string get_hls_fmp4_file(std::string vhost); + virtual std::string get_hls_init_file(std::string vhost); + virtual bool get_hls_ts_floor(std::string vhost); + virtual srs_utime_t get_hls_fragment(std::string vhost); + virtual double get_hls_td_ratio(std::string vhost); + virtual double get_hls_aof_ratio(std::string vhost); + virtual srs_utime_t get_hls_window(std::string vhost); + virtual std::string get_hls_on_error(std::string vhost); + virtual bool get_hls_cleanup(std::string vhost); + virtual srs_utime_t get_hls_dispose(std::string vhost); + virtual bool get_hls_wait_keyframe(std::string vhost); + virtual bool get_hls_keys(std::string vhost); + virtual int get_hls_fragments_per_key(std::string vhost); + virtual std::string get_hls_key_file(std::string vhost); + virtual std::string get_hls_key_file_path(std::string vhost); + virtual std::string get_hls_key_url(std::string vhost); + virtual int get_vhost_hls_nb_notify(std::string vhost); + virtual bool get_vhost_hls_dts_directly(std::string vhost); + virtual bool get_hls_ctx_enabled(std::string vhost); + virtual bool get_hls_ts_ctx_enabled(std::string vhost); + virtual bool get_hls_recover(std::string vhost); + virtual bool get_forward_enabled(std::string vhost); + virtual SrsConfDirective *get_forwards(std::string vhost); + virtual srs_utime_t get_queue_length(std::string vhost); + virtual SrsConfDirective *get_forward_backend(std::string vhost); + virtual bool get_atc(std::string vhost); + virtual int get_time_jitter(std::string vhost); + virtual bool get_mix_correct(std::string vhost); + virtual bool try_annexb_first(std::string vhost); + virtual bool get_vhost_is_edge(std::string vhost); + virtual bool get_atc_auto(std::string vhost); + virtual bool get_reduce_sequence_header(std::string vhost); + virtual bool get_parse_sps(std::string vhost); + // DVR methods + virtual std::string get_dvr_path(std::string vhost) { return "./[vhost]/[app]/[stream]/[2006]/[01]/[02]/[15].[04].[05].[999].flv"; } + virtual std::string get_dvr_plan(std::string vhost) { return "session"; } + virtual bool get_dvr_enabled(std::string vhost) { return false; } + virtual SrsConfDirective *get_dvr_apply(std::string vhost) { return NULL; } + virtual srs_utime_t get_dvr_duration(std::string vhost) { return 30 * SRS_UTIME_SECONDS; } + virtual int get_dvr_time_jitter(std::string vhost) { return 0; } + virtual bool get_dvr_wait_keyframe(std::string vhost) { return true; } + virtual bool get_vhost_enabled(SrsConfDirective *conf) { return true; } + virtual bool get_vhost_http_remux_enabled(std::string vhost) { return false; } + virtual bool get_vhost_http_remux_enabled(SrsConfDirective *vhost) { return false; } + virtual srs_utime_t get_vhost_http_remux_fast_cache(std::string vhost) { return 0; } + virtual bool get_vhost_http_remux_drop_if_not_match(std::string vhost) { return false; } + virtual bool get_vhost_http_remux_has_audio(std::string vhost) { return true; } + virtual bool get_vhost_http_remux_has_video(std::string vhost) { return true; } + virtual bool get_vhost_http_remux_guess_has_av(std::string vhost) { return true; } + virtual std::string get_vhost_http_remux_mount(std::string vhost) { return ""; } + virtual std::string get_vhost_edge_protocol(std::string vhost) { return "rtmp"; } + virtual bool get_vhost_edge_follow_client(std::string vhost) { return false; } + virtual std::string get_vhost_edge_transform_vhost(std::string vhost) { return ""; } + // DASH methods + virtual bool get_dash_enabled(std::string vhost) { return dash_enabled_; } + virtual bool get_dash_enabled(SrsConfDirective *vhost) { return dash_enabled_; } + virtual srs_utime_t get_dash_fragment(std::string vhost) { return 30 * SRS_UTIME_SECONDS; } + virtual srs_utime_t get_dash_update_period(std::string vhost) { return 30 * SRS_UTIME_SECONDS; } + virtual srs_utime_t get_dash_timeshift(std::string vhost) { return 300 * SRS_UTIME_SECONDS; } + virtual std::string get_dash_path(std::string vhost) { return "./[vhost]/[app]/[stream]/"; } + virtual std::string get_dash_mpd_file(std::string vhost) { return "[stream].mpd"; } + virtual int get_dash_window_size(std::string vhost) { return 10; } + virtual bool get_dash_cleanup(std::string vhost) { return true; } + virtual srs_utime_t get_dash_dispose(std::string vhost) { return dash_dispose_; } + // Exec config + virtual bool get_exec_enabled(std::string vhost) { return false; } + virtual std::vector get_exec_publishs(std::string vhost) { return std::vector(); } + // Ingest config + virtual void get_vhosts(std::vector &vhosts) {} + virtual std::vector get_ingesters(std::string vhost) { return std::vector(); } + virtual SrsConfDirective *get_ingest_by_id(std::string vhost, std::string ingest_id) { return NULL; } + virtual bool get_ingest_enabled(SrsConfDirective *conf) { return false; } + virtual std::string get_ingest_ffmpeg(SrsConfDirective *conf) { return ""; } + virtual std::string get_ingest_input_type(SrsConfDirective *conf) { return ""; } + virtual std::string get_ingest_input_url(SrsConfDirective *conf) { return ""; } + // FFmpeg log config + virtual bool get_ff_log_enabled() { return false; } + virtual std::string get_ff_log_dir() { return ""; } + virtual std::string get_ff_log_level() { return ""; } + // Transcode/Engine config + virtual SrsConfDirective *get_transcode(std::string vhost, std::string scope) { return NULL; } + virtual bool get_transcode_enabled(SrsConfDirective *conf) { return false; } + virtual std::string get_transcode_ffmpeg(SrsConfDirective *conf) { return ""; } + virtual std::vector get_transcode_engines(SrsConfDirective *conf) { return std::vector(); } + virtual bool get_engine_enabled(SrsConfDirective *conf) { return false; } + virtual std::vector get_engine_perfile(SrsConfDirective *conf) { return std::vector(); } + virtual std::string get_engine_iformat(SrsConfDirective *conf) { return ""; } + virtual std::vector get_engine_vfilter(SrsConfDirective *conf) { return std::vector(); } + virtual std::string get_engine_vcodec(SrsConfDirective *conf) { return ""; } + virtual int get_engine_vbitrate(SrsConfDirective *conf) { return 0; } + virtual double get_engine_vfps(SrsConfDirective *conf) { return 0; } + virtual int get_engine_vwidth(SrsConfDirective *conf) { return 0; } + virtual int get_engine_vheight(SrsConfDirective *conf) { return 0; } + virtual int get_engine_vthreads(SrsConfDirective *conf) { return 0; } + virtual std::string get_engine_vprofile(SrsConfDirective *conf) { return ""; } + virtual std::string get_engine_vpreset(SrsConfDirective *conf) { return ""; } + virtual std::vector get_engine_vparams(SrsConfDirective *conf) { return std::vector(); } + virtual std::string get_engine_acodec(SrsConfDirective *conf) { return ""; } + virtual int get_engine_abitrate(SrsConfDirective *conf) { return 0; } + virtual int get_engine_asample_rate(SrsConfDirective *conf) { return 0; } + virtual int get_engine_achannels(SrsConfDirective *conf) { return 0; } + virtual std::vector get_engine_aparams(SrsConfDirective *conf) { return std::vector(); } + virtual std::string get_engine_oformat(SrsConfDirective *conf) { return ""; } + virtual std::string get_engine_output(SrsConfDirective *conf) { return ""; } + void set_http_hooks_enabled(bool enabled); + void set_on_stop_urls(const std::vector &urls); + void clear_on_stop_directive(); + void set_on_unpublish_urls(const std::vector &urls); + void clear_on_unpublish_directive(); + void set_rtc_nack_enabled(bool enabled); + void set_rtc_nack_no_copy(bool no_copy); + void set_rtc_drop_for_pt(int pt); + void set_rtc_twcc_enabled(bool enabled); + void set_srt_enabled(bool enabled); + void set_rtc_to_rtmp(bool enabled); + void set_api_as_candidates(bool enabled); + void set_resolve_api_domain(bool enabled); + void set_keep_api_domain(bool enabled); +}; + +#endif + diff --git a/trunk/src/utest/srs_utest_protocol3.cpp b/trunk/src/utest/srs_utest_protocol3.cpp index 8104f4bb9..14bfa6c78 100644 --- a/trunk/src/utest/srs_utest_protocol3.cpp +++ b/trunk/src/utest/srs_utest_protocol3.cpp @@ -77,19 +77,6 @@ const SrsContextId &MockConnection::get_id() return id; } -MockExpire::MockExpire() : expired_(false) -{ -} - -MockExpire::~MockExpire() -{ -} - -void MockExpire::expire() -{ - expired_ = true; -} - VOID TEST(ProtocolConnTest, ISrsConnectionInterface) { MockConnection conn("192.168.1.100"); diff --git a/trunk/src/utest/srs_utest_protocol3.hpp b/trunk/src/utest/srs_utest_protocol3.hpp index 273c4c590..48037110c 100644 --- a/trunk/src/utest/srs_utest_protocol3.hpp +++ b/trunk/src/utest/srs_utest_protocol3.hpp @@ -30,17 +30,4 @@ public: virtual const SrsContextId &get_id(); }; -class MockExpire : public ISrsExpire -{ -public: - bool expired_; - -public: - MockExpire(); - virtual ~MockExpire(); - -public: - virtual void expire(); -}; - #endif diff --git a/trunk/src/utest/srs_utest_rtc_playstream.cpp b/trunk/src/utest/srs_utest_rtc_playstream.cpp index d0e6b5695..17ff56ae7 100644 --- a/trunk/src/utest/srs_utest_rtc_playstream.cpp +++ b/trunk/src/utest/srs_utest_rtc_playstream.cpp @@ -11,65 +11,11 @@ #include #include #include +#include -// MockRtcTrackDescriptionFactory implementation -MockRtcTrackDescriptionFactory::MockRtcTrackDescriptionFactory() -{ - audio_ssrc_ = 12345; - video_ssrc_ = 67890; - screen_ssrc_ = 98765; -} - -MockRtcTrackDescriptionFactory::~MockRtcTrackDescriptionFactory() -{ -} - -std::map MockRtcTrackDescriptionFactory::create_audio_video_tracks() -{ - std::map sub_relations; - - // Create audio track - SrsRtcTrackDescription *audio_desc = create_audio_track(audio_ssrc_, "audio-track-1", "0"); - sub_relations[audio_desc->ssrc_] = audio_desc; - - // Create video track - SrsRtcTrackDescription *video_desc = create_video_track(video_ssrc_, "video-track-1", "1"); - sub_relations[video_desc->ssrc_] = video_desc; - - // Create screen share track - SrsRtcTrackDescription *screen_desc = create_video_track(screen_ssrc_, "screen-track-1", "2"); - sub_relations[screen_desc->ssrc_] = screen_desc; - - return sub_relations; -} - -SrsRtcTrackDescription *MockRtcTrackDescriptionFactory::create_audio_track(uint32_t ssrc, std::string id, std::string mid) -{ - SrsRtcTrackDescription *audio_desc = new SrsRtcTrackDescription(); - audio_desc->type_ = "audio"; - audio_desc->ssrc_ = ssrc; - audio_desc->id_ = id; - audio_desc->is_active_ = true; - audio_desc->direction_ = "sendrecv"; - audio_desc->mid_ = mid; - audio_desc->media_ = new SrsAudioPayload(111, "opus", 48000, 2); - return audio_desc; -} - -SrsRtcTrackDescription *MockRtcTrackDescriptionFactory::create_video_track(uint32_t ssrc, std::string id, std::string mid) -{ - SrsRtcTrackDescription *video_desc = new SrsRtcTrackDescription(); - video_desc->type_ = "video"; - video_desc->ssrc_ = ssrc; - video_desc->id_ = id; - video_desc->is_active_ = true; - video_desc->direction_ = "sendrecv"; - video_desc->mid_ = mid; - video_desc->media_ = new SrsVideoPayload(96, "H264", 90000); - return video_desc; -} - -// Test SrsRtcPlayStream::start() - Basic success scenario +// This test is used to verify the basic workflow of the RTC play stream. +// It's finished with the help of AI, but each step is manually designed +// and verified. So this is not dominated by AI, but by humanbeing. VOID TEST(RtcPlayStreamTest, ManuallyVerifyBasicWorkflow) { srs_error_t err; @@ -207,6 +153,72 @@ VOID TEST(RtcPlayStreamTest, ManuallyVerifyBasicWorkflow) EXPECT_EQ(pkt->header_.get_ssrc(), track_factory.screen_ssrc_); } + // Receive a video packet again, to verify the hit cache track. + if (true) { + SrsUniquePtr test_pkt(new SrsRtpPacket()); + test_pkt->frame_type_ = SrsFrameTypeVideo; + test_pkt->header_.set_sequence(1001); + test_pkt->header_.set_timestamp(5001); + test_pkt->header_.set_ssrc(track_factory.video_ssrc_); + + // Push packet to source - this will feed all consumers including the play stream's consumer + HELPER_EXPECT_SUCCESS(play_stream->source_->on_rtp(test_pkt.get())); + + // Wait for coroutine to process the packet + srs_usleep(1 * SRS_UTIME_MILLISECONDS); + + // Check sender should have received the packet + EXPECT_EQ(mock_sender.send_packet_count_, 4); + // Check NACK ring buffer. + SrsRtpPacket *pkt = play_stream->cache_track0_->rtp_queue_->at(1001); + EXPECT_TRUE(pkt != NULL); + EXPECT_EQ(pkt->header_.get_ssrc(), track_factory.video_ssrc_); + } + + // Receive a audio packet again, to verify the hit cache track. + if (true) { + SrsUniquePtr test_pkt(new SrsRtpPacket()); + test_pkt->frame_type_ = SrsFrameTypeAudio; + test_pkt->header_.set_sequence(1001); + test_pkt->header_.set_timestamp(5001); + test_pkt->header_.set_ssrc(track_factory.audio_ssrc_); + + // Push packet to source - this will feed all consumers including the play stream's consumer + HELPER_EXPECT_SUCCESS(play_stream->source_->on_rtp(test_pkt.get())); + + // Wait for coroutine to process the packet + srs_usleep(1 * SRS_UTIME_MILLISECONDS); + + // Check sender should have received the packet + EXPECT_EQ(mock_sender.send_packet_count_, 5); + // Check NACK ring buffer. + SrsRtpPacket *pkt = play_stream->cache_track1_->rtp_queue_->at(1001); + EXPECT_TRUE(pkt != NULL); + EXPECT_EQ(pkt->header_.get_ssrc(), track_factory.audio_ssrc_); + } + + // Receive a screen share packet again, to verify the hit cache track. + if (true) { + SrsUniquePtr test_pkt(new SrsRtpPacket()); + test_pkt->frame_type_ = SrsFrameTypeVideo; + test_pkt->header_.set_sequence(1001); + test_pkt->header_.set_timestamp(5001); + test_pkt->header_.set_ssrc(track_factory.screen_ssrc_); + + // Push packet to source - this will feed all consumers including the play stream's consumer + HELPER_EXPECT_SUCCESS(play_stream->source_->on_rtp(test_pkt.get())); + + // Wait for coroutine to process the packet + srs_usleep(1 * SRS_UTIME_MILLISECONDS); + + // Check sender should have received the packet + EXPECT_EQ(mock_sender.send_packet_count_, 6); + // Check NACK ring buffer. + SrsRtpPacket *pkt = play_stream->cache_track2_->rtp_queue_->at(1001); + EXPECT_TRUE(pkt != NULL); + EXPECT_EQ(pkt->header_.get_ssrc(), track_factory.screen_ssrc_); + } + // Stop the play stream play_stream->stop(); diff --git a/trunk/src/utest/srs_utest_rtc_playstream.hpp b/trunk/src/utest/srs_utest_rtc_playstream.hpp index 1a146c49d..cb2f3b611 100644 --- a/trunk/src/utest/srs_utest_rtc_playstream.hpp +++ b/trunk/src/utest/srs_utest_rtc_playstream.hpp @@ -8,32 +8,5 @@ #define SRS_UTEST_RTC_PLAYSTREAM_HPP #include -#include - -class SrsRtcTrackDescription; - -// Helper class to create mock track descriptions for testing -class MockRtcTrackDescriptionFactory -{ -public: - MockRtcTrackDescriptionFactory(); - virtual ~MockRtcTrackDescriptionFactory(); - -public: - // Default SSRCs for audio and video tracks - uint32_t audio_ssrc_; - uint32_t video_ssrc_; - uint32_t screen_ssrc_; - -public: - // Create a map of track descriptions with audio and video tracks - std::map create_audio_video_tracks(); - - // Create a single audio track description - SrsRtcTrackDescription *create_audio_track(uint32_t ssrc, std::string id, std::string mid); - - // Create a single video track description - SrsRtcTrackDescription *create_video_track(uint32_t ssrc, std::string id, std::string mid); -}; #endif