http://blog.csdn.net/lcalqf/article/details/59543410
版权声明:本文为博主原创文章,未经博主允许不得转载。
- /**
- * the time jitter algorithm:
- * 1. full, to ensure stream start at zero, and ensure stream monotonically increasing.
- * 2. zero, only ensure sttream start at zero, ignore timestamp jitter.
- * 3. off, disable the time jitter algorithm, like atc.
- */
- enum SrsRtmpJitterAlgorithm
- {
- SrsRtmpJitterAlgorithmFULL = 0x01,
- SrsRtmpJitterAlgorithmZERO,
- SrsRtmpJitterAlgorithmOFF
- };
- int _srs_time_jitter_string2int(std::string time_jitter);
- /**
- * time jitter detect and correct,
- * to ensure the rtmp stream is monotonically.
- */
- class SrsRtmpJitter
- {
- private:
- int64_t last_pkt_time;
- int64_t last_pkt_correct_time;
- public:
- SrsRtmpJitter();
- virtual ~SrsRtmpJitter();
- 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.
- */
- virtual int correct(SrsSharedPtrMessage* msg, int tba, int tbv, SrsRtmpJitterAlgorithm ag);
- /**
- * get current client time, the last packet time.
- */
- virtual int get_time();
- };
- #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.
- #define SRS_PURE_AUDIO_GUESS_COUNT 115
- // when got these videos or audios, pure audio or video, mix ok.
- #define SRS_MIX_CORRECT_PURE_AV 10
- // the time to cleanup source in ms.
- #define SRS_SOURCE_CLEANUP 30000
- int _srs_time_jitter_string2int(std::string time_jitter)
- {
- if (time_jitter == "full") {
- return SrsRtmpJitterAlgorithmFULL;
- } else if (time_jitter == "zero") {
- return SrsRtmpJitterAlgorithmZERO;
- } else {
- return SrsRtmpJitterAlgorithmOFF;
- }
- }
- SrsRtmpJitter::SrsRtmpJitter()
- {
- last_pkt_correct_time = -1;
- last_pkt_time = 0;
- }
- SrsRtmpJitter::~SrsRtmpJitter()
- {
- }
- int SrsRtmpJitter::correct(SrsSharedPtrMessage* msg, SrsRtmpJitterAlgorithm ag)
- {
- int ret = ERROR_SUCCESS;
- // for performance issue
- if (ag != SrsRtmpJitterAlgorithmFULL) {
- // all jitter correct features is disabled, ignore.
- if (ag == SrsRtmpJitterAlgorithmOFF) {
- return ret;
- }
- // start at zero, but donot ensure monotonically increasing.
- if (ag == SrsRtmpJitterAlgorithmZERO) {
- // 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;
- return ret;
- }
- // other algorithm, ignore.
- return ret;
- }
- // full jitter algorithm, do jitter correct.
- // set to 0 for metadata.
- if (!msg->is_av()) {
- msg->timestamp = 0;
- return ret;
- }
- /**
- * we use a very simple time jitter detect/correct algorithm:
- * 1. delta: ensure the delta is positive and valid,
- * we set the delta to DEFAULT_FRAME_TIME_MS,
- * if the delta of time is nagative or greater than CONST_MAX_JITTER_MS.
- * 2. last_pkt_time: specifies the original packet time,
- * is used to detect next jitter.
- * 3. last_pkt_correct_time: simply add the positive delta,
- * and enforce the time monotonically.
- */
- int64_t time = msg->timestamp;
- int64_t delta = time - last_pkt_time;
- // if jitter detected, reset the delta.
- 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/ossrs/srs/issues/425
- 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);
- } else {
- srs_verbose("timestamp no jitter. time=%"PRId64", last_pkt=%"PRId64", correct_to=%"PRId64"",
- time, last_pkt_time, last_pkt_correct_time + delta);
- }
- last_pkt_correct_time = srs_max(0, last_pkt_correct_time + delta);
- msg->timestamp = last_pkt_correct_time;
- last_pkt_time = time;
- return ret;
- }
- int SrsRtmpJitter::get_time()
- {
- return (int)last_pkt_correct_time;
- }