AI: Add utest to cover rtsp module.
This commit is contained in:
parent
809d77b662
commit
94dde8e370
|
|
@ -347,6 +347,14 @@ void SrsRtspPlayStream::set_all_tracks_status(bool status)
|
||||||
srs_trace("RTSP: Init tracks %s ok", merged_log.str().c_str());
|
srs_trace("RTSP: Init tracks %s ok", merged_log.str().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ISrsRtspConnection::ISrsRtspConnection()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ISrsRtspConnection::~ISrsRtspConnection()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
SrsRtspConnection::SrsRtspConnection(ISrsResourceManager *cm, ISrsProtocolReadWriter *skt, std::string cip, int port)
|
SrsRtspConnection::SrsRtspConnection(ISrsResourceManager *cm, ISrsProtocolReadWriter *skt, std::string cip, int port)
|
||||||
{
|
{
|
||||||
manager_ = cm;
|
manager_ = cm;
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,24 @@ public:
|
||||||
void set_all_tracks_status(bool status);
|
void set_all_tracks_status(bool status);
|
||||||
};
|
};
|
||||||
|
|
||||||
class SrsRtspConnection : public ISrsResource, public ISrsDisposingHandler, public ISrsExpire, public ISrsCoroutineHandler, public ISrsStartable
|
// The handler for RTSP connection send packet.
|
||||||
|
class ISrsRtspConnection
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ISrsRtspConnection();
|
||||||
|
virtual ~ISrsRtspConnection();
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual srs_error_t do_send_packet(SrsRtpPacket *pkt) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// A RTSP session, client request and response with RTSP.
|
||||||
|
class SrsRtspConnection : public ISrsResource, // It's a resource.
|
||||||
|
public ISrsDisposingHandler,
|
||||||
|
public ISrsExpire,
|
||||||
|
public ISrsCoroutineHandler,
|
||||||
|
public ISrsStartable,
|
||||||
|
public ISrsRtspConnection
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
bool disposing_;
|
bool disposing_;
|
||||||
|
|
|
||||||
|
|
@ -250,6 +250,9 @@ SrsRtspSource::SrsRtspSource()
|
||||||
req_ = NULL;
|
req_ = NULL;
|
||||||
|
|
||||||
stream_die_at_ = 0;
|
stream_die_at_ = 0;
|
||||||
|
|
||||||
|
stat_ = _srs_stat;
|
||||||
|
circuit_breaker_ = _srs_circuit_breaker;
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsRtspSource::~SrsRtspSource()
|
SrsRtspSource::~SrsRtspSource()
|
||||||
|
|
@ -266,6 +269,9 @@ SrsRtspSource::~SrsRtspSource()
|
||||||
if (cid.empty())
|
if (cid.empty())
|
||||||
cid = _pre_source_id;
|
cid = _pre_source_id;
|
||||||
srs_trace("free rtc source id=[%s]", cid.c_str());
|
srs_trace("free rtc source id=[%s]", cid.c_str());
|
||||||
|
|
||||||
|
stat_ = NULL;
|
||||||
|
circuit_breaker_ = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// CRITICAL: This method is called AFTER the source has been added to the source pool
|
// CRITICAL: This method is called AFTER the source has been added to the source pool
|
||||||
|
|
@ -437,8 +443,7 @@ srs_error_t SrsRtspSource::on_publish()
|
||||||
return srs_error_wrap(err, "source id change");
|
return srs_error_wrap(err, "source id change");
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsStatistic *stat = _srs_stat;
|
stat_->on_stream_publish(req_, _source_id.c_str());
|
||||||
stat->on_stream_publish(req_, _source_id.c_str());
|
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
@ -457,8 +462,7 @@ void SrsRtspSource::on_unpublish()
|
||||||
}
|
}
|
||||||
_source_id = SrsContextId();
|
_source_id = SrsContextId();
|
||||||
|
|
||||||
SrsStatistic *stat = _srs_stat;
|
stat_->on_stream_close(req_);
|
||||||
stat->on_stream_close(req_);
|
|
||||||
|
|
||||||
// Destroy and cleanup source when no publishers and consumers.
|
// Destroy and cleanup source when no publishers and consumers.
|
||||||
if (consumers_.empty()) {
|
if (consumers_.empty()) {
|
||||||
|
|
@ -475,7 +479,7 @@ srs_error_t SrsRtspSource::on_rtp(SrsRtpPacket *pkt)
|
||||||
srs_error_t err = srs_success;
|
srs_error_t err = srs_success;
|
||||||
|
|
||||||
// If circuit-breaker is dying, drop packet.
|
// If circuit-breaker is dying, drop packet.
|
||||||
if (_srs_circuit_breaker->hybrid_dying_water_level()) {
|
if (circuit_breaker_->hybrid_dying_water_level()) {
|
||||||
_srs_pps_aloss2->sugar_ += (int64_t)consumers_.size();
|
_srs_pps_aloss2->sugar_ += (int64_t)consumers_.size();
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
@ -531,6 +535,8 @@ SrsRtspRtpBuilder::SrsRtspRtpBuilder(ISrsRtpTarget *target, SrsSharedPtr<SrsRtsp
|
||||||
// Lazy initialization flags
|
// Lazy initialization flags
|
||||||
audio_initialized_ = false;
|
audio_initialized_ = false;
|
||||||
video_initialized_ = false;
|
video_initialized_ = false;
|
||||||
|
|
||||||
|
config_ = _srs_config;
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsRtspRtpBuilder::~SrsRtspRtpBuilder()
|
SrsRtspRtpBuilder::~SrsRtspRtpBuilder()
|
||||||
|
|
@ -538,6 +544,8 @@ SrsRtspRtpBuilder::~SrsRtspRtpBuilder()
|
||||||
srs_freep(format_);
|
srs_freep(format_);
|
||||||
srs_freep(meta_);
|
srs_freep(meta_);
|
||||||
srs_freep(video_builder_);
|
srs_freep(video_builder_);
|
||||||
|
|
||||||
|
config_ = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
srs_error_t SrsRtspRtpBuilder::initialize_audio_track(SrsAudioCodecId codec)
|
srs_error_t SrsRtspRtpBuilder::initialize_audio_track(SrsAudioCodecId codec)
|
||||||
|
|
@ -679,7 +687,7 @@ srs_error_t SrsRtspRtpBuilder::initialize(ISrsRequest *r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup the SPS/PPS parsing strategy.
|
// Setup the SPS/PPS parsing strategy.
|
||||||
format_->try_annexb_first_ = _srs_config->try_annexb_first(r->vhost_);
|
format_->try_annexb_first_ = config_->try_annexb_first(r->vhost_);
|
||||||
|
|
||||||
srs_trace("RTSP bridge from RTMP, try_annexb_first=%d", format_->try_annexb_first_);
|
srs_trace("RTSP bridge from RTMP, try_annexb_first=%d", format_->try_annexb_first_);
|
||||||
|
|
||||||
|
|
@ -997,7 +1005,7 @@ srs_error_t SrsRtspRtpBuilder::consume_packets(vector<SrsRtpPacket *> &pkts)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsRtspSendTrack::SrsRtspSendTrack(SrsRtspConnection *session, SrsRtcTrackDescription *track_desc, bool is_audio)
|
SrsRtspSendTrack::SrsRtspSendTrack(ISrsRtspConnection *session, SrsRtcTrackDescription *track_desc, bool is_audio)
|
||||||
{
|
{
|
||||||
session_ = session;
|
session_ = session;
|
||||||
track_desc_ = track_desc->copy();
|
track_desc_ = track_desc->copy();
|
||||||
|
|
@ -1031,7 +1039,7 @@ std::string SrsRtspSendTrack::get_track_id()
|
||||||
return track_desc_->id_;
|
return track_desc_->id_;
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsRtspAudioSendTrack::SrsRtspAudioSendTrack(SrsRtspConnection *session, SrsRtcTrackDescription *track_desc)
|
SrsRtspAudioSendTrack::SrsRtspAudioSendTrack(ISrsRtspConnection *session, SrsRtcTrackDescription *track_desc)
|
||||||
: SrsRtspSendTrack(session, track_desc, true)
|
: SrsRtspSendTrack(session, track_desc, true)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
@ -1071,7 +1079,7 @@ srs_error_t SrsRtspAudioSendTrack::on_rtp(SrsRtpPacket *pkt)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
SrsRtspVideoSendTrack::SrsRtspVideoSendTrack(SrsRtspConnection *session, SrsRtcTrackDescription *track_desc)
|
SrsRtspVideoSendTrack::SrsRtspVideoSendTrack(ISrsRtspConnection *session, SrsRtcTrackDescription *track_desc)
|
||||||
: SrsRtspSendTrack(session, track_desc, false)
|
: SrsRtspSendTrack(session, track_desc, false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,10 @@ class SrsRtcSourceDescription;
|
||||||
class SrsResourceManager;
|
class SrsResourceManager;
|
||||||
class SrsRtspConnection;
|
class SrsRtspConnection;
|
||||||
class SrsRtpVideoBuilder;
|
class SrsRtpVideoBuilder;
|
||||||
|
class ISrsStatistic;
|
||||||
|
class ISrsCircuitBreaker;
|
||||||
|
class ISrsAppConfig;
|
||||||
|
class ISrsRtspConnection;
|
||||||
|
|
||||||
// The RTSP stream consumer, consume packets from RTSP stream source.
|
// The RTSP stream consumer, consume packets from RTSP stream source.
|
||||||
class SrsRtspConsumer
|
class SrsRtspConsumer
|
||||||
|
|
@ -118,6 +122,10 @@ extern SrsResourceManager *_srs_rtsp_manager;
|
||||||
// A Source is a stream, to publish and to play with, binding to SrsRtspPlayStream.
|
// A Source is a stream, to publish and to play with, binding to SrsRtspPlayStream.
|
||||||
class SrsRtspSource : public ISrsRtpTarget
|
class SrsRtspSource : public ISrsRtpTarget
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
ISrsStatistic *stat_;
|
||||||
|
ISrsCircuitBreaker *circuit_breaker_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// For publish, it's the publish client id.
|
// For publish, it's the publish client id.
|
||||||
// For edge, it's the edge ingest id.
|
// For edge, it's the edge ingest id.
|
||||||
|
|
@ -201,6 +209,9 @@ public:
|
||||||
// Convert AV frame to RTSP RTP packets.
|
// Convert AV frame to RTSP RTP packets.
|
||||||
class SrsRtspRtpBuilder
|
class SrsRtspRtpBuilder
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
ISrsAppConfig *config_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ISrsRequest *req_;
|
ISrsRequest *req_;
|
||||||
ISrsRtpTarget *rtp_target_;
|
ISrsRtpTarget *rtp_target_;
|
||||||
|
|
@ -264,10 +275,10 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// The owner connection for this track.
|
// The owner connection for this track.
|
||||||
SrsRtspConnection *session_;
|
ISrsRtspConnection *session_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SrsRtspSendTrack(SrsRtspConnection *session, SrsRtcTrackDescription *track_desc, bool is_audio);
|
SrsRtspSendTrack(ISrsRtspConnection *session, SrsRtcTrackDescription *track_desc, bool is_audio);
|
||||||
virtual ~SrsRtspSendTrack();
|
virtual ~SrsRtspSendTrack();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -284,7 +295,7 @@ public:
|
||||||
class SrsRtspAudioSendTrack : public SrsRtspSendTrack
|
class SrsRtspAudioSendTrack : public SrsRtspSendTrack
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SrsRtspAudioSendTrack(SrsRtspConnection *session, SrsRtcTrackDescription *track_desc);
|
SrsRtspAudioSendTrack(ISrsRtspConnection *session, SrsRtcTrackDescription *track_desc);
|
||||||
virtual ~SrsRtspAudioSendTrack();
|
virtual ~SrsRtspAudioSendTrack();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -294,7 +305,7 @@ public:
|
||||||
class SrsRtspVideoSendTrack : public SrsRtspSendTrack
|
class SrsRtspVideoSendTrack : public SrsRtspSendTrack
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SrsRtspVideoSendTrack(SrsRtspConnection *session, SrsRtcTrackDescription *track_desc);
|
SrsRtspVideoSendTrack(ISrsRtspConnection *session, SrsRtcTrackDescription *track_desc);
|
||||||
virtual ~SrsRtspVideoSendTrack();
|
virtual ~SrsRtspVideoSendTrack();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
|
|
@ -531,7 +531,6 @@ srs_error_t SrsMpegtsSrtConn::do_playing()
|
||||||
|
|
||||||
srs_assert(consumer_raw);
|
srs_assert(consumer_raw);
|
||||||
SrsUniquePtr<ISrsSrtConsumer> consumer(consumer_raw);
|
SrsUniquePtr<ISrsSrtConsumer> consumer(consumer_raw);
|
||||||
SrsSrtConsumer *consumer_impl = dynamic_cast<SrsSrtConsumer *>(consumer_raw);
|
|
||||||
|
|
||||||
// TODO: FIXME: Dumps the SPS/PPS from gop cache, without other frames.
|
// TODO: FIXME: Dumps the SPS/PPS from gop cache, without other frames.
|
||||||
if ((err = srt_source_->consumer_dumps(consumer.get())) != srs_success) {
|
if ((err = srt_source_->consumer_dumps(consumer.get())) != srs_success) {
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -12,9 +12,10 @@
|
||||||
*/
|
*/
|
||||||
#include <srs_utest.hpp>
|
#include <srs_utest.hpp>
|
||||||
|
|
||||||
#include <srs_utest_app6.hpp>
|
#include <srs_app_rtsp_conn.hpp>
|
||||||
#include <srs_app_stream_bridge.hpp>
|
#include <srs_app_stream_bridge.hpp>
|
||||||
#include <srs_protocol_rtmp_stack.hpp>
|
#include <srs_protocol_rtmp_stack.hpp>
|
||||||
|
#include <srs_utest_app6.hpp>
|
||||||
|
|
||||||
// Mock frame target for testing SrsSrtFrameBuilder
|
// Mock frame target for testing SrsSrtFrameBuilder
|
||||||
class MockSrtFrameTarget : public ISrsFrameTarget
|
class MockSrtFrameTarget : public ISrsFrameTarget
|
||||||
|
|
@ -107,5 +108,52 @@ public:
|
||||||
void reset();
|
void reset();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
// Forward declaration
|
||||||
|
class SrsRtspConsumer;
|
||||||
|
|
||||||
|
// Mock RTSP source for testing SrsRtspConsumer
|
||||||
|
class MockRtspSource
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int on_consumer_destroy_count_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
MockRtspSource();
|
||||||
|
virtual ~MockRtspSource();
|
||||||
|
void on_consumer_destroy(SrsRtspConsumer *consumer);
|
||||||
|
void reset();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Mock RTP target for testing SrsRtspRtpBuilder
|
||||||
|
class MockRtspRtpTarget : public ISrsRtpTarget
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int on_rtp_count_;
|
||||||
|
SrsRtpPacket *last_rtp_;
|
||||||
|
srs_error_t rtp_error_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
MockRtspRtpTarget();
|
||||||
|
virtual ~MockRtspRtpTarget();
|
||||||
|
virtual srs_error_t on_rtp(SrsRtpPacket *pkt);
|
||||||
|
void set_rtp_error(srs_error_t err);
|
||||||
|
void reset();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Mock RTSP connection for testing SrsRtspSendTrack
|
||||||
|
class MockRtspConnection : public ISrsRtspConnection
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int do_send_packet_count_;
|
||||||
|
SrsRtpPacket *last_packet_;
|
||||||
|
srs_error_t send_error_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
MockRtspConnection();
|
||||||
|
virtual ~MockRtspConnection();
|
||||||
|
virtual srs_error_t do_send_packet(SrsRtpPacket *pkt);
|
||||||
|
void set_send_error(srs_error_t err);
|
||||||
|
void reset();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user