fix #425, refine the time jitter, correct (-inf,-250)+(250,+inf) to 10ms. 2.0.175
正在显示
9 个修改的文件
包含
71 行增加
和
106 行删除
@@ -344,6 +344,7 @@ Remark: | @@ -344,6 +344,7 @@ Remark: | ||
344 | 344 | ||
345 | ### SRS 2.0 history | 345 | ### SRS 2.0 history |
346 | 346 | ||
347 | +* 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 | ||
347 | * v2.0, 2015-06-10, fix [#424](https://github.com/simple-rtmp-server/srs/issues/424) fix aggregate timestamp bug. 2.0.174 | 348 | * v2.0, 2015-06-10, fix [#424](https://github.com/simple-rtmp-server/srs/issues/424) fix aggregate timestamp bug. 2.0.174 |
348 | * v2.0, 2015-06-06, fix [#421](https://github.com/simple-rtmp-server/srs/issues/421) drop video for unkown RTMP header. | 349 | * v2.0, 2015-06-06, fix [#421](https://github.com/simple-rtmp-server/srs/issues/421) drop video for unkown RTMP header. |
349 | * v2.0, 2015-06-05, fix [#420](https://github.com/simple-rtmp-server/srs/issues/420) remove ts for hls ram mode. | 350 | * 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) | @@ -273,7 +273,7 @@ int SrsFlvSegment::write_audio(SrsSharedPtrMessage* shared_audio) | ||
273 | SrsSharedPtrMessage* audio = shared_audio->copy(); | 273 | SrsSharedPtrMessage* audio = shared_audio->copy(); |
274 | SrsAutoFree(SrsSharedPtrMessage, audio); | 274 | SrsAutoFree(SrsSharedPtrMessage, audio); |
275 | 275 | ||
276 | - if ((jitter->correct(audio, 0, 0, jitter_algorithm)) != ERROR_SUCCESS) { | 276 | + if ((jitter->correct(audio, jitter_algorithm)) != ERROR_SUCCESS) { |
277 | return ret; | 277 | return ret; |
278 | } | 278 | } |
279 | 279 | ||
@@ -324,7 +324,7 @@ int SrsFlvSegment::write_video(SrsSharedPtrMessage* shared_video) | @@ -324,7 +324,7 @@ int SrsFlvSegment::write_video(SrsSharedPtrMessage* shared_video) | ||
324 | } | 324 | } |
325 | } | 325 | } |
326 | 326 | ||
327 | - if ((jitter->correct(video, 0, 0, jitter_algorithm)) != ERROR_SUCCESS) { | 327 | + if ((jitter->correct(video, jitter_algorithm)) != ERROR_SUCCESS) { |
328 | return ret; | 328 | return ret; |
329 | } | 329 | } |
330 | 330 | ||
@@ -334,7 +334,7 @@ int SrsFlvSegment::write_video(SrsSharedPtrMessage* shared_video) | @@ -334,7 +334,7 @@ int SrsFlvSegment::write_video(SrsSharedPtrMessage* shared_video) | ||
334 | return ret; | 334 | return ret; |
335 | } | 335 | } |
336 | 336 | ||
337 | - int32_t timestamp = plan->filter_timestamp(video->timestamp); | 337 | + int32_t timestamp = (int32_t)plan->filter_timestamp(video->timestamp); |
338 | if ((ret = enc->write_video(timestamp, payload, size)) != ERROR_SUCCESS) { | 338 | if ((ret = enc->write_video(timestamp, payload, size)) != ERROR_SUCCESS) { |
339 | return ret; | 339 | return ret; |
340 | } | 340 | } |
@@ -163,7 +163,8 @@ int SrsForwarder::on_meta_data(SrsSharedPtrMessage* shared_metadata) | @@ -163,7 +163,8 @@ int SrsForwarder::on_meta_data(SrsSharedPtrMessage* shared_metadata) | ||
163 | 163 | ||
164 | SrsSharedPtrMessage* metadata = shared_metadata->copy(); | 164 | SrsSharedPtrMessage* metadata = shared_metadata->copy(); |
165 | 165 | ||
166 | - if ((ret = jitter->correct(metadata, 0, 0, SrsRtmpJitterAlgorithmFULL)) != ERROR_SUCCESS) { | 166 | + // TODO: FIXME: config the jitter of Forwarder. |
167 | + if ((ret = jitter->correct(metadata, SrsRtmpJitterAlgorithmFULL)) != ERROR_SUCCESS) { | ||
167 | srs_freep(metadata); | 168 | srs_freep(metadata); |
168 | return ret; | 169 | return ret; |
169 | } | 170 | } |
@@ -180,8 +181,9 @@ int SrsForwarder::on_audio(SrsSharedPtrMessage* shared_audio) | @@ -180,8 +181,9 @@ int SrsForwarder::on_audio(SrsSharedPtrMessage* shared_audio) | ||
180 | int ret = ERROR_SUCCESS; | 181 | int ret = ERROR_SUCCESS; |
181 | 182 | ||
182 | SrsSharedPtrMessage* msg = shared_audio->copy(); | 183 | SrsSharedPtrMessage* msg = shared_audio->copy(); |
183 | - | ||
184 | - if ((ret = jitter->correct(msg, 0, 0, SrsRtmpJitterAlgorithmFULL)) != ERROR_SUCCESS) { | 184 | + |
185 | + // TODO: FIXME: config the jitter of Forwarder. | ||
186 | + if ((ret = jitter->correct(msg, SrsRtmpJitterAlgorithmFULL)) != ERROR_SUCCESS) { | ||
185 | srs_freep(msg); | 187 | srs_freep(msg); |
186 | return ret; | 188 | return ret; |
187 | } | 189 | } |
@@ -204,7 +206,8 @@ int SrsForwarder::on_video(SrsSharedPtrMessage* shared_video) | @@ -204,7 +206,8 @@ int SrsForwarder::on_video(SrsSharedPtrMessage* shared_video) | ||
204 | 206 | ||
205 | SrsSharedPtrMessage* msg = shared_video->copy(); | 207 | SrsSharedPtrMessage* msg = shared_video->copy(); |
206 | 208 | ||
207 | - if ((ret = jitter->correct(msg, 0, 0, SrsRtmpJitterAlgorithmFULL)) != ERROR_SUCCESS) { | 209 | + // TODO: FIXME: config the jitter of Forwarder. |
210 | + if ((ret = jitter->correct(msg, SrsRtmpJitterAlgorithmFULL)) != ERROR_SUCCESS) { | ||
208 | srs_freep(msg); | 211 | srs_freep(msg); |
209 | return ret; | 212 | return ret; |
210 | } | 213 | } |
@@ -1337,7 +1337,8 @@ int SrsHls::on_audio(SrsSharedPtrMessage* shared_audio) | @@ -1337,7 +1337,8 @@ int SrsHls::on_audio(SrsSharedPtrMessage* shared_audio) | ||
1337 | return hls_cache->on_sequence_header(muxer); | 1337 | return hls_cache->on_sequence_header(muxer); |
1338 | } | 1338 | } |
1339 | 1339 | ||
1340 | - if ((ret = jitter->correct(audio, 0, 0, SrsRtmpJitterAlgorithmFULL)) != ERROR_SUCCESS) { | 1340 | + // TODO: FIXME: config the jitter of HLS. |
1341 | + if ((ret = jitter->correct(audio, SrsRtmpJitterAlgorithmFULL)) != ERROR_SUCCESS) { | ||
1341 | srs_error("rtmp jitter correct audio failed. ret=%d", ret); | 1342 | srs_error("rtmp jitter correct audio failed. ret=%d", ret); |
1342 | return ret; | 1343 | return ret; |
1343 | } | 1344 | } |
@@ -1394,7 +1395,8 @@ int SrsHls::on_video(SrsSharedPtrMessage* shared_video) | @@ -1394,7 +1395,8 @@ int SrsHls::on_video(SrsSharedPtrMessage* shared_video) | ||
1394 | return hls_cache->on_sequence_header(muxer); | 1395 | return hls_cache->on_sequence_header(muxer); |
1395 | } | 1396 | } |
1396 | 1397 | ||
1397 | - if ((ret = jitter->correct(video, 0, 0, SrsRtmpJitterAlgorithmFULL)) != ERROR_SUCCESS) { | 1398 | + // TODO: FIXME: config the jitter of HLS. |
1399 | + if ((ret = jitter->correct(video, SrsRtmpJitterAlgorithmFULL)) != ERROR_SUCCESS) { | ||
1398 | srs_error("rtmp jitter correct video failed. ret=%d", ret); | 1400 | srs_error("rtmp jitter correct video failed. ret=%d", ret); |
1399 | return ret; | 1401 | return ret; |
1400 | } | 1402 | } |
@@ -1265,7 +1265,7 @@ int SrsStreamCache::start() | @@ -1265,7 +1265,7 @@ int SrsStreamCache::start() | ||
1265 | return pthread->start(); | 1265 | return pthread->start(); |
1266 | } | 1266 | } |
1267 | 1267 | ||
1268 | -int SrsStreamCache::dump_cache(SrsConsumer* consumer) | 1268 | +int SrsStreamCache::dump_cache(SrsConsumer* consumer, SrsRtmpJitterAlgorithm jitter) |
1269 | { | 1269 | { |
1270 | int ret = ERROR_SUCCESS; | 1270 | int ret = ERROR_SUCCESS; |
1271 | 1271 | ||
@@ -1276,8 +1276,8 @@ int SrsStreamCache::dump_cache(SrsConsumer* consumer) | @@ -1276,8 +1276,8 @@ int SrsStreamCache::dump_cache(SrsConsumer* consumer) | ||
1276 | return ret; | 1276 | return ret; |
1277 | } | 1277 | } |
1278 | 1278 | ||
1279 | - // TODO: FIXME: config it. | ||
1280 | - if ((ret = queue->dump_packets(consumer, false, 0, 0, SrsRtmpJitterAlgorithmOFF)) != ERROR_SUCCESS) { | 1279 | + // the jitter is get from SrsSource, which means the time_jitter of vhost. |
1280 | + if ((ret = queue->dump_packets(consumer, false, jitter)) != ERROR_SUCCESS) { | ||
1281 | return ret; | 1281 | return ret; |
1282 | } | 1282 | } |
1283 | 1283 | ||
@@ -1398,7 +1398,7 @@ bool SrsTsStreamEncoder::has_cache() | @@ -1398,7 +1398,7 @@ bool SrsTsStreamEncoder::has_cache() | ||
1398 | return false; | 1398 | return false; |
1399 | } | 1399 | } |
1400 | 1400 | ||
1401 | -int SrsTsStreamEncoder::dump_cache(SrsConsumer* /*consumer*/) | 1401 | +int SrsTsStreamEncoder::dump_cache(SrsConsumer* /*consumer*/, SrsRtmpJitterAlgorithm /*jitter*/) |
1402 | { | 1402 | { |
1403 | // for ts stream, ignore cache. | 1403 | // for ts stream, ignore cache. |
1404 | return ERROR_SUCCESS; | 1404 | return ERROR_SUCCESS; |
@@ -1451,7 +1451,7 @@ bool SrsFlvStreamEncoder::has_cache() | @@ -1451,7 +1451,7 @@ bool SrsFlvStreamEncoder::has_cache() | ||
1451 | return false; | 1451 | return false; |
1452 | } | 1452 | } |
1453 | 1453 | ||
1454 | -int SrsFlvStreamEncoder::dump_cache(SrsConsumer* /*consumer*/) | 1454 | +int SrsFlvStreamEncoder::dump_cache(SrsConsumer* /*consumer*/, SrsRtmpJitterAlgorithm /*jitter*/) |
1455 | { | 1455 | { |
1456 | // for flv stream, ignore cache. | 1456 | // for flv stream, ignore cache. |
1457 | return ERROR_SUCCESS; | 1457 | return ERROR_SUCCESS; |
@@ -1518,10 +1518,10 @@ bool SrsAacStreamEncoder::has_cache() | @@ -1518,10 +1518,10 @@ bool SrsAacStreamEncoder::has_cache() | ||
1518 | return true; | 1518 | return true; |
1519 | } | 1519 | } |
1520 | 1520 | ||
1521 | -int SrsAacStreamEncoder::dump_cache(SrsConsumer* consumer) | 1521 | +int SrsAacStreamEncoder::dump_cache(SrsConsumer* consumer, SrsRtmpJitterAlgorithm jitter) |
1522 | { | 1522 | { |
1523 | srs_assert(cache); | 1523 | srs_assert(cache); |
1524 | - return cache->dump_cache(consumer); | 1524 | + return cache->dump_cache(consumer, jitter); |
1525 | } | 1525 | } |
1526 | 1526 | ||
1527 | SrsMp3StreamEncoder::SrsMp3StreamEncoder() | 1527 | SrsMp3StreamEncoder::SrsMp3StreamEncoder() |
@@ -1574,10 +1574,10 @@ bool SrsMp3StreamEncoder::has_cache() | @@ -1574,10 +1574,10 @@ bool SrsMp3StreamEncoder::has_cache() | ||
1574 | return true; | 1574 | return true; |
1575 | } | 1575 | } |
1576 | 1576 | ||
1577 | -int SrsMp3StreamEncoder::dump_cache(SrsConsumer* consumer) | 1577 | +int SrsMp3StreamEncoder::dump_cache(SrsConsumer* consumer, SrsRtmpJitterAlgorithm jitter) |
1578 | { | 1578 | { |
1579 | srs_assert(cache); | 1579 | srs_assert(cache); |
1580 | - return cache->dump_cache(consumer); | 1580 | + return cache->dump_cache(consumer, jitter); |
1581 | } | 1581 | } |
1582 | 1582 | ||
1583 | SrsStreamWriter::SrsStreamWriter(ISrsHttpResponseWriter* w) | 1583 | SrsStreamWriter::SrsStreamWriter(ISrsHttpResponseWriter* w) |
@@ -1686,7 +1686,7 @@ int SrsLiveStream::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) | @@ -1686,7 +1686,7 @@ int SrsLiveStream::serve_http(ISrsHttpResponseWriter* w, ISrsHttpMessage* r) | ||
1686 | 1686 | ||
1687 | // if gop cache enabled for encoder, dump to consumer. | 1687 | // if gop cache enabled for encoder, dump to consumer. |
1688 | if (enc->has_cache()) { | 1688 | if (enc->has_cache()) { |
1689 | - if ((ret = enc->dump_cache(consumer)) != ERROR_SUCCESS) { | 1689 | + if ((ret = enc->dump_cache(consumer, source->jitter())) != ERROR_SUCCESS) { |
1690 | srs_error("http: dump cache to consumer failed. ret=%d", ret); | 1690 | srs_error("http: dump cache to consumer failed. ret=%d", ret); |
1691 | return ret; | 1691 | return ret; |
1692 | } | 1692 | } |
@@ -46,6 +46,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -46,6 +46,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
46 | #include <srs_kernel_file.hpp> | 46 | #include <srs_kernel_file.hpp> |
47 | #include <srs_app_thread.hpp> | 47 | #include <srs_app_thread.hpp> |
48 | #include <srs_app_conn.hpp> | 48 | #include <srs_app_conn.hpp> |
49 | +#include <srs_app_source.hpp> | ||
49 | 50 | ||
50 | class SrsServer; | 51 | class SrsServer; |
51 | class SrsSource; | 52 | class SrsSource; |
@@ -407,7 +408,7 @@ public: | @@ -407,7 +408,7 @@ public: | ||
407 | virtual ~SrsStreamCache(); | 408 | virtual ~SrsStreamCache(); |
408 | public: | 409 | public: |
409 | virtual int start(); | 410 | virtual int start(); |
410 | - virtual int dump_cache(SrsConsumer* consumer); | 411 | + virtual int dump_cache(SrsConsumer* consumer, SrsRtmpJitterAlgorithm jitter); |
411 | // interface ISrsEndlessThreadHandler. | 412 | // interface ISrsEndlessThreadHandler. |
412 | public: | 413 | public: |
413 | virtual int cycle(); | 414 | virtual int cycle(); |
@@ -444,7 +445,7 @@ public: | @@ -444,7 +445,7 @@ public: | ||
444 | /** | 445 | /** |
445 | * dumps the cache of encoder to consumer. | 446 | * dumps the cache of encoder to consumer. |
446 | */ | 447 | */ |
447 | - virtual int dump_cache(SrsConsumer* consumer) = 0; | 448 | + virtual int dump_cache(SrsConsumer* consumer, SrsRtmpJitterAlgorithm jitter) = 0; |
448 | }; | 449 | }; |
449 | 450 | ||
450 | /** | 451 | /** |
@@ -464,7 +465,7 @@ public: | @@ -464,7 +465,7 @@ public: | ||
464 | virtual int write_metadata(int64_t timestamp, char* data, int size); | 465 | virtual int write_metadata(int64_t timestamp, char* data, int size); |
465 | public: | 466 | public: |
466 | virtual bool has_cache(); | 467 | virtual bool has_cache(); |
467 | - virtual int dump_cache(SrsConsumer* consumer); | 468 | + virtual int dump_cache(SrsConsumer* consumer, SrsRtmpJitterAlgorithm jitter); |
468 | }; | 469 | }; |
469 | 470 | ||
470 | #ifdef SRS_PERF_FAST_FLV_ENCODER | 471 | #ifdef SRS_PERF_FAST_FLV_ENCODER |
@@ -502,7 +503,7 @@ public: | @@ -502,7 +503,7 @@ public: | ||
502 | virtual int write_metadata(int64_t timestamp, char* data, int size); | 503 | virtual int write_metadata(int64_t timestamp, char* data, int size); |
503 | public: | 504 | public: |
504 | virtual bool has_cache(); | 505 | virtual bool has_cache(); |
505 | - virtual int dump_cache(SrsConsumer* consumer); | 506 | + virtual int dump_cache(SrsConsumer* consumer, SrsRtmpJitterAlgorithm jitter); |
506 | }; | 507 | }; |
507 | 508 | ||
508 | /** | 509 | /** |
@@ -523,7 +524,7 @@ public: | @@ -523,7 +524,7 @@ public: | ||
523 | virtual int write_metadata(int64_t timestamp, char* data, int size); | 524 | virtual int write_metadata(int64_t timestamp, char* data, int size); |
524 | public: | 525 | public: |
525 | virtual bool has_cache(); | 526 | virtual bool has_cache(); |
526 | - virtual int dump_cache(SrsConsumer* consumer); | 527 | + virtual int dump_cache(SrsConsumer* consumer, SrsRtmpJitterAlgorithm jitter); |
527 | }; | 528 | }; |
528 | 529 | ||
529 | /** | 530 | /** |
@@ -544,7 +545,7 @@ public: | @@ -544,7 +545,7 @@ public: | ||
544 | virtual int write_metadata(int64_t timestamp, char* data, int size); | 545 | virtual int write_metadata(int64_t timestamp, char* data, int size); |
545 | public: | 546 | public: |
546 | virtual bool has_cache(); | 547 | virtual bool has_cache(); |
547 | - virtual int dump_cache(SrsConsumer* consumer); | 548 | + virtual int dump_cache(SrsConsumer* consumer, SrsRtmpJitterAlgorithm jitter); |
548 | }; | 549 | }; |
549 | 550 | ||
550 | /** | 551 | /** |
@@ -47,8 +47,9 @@ using namespace std; | @@ -47,8 +47,9 @@ using namespace std; | ||
47 | #include <srs_core_autofree.hpp> | 47 | #include <srs_core_autofree.hpp> |
48 | #include <srs_rtmp_utility.hpp> | 48 | #include <srs_rtmp_utility.hpp> |
49 | 49 | ||
50 | -#define CONST_MAX_JITTER_MS 500 | ||
51 | -#define DEFAULT_FRAME_TIME_MS 40 | 50 | +#define CONST_MAX_JITTER_MS 250 |
51 | +#define CONST_MAX_JITTER_MS_NEG -250 | ||
52 | +#define DEFAULT_FRAME_TIME_MS 10 | ||
52 | 53 | ||
53 | // for 26ms per audio packet, | 54 | // for 26ms per audio packet, |
54 | // 115 packets is 3s. | 55 | // 115 packets is 3s. |
@@ -70,14 +71,15 @@ int _srs_time_jitter_string2int(std::string time_jitter) | @@ -70,14 +71,15 @@ int _srs_time_jitter_string2int(std::string time_jitter) | ||
70 | 71 | ||
71 | SrsRtmpJitter::SrsRtmpJitter() | 72 | SrsRtmpJitter::SrsRtmpJitter() |
72 | { | 73 | { |
73 | - last_pkt_correct_time = last_pkt_time = 0; | 74 | + last_pkt_correct_time = -1; |
75 | + last_pkt_time = 0; | ||
74 | } | 76 | } |
75 | 77 | ||
76 | SrsRtmpJitter::~SrsRtmpJitter() | 78 | SrsRtmpJitter::~SrsRtmpJitter() |
77 | { | 79 | { |
78 | } | 80 | } |
79 | 81 | ||
80 | -int SrsRtmpJitter::correct(SrsSharedPtrMessage* msg, int tba, int tbv, SrsRtmpJitterAlgorithm ag) | 82 | +int SrsRtmpJitter::correct(SrsSharedPtrMessage* msg, SrsRtmpJitterAlgorithm ag) |
81 | { | 83 | { |
82 | int ret = ERROR_SUCCESS; | 84 | int ret = ERROR_SUCCESS; |
83 | 85 | ||
@@ -90,9 +92,8 @@ int SrsRtmpJitter::correct(SrsSharedPtrMessage* msg, int tba, int tbv, SrsRtmpJi | @@ -90,9 +92,8 @@ int SrsRtmpJitter::correct(SrsSharedPtrMessage* msg, int tba, int tbv, SrsRtmpJi | ||
90 | 92 | ||
91 | // start at zero, but donot ensure monotonically increasing. | 93 | // start at zero, but donot ensure monotonically increasing. |
92 | if (ag == SrsRtmpJitterAlgorithmZERO) { | 94 | if (ag == SrsRtmpJitterAlgorithmZERO) { |
93 | - // for the first time, last_pkt_correct_time is zero. | ||
94 | - // while when timestamp overflow, the timestamp become smaller, reset the last_pkt_correct_time. | ||
95 | - if (last_pkt_correct_time <= 0 || msg->timestamp < last_pkt_correct_time) { | 95 | + // for the first time, last_pkt_correct_time is -1. |
96 | + if (last_pkt_correct_time == -1) { | ||
96 | last_pkt_correct_time = msg->timestamp; | 97 | last_pkt_correct_time = msg->timestamp; |
97 | } | 98 | } |
98 | msg->timestamp -= last_pkt_correct_time; | 99 | msg->timestamp -= last_pkt_correct_time; |
@@ -104,16 +105,12 @@ int SrsRtmpJitter::correct(SrsSharedPtrMessage* msg, int tba, int tbv, SrsRtmpJi | @@ -104,16 +105,12 @@ int SrsRtmpJitter::correct(SrsSharedPtrMessage* msg, int tba, int tbv, SrsRtmpJi | ||
104 | } | 105 | } |
105 | 106 | ||
106 | // full jitter algorithm, do jitter correct. | 107 | // full jitter algorithm, do jitter correct. |
107 | - | ||
108 | // set to 0 for metadata. | 108 | // set to 0 for metadata. |
109 | if (!msg->is_av()) { | 109 | if (!msg->is_av()) { |
110 | msg->timestamp = 0; | 110 | msg->timestamp = 0; |
111 | return ret; | 111 | return ret; |
112 | } | 112 | } |
113 | 113 | ||
114 | - int sample_rate = tba; | ||
115 | - int frame_rate = tbv; | ||
116 | - | ||
117 | /** | 114 | /** |
118 | * we use a very simple time jitter detect/correct algorithm: | 115 | * we use a very simple time jitter detect/correct algorithm: |
119 | * 1. delta: ensure the delta is positive and valid, | 116 | * 1. delta: ensure the delta is positive and valid, |
@@ -128,20 +125,10 @@ int SrsRtmpJitter::correct(SrsSharedPtrMessage* msg, int tba, int tbv, SrsRtmpJi | @@ -128,20 +125,10 @@ int SrsRtmpJitter::correct(SrsSharedPtrMessage* msg, int tba, int tbv, SrsRtmpJi | ||
128 | int64_t delta = time - last_pkt_time; | 125 | int64_t delta = time - last_pkt_time; |
129 | 126 | ||
130 | // if jitter detected, reset the delta. | 127 | // if jitter detected, reset the delta. |
131 | - if (delta < 0 || delta > CONST_MAX_JITTER_MS) { | ||
132 | - // calc the right diff by audio sample rate | ||
133 | - if (msg->is_audio() && sample_rate > 0) { | ||
134 | - delta = (int64_t)(delta * 1000.0 / sample_rate); | ||
135 | - } else if (msg->is_video() && frame_rate > 0) { | ||
136 | - delta = (int64_t)(delta * 1.0 / frame_rate); | ||
137 | - } else { | ||
138 | - delta = DEFAULT_FRAME_TIME_MS; | ||
139 | - } | ||
140 | - | ||
141 | - // sometimes, the time is absolute time, so correct it again. | ||
142 | - if (delta < 0 || delta > CONST_MAX_JITTER_MS) { | ||
143 | - delta = DEFAULT_FRAME_TIME_MS; | ||
144 | - } | 128 | + if (delta < CONST_MAX_JITTER_MS_NEG || delta > CONST_MAX_JITTER_MS) { |
129 | + // use default 10ms to notice the problem of stream. | ||
130 | + // @see https://github.com/simple-rtmp-server/srs/issues/425 | ||
131 | + delta = DEFAULT_FRAME_TIME_MS; | ||
145 | 132 | ||
146 | srs_info("jitter detected, last_pts=%"PRId64", pts=%"PRId64", diff=%"PRId64", last_time=%"PRId64", time=%"PRId64", diff=%"PRId64"", | 133 | srs_info("jitter detected, last_pts=%"PRId64", pts=%"PRId64", diff=%"PRId64", last_time=%"PRId64", time=%"PRId64", diff=%"PRId64"", |
147 | last_pkt_time, time, time - last_pkt_time, last_pkt_correct_time, last_pkt_correct_time + delta, delta); | 134 | 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 | @@ -338,7 +325,7 @@ int SrsMessageQueue::dump_packets(int max_count, SrsSharedPtrMessage** pmsgs, in | ||
338 | return ret; | 325 | return ret; |
339 | } | 326 | } |
340 | 327 | ||
341 | -int SrsMessageQueue::dump_packets(SrsConsumer* consumer, bool atc, int tba, int tbv, SrsRtmpJitterAlgorithm ag) | 328 | +int SrsMessageQueue::dump_packets(SrsConsumer* consumer, bool atc, SrsRtmpJitterAlgorithm ag) |
342 | { | 329 | { |
343 | int ret = ERROR_SUCCESS; | 330 | int ret = ERROR_SUCCESS; |
344 | 331 | ||
@@ -350,7 +337,7 @@ int SrsMessageQueue::dump_packets(SrsConsumer* consumer, bool atc, int tba, int | @@ -350,7 +337,7 @@ int SrsMessageQueue::dump_packets(SrsConsumer* consumer, bool atc, int tba, int | ||
350 | SrsSharedPtrMessage** omsgs = msgs.data(); | 337 | SrsSharedPtrMessage** omsgs = msgs.data(); |
351 | for (int i = 0; i < nb_msgs; i++) { | 338 | for (int i = 0; i < nb_msgs; i++) { |
352 | SrsSharedPtrMessage* msg = omsgs[i]; | 339 | SrsSharedPtrMessage* msg = omsgs[i]; |
353 | - if ((ret = consumer->enqueue(msg, atc, tba, tbv, ag)) != ERROR_SUCCESS) { | 340 | + if ((ret = consumer->enqueue(msg, atc, ag)) != ERROR_SUCCESS) { |
354 | return ret; | 341 | return ret; |
355 | } | 342 | } |
356 | } | 343 | } |
@@ -473,14 +460,14 @@ int SrsConsumer::get_time() | @@ -473,14 +460,14 @@ int SrsConsumer::get_time() | ||
473 | return jitter->get_time(); | 460 | return jitter->get_time(); |
474 | } | 461 | } |
475 | 462 | ||
476 | -int SrsConsumer::enqueue(SrsSharedPtrMessage* shared_msg, bool atc, int tba, int tbv, SrsRtmpJitterAlgorithm ag) | 463 | +int SrsConsumer::enqueue(SrsSharedPtrMessage* shared_msg, bool atc, SrsRtmpJitterAlgorithm ag) |
477 | { | 464 | { |
478 | int ret = ERROR_SUCCESS; | 465 | int ret = ERROR_SUCCESS; |
479 | 466 | ||
480 | SrsSharedPtrMessage* msg = shared_msg->copy(); | 467 | SrsSharedPtrMessage* msg = shared_msg->copy(); |
481 | 468 | ||
482 | if (!atc) { | 469 | if (!atc) { |
483 | - if ((ret = jitter->correct(msg, tba, tbv, ag)) != ERROR_SUCCESS) { | 470 | + if ((ret = jitter->correct(msg, ag)) != ERROR_SUCCESS) { |
484 | srs_freep(msg); | 471 | srs_freep(msg); |
485 | return ret; | 472 | return ret; |
486 | } | 473 | } |
@@ -683,14 +670,14 @@ void SrsGopCache::clear() | @@ -683,14 +670,14 @@ void SrsGopCache::clear() | ||
683 | audio_after_last_video_count = 0; | 670 | audio_after_last_video_count = 0; |
684 | } | 671 | } |
685 | 672 | ||
686 | -int SrsGopCache::dump(SrsConsumer* consumer, bool atc, int tba, int tbv, SrsRtmpJitterAlgorithm jitter_algorithm) | 673 | +int SrsGopCache::dump(SrsConsumer* consumer, bool atc, SrsRtmpJitterAlgorithm jitter_algorithm) |
687 | { | 674 | { |
688 | int ret = ERROR_SUCCESS; | 675 | int ret = ERROR_SUCCESS; |
689 | 676 | ||
690 | std::vector<SrsSharedPtrMessage*>::iterator it; | 677 | std::vector<SrsSharedPtrMessage*>::iterator it; |
691 | for (it = gop_cache.begin(); it != gop_cache.end(); ++it) { | 678 | for (it = gop_cache.begin(); it != gop_cache.end(); ++it) { |
692 | SrsSharedPtrMessage* msg = *it; | 679 | SrsSharedPtrMessage* msg = *it; |
693 | - if ((ret = consumer->enqueue(msg, atc, tba, tbv, jitter_algorithm)) != ERROR_SUCCESS) { | 680 | + if ((ret = consumer->enqueue(msg, atc, jitter_algorithm)) != ERROR_SUCCESS) { |
694 | srs_error("dispatch cached gop failed. ret=%d", ret); | 681 | srs_error("dispatch cached gop failed. ret=%d", ret); |
695 | return ret; | 682 | return ret; |
696 | } | 683 | } |
@@ -906,7 +893,6 @@ SrsSource::SrsSource() | @@ -906,7 +893,6 @@ SrsSource::SrsSource() | ||
906 | 893 | ||
907 | cache_metadata = cache_sh_video = cache_sh_audio = NULL; | 894 | cache_metadata = cache_sh_video = cache_sh_audio = NULL; |
908 | 895 | ||
909 | - frame_rate = sample_rate = 0; | ||
910 | _can_publish = true; | 896 | _can_publish = true; |
911 | _source_id = -1; | 897 | _source_id = -1; |
912 | 898 | ||
@@ -1413,17 +1399,6 @@ int SrsSource::on_meta_data(SrsCommonMessage* msg, SrsOnMetaDataPacket* metadata | @@ -1413,17 +1399,6 @@ int SrsSource::on_meta_data(SrsCommonMessage* msg, SrsOnMetaDataPacket* metadata | ||
1413 | // add version to metadata, please donot remove it, for debug. | 1399 | // add version to metadata, please donot remove it, for debug. |
1414 | metadata->metadata->set("server_version", SrsAmf0Any::str(RTMP_SIG_SRS_VERSION)); | 1400 | metadata->metadata->set("server_version", SrsAmf0Any::str(RTMP_SIG_SRS_VERSION)); |
1415 | 1401 | ||
1416 | - if ((prop = metadata->metadata->get_property("audiosamplerate")) != NULL) { | ||
1417 | - if (prop->is_number()) { | ||
1418 | - sample_rate = (int)prop->to_number(); | ||
1419 | - } | ||
1420 | - } | ||
1421 | - if ((prop = metadata->metadata->get_property("framerate")) != NULL) { | ||
1422 | - if (prop->is_number()) { | ||
1423 | - frame_rate = (int)prop->to_number(); | ||
1424 | - } | ||
1425 | - } | ||
1426 | - | ||
1427 | // if allow atc_auto and bravo-atc detected, open atc for vhost. | 1402 | // if allow atc_auto and bravo-atc detected, open atc for vhost. |
1428 | atc = _srs_config->get_atc(_req->vhost); | 1403 | atc = _srs_config->get_atc(_req->vhost); |
1429 | if (_srs_config->get_atc_auto(_req->vhost)) { | 1404 | if (_srs_config->get_atc_auto(_req->vhost)) { |
@@ -1466,7 +1441,7 @@ int SrsSource::on_meta_data(SrsCommonMessage* msg, SrsOnMetaDataPacket* metadata | @@ -1466,7 +1441,7 @@ int SrsSource::on_meta_data(SrsCommonMessage* msg, SrsOnMetaDataPacket* metadata | ||
1466 | std::vector<SrsConsumer*>::iterator it; | 1441 | std::vector<SrsConsumer*>::iterator it; |
1467 | for (it = consumers.begin(); it != consumers.end(); ++it) { | 1442 | for (it = consumers.begin(); it != consumers.end(); ++it) { |
1468 | SrsConsumer* consumer = *it; | 1443 | SrsConsumer* consumer = *it; |
1469 | - if ((ret = consumer->enqueue(cache_metadata, atc, sample_rate, frame_rate, jitter_algorithm)) != ERROR_SUCCESS) { | 1444 | + if ((ret = consumer->enqueue(cache_metadata, atc, jitter_algorithm)) != ERROR_SUCCESS) { |
1470 | srs_error("dispatch the metadata failed. ret=%d", ret); | 1445 | srs_error("dispatch the metadata failed. ret=%d", ret); |
1471 | return ret; | 1446 | return ret; |
1472 | } | 1447 | } |
@@ -1600,7 +1575,7 @@ int SrsSource::on_audio_imp(SrsSharedPtrMessage* msg) | @@ -1600,7 +1575,7 @@ int SrsSource::on_audio_imp(SrsSharedPtrMessage* msg) | ||
1600 | SrsConsumer** pconsumer = consumers.data(); | 1575 | SrsConsumer** pconsumer = consumers.data(); |
1601 | for (int i = 0; i < nb_consumers; i++) { | 1576 | for (int i = 0; i < nb_consumers; i++) { |
1602 | SrsConsumer* consumer = pconsumer[i]; | 1577 | SrsConsumer* consumer = pconsumer[i]; |
1603 | - if ((ret = consumer->enqueue(msg, atc, sample_rate, frame_rate, jitter_algorithm)) != ERROR_SUCCESS) { | 1578 | + if ((ret = consumer->enqueue(msg, atc, jitter_algorithm)) != ERROR_SUCCESS) { |
1604 | srs_error("dispatch the audio failed. ret=%d", ret); | 1579 | srs_error("dispatch the audio failed. ret=%d", ret); |
1605 | return ret; | 1580 | return ret; |
1606 | } | 1581 | } |
@@ -1802,7 +1777,7 @@ int SrsSource::on_video_imp(SrsSharedPtrMessage* msg) | @@ -1802,7 +1777,7 @@ int SrsSource::on_video_imp(SrsSharedPtrMessage* msg) | ||
1802 | if (true) { | 1777 | if (true) { |
1803 | for (int i = 0; i < (int)consumers.size(); i++) { | 1778 | for (int i = 0; i < (int)consumers.size(); i++) { |
1804 | SrsConsumer* consumer = consumers.at(i); | 1779 | SrsConsumer* consumer = consumers.at(i); |
1805 | - if ((ret = consumer->enqueue(msg, atc, sample_rate, frame_rate, jitter_algorithm)) != ERROR_SUCCESS) { | 1780 | + if ((ret = consumer->enqueue(msg, atc, jitter_algorithm)) != ERROR_SUCCESS) { |
1806 | srs_error("dispatch the video failed. ret=%d", ret); | 1781 | srs_error("dispatch the video failed. ret=%d", ret); |
1807 | return ret; | 1782 | return ret; |
1808 | } | 1783 | } |
@@ -2091,8 +2066,6 @@ void SrsSource::on_unpublish() | @@ -2091,8 +2066,6 @@ void SrsSource::on_unpublish() | ||
2091 | gop_cache->clear(); | 2066 | gop_cache->clear(); |
2092 | 2067 | ||
2093 | srs_freep(cache_metadata); | 2068 | srs_freep(cache_metadata); |
2094 | - frame_rate = sample_rate = 0; | ||
2095 | - | ||
2096 | srs_freep(cache_sh_video); | 2069 | srs_freep(cache_sh_video); |
2097 | srs_freep(cache_sh_audio); | 2070 | srs_freep(cache_sh_audio); |
2098 | 2071 | ||
@@ -2131,13 +2104,9 @@ int SrsSource::create_consumer(SrsConsumer*& consumer, bool ds, bool dm, bool dg | @@ -2131,13 +2104,9 @@ int SrsSource::create_consumer(SrsConsumer*& consumer, bool ds, bool dm, bool dg | ||
2131 | cache_sh_audio->timestamp = gop_cache->start_time(); | 2104 | cache_sh_audio->timestamp = gop_cache->start_time(); |
2132 | } | 2105 | } |
2133 | } | 2106 | } |
2134 | - | ||
2135 | - int tba = sample_rate; | ||
2136 | - int tbv = frame_rate; | ||
2137 | - SrsRtmpJitterAlgorithm ag = jitter_algorithm; | ||
2138 | 2107 | ||
2139 | // copy metadata. | 2108 | // copy metadata. |
2140 | - if (dm && cache_metadata && (ret = consumer->enqueue(cache_metadata, atc, tba, tbv, ag)) != ERROR_SUCCESS) { | 2109 | + if (dm && cache_metadata && (ret = consumer->enqueue(cache_metadata, atc, jitter_algorithm)) != ERROR_SUCCESS) { |
2141 | srs_error("dispatch metadata failed. ret=%d", ret); | 2110 | srs_error("dispatch metadata failed. ret=%d", ret); |
2142 | return ret; | 2111 | return ret; |
2143 | } | 2112 | } |
@@ -2146,28 +2115,28 @@ int SrsSource::create_consumer(SrsConsumer*& consumer, bool ds, bool dm, bool dg | @@ -2146,28 +2115,28 @@ int SrsSource::create_consumer(SrsConsumer*& consumer, bool ds, bool dm, bool dg | ||
2146 | // copy sequence header | 2115 | // copy sequence header |
2147 | // copy audio sequence first, for hls to fast parse the "right" audio codec. | 2116 | // copy audio sequence first, for hls to fast parse the "right" audio codec. |
2148 | // @see https://github.com/simple-rtmp-server/srs/issues/301 | 2117 | // @see https://github.com/simple-rtmp-server/srs/issues/301 |
2149 | - if (ds && cache_sh_audio && (ret = consumer->enqueue(cache_sh_audio, atc, tba, tbv, ag)) != ERROR_SUCCESS) { | 2118 | + if (ds && cache_sh_audio && (ret = consumer->enqueue(cache_sh_audio, atc, jitter_algorithm)) != ERROR_SUCCESS) { |
2150 | srs_error("dispatch audio sequence header failed. ret=%d", ret); | 2119 | srs_error("dispatch audio sequence header failed. ret=%d", ret); |
2151 | return ret; | 2120 | return ret; |
2152 | } | 2121 | } |
2153 | srs_info("dispatch audio sequence header success"); | 2122 | srs_info("dispatch audio sequence header success"); |
2154 | 2123 | ||
2155 | - if (ds && cache_sh_video && (ret = consumer->enqueue(cache_sh_video, atc, tba, tbv, ag)) != ERROR_SUCCESS) { | 2124 | + if (ds && cache_sh_video && (ret = consumer->enqueue(cache_sh_video, atc, jitter_algorithm)) != ERROR_SUCCESS) { |
2156 | srs_error("dispatch video sequence header failed. ret=%d", ret); | 2125 | srs_error("dispatch video sequence header failed. ret=%d", ret); |
2157 | return ret; | 2126 | return ret; |
2158 | } | 2127 | } |
2159 | srs_info("dispatch video sequence header success"); | 2128 | srs_info("dispatch video sequence header success"); |
2160 | 2129 | ||
2161 | // copy gop cache to client. | 2130 | // copy gop cache to client. |
2162 | - if (dg && (ret = gop_cache->dump(consumer, atc, tba, tbv, ag)) != ERROR_SUCCESS) { | 2131 | + if (dg && (ret = gop_cache->dump(consumer, atc, jitter_algorithm)) != ERROR_SUCCESS) { |
2163 | return ret; | 2132 | return ret; |
2164 | } | 2133 | } |
2165 | 2134 | ||
2166 | // print status. | 2135 | // print status. |
2167 | if (dg) { | 2136 | if (dg) { |
2168 | - srs_trace("create consumer, queue_size=%.2f, tba=%d, tbv=%d", queue_size, sample_rate, frame_rate); | 2137 | + srs_trace("create consumer, queue_size=%.2f, jitter=%d", queue_size, jitter_algorithm); |
2169 | } else { | 2138 | } else { |
2170 | - srs_trace("create consumer, ignore gop cache, tba=%d, tbv=%d", sample_rate, frame_rate); | 2139 | + srs_trace("create consumer, ignore gop cache, jitter=%d", jitter_algorithm); |
2171 | } | 2140 | } |
2172 | 2141 | ||
2173 | return ret; | 2142 | return ret; |
@@ -2192,6 +2161,11 @@ void SrsSource::set_cache(bool enabled) | @@ -2192,6 +2161,11 @@ void SrsSource::set_cache(bool enabled) | ||
2192 | gop_cache->set(enabled); | 2161 | gop_cache->set(enabled); |
2193 | } | 2162 | } |
2194 | 2163 | ||
2164 | +SrsRtmpJitterAlgorithm SrsSource::jitter() | ||
2165 | +{ | ||
2166 | + return jitter_algorithm; | ||
2167 | +} | ||
2168 | + | ||
2195 | int SrsSource::on_edge_start_play() | 2169 | int SrsSource::on_edge_start_play() |
2196 | { | 2170 | { |
2197 | return play_edge->on_client_play(); | 2171 | return play_edge->on_client_play(); |
@@ -95,12 +95,9 @@ public: | @@ -95,12 +95,9 @@ public: | ||
95 | public: | 95 | public: |
96 | /** | 96 | /** |
97 | * detect the time jitter and correct it. | 97 | * detect the time jitter and correct it. |
98 | - * @param tba, the audio timebase, used to calc the "right" delta if jitter detected. | ||
99 | - * @param tbv, the video timebase, used to calc the "right" delta if jitter detected. | ||
100 | - * @param start_at_zero whether ensure stream start at zero. | ||
101 | - * @param mono_increasing whether ensure stream is monotonically inscreasing. | 98 | + * @param ag the algorithm to use for time jitter. |
102 | */ | 99 | */ |
103 | - virtual int correct(SrsSharedPtrMessage* msg, int tba, int tbv, SrsRtmpJitterAlgorithm ag); | 100 | + virtual int correct(SrsSharedPtrMessage* msg, SrsRtmpJitterAlgorithm ag); |
104 | /** | 101 | /** |
105 | * get current client time, the last packet time. | 102 | * get current client time, the last packet time. |
106 | */ | 103 | */ |
@@ -186,7 +183,7 @@ public: | @@ -186,7 +183,7 @@ public: | ||
186 | * dumps packets to consumer, use specified args. | 183 | * dumps packets to consumer, use specified args. |
187 | * @remark the atc/tba/tbv/ag are same to SrsConsumer.enqueue(). | 184 | * @remark the atc/tba/tbv/ag are same to SrsConsumer.enqueue(). |
188 | */ | 185 | */ |
189 | - virtual int dump_packets(SrsConsumer* consumer, bool atc, int tba, int tbv, SrsRtmpJitterAlgorithm ag); | 186 | + virtual int dump_packets(SrsConsumer* consumer, bool atc, SrsRtmpJitterAlgorithm ag); |
190 | private: | 187 | private: |
191 | /** | 188 | /** |
192 | * remove a gop from the front. | 189 | * remove a gop from the front. |
@@ -255,13 +252,9 @@ public: | @@ -255,13 +252,9 @@ public: | ||
255 | * enqueue an shared ptr message. | 252 | * enqueue an shared ptr message. |
256 | * @param shared_msg, directly ptr, copy it if need to save it. | 253 | * @param shared_msg, directly ptr, copy it if need to save it. |
257 | * @param whether atc, donot use jitter correct if true. | 254 | * @param whether atc, donot use jitter correct if true. |
258 | - * @param tba timebase of audio. | ||
259 | - * used to calc the audio time delta if time-jitter detected. | ||
260 | - * @param tbv timebase of video. | ||
261 | - * used to calc the video time delta if time-jitter detected. | ||
262 | * @param ag the algorithm of time jitter. | 255 | * @param ag the algorithm of time jitter. |
263 | */ | 256 | */ |
264 | - virtual int enqueue(SrsSharedPtrMessage* shared_msg, bool atc, int tba, int tbv, SrsRtmpJitterAlgorithm ag); | 257 | + virtual int enqueue(SrsSharedPtrMessage* shared_msg, bool atc, SrsRtmpJitterAlgorithm ag); |
265 | /** | 258 | /** |
266 | * get packets in consumer queue. | 259 | * get packets in consumer queue. |
267 | * @param msgs the msgs array to dump packets to send. | 260 | * @param msgs the msgs array to dump packets to send. |
@@ -351,9 +344,7 @@ public: | @@ -351,9 +344,7 @@ public: | ||
351 | /** | 344 | /** |
352 | * dump the cached gop to consumer. | 345 | * dump the cached gop to consumer. |
353 | */ | 346 | */ |
354 | - virtual int dump(SrsConsumer* consumer, | ||
355 | - bool atc, int tba, int tbv, SrsRtmpJitterAlgorithm jitter_algorithm | ||
356 | - ); | 347 | + virtual int dump(SrsConsumer* consumer, bool atc, SrsRtmpJitterAlgorithm jitter_algorithm); |
357 | /** | 348 | /** |
358 | * used for atc to get the time of gop cache, | 349 | * used for atc to get the time of gop cache, |
359 | * the atc will adjust the sequence header timestamp to gop cache. | 350 | * the atc will adjust the sequence header timestamp to gop cache. |
@@ -492,14 +483,6 @@ private: | @@ -492,14 +483,6 @@ private: | ||
492 | ISrsSourceHandler* handler; | 483 | ISrsSourceHandler* handler; |
493 | private: | 484 | private: |
494 | /** | 485 | /** |
495 | - * the sample rate of audio in metadata. | ||
496 | - */ | ||
497 | - int sample_rate; | ||
498 | - /** | ||
499 | - * the video frame rate in metadata. | ||
500 | - */ | ||
501 | - int frame_rate; | ||
502 | - /** | ||
503 | * can publish, true when is not streaming | 486 | * can publish, true when is not streaming |
504 | */ | 487 | */ |
505 | bool _can_publish; | 488 | bool _can_publish; |
@@ -595,6 +578,7 @@ public: | @@ -595,6 +578,7 @@ public: | ||
595 | ); | 578 | ); |
596 | virtual void on_consumer_destroy(SrsConsumer* consumer); | 579 | virtual void on_consumer_destroy(SrsConsumer* consumer); |
597 | virtual void set_cache(bool enabled); | 580 | virtual void set_cache(bool enabled); |
581 | + virtual SrsRtmpJitterAlgorithm jitter(); | ||
598 | // internal | 582 | // internal |
599 | public: | 583 | public: |
600 | // for edge, when play edge stream, check the state | 584 | // 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. | @@ -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 2 | 32 | #define VERSION_MAJOR 2 |
33 | #define VERSION_MINOR 0 | 33 | #define VERSION_MINOR 0 |
34 | -#define VERSION_REVISION 174 | 34 | +#define VERSION_REVISION 175 |
35 | 35 | ||
36 | // server info. | 36 | // server info. |
37 | #define RTMP_SIG_SRS_KEY "SRS" | 37 | #define RTMP_SIG_SRS_KEY "SRS" |
-
请 注册 或 登录 后发表评论