mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
fix #425, refine the time jitter, correct (-inf,-250)+(250,+inf) to 10ms. 2.0.175
This commit is contained in:
parent
6941f2c072
commit
56938efdbd
9 changed files with 71 additions and 106 deletions
|
@ -344,6 +344,7 @@ Remark:
|
|||
|
||||
### SRS 2.0 history
|
||||
|
||||
* v2.0, 2015-06-10, fix [#425](https://github.com/simple-rtmp-server/srs/issues/425) refine the time jitter, correct (-inf,-250)+(250,+inf) to 10ms. 2.0.175
|
||||
* v2.0, 2015-06-10, fix [#424](https://github.com/simple-rtmp-server/srs/issues/424) fix aggregate timestamp bug. 2.0.174
|
||||
* v2.0, 2015-06-06, fix [#421](https://github.com/simple-rtmp-server/srs/issues/421) drop video for unkown RTMP header.
|
||||
* v2.0, 2015-06-05, fix [#420](https://github.com/simple-rtmp-server/srs/issues/420) remove ts for hls ram mode.
|
||||
|
|
|
@ -273,7 +273,7 @@ int SrsFlvSegment::write_audio(SrsSharedPtrMessage* shared_audio)
|
|||
SrsSharedPtrMessage* audio = shared_audio->copy();
|
||||
SrsAutoFree(SrsSharedPtrMessage, audio);
|
||||
|
||||
if ((jitter->correct(audio, 0, 0, jitter_algorithm)) != ERROR_SUCCESS) {
|
||||
if ((jitter->correct(audio, jitter_algorithm)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -324,7 +324,7 @@ int SrsFlvSegment::write_video(SrsSharedPtrMessage* shared_video)
|
|||
}
|
||||
}
|
||||
|
||||
if ((jitter->correct(video, 0, 0, jitter_algorithm)) != ERROR_SUCCESS) {
|
||||
if ((jitter->correct(video, jitter_algorithm)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -334,7 +334,7 @@ int SrsFlvSegment::write_video(SrsSharedPtrMessage* shared_video)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int32_t timestamp = plan->filter_timestamp(video->timestamp);
|
||||
int32_t timestamp = (int32_t)plan->filter_timestamp(video->timestamp);
|
||||
if ((ret = enc->write_video(timestamp, payload, size)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -163,7 +163,8 @@ int SrsForwarder::on_meta_data(SrsSharedPtrMessage* shared_metadata)
|
|||
|
||||
SrsSharedPtrMessage* metadata = shared_metadata->copy();
|
||||
|
||||
if ((ret = jitter->correct(metadata, 0, 0, SrsRtmpJitterAlgorithmFULL)) != ERROR_SUCCESS) {
|
||||
// TODO: FIXME: config the jitter of Forwarder.
|
||||
if ((ret = jitter->correct(metadata, SrsRtmpJitterAlgorithmFULL)) != ERROR_SUCCESS) {
|
||||
srs_freep(metadata);
|
||||
return ret;
|
||||
}
|
||||
|
@ -181,7 +182,8 @@ int SrsForwarder::on_audio(SrsSharedPtrMessage* shared_audio)
|
|||
|
||||
SrsSharedPtrMessage* msg = shared_audio->copy();
|
||||
|
||||
if ((ret = jitter->correct(msg, 0, 0, SrsRtmpJitterAlgorithmFULL)) != ERROR_SUCCESS) {
|
||||
// TODO: FIXME: config the jitter of Forwarder.
|
||||
if ((ret = jitter->correct(msg, SrsRtmpJitterAlgorithmFULL)) != ERROR_SUCCESS) {
|
||||
srs_freep(msg);
|
||||
return ret;
|
||||
}
|
||||
|
@ -204,7 +206,8 @@ int SrsForwarder::on_video(SrsSharedPtrMessage* shared_video)
|
|||
|
||||
SrsSharedPtrMessage* msg = shared_video->copy();
|
||||
|
||||
if ((ret = jitter->correct(msg, 0, 0, SrsRtmpJitterAlgorithmFULL)) != ERROR_SUCCESS) {
|
||||
// TODO: FIXME: config the jitter of Forwarder.
|
||||
if ((ret = jitter->correct(msg, SrsRtmpJitterAlgorithmFULL)) != ERROR_SUCCESS) {
|
||||
srs_freep(msg);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -1337,7 +1337,8 @@ int SrsHls::on_audio(SrsSharedPtrMessage* shared_audio)
|
|||
return hls_cache->on_sequence_header(muxer);
|
||||
}
|
||||
|
||||
if ((ret = jitter->correct(audio, 0, 0, SrsRtmpJitterAlgorithmFULL)) != ERROR_SUCCESS) {
|
||||
// TODO: FIXME: config the jitter of HLS.
|
||||
if ((ret = jitter->correct(audio, SrsRtmpJitterAlgorithmFULL)) != ERROR_SUCCESS) {
|
||||
srs_error("rtmp jitter correct audio failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1394,7 +1395,8 @@ int SrsHls::on_video(SrsSharedPtrMessage* shared_video)
|
|||
return hls_cache->on_sequence_header(muxer);
|
||||
}
|
||||
|
||||
if ((ret = jitter->correct(video, 0, 0, SrsRtmpJitterAlgorithmFULL)) != ERROR_SUCCESS) {
|
||||
// TODO: FIXME: config the jitter of HLS.
|
||||
if ((ret = jitter->correct(video, SrsRtmpJitterAlgorithmFULL)) != ERROR_SUCCESS) {
|
||||
srs_error("rtmp jitter correct video failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -1265,7 +1265,7 @@ int SrsStreamCache::start()
|
|||
return pthread->start();
|
||||
}
|
||||
|
||||
int SrsStreamCache::dump_cache(SrsConsumer* consumer)
|
||||
int SrsStreamCache::dump_cache(SrsConsumer* consumer, SrsRtmpJitterAlgorithm jitter)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
|
@ -1276,8 +1276,8 @@ int SrsStreamCache::dump_cache(SrsConsumer* consumer)
|
|||
return ret;
|
||||
}
|
||||
|
||||
// TODO: FIXME: config it.
|
||||
if ((ret = queue->dump_packets(consumer, false, 0, 0, SrsRtmpJitterAlgorithmOFF)) != ERROR_SUCCESS) {
|
||||
// the jitter is get from SrsSource, which means the time_jitter of vhost.
|
||||
if ((ret = queue->dump_packets(consumer, false, jitter)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -1398,7 +1398,7 @@ bool SrsTsStreamEncoder::has_cache()
|
|||
return false;
|
||||
}
|
||||
|
||||
int SrsTsStreamEncoder::dump_cache(SrsConsumer* /*consumer*/)
|
||||
int SrsTsStreamEncoder::dump_cache(SrsConsumer* /*consumer*/, SrsRtmpJitterAlgorithm /*jitter*/)
|
||||
{
|
||||
// for ts stream, ignore cache.
|
||||
return ERROR_SUCCESS;
|
||||
|
@ -1451,7 +1451,7 @@ bool SrsFlvStreamEncoder::has_cache()
|
|||
return false;
|
||||
}
|
||||
|
||||
int SrsFlvStreamEncoder::dump_cache(SrsConsumer* /*consumer*/)
|
||||
int SrsFlvStreamEncoder::dump_cache(SrsConsumer* /*consumer*/, SrsRtmpJitterAlgorithm /*jitter*/)
|
||||
{
|
||||
// for flv stream, ignore cache.
|
||||
return ERROR_SUCCESS;
|
||||
|
@ -1518,10 +1518,10 @@ bool SrsAacStreamEncoder::has_cache()
|
|||
return true;
|
||||
}
|
||||
|
||||
int SrsAacStreamEncoder::dump_cache(SrsConsumer* consumer)
|
||||
int SrsAacStreamEncoder::dump_cache(SrsConsumer* consumer, SrsRtmpJitterAlgorithm jitter)
|
||||
{
|
||||
srs_assert(cache);
|
||||
return cache->dump_cache(consumer);
|
||||
return cache->dump_cache(consumer, jitter);
|
||||
}
|
||||
|
||||
SrsMp3StreamEncoder::SrsMp3StreamEncoder()
|
||||
|
@ -1574,10 +1574,10 @@ bool SrsMp3StreamEncoder::has_cache()
|
|||
return true;
|
||||
}
|
||||
|
||||
int SrsMp3StreamEncoder::dump_cache(SrsConsumer* consumer)
|
||||
int SrsMp3StreamEncoder::dump_cache(SrsConsumer* consumer, SrsRtmpJitterAlgorithm jitter)
|
||||
{
|
||||
srs_assert(cache);
|
||||
return cache->dump_cache(consumer);
|
||||
return cache->dump_cache(consumer, jitter);
|
||||
}
|
||||
|
||||
SrsStreamWriter::SrsStreamWriter(ISrsHttpResponseWriter* w)
|
||||
|
@ -1686,7 +1686,7 @@ int SrsLiveStream::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r)
|
|||
|
||||
// if gop cache enabled for encoder, dump to consumer.
|
||||
if (enc->has_cache()) {
|
||||
if ((ret = enc->dump_cache(consumer)) != ERROR_SUCCESS) {
|
||||
if ((ret = enc->dump_cache(consumer, source->jitter())) != ERROR_SUCCESS) {
|
||||
srs_error("http: dump cache to consumer failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
#include <srs_kernel_file.hpp>
|
||||
#include <srs_app_thread.hpp>
|
||||
#include <srs_app_conn.hpp>
|
||||
#include <srs_app_source.hpp>
|
||||
|
||||
class SrsServer;
|
||||
class SrsSource;
|
||||
|
@ -407,7 +408,7 @@ public:
|
|||
virtual ~SrsStreamCache();
|
||||
public:
|
||||
virtual int start();
|
||||
virtual int dump_cache(SrsConsumer* consumer);
|
||||
virtual int dump_cache(SrsConsumer* consumer, SrsRtmpJitterAlgorithm jitter);
|
||||
// interface ISrsEndlessThreadHandler.
|
||||
public:
|
||||
virtual int cycle();
|
||||
|
@ -444,7 +445,7 @@ public:
|
|||
/**
|
||||
* dumps the cache of encoder to consumer.
|
||||
*/
|
||||
virtual int dump_cache(SrsConsumer* consumer) = 0;
|
||||
virtual int dump_cache(SrsConsumer* consumer, SrsRtmpJitterAlgorithm jitter) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -464,7 +465,7 @@ public:
|
|||
virtual int write_metadata(int64_t timestamp, char* data, int size);
|
||||
public:
|
||||
virtual bool has_cache();
|
||||
virtual int dump_cache(SrsConsumer* consumer);
|
||||
virtual int dump_cache(SrsConsumer* consumer, SrsRtmpJitterAlgorithm jitter);
|
||||
};
|
||||
|
||||
#ifdef SRS_PERF_FAST_FLV_ENCODER
|
||||
|
@ -502,7 +503,7 @@ public:
|
|||
virtual int write_metadata(int64_t timestamp, char* data, int size);
|
||||
public:
|
||||
virtual bool has_cache();
|
||||
virtual int dump_cache(SrsConsumer* consumer);
|
||||
virtual int dump_cache(SrsConsumer* consumer, SrsRtmpJitterAlgorithm jitter);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -523,7 +524,7 @@ public:
|
|||
virtual int write_metadata(int64_t timestamp, char* data, int size);
|
||||
public:
|
||||
virtual bool has_cache();
|
||||
virtual int dump_cache(SrsConsumer* consumer);
|
||||
virtual int dump_cache(SrsConsumer* consumer, SrsRtmpJitterAlgorithm jitter);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -544,7 +545,7 @@ public:
|
|||
virtual int write_metadata(int64_t timestamp, char* data, int size);
|
||||
public:
|
||||
virtual bool has_cache();
|
||||
virtual int dump_cache(SrsConsumer* consumer);
|
||||
virtual int dump_cache(SrsConsumer* consumer, SrsRtmpJitterAlgorithm jitter);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -47,8 +47,9 @@ using namespace std;
|
|||
#include <srs_core_autofree.hpp>
|
||||
#include <srs_rtmp_utility.hpp>
|
||||
|
||||
#define CONST_MAX_JITTER_MS 500
|
||||
#define DEFAULT_FRAME_TIME_MS 40
|
||||
#define CONST_MAX_JITTER_MS 250
|
||||
#define CONST_MAX_JITTER_MS_NEG -250
|
||||
#define DEFAULT_FRAME_TIME_MS 10
|
||||
|
||||
// for 26ms per audio packet,
|
||||
// 115 packets is 3s.
|
||||
|
@ -70,14 +71,15 @@ int _srs_time_jitter_string2int(std::string time_jitter)
|
|||
|
||||
SrsRtmpJitter::SrsRtmpJitter()
|
||||
{
|
||||
last_pkt_correct_time = last_pkt_time = 0;
|
||||
last_pkt_correct_time = -1;
|
||||
last_pkt_time = 0;
|
||||
}
|
||||
|
||||
SrsRtmpJitter::~SrsRtmpJitter()
|
||||
{
|
||||
}
|
||||
|
||||
int SrsRtmpJitter::correct(SrsSharedPtrMessage* msg, int tba, int tbv, SrsRtmpJitterAlgorithm ag)
|
||||
int SrsRtmpJitter::correct(SrsSharedPtrMessage* msg, SrsRtmpJitterAlgorithm ag)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
|
@ -90,9 +92,8 @@ int SrsRtmpJitter::correct(SrsSharedPtrMessage* msg, int tba, int tbv, SrsRtmpJi
|
|||
|
||||
// start at zero, but donot ensure monotonically increasing.
|
||||
if (ag == SrsRtmpJitterAlgorithmZERO) {
|
||||
// for the first time, last_pkt_correct_time is zero.
|
||||
// while when timestamp overflow, the timestamp become smaller, reset the last_pkt_correct_time.
|
||||
if (last_pkt_correct_time <= 0 || msg->timestamp < last_pkt_correct_time) {
|
||||
// for the first time, last_pkt_correct_time is -1.
|
||||
if (last_pkt_correct_time == -1) {
|
||||
last_pkt_correct_time = msg->timestamp;
|
||||
}
|
||||
msg->timestamp -= last_pkt_correct_time;
|
||||
|
@ -104,16 +105,12 @@ int SrsRtmpJitter::correct(SrsSharedPtrMessage* msg, int tba, int tbv, SrsRtmpJi
|
|||
}
|
||||
|
||||
// full jitter algorithm, do jitter correct.
|
||||
|
||||
// set to 0 for metadata.
|
||||
if (!msg->is_av()) {
|
||||
msg->timestamp = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int sample_rate = tba;
|
||||
int frame_rate = tbv;
|
||||
|
||||
/**
|
||||
* we use a very simple time jitter detect/correct algorithm:
|
||||
* 1. delta: ensure the delta is positive and valid,
|
||||
|
@ -128,20 +125,10 @@ int SrsRtmpJitter::correct(SrsSharedPtrMessage* msg, int tba, int tbv, SrsRtmpJi
|
|||
int64_t delta = time - last_pkt_time;
|
||||
|
||||
// if jitter detected, reset the delta.
|
||||
if (delta < 0 || delta > CONST_MAX_JITTER_MS) {
|
||||
// calc the right diff by audio sample rate
|
||||
if (msg->is_audio() && sample_rate > 0) {
|
||||
delta = (int64_t)(delta * 1000.0 / sample_rate);
|
||||
} else if (msg->is_video() && frame_rate > 0) {
|
||||
delta = (int64_t)(delta * 1.0 / frame_rate);
|
||||
} else {
|
||||
if (delta < CONST_MAX_JITTER_MS_NEG || delta > CONST_MAX_JITTER_MS) {
|
||||
// use default 10ms to notice the problem of stream.
|
||||
// @see https://github.com/simple-rtmp-server/srs/issues/425
|
||||
delta = DEFAULT_FRAME_TIME_MS;
|
||||
}
|
||||
|
||||
// sometimes, the time is absolute time, so correct it again.
|
||||
if (delta < 0 || delta > CONST_MAX_JITTER_MS) {
|
||||
delta = DEFAULT_FRAME_TIME_MS;
|
||||
}
|
||||
|
||||
srs_info("jitter detected, last_pts=%"PRId64", pts=%"PRId64", diff=%"PRId64", last_time=%"PRId64", time=%"PRId64", diff=%"PRId64"",
|
||||
last_pkt_time, time, time - last_pkt_time, last_pkt_correct_time, last_pkt_correct_time + delta, delta);
|
||||
|
@ -338,7 +325,7 @@ int SrsMessageQueue::dump_packets(int max_count, SrsSharedPtrMessage** pmsgs, in
|
|||
return ret;
|
||||
}
|
||||
|
||||
int SrsMessageQueue::dump_packets(SrsConsumer* consumer, bool atc, int tba, int tbv, SrsRtmpJitterAlgorithm ag)
|
||||
int SrsMessageQueue::dump_packets(SrsConsumer* consumer, bool atc, SrsRtmpJitterAlgorithm ag)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
|
@ -350,7 +337,7 @@ int SrsMessageQueue::dump_packets(SrsConsumer* consumer, bool atc, int tba, int
|
|||
SrsSharedPtrMessage** omsgs = msgs.data();
|
||||
for (int i = 0; i < nb_msgs; i++) {
|
||||
SrsSharedPtrMessage* msg = omsgs[i];
|
||||
if ((ret = consumer->enqueue(msg, atc, tba, tbv, ag)) != ERROR_SUCCESS) {
|
||||
if ((ret = consumer->enqueue(msg, atc, ag)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
@ -473,14 +460,14 @@ int SrsConsumer::get_time()
|
|||
return jitter->get_time();
|
||||
}
|
||||
|
||||
int SrsConsumer::enqueue(SrsSharedPtrMessage* shared_msg, bool atc, int tba, int tbv, SrsRtmpJitterAlgorithm ag)
|
||||
int SrsConsumer::enqueue(SrsSharedPtrMessage* shared_msg, bool atc, SrsRtmpJitterAlgorithm ag)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
SrsSharedPtrMessage* msg = shared_msg->copy();
|
||||
|
||||
if (!atc) {
|
||||
if ((ret = jitter->correct(msg, tba, tbv, ag)) != ERROR_SUCCESS) {
|
||||
if ((ret = jitter->correct(msg, ag)) != ERROR_SUCCESS) {
|
||||
srs_freep(msg);
|
||||
return ret;
|
||||
}
|
||||
|
@ -683,14 +670,14 @@ void SrsGopCache::clear()
|
|||
audio_after_last_video_count = 0;
|
||||
}
|
||||
|
||||
int SrsGopCache::dump(SrsConsumer* consumer, bool atc, int tba, int tbv, SrsRtmpJitterAlgorithm jitter_algorithm)
|
||||
int SrsGopCache::dump(SrsConsumer* consumer, bool atc, SrsRtmpJitterAlgorithm jitter_algorithm)
|
||||
{
|
||||
int ret = ERROR_SUCCESS;
|
||||
|
||||
std::vector<SrsSharedPtrMessage*>::iterator it;
|
||||
for (it = gop_cache.begin(); it != gop_cache.end(); ++it) {
|
||||
SrsSharedPtrMessage* msg = *it;
|
||||
if ((ret = consumer->enqueue(msg, atc, tba, tbv, jitter_algorithm)) != ERROR_SUCCESS) {
|
||||
if ((ret = consumer->enqueue(msg, atc, jitter_algorithm)) != ERROR_SUCCESS) {
|
||||
srs_error("dispatch cached gop failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -906,7 +893,6 @@ SrsSource::SrsSource()
|
|||
|
||||
cache_metadata = cache_sh_video = cache_sh_audio = NULL;
|
||||
|
||||
frame_rate = sample_rate = 0;
|
||||
_can_publish = true;
|
||||
_source_id = -1;
|
||||
|
||||
|
@ -1413,17 +1399,6 @@ int SrsSource::on_meta_data(SrsCommonMessage* msg, SrsOnMetaDataPacket* metadata
|
|||
// add version to metadata, please donot remove it, for debug.
|
||||
metadata->metadata->set("server_version", SrsAmf0Any::str(RTMP_SIG_SRS_VERSION));
|
||||
|
||||
if ((prop = metadata->metadata->get_property("audiosamplerate")) != NULL) {
|
||||
if (prop->is_number()) {
|
||||
sample_rate = (int)prop->to_number();
|
||||
}
|
||||
}
|
||||
if ((prop = metadata->metadata->get_property("framerate")) != NULL) {
|
||||
if (prop->is_number()) {
|
||||
frame_rate = (int)prop->to_number();
|
||||
}
|
||||
}
|
||||
|
||||
// if allow atc_auto and bravo-atc detected, open atc for vhost.
|
||||
atc = _srs_config->get_atc(_req->vhost);
|
||||
if (_srs_config->get_atc_auto(_req->vhost)) {
|
||||
|
@ -1466,7 +1441,7 @@ int SrsSource::on_meta_data(SrsCommonMessage* msg, SrsOnMetaDataPacket* metadata
|
|||
std::vector<SrsConsumer*>::iterator it;
|
||||
for (it = consumers.begin(); it != consumers.end(); ++it) {
|
||||
SrsConsumer* consumer = *it;
|
||||
if ((ret = consumer->enqueue(cache_metadata, atc, sample_rate, frame_rate, jitter_algorithm)) != ERROR_SUCCESS) {
|
||||
if ((ret = consumer->enqueue(cache_metadata, atc, jitter_algorithm)) != ERROR_SUCCESS) {
|
||||
srs_error("dispatch the metadata failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1600,7 +1575,7 @@ int SrsSource::on_audio_imp(SrsSharedPtrMessage* msg)
|
|||
SrsConsumer** pconsumer = consumers.data();
|
||||
for (int i = 0; i < nb_consumers; i++) {
|
||||
SrsConsumer* consumer = pconsumer[i];
|
||||
if ((ret = consumer->enqueue(msg, atc, sample_rate, frame_rate, jitter_algorithm)) != ERROR_SUCCESS) {
|
||||
if ((ret = consumer->enqueue(msg, atc, jitter_algorithm)) != ERROR_SUCCESS) {
|
||||
srs_error("dispatch the audio failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1802,7 +1777,7 @@ int SrsSource::on_video_imp(SrsSharedPtrMessage* msg)
|
|||
if (true) {
|
||||
for (int i = 0; i < (int)consumers.size(); i++) {
|
||||
SrsConsumer* consumer = consumers.at(i);
|
||||
if ((ret = consumer->enqueue(msg, atc, sample_rate, frame_rate, jitter_algorithm)) != ERROR_SUCCESS) {
|
||||
if ((ret = consumer->enqueue(msg, atc, jitter_algorithm)) != ERROR_SUCCESS) {
|
||||
srs_error("dispatch the video failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -2091,8 +2066,6 @@ void SrsSource::on_unpublish()
|
|||
gop_cache->clear();
|
||||
|
||||
srs_freep(cache_metadata);
|
||||
frame_rate = sample_rate = 0;
|
||||
|
||||
srs_freep(cache_sh_video);
|
||||
srs_freep(cache_sh_audio);
|
||||
|
||||
|
@ -2132,12 +2105,8 @@ int SrsSource::create_consumer(SrsConsumer*& consumer, bool ds, bool dm, bool dg
|
|||
}
|
||||
}
|
||||
|
||||
int tba = sample_rate;
|
||||
int tbv = frame_rate;
|
||||
SrsRtmpJitterAlgorithm ag = jitter_algorithm;
|
||||
|
||||
// copy metadata.
|
||||
if (dm && cache_metadata && (ret = consumer->enqueue(cache_metadata, atc, tba, tbv, ag)) != ERROR_SUCCESS) {
|
||||
if (dm && cache_metadata && (ret = consumer->enqueue(cache_metadata, atc, jitter_algorithm)) != ERROR_SUCCESS) {
|
||||
srs_error("dispatch metadata failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -2146,28 +2115,28 @@ int SrsSource::create_consumer(SrsConsumer*& consumer, bool ds, bool dm, bool dg
|
|||
// copy sequence header
|
||||
// copy audio sequence first, for hls to fast parse the "right" audio codec.
|
||||
// @see https://github.com/simple-rtmp-server/srs/issues/301
|
||||
if (ds && cache_sh_audio && (ret = consumer->enqueue(cache_sh_audio, atc, tba, tbv, ag)) != ERROR_SUCCESS) {
|
||||
if (ds && cache_sh_audio && (ret = consumer->enqueue(cache_sh_audio, atc, jitter_algorithm)) != ERROR_SUCCESS) {
|
||||
srs_error("dispatch audio sequence header failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
srs_info("dispatch audio sequence header success");
|
||||
|
||||
if (ds && cache_sh_video && (ret = consumer->enqueue(cache_sh_video, atc, tba, tbv, ag)) != ERROR_SUCCESS) {
|
||||
if (ds && cache_sh_video && (ret = consumer->enqueue(cache_sh_video, atc, jitter_algorithm)) != ERROR_SUCCESS) {
|
||||
srs_error("dispatch video sequence header failed. ret=%d", ret);
|
||||
return ret;
|
||||
}
|
||||
srs_info("dispatch video sequence header success");
|
||||
|
||||
// copy gop cache to client.
|
||||
if (dg && (ret = gop_cache->dump(consumer, atc, tba, tbv, ag)) != ERROR_SUCCESS) {
|
||||
if (dg && (ret = gop_cache->dump(consumer, atc, jitter_algorithm)) != ERROR_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// print status.
|
||||
if (dg) {
|
||||
srs_trace("create consumer, queue_size=%.2f, tba=%d, tbv=%d", queue_size, sample_rate, frame_rate);
|
||||
srs_trace("create consumer, queue_size=%.2f, jitter=%d", queue_size, jitter_algorithm);
|
||||
} else {
|
||||
srs_trace("create consumer, ignore gop cache, tba=%d, tbv=%d", sample_rate, frame_rate);
|
||||
srs_trace("create consumer, ignore gop cache, jitter=%d", jitter_algorithm);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -2192,6 +2161,11 @@ void SrsSource::set_cache(bool enabled)
|
|||
gop_cache->set(enabled);
|
||||
}
|
||||
|
||||
SrsRtmpJitterAlgorithm SrsSource::jitter()
|
||||
{
|
||||
return jitter_algorithm;
|
||||
}
|
||||
|
||||
int SrsSource::on_edge_start_play()
|
||||
{
|
||||
return play_edge->on_client_play();
|
||||
|
|
|
@ -95,12 +95,9 @@ public:
|
|||
public:
|
||||
/**
|
||||
* detect the time jitter and correct it.
|
||||
* @param tba, the audio timebase, used to calc the "right" delta if jitter detected.
|
||||
* @param tbv, the video timebase, used to calc the "right" delta if jitter detected.
|
||||
* @param start_at_zero whether ensure stream start at zero.
|
||||
* @param mono_increasing whether ensure stream is monotonically inscreasing.
|
||||
* @param ag the algorithm to use for time jitter.
|
||||
*/
|
||||
virtual int correct(SrsSharedPtrMessage* msg, int tba, int tbv, SrsRtmpJitterAlgorithm ag);
|
||||
virtual int correct(SrsSharedPtrMessage* msg, SrsRtmpJitterAlgorithm ag);
|
||||
/**
|
||||
* get current client time, the last packet time.
|
||||
*/
|
||||
|
@ -186,7 +183,7 @@ public:
|
|||
* dumps packets to consumer, use specified args.
|
||||
* @remark the atc/tba/tbv/ag are same to SrsConsumer.enqueue().
|
||||
*/
|
||||
virtual int dump_packets(SrsConsumer* consumer, bool atc, int tba, int tbv, SrsRtmpJitterAlgorithm ag);
|
||||
virtual int dump_packets(SrsConsumer* consumer, bool atc, SrsRtmpJitterAlgorithm ag);
|
||||
private:
|
||||
/**
|
||||
* remove a gop from the front.
|
||||
|
@ -255,13 +252,9 @@ public:
|
|||
* enqueue an shared ptr message.
|
||||
* @param shared_msg, directly ptr, copy it if need to save it.
|
||||
* @param whether atc, donot use jitter correct if true.
|
||||
* @param tba timebase of audio.
|
||||
* used to calc the audio time delta if time-jitter detected.
|
||||
* @param tbv timebase of video.
|
||||
* used to calc the video time delta if time-jitter detected.
|
||||
* @param ag the algorithm of time jitter.
|
||||
*/
|
||||
virtual int enqueue(SrsSharedPtrMessage* shared_msg, bool atc, int tba, int tbv, SrsRtmpJitterAlgorithm ag);
|
||||
virtual int enqueue(SrsSharedPtrMessage* shared_msg, bool atc, SrsRtmpJitterAlgorithm ag);
|
||||
/**
|
||||
* get packets in consumer queue.
|
||||
* @param msgs the msgs array to dump packets to send.
|
||||
|
@ -351,9 +344,7 @@ public:
|
|||
/**
|
||||
* dump the cached gop to consumer.
|
||||
*/
|
||||
virtual int dump(SrsConsumer* consumer,
|
||||
bool atc, int tba, int tbv, SrsRtmpJitterAlgorithm jitter_algorithm
|
||||
);
|
||||
virtual int dump(SrsConsumer* consumer, bool atc, SrsRtmpJitterAlgorithm jitter_algorithm);
|
||||
/**
|
||||
* used for atc to get the time of gop cache,
|
||||
* the atc will adjust the sequence header timestamp to gop cache.
|
||||
|
@ -491,14 +482,6 @@ private:
|
|||
// the event handler.
|
||||
ISrsSourceHandler* handler;
|
||||
private:
|
||||
/**
|
||||
* the sample rate of audio in metadata.
|
||||
*/
|
||||
int sample_rate;
|
||||
/**
|
||||
* the video frame rate in metadata.
|
||||
*/
|
||||
int frame_rate;
|
||||
/**
|
||||
* can publish, true when is not streaming
|
||||
*/
|
||||
|
@ -595,6 +578,7 @@ public:
|
|||
);
|
||||
virtual void on_consumer_destroy(SrsConsumer* consumer);
|
||||
virtual void set_cache(bool enabled);
|
||||
virtual SrsRtmpJitterAlgorithm jitter();
|
||||
// internal
|
||||
public:
|
||||
// for edge, when play edge stream, check the state
|
||||
|
|
|
@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
// current release version
|
||||
#define VERSION_MAJOR 2
|
||||
#define VERSION_MINOR 0
|
||||
#define VERSION_REVISION 174
|
||||
#define VERSION_REVISION 175
|
||||
|
||||
// server info.
|
||||
#define RTMP_SIG_SRS_KEY "SRS"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue