winlin

fix #108: disable the time jitter for encoder non-monotonical stream. 0.9.133

@@ -241,6 +241,7 @@ Supported operating systems and hardware: @@ -241,6 +241,7 @@ Supported operating systems and hardware:
241 * 2013-10-17, Created.<br/> 241 * 2013-10-17, Created.<br/>
242 242
243 ## History 243 ## History
  244 +* v1.0, 2014-06-25, fix [#108](https://github.com/winlinvip/simple-rtmp-server/issues/108), disable the time jitter for encoder non-monotonical stream. 0.9.133
244 * v1.0, 2014-06-23, support report summaries in heartbeat. 0.9.132 245 * v1.0, 2014-06-23, support report summaries in heartbeat. 0.9.132
245 * v1.0, 2014-06-22, performance refine, support [3k+](https://github.com/winlinvip/simple-rtmp-server/wiki/Performance#%E6%80%A7%E8%83%BD%E4%BE%8B%E8%A1%8C%E6%8A%A5%E5%91%8A4k) connections(270kbps). 0.9.130 246 * v1.0, 2014-06-22, performance refine, support [3k+](https://github.com/winlinvip/simple-rtmp-server/wiki/Performance#%E6%80%A7%E8%83%BD%E4%BE%8B%E8%A1%8C%E6%8A%A5%E5%91%8A4k) connections(270kbps). 0.9.130
246 * v1.0, 2014-06-21, support edge [token traverse](https://github.com/winlinvip/simple-rtmp-server/wiki/DRM#tokentraverse), fix [#104](https://github.com/winlinvip/simple-rtmp-server/issues/104). 0.9.129 247 * v1.0, 2014-06-21, support edge [token traverse](https://github.com/winlinvip/simple-rtmp-server/wiki/DRM#tokentraverse), fix [#104](https://github.com/winlinvip/simple-rtmp-server/issues/104). 0.9.129
@@ -187,6 +187,18 @@ vhost dvr.srs.com { @@ -187,6 +187,18 @@ vhost dvr.srs.com {
187 # the param for plan(segment), in seconds. 187 # the param for plan(segment), in seconds.
188 # default: 30 188 # default: 30
189 dvr_duration 30; 189 dvr_duration 30;
  190 + # about the stream monotonically increasing:
  191 + # 1. video timestamp is monotonically increasing,
  192 + # 2. audio timestamp is monotonically increasing,
  193 + # 3. video and audio timestamp is interleaved monotonically increasing.
  194 + # it's specified by RTMP specification, @see 3. Byte Order, Alignment, and Time Format
  195 + # however, some encoder cannot provides this feature, please set this to off to ignore time jitter.
  196 + # the time jitter algorithm:
  197 + # 1. full, to ensure stream start at zero, and ensure stream monotonically increasing.
  198 + # 2. zero, only ensure sttream start at zero, ignore timestamp jitter.
  199 + # 3. off, disable the time jitter algorithm, like atc.
  200 + # default: full
  201 + time_jitter full;
190 } 202 }
191 } 203 }
192 204
@@ -906,6 +918,22 @@ vhost chunksize.srs.com { @@ -906,6 +918,22 @@ vhost chunksize.srs.com {
906 chunk_size 128; 918 chunk_size 128;
907 } 919 }
908 920
  921 +# vhost for time jitter
  922 +vhost jitter.srs.com {
  923 + # about the stream monotonically increasing:
  924 + # 1. video timestamp is monotonically increasing,
  925 + # 2. audio timestamp is monotonically increasing,
  926 + # 3. video and audio timestamp is interleaved monotonically increasing.
  927 + # it's specified by RTMP specification, @see 3. Byte Order, Alignment, and Time Format
  928 + # however, some encoder cannot provides this feature, please set this to off to ignore time jitter.
  929 + # the time jitter algorithm:
  930 + # 1. full, to ensure stream start at zero, and ensure stream monotonically increasing.
  931 + # 2. zero, only ensure sttream start at zero, ignore timestamp jitter.
  932 + # 3. off, disable the time jitter algorithm, like atc.
  933 + # default: full
  934 + time_jitter full;
  935 +}
  936 +
909 # vhost for atc. 937 # vhost for atc.
910 vhost atc.srs.com { 938 vhost atc.srs.com {
911 # vhost for atc for hls/hds/rtmp backup. 939 # vhost for atc for hls/hds/rtmp backup.
@@ -41,6 +41,7 @@ using namespace std; @@ -41,6 +41,7 @@ using namespace std;
41 #include <srs_kernel_log.hpp> 41 #include <srs_kernel_log.hpp>
42 #include <srs_protocol_utility.hpp> 42 #include <srs_protocol_utility.hpp>
43 #include <srs_core_autofree.hpp> 43 #include <srs_core_autofree.hpp>
  44 +#include <srs_app_source.hpp>
44 45
45 #define SRS_WIKI_URL_LOG "https://github.com/winlinvip/simple-rtmp-server/wiki/SrsLog" 46 #define SRS_WIKI_URL_LOG "https://github.com/winlinvip/simple-rtmp-server/wiki/SrsLog"
46 47
@@ -947,6 +948,17 @@ int SrsConfig::reload_vhost(SrsConfDirective* old_root) @@ -947,6 +948,17 @@ int SrsConfig::reload_vhost(SrsConfDirective* old_root)
947 } 948 }
948 srs_trace("vhost %s reload queue_length success.", vhost.c_str()); 949 srs_trace("vhost %s reload queue_length success.", vhost.c_str());
949 } 950 }
  951 + // time_jitter, only one per vhost
  952 + if (!srs_directive_equals(new_vhost->get("time_jitter"), old_vhost->get("time_jitter"))) {
  953 + for (it = subscribes.begin(); it != subscribes.end(); ++it) {
  954 + ISrsReloadHandler* subscribe = *it;
  955 + if ((ret = subscribe->on_reload_vhost_time_jitter(vhost)) != ERROR_SUCCESS) {
  956 + srs_error("vhost %s notify subscribes time_jitter failed. ret=%d", vhost.c_str(), ret);
  957 + return ret;
  958 + }
  959 + }
  960 + srs_trace("vhost %s reload time_jitter success.", vhost.c_str());
  961 + }
950 // forward, only one per vhost 962 // forward, only one per vhost
951 if (!srs_directive_equals(new_vhost->get("forward"), old_vhost->get("forward"))) { 963 if (!srs_directive_equals(new_vhost->get("forward"), old_vhost->get("forward"))) {
952 for (it = subscribes.begin(); it != subscribes.end(); ++it) { 964 for (it = subscribes.begin(); it != subscribes.end(); ++it) {
@@ -1788,6 +1800,23 @@ bool SrsConfig::get_atc_auto(string vhost) @@ -1788,6 +1800,23 @@ bool SrsConfig::get_atc_auto(string vhost)
1788 return true; 1800 return true;
1789 } 1801 }
1790 1802
  1803 +int SrsConfig::get_time_jitter(string vhost)
  1804 +{
  1805 + SrsConfDirective* dvr = get_vhost(vhost);
  1806 +
  1807 + std::string time_jitter = SRS_CONF_DEFAULT_TIME_JITTER;
  1808 +
  1809 + if (dvr) {
  1810 + SrsConfDirective* conf = dvr->get("time_jitter");
  1811 +
  1812 + if (conf) {
  1813 + time_jitter = conf->arg0();
  1814 + }
  1815 + }
  1816 +
  1817 + return _srs_time_jitter_string2int(time_jitter);
  1818 +}
  1819 +
1791 double SrsConfig::get_queue_length(string vhost) 1820 double SrsConfig::get_queue_length(string vhost)
1792 { 1821 {
1793 SrsConfDirective* conf = get_vhost(vhost); 1822 SrsConfDirective* conf = get_vhost(vhost);
@@ -2636,6 +2665,23 @@ int SrsConfig::get_dvr_duration(string vhost) @@ -2636,6 +2665,23 @@ int SrsConfig::get_dvr_duration(string vhost)
2636 return ::atoi(conf->arg0().c_str()); 2665 return ::atoi(conf->arg0().c_str());
2637 } 2666 }
2638 2667
  2668 +int SrsConfig::get_dvr_time_jitter(string vhost)
  2669 +{
  2670 + SrsConfDirective* dvr = get_dvr(vhost);
  2671 +
  2672 + std::string time_jitter = SRS_CONF_DEFAULT_TIME_JITTER;
  2673 +
  2674 + if (dvr) {
  2675 + SrsConfDirective* conf = dvr->get("time_jitter");
  2676 +
  2677 + if (conf) {
  2678 + time_jitter = conf->arg0();
  2679 + }
  2680 + }
  2681 +
  2682 + return _srs_time_jitter_string2int(time_jitter);
  2683 +}
  2684 +
2639 SrsConfDirective* SrsConfig::get_http_api() 2685 SrsConfDirective* SrsConfig::get_http_api()
2640 { 2686 {
2641 return root->get("http_api"); 2687 return root->get("http_api");
@@ -49,6 +49,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -49,6 +49,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
49 #define SRS_CONF_DEFAULT_DVR_PLAN_HSS "hss" 49 #define SRS_CONF_DEFAULT_DVR_PLAN_HSS "hss"
50 #define SRS_CONF_DEFAULT_DVR_PLAN SRS_CONF_DEFAULT_DVR_PLAN_SESSION 50 #define SRS_CONF_DEFAULT_DVR_PLAN SRS_CONF_DEFAULT_DVR_PLAN_SESSION
51 #define SRS_CONF_DEFAULT_DVR_DURATION 30 51 #define SRS_CONF_DEFAULT_DVR_DURATION 30
  52 +#define SRS_CONF_DEFAULT_TIME_JITTER "full"
52 // in ms, for HLS aac sync time. 53 // in ms, for HLS aac sync time.
53 #define SRS_CONF_DEFAULT_AAC_SYNC 100 54 #define SRS_CONF_DEFAULT_AAC_SYNC 100
54 // in ms, for HLS aac flush the audio 55 // in ms, for HLS aac flush the audio
@@ -200,6 +201,7 @@ public: @@ -200,6 +201,7 @@ public:
200 virtual bool get_gop_cache(std::string vhost); 201 virtual bool get_gop_cache(std::string vhost);
201 virtual bool get_atc(std::string vhost); 202 virtual bool get_atc(std::string vhost);
202 virtual bool get_atc_auto(std::string vhost); 203 virtual bool get_atc_auto(std::string vhost);
  204 + virtual int get_time_jitter(std::string vhost);
203 virtual double get_queue_length(std::string vhost); 205 virtual double get_queue_length(std::string vhost);
204 virtual SrsConfDirective* get_forward(std::string vhost); 206 virtual SrsConfDirective* get_forward(std::string vhost);
205 virtual SrsConfDirective* get_refer(std::string vhost); 207 virtual SrsConfDirective* get_refer(std::string vhost);
@@ -272,6 +274,7 @@ public: @@ -272,6 +274,7 @@ public:
272 virtual std::string get_dvr_path(std::string vhost); 274 virtual std::string get_dvr_path(std::string vhost);
273 virtual std::string get_dvr_plan(std::string vhost); 275 virtual std::string get_dvr_plan(std::string vhost);
274 virtual int get_dvr_duration(std::string vhost); 276 virtual int get_dvr_duration(std::string vhost);
  277 + virtual int get_dvr_time_jitter(std::string vhost);
275 // http api section 278 // http api section
276 private: 279 private:
277 virtual SrsConfDirective* get_http_api(); 280 virtual SrsConfDirective* get_http_api();
@@ -70,10 +70,15 @@ SrsDvrPlan::SrsDvrPlan() @@ -70,10 +70,15 @@ SrsDvrPlan::SrsDvrPlan()
70 fs = new SrsFileStream(); 70 fs = new SrsFileStream();
71 enc = new SrsFlvEncoder(); 71 enc = new SrsFlvEncoder();
72 segment = new SrsFlvSegment(); 72 segment = new SrsFlvSegment();
  73 + jitter_algorithm = SrsRtmpJitterAlgorithmOFF;
  74 +
  75 + _srs_config->subscribe(this);
73 } 76 }
74 77
75 SrsDvrPlan::~SrsDvrPlan() 78 SrsDvrPlan::~SrsDvrPlan()
76 { 79 {
  80 + _srs_config->unsubscribe(this);
  81 +
77 srs_freep(jitter); 82 srs_freep(jitter);
78 srs_freep(fs); 83 srs_freep(fs);
79 srs_freep(enc); 84 srs_freep(enc);
@@ -87,6 +92,8 @@ int SrsDvrPlan::initialize(SrsSource* source, SrsRequest* req) @@ -87,6 +92,8 @@ int SrsDvrPlan::initialize(SrsSource* source, SrsRequest* req)
87 _source = source; 92 _source = source;
88 _req = req; 93 _req = req;
89 94
  95 + jitter_algorithm = (SrsRtmpJitterAlgorithm)_srs_config->get_dvr_time_jitter(_req->vhost);
  96 +
90 return ret; 97 return ret;
91 } 98 }
92 99
@@ -198,7 +205,7 @@ int SrsDvrPlan::on_audio(SrsSharedPtrMessage* audio) @@ -198,7 +205,7 @@ int SrsDvrPlan::on_audio(SrsSharedPtrMessage* audio)
198 return ret; 205 return ret;
199 } 206 }
200 207
201 - if ((jitter->correct(audio, 0, 0)) != ERROR_SUCCESS) { 208 + if ((jitter->correct(audio, 0, 0, jitter_algorithm)) != ERROR_SUCCESS) {
202 return ret; 209 return ret;
203 } 210 }
204 211
@@ -240,7 +247,7 @@ int SrsDvrPlan::on_video(SrsSharedPtrMessage* video) @@ -240,7 +247,7 @@ int SrsDvrPlan::on_video(SrsSharedPtrMessage* video)
240 srs_verbose("dvr video is key: %d", is_key_frame); 247 srs_verbose("dvr video is key: %d", is_key_frame);
241 #endif 248 #endif
242 249
243 - if ((jitter->correct(video, 0, 0)) != ERROR_SUCCESS) { 250 + if ((jitter->correct(video, 0, 0, jitter_algorithm)) != ERROR_SUCCESS) {
244 return ret; 251 return ret;
245 } 252 }
246 253
@@ -256,6 +263,15 @@ int SrsDvrPlan::on_video(SrsSharedPtrMessage* video) @@ -256,6 +263,15 @@ int SrsDvrPlan::on_video(SrsSharedPtrMessage* video)
256 return ret; 263 return ret;
257 } 264 }
258 265
  266 +int SrsDvrPlan::on_reload_vhost_dvr(std::string vhost)
  267 +{
  268 + int ret = ERROR_SUCCESS;
  269 +
  270 + jitter_algorithm = (SrsRtmpJitterAlgorithm)_srs_config->get_dvr_time_jitter(_req->vhost);
  271 +
  272 + return ret;
  273 +}
  274 +
259 int SrsDvrPlan::flv_open(string stream, string path) 275 int SrsDvrPlan::flv_open(string stream, string path)
260 { 276 {
261 int ret = ERROR_SUCCESS; 277 int ret = ERROR_SUCCESS;
@@ -42,6 +42,9 @@ class SrsSharedPtrMessage; @@ -42,6 +42,9 @@ class SrsSharedPtrMessage;
42 class SrsFileStream; 42 class SrsFileStream;
43 class SrsFlvEncoder; 43 class SrsFlvEncoder;
44 44
  45 +#include <srs_app_source.hpp>
  46 +#include <srs_app_reload.hpp>
  47 +
45 /** 48 /**
46 * a piece of flv segment. 49 * a piece of flv segment.
47 */ 50 */
@@ -93,21 +96,23 @@ public: @@ -93,21 +96,23 @@ public:
93 * 2. reap flv: when to reap the flv and start new piece. 96 * 2. reap flv: when to reap the flv and start new piece.
94 */ 97 */
95 // TODO: FIXME: the plan is too fat, refine me. 98 // TODO: FIXME: the plan is too fat, refine me.
96 -class SrsDvrPlan 99 +class SrsDvrPlan : public ISrsReloadHandler
97 { 100 {
98 -protected: 101 +private:
99 /** 102 /**
100 * the underlayer dvr stream. 103 * the underlayer dvr stream.
101 * if close, the flv is reap and closed. 104 * if close, the flv is reap and closed.
102 * if open, new flv file is crote. 105 * if open, new flv file is crote.
103 */ 106 */
104 - SrsFileStream* fs;  
105 SrsFlvEncoder* enc; 107 SrsFlvEncoder* enc;
106 - bool dvr_enabled;  
107 SrsSource* _source; 108 SrsSource* _source;
108 - SrsRequest* _req;  
109 SrsRtmpJitter* jitter; 109 SrsRtmpJitter* jitter;
  110 + SrsRtmpJitterAlgorithm jitter_algorithm;
  111 +protected:
110 SrsFlvSegment* segment; 112 SrsFlvSegment* segment;
  113 + SrsRequest* _req;
  114 + bool dvr_enabled;
  115 + SrsFileStream* fs;
111 public: 116 public:
112 SrsDvrPlan(); 117 SrsDvrPlan();
113 virtual ~SrsDvrPlan(); 118 virtual ~SrsDvrPlan();
@@ -118,6 +123,9 @@ public: @@ -118,6 +123,9 @@ public:
118 virtual int on_meta_data(SrsOnMetaDataPacket* metadata); 123 virtual int on_meta_data(SrsOnMetaDataPacket* metadata);
119 virtual int on_audio(SrsSharedPtrMessage* audio); 124 virtual int on_audio(SrsSharedPtrMessage* audio);
120 virtual int on_video(SrsSharedPtrMessage* video); 125 virtual int on_video(SrsSharedPtrMessage* video);
  126 +// interface ISrsReloadHandler
  127 +public:
  128 + virtual int on_reload_vhost_dvr(std::string vhost);
121 protected: 129 protected:
122 virtual int flv_open(std::string stream, std::string path); 130 virtual int flv_open(std::string stream, std::string path);
123 virtual int flv_close(); 131 virtual int flv_close();
@@ -162,7 +162,7 @@ int SrsForwarder::on_meta_data(SrsSharedPtrMessage* metadata) @@ -162,7 +162,7 @@ int SrsForwarder::on_meta_data(SrsSharedPtrMessage* metadata)
162 { 162 {
163 int ret = ERROR_SUCCESS; 163 int ret = ERROR_SUCCESS;
164 164
165 - if ((ret = jitter->correct(metadata, 0, 0)) != ERROR_SUCCESS) { 165 + if ((ret = jitter->correct(metadata, 0, 0, SrsRtmpJitterAlgorithmFULL)) != ERROR_SUCCESS) {
166 srs_freep(metadata); 166 srs_freep(metadata);
167 return ret; 167 return ret;
168 } 168 }
@@ -178,7 +178,7 @@ int SrsForwarder::on_audio(SrsSharedPtrMessage* msg) @@ -178,7 +178,7 @@ int SrsForwarder::on_audio(SrsSharedPtrMessage* msg)
178 { 178 {
179 int ret = ERROR_SUCCESS; 179 int ret = ERROR_SUCCESS;
180 180
181 - if ((ret = jitter->correct(msg, 0, 0)) != ERROR_SUCCESS) { 181 + if ((ret = jitter->correct(msg, 0, 0, SrsRtmpJitterAlgorithmFULL)) != ERROR_SUCCESS) {
182 srs_freep(msg); 182 srs_freep(msg);
183 return ret; 183 return ret;
184 } 184 }
@@ -194,7 +194,7 @@ int SrsForwarder::on_video(SrsSharedPtrMessage* msg) @@ -194,7 +194,7 @@ int SrsForwarder::on_video(SrsSharedPtrMessage* msg)
194 { 194 {
195 int ret = ERROR_SUCCESS; 195 int ret = ERROR_SUCCESS;
196 196
197 - if ((ret = jitter->correct(msg, 0, 0)) != ERROR_SUCCESS) { 197 + if ((ret = jitter->correct(msg, 0, 0, SrsRtmpJitterAlgorithmFULL)) != ERROR_SUCCESS) {
198 srs_freep(msg); 198 srs_freep(msg);
199 return ret; 199 return ret;
200 } 200 }
@@ -1411,7 +1411,7 @@ int SrsHls::on_audio(SrsSharedPtrMessage* audio) @@ -1411,7 +1411,7 @@ int SrsHls::on_audio(SrsSharedPtrMessage* audio)
1411 return hls_cache->on_sequence_header(muxer); 1411 return hls_cache->on_sequence_header(muxer);
1412 } 1412 }
1413 1413
1414 - if ((ret = jitter->correct(audio, 0, 0)) != ERROR_SUCCESS) { 1414 + if ((ret = jitter->correct(audio, 0, 0, SrsRtmpJitterAlgorithmFULL)) != ERROR_SUCCESS) {
1415 srs_error("rtmp jitter correct audio failed. ret=%d", ret); 1415 srs_error("rtmp jitter correct audio failed. ret=%d", ret);
1416 return ret; 1416 return ret;
1417 } 1417 }
@@ -1456,7 +1456,7 @@ int SrsHls::on_video(SrsSharedPtrMessage* video) @@ -1456,7 +1456,7 @@ int SrsHls::on_video(SrsSharedPtrMessage* video)
1456 return hls_cache->on_sequence_header(muxer); 1456 return hls_cache->on_sequence_header(muxer);
1457 } 1457 }
1458 1458
1459 - if ((ret = jitter->correct(video, 0, 0)) != ERROR_SUCCESS) { 1459 + if ((ret = jitter->correct(video, 0, 0, SrsRtmpJitterAlgorithmFULL)) != ERROR_SUCCESS) {
1460 srs_error("rtmp jitter correct video failed. ret=%d", ret); 1460 srs_error("rtmp jitter correct video failed. ret=%d", ret);
1461 return ret; 1461 return ret;
1462 } 1462 }
@@ -120,6 +120,11 @@ int ISrsReloadHandler::on_reload_vhost_queue_length(string /*vhost*/) @@ -120,6 +120,11 @@ int ISrsReloadHandler::on_reload_vhost_queue_length(string /*vhost*/)
120 return ERROR_SUCCESS; 120 return ERROR_SUCCESS;
121 } 121 }
122 122
  123 +int ISrsReloadHandler::on_reload_vhost_time_jitter(string /*vhost*/)
  124 +{
  125 + return ERROR_SUCCESS;
  126 +}
  127 +
123 int ISrsReloadHandler::on_reload_vhost_forward(string /*vhost*/) 128 int ISrsReloadHandler::on_reload_vhost_forward(string /*vhost*/)
124 { 129 {
125 return ERROR_SUCCESS; 130 return ERROR_SUCCESS;
@@ -61,6 +61,7 @@ public: @@ -61,6 +61,7 @@ public:
61 virtual int on_reload_vhost_atc(std::string vhost); 61 virtual int on_reload_vhost_atc(std::string vhost);
62 virtual int on_reload_vhost_gop_cache(std::string vhost); 62 virtual int on_reload_vhost_gop_cache(std::string vhost);
63 virtual int on_reload_vhost_queue_length(std::string vhost); 63 virtual int on_reload_vhost_queue_length(std::string vhost);
  64 + virtual int on_reload_vhost_time_jitter(std::string vhost);
64 virtual int on_reload_vhost_forward(std::string vhost); 65 virtual int on_reload_vhost_forward(std::string vhost);
65 virtual int on_reload_vhost_hls(std::string vhost); 66 virtual int on_reload_vhost_hls(std::string vhost);
66 virtual int on_reload_vhost_dvr(std::string vhost); 67 virtual int on_reload_vhost_dvr(std::string vhost);
@@ -45,6 +45,17 @@ using namespace std; @@ -45,6 +45,17 @@ using namespace std;
45 #define CONST_MAX_JITTER_MS 500 45 #define CONST_MAX_JITTER_MS 500
46 #define DEFAULT_FRAME_TIME_MS 40 46 #define DEFAULT_FRAME_TIME_MS 40
47 47
  48 +int _srs_time_jitter_string2int(std::string time_jitter)
  49 +{
  50 + if (time_jitter == "full") {
  51 + return SrsRtmpJitterAlgorithmFULL;
  52 + } else if (time_jitter == "zero") {
  53 + return SrsRtmpJitterAlgorithmZERO;
  54 + } else {
  55 + return SrsRtmpJitterAlgorithmOFF;
  56 + }
  57 +}
  58 +
48 SrsRtmpJitter::SrsRtmpJitter() 59 SrsRtmpJitter::SrsRtmpJitter()
49 { 60 {
50 last_pkt_correct_time = last_pkt_time = 0; 61 last_pkt_correct_time = last_pkt_time = 0;
@@ -54,10 +65,27 @@ SrsRtmpJitter::~SrsRtmpJitter() @@ -54,10 +65,27 @@ SrsRtmpJitter::~SrsRtmpJitter()
54 { 65 {
55 } 66 }
56 67
57 -int SrsRtmpJitter::correct(SrsSharedPtrMessage* msg, int tba, int tbv) 68 +int SrsRtmpJitter::correct(SrsSharedPtrMessage* msg, int tba, int tbv, SrsRtmpJitterAlgorithm ag)
58 { 69 {
59 int ret = ERROR_SUCCESS; 70 int ret = ERROR_SUCCESS;
60 71
  72 + // all jitter correct features is disabled, ignore.
  73 + if (ag == SrsRtmpJitterAlgorithmOFF) {
  74 + return ret;
  75 + }
  76 +
  77 +
  78 + // start at zero, but donot ensure monotonically increasing.
  79 + if (ag == SrsRtmpJitterAlgorithmZERO) {
  80 + if (last_pkt_correct_time <= 0) {
  81 + last_pkt_correct_time = msg->header.timestamp;
  82 + }
  83 + msg->header.timestamp -= last_pkt_correct_time;
  84 + return ret;
  85 + }
  86 +
  87 + // full jitter algorithm, do jitter correct.
  88 +
61 // set to 0 for metadata. 89 // set to 0 for metadata.
62 if (!msg->header.is_video() && !msg->header.is_audio()) { 90 if (!msg->header.is_video() && !msg->header.is_audio()) {
63 msg->header.timestamp = 0; 91 msg->header.timestamp = 0;
@@ -266,12 +294,12 @@ int SrsConsumer::get_time() @@ -266,12 +294,12 @@ int SrsConsumer::get_time()
266 return jitter->get_time(); 294 return jitter->get_time();
267 } 295 }
268 296
269 -int SrsConsumer::enqueue(SrsSharedPtrMessage* msg, bool atc, int tba, int tbv) 297 +int SrsConsumer::enqueue(SrsSharedPtrMessage* msg, bool atc, int tba, int tbv, SrsRtmpJitterAlgorithm ag)
270 { 298 {
271 int ret = ERROR_SUCCESS; 299 int ret = ERROR_SUCCESS;
272 300
273 if (!atc) { 301 if (!atc) {
274 - if ((ret = jitter->correct(msg, tba, tbv)) != ERROR_SUCCESS) { 302 + if ((ret = jitter->correct(msg, tba, tbv, ag)) != ERROR_SUCCESS) {
275 srs_freep(msg); 303 srs_freep(msg);
276 return ret; 304 return ret;
277 } 305 }
@@ -384,7 +412,7 @@ void SrsGopCache::clear() @@ -384,7 +412,7 @@ void SrsGopCache::clear()
384 cached_video_count = 0; 412 cached_video_count = 0;
385 } 413 }
386 414
387 -int SrsGopCache::dump(SrsConsumer* consumer, bool atc, int tba, int tbv) 415 +int SrsGopCache::dump(SrsConsumer* consumer, bool atc, int tba, int tbv, SrsRtmpJitterAlgorithm jitter_algorithm)
388 { 416 {
389 int ret = ERROR_SUCCESS; 417 int ret = ERROR_SUCCESS;
390 418
@@ -392,7 +420,7 @@ int SrsGopCache::dump(SrsConsumer* consumer, bool atc, int tba, int tbv) @@ -392,7 +420,7 @@ int SrsGopCache::dump(SrsConsumer* consumer, bool atc, int tba, int tbv)
392 for (it = gop_cache.begin(); it != gop_cache.end(); ++it) { 420 for (it = gop_cache.begin(); it != gop_cache.end(); ++it) {
393 SrsSharedPtrMessage* msg = *it; 421 SrsSharedPtrMessage* msg = *it;
394 SrsSharedPtrMessage* copy = msg->copy(); 422 SrsSharedPtrMessage* copy = msg->copy();
395 - if ((ret = consumer->enqueue(copy, atc, tba, tbv)) != ERROR_SUCCESS) { 423 + if ((ret = consumer->enqueue(copy, atc, tba, tbv, jitter_algorithm)) != ERROR_SUCCESS) {
396 srs_error("dispatch cached gop failed. ret=%d", ret); 424 srs_error("dispatch cached gop failed. ret=%d", ret);
397 return ret; 425 return ret;
398 } 426 }
@@ -464,6 +492,7 @@ void SrsSource::destroy() @@ -464,6 +492,7 @@ void SrsSource::destroy()
464 SrsSource::SrsSource(SrsRequest* req) 492 SrsSource::SrsSource(SrsRequest* req)
465 { 493 {
466 _req = req->copy(); 494 _req = req->copy();
  495 + jitter_algorithm = SrsRtmpJitterAlgorithmOFF;
467 496
468 #ifdef SRS_AUTO_HLS 497 #ifdef SRS_AUTO_HLS
469 hls = new SrsHls(this); 498 hls = new SrsHls(this);
@@ -549,6 +578,8 @@ int SrsSource::initialize() @@ -549,6 +578,8 @@ int SrsSource::initialize()
549 double queue_size = _srs_config->get_queue_length(_req->vhost); 578 double queue_size = _srs_config->get_queue_length(_req->vhost);
550 publish_edge->set_queue_size(queue_size); 579 publish_edge->set_queue_size(queue_size);
551 580
  581 + jitter_algorithm = (SrsRtmpJitterAlgorithm)_srs_config->get_time_jitter(_req->vhost);
  582 +
552 return ret; 583 return ret;
553 } 584 }
554 585
@@ -630,6 +661,19 @@ int SrsSource::on_reload_vhost_queue_length(string vhost) @@ -630,6 +661,19 @@ int SrsSource::on_reload_vhost_queue_length(string vhost)
630 return ret; 661 return ret;
631 } 662 }
632 663
  664 +int SrsSource::on_reload_vhost_time_jitter(string vhost)
  665 +{
  666 + int ret = ERROR_SUCCESS;
  667 +
  668 + if (_req->vhost != vhost) {
  669 + return ret;
  670 + }
  671 +
  672 + jitter_algorithm = (SrsRtmpJitterAlgorithm)_srs_config->get_time_jitter(_req->vhost);
  673 +
  674 + return ret;
  675 +}
  676 +
633 int SrsSource::on_reload_vhost_forward(string vhost) 677 int SrsSource::on_reload_vhost_forward(string vhost)
634 { 678 {
635 int ret = ERROR_SUCCESS; 679 int ret = ERROR_SUCCESS;
@@ -928,7 +972,7 @@ int SrsSource::on_meta_data(SrsMessage* msg, SrsOnMetaDataPacket* metadata) @@ -928,7 +972,7 @@ int SrsSource::on_meta_data(SrsMessage* msg, SrsOnMetaDataPacket* metadata)
928 for (it = consumers.begin(); it != consumers.end(); ++it) { 972 for (it = consumers.begin(); it != consumers.end(); ++it) {
929 SrsConsumer* consumer = *it; 973 SrsConsumer* consumer = *it;
930 SrsSharedPtrMessage* copy = cache_metadata->copy(); 974 SrsSharedPtrMessage* copy = cache_metadata->copy();
931 - if ((ret = consumer->enqueue(copy, atc, sample_rate, frame_rate)) != ERROR_SUCCESS) { 975 + if ((ret = consumer->enqueue(copy, atc, sample_rate, frame_rate, jitter_algorithm)) != ERROR_SUCCESS) {
932 srs_error("dispatch the metadata failed. ret=%d", ret); 976 srs_error("dispatch the metadata failed. ret=%d", ret);
933 return ret; 977 return ret;
934 } 978 }
@@ -992,7 +1036,7 @@ int SrsSource::on_audio(SrsMessage* audio) @@ -992,7 +1036,7 @@ int SrsSource::on_audio(SrsMessage* audio)
992 for (int i = 0; i < (int)consumers.size(); i++) { 1036 for (int i = 0; i < (int)consumers.size(); i++) {
993 SrsConsumer* consumer = consumers.at(i); 1037 SrsConsumer* consumer = consumers.at(i);
994 SrsSharedPtrMessage* copy = msg->copy(); 1038 SrsSharedPtrMessage* copy = msg->copy();
995 - if ((ret = consumer->enqueue(copy, atc, sample_rate, frame_rate)) != ERROR_SUCCESS) { 1039 + if ((ret = consumer->enqueue(copy, atc, sample_rate, frame_rate, jitter_algorithm)) != ERROR_SUCCESS) {
996 srs_error("dispatch the audio failed. ret=%d", ret); 1040 srs_error("dispatch the audio failed. ret=%d", ret);
997 return ret; 1041 return ret;
998 } 1042 }
@@ -1082,7 +1126,7 @@ int SrsSource::on_video(SrsMessage* video) @@ -1082,7 +1126,7 @@ int SrsSource::on_video(SrsMessage* video)
1082 for (int i = 0; i < (int)consumers.size(); i++) { 1126 for (int i = 0; i < (int)consumers.size(); i++) {
1083 SrsConsumer* consumer = consumers.at(i); 1127 SrsConsumer* consumer = consumers.at(i);
1084 SrsSharedPtrMessage* copy = msg->copy(); 1128 SrsSharedPtrMessage* copy = msg->copy();
1085 - if ((ret = consumer->enqueue(copy, atc, sample_rate, frame_rate)) != ERROR_SUCCESS) { 1129 + if ((ret = consumer->enqueue(copy, atc, sample_rate, frame_rate, jitter_algorithm)) != ERROR_SUCCESS) {
1086 srs_error("dispatch the video failed. ret=%d", ret); 1130 srs_error("dispatch the video failed. ret=%d", ret);
1087 return ret; 1131 return ret;
1088 } 1132 }
@@ -1328,28 +1372,32 @@ void SrsSource::on_unpublish() @@ -1328,28 +1372,32 @@ void SrsSource::on_unpublish()
1328 } 1372 }
1329 } 1373 }
1330 1374
  1375 + int tba = sample_rate;
  1376 + int tbv = frame_rate;
  1377 + SrsRtmpJitterAlgorithm ag = jitter_algorithm;
  1378 +
1331 // copy metadata. 1379 // copy metadata.
1332 - if (cache_metadata && (ret = consumer->enqueue(cache_metadata->copy(), atc, sample_rate, frame_rate)) != ERROR_SUCCESS) { 1380 + if (cache_metadata && (ret = consumer->enqueue(cache_metadata->copy(), atc, tba, tbv, ag)) != ERROR_SUCCESS) {
1333 srs_error("dispatch metadata failed. ret=%d", ret); 1381 srs_error("dispatch metadata failed. ret=%d", ret);
1334 return ret; 1382 return ret;
1335 } 1383 }
1336 srs_info("dispatch metadata success"); 1384 srs_info("dispatch metadata success");
1337 1385
1338 // copy sequence header 1386 // copy sequence header
1339 - if (cache_sh_video && (ret = consumer->enqueue(cache_sh_video->copy(), atc, sample_rate, frame_rate)) != ERROR_SUCCESS) { 1387 + if (cache_sh_video && (ret = consumer->enqueue(cache_sh_video->copy(), atc, tba, tbv, ag)) != ERROR_SUCCESS) {
1340 srs_error("dispatch video sequence header failed. ret=%d", ret); 1388 srs_error("dispatch video sequence header failed. ret=%d", ret);
1341 return ret; 1389 return ret;
1342 } 1390 }
1343 srs_info("dispatch video sequence header success"); 1391 srs_info("dispatch video sequence header success");
1344 1392
1345 - if (cache_sh_audio && (ret = consumer->enqueue(cache_sh_audio->copy(), atc, sample_rate, frame_rate)) != ERROR_SUCCESS) { 1393 + if (cache_sh_audio && (ret = consumer->enqueue(cache_sh_audio->copy(), atc, tba, tbv, ag)) != ERROR_SUCCESS) {
1346 srs_error("dispatch audio sequence header failed. ret=%d", ret); 1394 srs_error("dispatch audio sequence header failed. ret=%d", ret);
1347 return ret; 1395 return ret;
1348 } 1396 }
1349 srs_info("dispatch audio sequence header success"); 1397 srs_info("dispatch audio sequence header success");
1350 1398
1351 // copy gop cache to client. 1399 // copy gop cache to client.
1352 - if ((ret = gop_cache->dump(consumer, atc, sample_rate, frame_rate)) != ERROR_SUCCESS) { 1400 + if ((ret = gop_cache->dump(consumer, atc, tba, tbv, ag)) != ERROR_SUCCESS) {
1353 return ret; 1401 return ret;
1354 } 1402 }
1355 1403
@@ -60,6 +60,20 @@ class SrsEncoder; @@ -60,6 +60,20 @@ class SrsEncoder;
60 class SrsStream; 60 class SrsStream;
61 61
62 /** 62 /**
  63 +* the time jitter algorithm:
  64 +* 1. full, to ensure stream start at zero, and ensure stream monotonically increasing.
  65 +* 2. zero, only ensure sttream start at zero, ignore timestamp jitter.
  66 +* 3. off, disable the time jitter algorithm, like atc.
  67 +*/
  68 +enum SrsRtmpJitterAlgorithm
  69 +{
  70 + SrsRtmpJitterAlgorithmFULL = 0x01,
  71 + SrsRtmpJitterAlgorithmZERO,
  72 + SrsRtmpJitterAlgorithmOFF
  73 +};
  74 +int _srs_time_jitter_string2int(std::string time_jitter);
  75 +
  76 +/**
63 * time jitter detect and correct, 77 * time jitter detect and correct,
64 * to ensure the rtmp stream is monotonically. 78 * to ensure the rtmp stream is monotonically.
65 */ 79 */
@@ -74,8 +88,12 @@ public: @@ -74,8 +88,12 @@ public:
74 public: 88 public:
75 /** 89 /**
76 * detect the time jitter and correct it. 90 * detect the time jitter and correct it.
  91 + * @param tba, the audio timebase, used to calc the "right" delta if jitter detected.
  92 + * @param tbv, the video timebase, used to calc the "right" delta if jitter detected.
  93 + * @param start_at_zero whether ensure stream start at zero.
  94 + * @param mono_increasing whether ensure stream is monotonically inscreasing.
77 */ 95 */
78 - virtual int correct(SrsSharedPtrMessage* msg, int tba, int tbv); 96 + virtual int correct(SrsSharedPtrMessage* msg, int tba, int tbv, SrsRtmpJitterAlgorithm ag);
79 /** 97 /**
80 * get current client time, the last packet time. 98 * get current client time, the last packet time.
81 */ 99 */
@@ -160,8 +178,9 @@ public: @@ -160,8 +178,9 @@ public:
160 * used to calc the audio time delta if time-jitter detected. 178 * used to calc the audio time delta if time-jitter detected.
161 * @param tbv timebase of video. 179 * @param tbv timebase of video.
162 * used to calc the video time delta if time-jitter detected. 180 * used to calc the video time delta if time-jitter detected.
  181 + * @param ag the algorithm of time jitter.
163 */ 182 */
164 - virtual int enqueue(SrsSharedPtrMessage* msg, bool atc, int tba, int tbv); 183 + virtual int enqueue(SrsSharedPtrMessage* msg, bool atc, int tba, int tbv, SrsRtmpJitterAlgorithm ag);
165 /** 184 /**
166 * get packets in consumer queue. 185 * get packets in consumer queue.
167 * @pmsgs SrsMessages*[], used to store the msgs, user must alloc it. 186 * @pmsgs SrsMessages*[], used to store the msgs, user must alloc it.
@@ -209,7 +228,7 @@ public: @@ -209,7 +228,7 @@ public:
209 */ 228 */
210 virtual int cache(SrsSharedPtrMessage* msg); 229 virtual int cache(SrsSharedPtrMessage* msg);
211 virtual void clear(); 230 virtual void clear();
212 - virtual int dump(SrsConsumer* consumer, bool atc, int tba, int tbv); 231 + virtual int dump(SrsConsumer* consumer, bool atc, int tba, int tbv, SrsRtmpJitterAlgorithm jitter_algorithm);
213 /** 232 /**
214 * used for atc to get the time of gop cache, 233 * used for atc to get the time of gop cache,
215 * the atc will adjust the sequence header timestamp to gop cache. 234 * the atc will adjust the sequence header timestamp to gop cache.
@@ -249,6 +268,8 @@ private: @@ -249,6 +268,8 @@ private:
249 SrsRequest* _req; 268 SrsRequest* _req;
250 // to delivery stream to clients. 269 // to delivery stream to clients.
251 std::vector<SrsConsumer*> consumers; 270 std::vector<SrsConsumer*> consumers;
  271 + // the time jitter algorithm for vhost.
  272 + SrsRtmpJitterAlgorithm jitter_algorithm;
252 // hls handler. 273 // hls handler.
253 #ifdef SRS_AUTO_HLS 274 #ifdef SRS_AUTO_HLS
254 SrsHls* hls; 275 SrsHls* hls;
@@ -310,6 +331,7 @@ public: @@ -310,6 +331,7 @@ public:
310 virtual int on_reload_vhost_atc(std::string vhost); 331 virtual int on_reload_vhost_atc(std::string vhost);
311 virtual int on_reload_vhost_gop_cache(std::string vhost); 332 virtual int on_reload_vhost_gop_cache(std::string vhost);
312 virtual int on_reload_vhost_queue_length(std::string vhost); 333 virtual int on_reload_vhost_queue_length(std::string vhost);
  334 + virtual int on_reload_vhost_time_jitter(std::string vhost);
313 virtual int on_reload_vhost_forward(std::string vhost); 335 virtual int on_reload_vhost_forward(std::string vhost);
314 virtual int on_reload_vhost_hls(std::string vhost); 336 virtual int on_reload_vhost_hls(std::string vhost);
315 virtual int on_reload_vhost_dvr(std::string vhost); 337 virtual int on_reload_vhost_dvr(std::string vhost);
@@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 // current release version 31 // current release version
32 #define VERSION_MAJOR "0" 32 #define VERSION_MAJOR "0"
33 #define VERSION_MINOR "9" 33 #define VERSION_MINOR "9"
34 -#define VERSION_REVISION "132" 34 +#define VERSION_REVISION "133"
35 #define RTMP_SIG_SRS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_REVISION 35 #define RTMP_SIG_SRS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_REVISION
36 // server info. 36 // server info.
37 #define RTMP_SIG_SRS_KEY "SRS" 37 #define RTMP_SIG_SRS_KEY "SRS"