正在显示
9 个修改的文件
包含
189 行增加
和
17 行删除
@@ -562,6 +562,7 @@ Supported operating systems and hardware: | @@ -562,6 +562,7 @@ Supported operating systems and hardware: | ||
562 | 562 | ||
563 | ### SRS 2.0 history | 563 | ### SRS 2.0 history |
564 | 564 | ||
565 | +* v2.0, 2015-04-15, for [#383](https://github.com/winlinvip/simple-rtmp-server/issues/383), support mix_correct algorithm. 2.0.161. | ||
565 | * v2.0, 2015-04-13, for [#381](https://github.com/winlinvip/simple-rtmp-server/issues/381), support reap hls/ts by gop or not. 2.0.160. | 566 | * v2.0, 2015-04-13, for [#381](https://github.com/winlinvip/simple-rtmp-server/issues/381), support reap hls/ts by gop or not. 2.0.160. |
566 | * v2.0, 2015-04-10, enhanced on_hls_notify, support HTTP GET when reap ts. | 567 | * v2.0, 2015-04-10, enhanced on_hls_notify, support HTTP GET when reap ts. |
567 | * v2.0, 2015-04-10, refine the hls deviation for floor algorithm. | 568 | * v2.0, 2015-04-10, refine the hls deviation for floor algorithm. |
@@ -1329,7 +1329,7 @@ vhost jitter.srs.com { | @@ -1329,7 +1329,7 @@ vhost jitter.srs.com { | ||
1329 | # about the stream monotonically increasing: | 1329 | # about the stream monotonically increasing: |
1330 | # 1. video timestamp is monotonically increasing, | 1330 | # 1. video timestamp is monotonically increasing, |
1331 | # 2. audio timestamp is monotonically increasing, | 1331 | # 2. audio timestamp is monotonically increasing, |
1332 | - # 3. video and audio timestamp is interleaved monotonically increasing. | 1332 | + # 3. video and audio timestamp is interleaved/mixed monotonically increasing. |
1333 | # it's specified by RTMP specification, @see 3. Byte Order, Alignment, and Time Format | 1333 | # it's specified by RTMP specification, @see 3. Byte Order, Alignment, and Time Format |
1334 | # however, some encoder cannot provides this feature, please set this to off to ignore time jitter. | 1334 | # however, some encoder cannot provides this feature, please set this to off to ignore time jitter. |
1335 | # the time jitter algorithm: | 1335 | # the time jitter algorithm: |
@@ -1338,8 +1338,8 @@ vhost jitter.srs.com { | @@ -1338,8 +1338,8 @@ vhost jitter.srs.com { | ||
1338 | # 3. off, disable the time jitter algorithm, like atc. | 1338 | # 3. off, disable the time jitter algorithm, like atc. |
1339 | # default: full | 1339 | # default: full |
1340 | time_jitter full; | 1340 | time_jitter full; |
1341 | - # whether use the mix algorithm to correct the timestamp. | ||
1342 | - # if on, always ensure the timestamp of audio+video is monotonically increase. | 1341 | + # whether use the interleaved/mixed algorithm to correct the timestamp. |
1342 | + # if on, always ensure the timestamp of audio+video is interleaved/mixed monotonically increase. | ||
1343 | # if off, use time_jitter to correct the timestamp if required. | 1343 | # if off, use time_jitter to correct the timestamp if required. |
1344 | # default: off | 1344 | # default: off |
1345 | mix_correct off; | 1345 | mix_correct off; |
@@ -807,6 +807,17 @@ int SrsConfig::reload_vhost(SrsConfDirective* old_root) | @@ -807,6 +807,17 @@ int SrsConfig::reload_vhost(SrsConfDirective* old_root) | ||
807 | } | 807 | } |
808 | srs_trace("vhost %s reload time_jitter success.", vhost.c_str()); | 808 | srs_trace("vhost %s reload time_jitter success.", vhost.c_str()); |
809 | } | 809 | } |
810 | + // mix_correct, only one per vhost | ||
811 | + if (!srs_directive_equals(new_vhost->get("mix_correct"), old_vhost->get("mix_correct"))) { | ||
812 | + for (it = subscribes.begin(); it != subscribes.end(); ++it) { | ||
813 | + ISrsReloadHandler* subscribe = *it; | ||
814 | + if ((ret = subscribe->on_reload_vhost_mix_correct(vhost)) != ERROR_SUCCESS) { | ||
815 | + srs_error("vhost %s notify subscribes mix_correct failed. ret=%d", vhost.c_str(), ret); | ||
816 | + return ret; | ||
817 | + } | ||
818 | + } | ||
819 | + srs_trace("vhost %s reload mix_correct success.", vhost.c_str()); | ||
820 | + } | ||
810 | // forward, only one per vhost | 821 | // forward, only one per vhost |
811 | if (!srs_directive_equals(new_vhost->get("forward"), old_vhost->get("forward"))) { | 822 | if (!srs_directive_equals(new_vhost->get("forward"), old_vhost->get("forward"))) { |
812 | for (it = subscribes.begin(); it != subscribes.end(); ++it) { | 823 | for (it = subscribes.begin(); it != subscribes.end(); ++it) { |
@@ -1419,7 +1430,7 @@ int SrsConfig::check_config() | @@ -1419,7 +1430,7 @@ int SrsConfig::check_config() | ||
1419 | && n != "gop_cache" && n != "queue_length" | 1430 | && n != "gop_cache" && n != "queue_length" |
1420 | && n != "refer" && n != "refer_publish" && n != "refer_play" | 1431 | && n != "refer" && n != "refer_publish" && n != "refer_play" |
1421 | && n != "forward" && n != "transcode" && n != "bandcheck" | 1432 | && n != "forward" && n != "transcode" && n != "bandcheck" |
1422 | - && n != "time_jitter" | 1433 | + && n != "time_jitter" && n != "mix_correct" |
1423 | && n != "atc" && n != "atc_auto" | 1434 | && n != "atc" && n != "atc_auto" |
1424 | && n != "debug_srs_upnode" | 1435 | && n != "debug_srs_upnode" |
1425 | && n != "mr" && n != "mw_latency" && n != "min_latency" | 1436 | && n != "mr" && n != "mw_latency" && n != "min_latency" |
@@ -2118,12 +2129,12 @@ bool SrsConfig::get_atc_auto(string vhost) | @@ -2118,12 +2129,12 @@ bool SrsConfig::get_atc_auto(string vhost) | ||
2118 | SrsConfDirective* conf = get_vhost(vhost); | 2129 | SrsConfDirective* conf = get_vhost(vhost); |
2119 | 2130 | ||
2120 | if (!conf) { | 2131 | if (!conf) { |
2121 | - return true; | 2132 | + return SRS_CONF_DEFAULT_ATC_AUTO; |
2122 | } | 2133 | } |
2123 | 2134 | ||
2124 | conf = conf->get("atc_auto"); | 2135 | conf = conf->get("atc_auto"); |
2125 | if (!conf || conf->arg0().empty()) { | 2136 | if (!conf || conf->arg0().empty()) { |
2126 | - return true; | 2137 | + return SRS_CONF_DEFAULT_ATC_AUTO; |
2127 | } | 2138 | } |
2128 | 2139 | ||
2129 | return SRS_CONF_PERFER_TRUE(conf->arg0()); | 2140 | return SRS_CONF_PERFER_TRUE(conf->arg0()); |
@@ -2131,14 +2142,14 @@ bool SrsConfig::get_atc_auto(string vhost) | @@ -2131,14 +2142,14 @@ bool SrsConfig::get_atc_auto(string vhost) | ||
2131 | 2142 | ||
2132 | int SrsConfig::get_time_jitter(string vhost) | 2143 | int SrsConfig::get_time_jitter(string vhost) |
2133 | { | 2144 | { |
2134 | - SrsConfDirective* dvr = get_vhost(vhost); | 2145 | + SrsConfDirective* conf = get_vhost(vhost); |
2135 | 2146 | ||
2136 | std::string time_jitter = SRS_CONF_DEFAULT_TIME_JITTER; | 2147 | std::string time_jitter = SRS_CONF_DEFAULT_TIME_JITTER; |
2137 | 2148 | ||
2138 | - if (dvr) { | ||
2139 | - SrsConfDirective* conf = dvr->get("time_jitter"); | 2149 | + if (conf) { |
2150 | + conf = conf->get("time_jitter"); | ||
2140 | 2151 | ||
2141 | - if (conf) { | 2152 | + if (conf && !conf->arg0().empty()) { |
2142 | time_jitter = conf->arg0(); | 2153 | time_jitter = conf->arg0(); |
2143 | } | 2154 | } |
2144 | } | 2155 | } |
@@ -2146,6 +2157,22 @@ int SrsConfig::get_time_jitter(string vhost) | @@ -2146,6 +2157,22 @@ int SrsConfig::get_time_jitter(string vhost) | ||
2146 | return _srs_time_jitter_string2int(time_jitter); | 2157 | return _srs_time_jitter_string2int(time_jitter); |
2147 | } | 2158 | } |
2148 | 2159 | ||
2160 | +bool SrsConfig::get_mix_correct(string vhost) | ||
2161 | +{ | ||
2162 | + SrsConfDirective* conf = get_vhost(vhost); | ||
2163 | + | ||
2164 | + if (!conf) { | ||
2165 | + return SRS_CONF_DEFAULT_MIX_CORRECT; | ||
2166 | + } | ||
2167 | + | ||
2168 | + conf = conf->get("mix_correct"); | ||
2169 | + if (!conf || conf->arg0().empty()) { | ||
2170 | + return SRS_CONF_DEFAULT_MIX_CORRECT; | ||
2171 | + } | ||
2172 | + | ||
2173 | + return SRS_CONF_PERFER_FALSE(conf->arg0()); | ||
2174 | +} | ||
2175 | + | ||
2149 | double SrsConfig::get_queue_length(string vhost) | 2176 | double SrsConfig::get_queue_length(string vhost) |
2150 | { | 2177 | { |
2151 | SrsConfDirective* conf = get_vhost(vhost); | 2178 | SrsConfDirective* conf = get_vhost(vhost); |
@@ -72,6 +72,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | @@ -72,6 +72,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
72 | #define SRS_CONF_DEFAULT_DVR_PLAN SRS_CONF_DEFAULT_DVR_PLAN_SESSION | 72 | #define SRS_CONF_DEFAULT_DVR_PLAN SRS_CONF_DEFAULT_DVR_PLAN_SESSION |
73 | #define SRS_CONF_DEFAULT_DVR_DURATION 30 | 73 | #define SRS_CONF_DEFAULT_DVR_DURATION 30 |
74 | #define SRS_CONF_DEFAULT_TIME_JITTER "full" | 74 | #define SRS_CONF_DEFAULT_TIME_JITTER "full" |
75 | +#define SRS_CONF_DEFAULT_ATC_AUTO true | ||
76 | +#define SRS_CONF_DEFAULT_MIX_CORRECT false | ||
75 | // in seconds, the paused queue length. | 77 | // in seconds, the paused queue length. |
76 | #define SRS_CONF_DEFAULT_PAUSED_LENGTH 10 | 78 | #define SRS_CONF_DEFAULT_PAUSED_LENGTH 10 |
77 | // the interval in seconds for bandwidth check | 79 | // the interval in seconds for bandwidth check |
@@ -532,6 +534,11 @@ public: | @@ -532,6 +534,11 @@ public: | ||
532 | */ | 534 | */ |
533 | virtual int get_time_jitter(std::string vhost); | 535 | virtual int get_time_jitter(std::string vhost); |
534 | /** | 536 | /** |
537 | + * whether use mix correct algorithm to ensure the timestamp | ||
538 | + * monotonically increase. | ||
539 | + */ | ||
540 | + virtual bool get_mix_correct(std::string vhost); | ||
541 | + /** | ||
535 | * get the cache queue length, in seconds. | 542 | * get the cache queue length, in seconds. |
536 | * when exceed the queue length, drop packet util I frame. | 543 | * when exceed the queue length, drop packet util I frame. |
537 | * @remark, default 10. | 544 | * @remark, default 10. |
@@ -130,6 +130,11 @@ int ISrsReloadHandler::on_reload_vhost_time_jitter(string /*vhost*/) | @@ -130,6 +130,11 @@ int ISrsReloadHandler::on_reload_vhost_time_jitter(string /*vhost*/) | ||
130 | return ERROR_SUCCESS; | 130 | return ERROR_SUCCESS; |
131 | } | 131 | } |
132 | 132 | ||
133 | +int ISrsReloadHandler::on_reload_vhost_mix_correct(string /*vhost*/) | ||
134 | +{ | ||
135 | + return ERROR_SUCCESS; | ||
136 | +} | ||
137 | + | ||
133 | int ISrsReloadHandler::on_reload_vhost_forward(string /*vhost*/) | 138 | int ISrsReloadHandler::on_reload_vhost_forward(string /*vhost*/) |
134 | { | 139 | { |
135 | return ERROR_SUCCESS; | 140 | return ERROR_SUCCESS; |
@@ -63,6 +63,7 @@ public: | @@ -63,6 +63,7 @@ public: | ||
63 | virtual int on_reload_vhost_gop_cache(std::string vhost); | 63 | virtual int on_reload_vhost_gop_cache(std::string vhost); |
64 | virtual int on_reload_vhost_queue_length(std::string vhost); | 64 | virtual int on_reload_vhost_queue_length(std::string vhost); |
65 | virtual int on_reload_vhost_time_jitter(std::string vhost); | 65 | virtual int on_reload_vhost_time_jitter(std::string vhost); |
66 | + virtual int on_reload_vhost_mix_correct(std::string vhost); | ||
66 | virtual int on_reload_vhost_forward(std::string vhost); | 67 | virtual int on_reload_vhost_forward(std::string vhost); |
67 | virtual int on_reload_vhost_hls(std::string vhost); | 68 | virtual int on_reload_vhost_hls(std::string vhost); |
68 | virtual int on_reload_vhost_hds(std::string vhost); | 69 | virtual int on_reload_vhost_hds(std::string vhost); |
@@ -44,6 +44,7 @@ using namespace std; | @@ -44,6 +44,7 @@ using namespace std; | ||
44 | #include <srs_rtmp_msg_array.hpp> | 44 | #include <srs_rtmp_msg_array.hpp> |
45 | #include <srs_app_hds.hpp> | 45 | #include <srs_app_hds.hpp> |
46 | #include <srs_app_statistic.hpp> | 46 | #include <srs_app_statistic.hpp> |
47 | +#include <srs_core_autofree.hpp> | ||
47 | 48 | ||
48 | #define CONST_MAX_JITTER_MS 500 | 49 | #define CONST_MAX_JITTER_MS 500 |
49 | #define DEFAULT_FRAME_TIME_MS 40 | 50 | #define DEFAULT_FRAME_TIME_MS 40 |
@@ -768,10 +769,62 @@ void SrsSource::destroy() | @@ -768,10 +769,62 @@ void SrsSource::destroy() | ||
768 | pool.clear(); | 769 | pool.clear(); |
769 | } | 770 | } |
770 | 771 | ||
772 | +SrsMixQueue::SrsMixQueue() | ||
773 | +{ | ||
774 | + nb_videos = 0; | ||
775 | +} | ||
776 | + | ||
777 | +SrsMixQueue::~SrsMixQueue() | ||
778 | +{ | ||
779 | + clear(); | ||
780 | +} | ||
781 | + | ||
782 | +void SrsMixQueue::clear() | ||
783 | +{ | ||
784 | + std::multimap<int64_t, SrsSharedPtrMessage*>::iterator it; | ||
785 | + for (it = msgs.begin(); it != msgs.end(); ++it) { | ||
786 | + SrsSharedPtrMessage* msg = it->second; | ||
787 | + srs_freep(msg); | ||
788 | + } | ||
789 | + msgs.clear(); | ||
790 | + | ||
791 | + nb_videos = 0; | ||
792 | +} | ||
793 | + | ||
794 | +void SrsMixQueue::push(SrsSharedPtrMessage* msg) | ||
795 | +{ | ||
796 | + msgs.insert(std::make_pair(msg->timestamp, msg)); | ||
797 | + | ||
798 | + if (msg->is_video()) { | ||
799 | + nb_videos++; | ||
800 | + } | ||
801 | +} | ||
802 | + | ||
803 | +SrsSharedPtrMessage* SrsMixQueue::pop() | ||
804 | +{ | ||
805 | + // always keep 2+ videos | ||
806 | + if (nb_videos < 2) { | ||
807 | + return NULL; | ||
808 | + } | ||
809 | + | ||
810 | + // pop the first msg. | ||
811 | + std::multimap<int64_t, SrsSharedPtrMessage*>::iterator it = msgs.begin(); | ||
812 | + SrsSharedPtrMessage* msg = it->second; | ||
813 | + msgs.erase(it); | ||
814 | + | ||
815 | + if (msg->is_video()) { | ||
816 | + nb_videos--; | ||
817 | + } | ||
818 | + | ||
819 | + return msg; | ||
820 | +} | ||
821 | + | ||
771 | SrsSource::SrsSource() | 822 | SrsSource::SrsSource() |
772 | { | 823 | { |
773 | _req = NULL; | 824 | _req = NULL; |
774 | jitter_algorithm = SrsRtmpJitterAlgorithmOFF; | 825 | jitter_algorithm = SrsRtmpJitterAlgorithmOFF; |
826 | + mix_correct = false; | ||
827 | + mix_queue = new SrsMixQueue(); | ||
775 | 828 | ||
776 | #ifdef SRS_AUTO_HLS | 829 | #ifdef SRS_AUTO_HLS |
777 | hls = new SrsHls(); | 830 | hls = new SrsHls(); |
@@ -818,6 +871,7 @@ SrsSource::~SrsSource() | @@ -818,6 +871,7 @@ SrsSource::~SrsSource() | ||
818 | forwarders.clear(); | 871 | forwarders.clear(); |
819 | } | 872 | } |
820 | 873 | ||
874 | + srs_freep(mix_queue); | ||
821 | srs_freep(cache_metadata); | 875 | srs_freep(cache_metadata); |
822 | srs_freep(cache_sh_video); | 876 | srs_freep(cache_sh_video); |
823 | srs_freep(cache_sh_audio); | 877 | srs_freep(cache_sh_audio); |
@@ -878,6 +932,7 @@ int SrsSource::initialize(SrsRequest* r, ISrsSourceHandler* h, ISrsHlsHandler* h | @@ -878,6 +932,7 @@ int SrsSource::initialize(SrsRequest* r, ISrsSourceHandler* h, ISrsHlsHandler* h | ||
878 | publish_edge->set_queue_size(queue_size); | 932 | publish_edge->set_queue_size(queue_size); |
879 | 933 | ||
880 | jitter_algorithm = (SrsRtmpJitterAlgorithm)_srs_config->get_time_jitter(_req->vhost); | 934 | jitter_algorithm = (SrsRtmpJitterAlgorithm)_srs_config->get_time_jitter(_req->vhost); |
935 | + mix_correct = _srs_config->get_mix_correct(_req->vhost); | ||
881 | 936 | ||
882 | return ret; | 937 | return ret; |
883 | } | 938 | } |
@@ -973,6 +1028,25 @@ int SrsSource::on_reload_vhost_time_jitter(string vhost) | @@ -973,6 +1028,25 @@ int SrsSource::on_reload_vhost_time_jitter(string vhost) | ||
973 | return ret; | 1028 | return ret; |
974 | } | 1029 | } |
975 | 1030 | ||
1031 | +int SrsSource::on_reload_vhost_mix_correct(string vhost) | ||
1032 | +{ | ||
1033 | + int ret = ERROR_SUCCESS; | ||
1034 | + | ||
1035 | + if (_req->vhost != vhost) { | ||
1036 | + return ret; | ||
1037 | + } | ||
1038 | + | ||
1039 | + bool v = _srs_config->get_mix_correct(_req->vhost); | ||
1040 | + | ||
1041 | + // when changed, clear the mix queue. | ||
1042 | + if (v != mix_correct) { | ||
1043 | + mix_queue->clear(); | ||
1044 | + } | ||
1045 | + mix_correct = v; | ||
1046 | + | ||
1047 | + return ret; | ||
1048 | +} | ||
1049 | + | ||
976 | int SrsSource::on_reload_vhost_forward(string vhost) | 1050 | int SrsSource::on_reload_vhost_forward(string vhost) |
977 | { | 1051 | { |
978 | int ret = ERROR_SUCCESS; | 1052 | int ret = ERROR_SUCCESS; |
@@ -1330,17 +1404,21 @@ int SrsSource::on_audio(SrsCommonMessage* shared_audio) | @@ -1330,17 +1404,21 @@ int SrsSource::on_audio(SrsCommonMessage* shared_audio) | ||
1330 | srs_error("initialize the audio failed. ret=%d", ret); | 1404 | srs_error("initialize the audio failed. ret=%d", ret); |
1331 | return ret; | 1405 | return ret; |
1332 | } | 1406 | } |
1333 | - srs_verbose("initialize shared ptr audio success."); | 1407 | + srs_info("Audio dts=%"PRId64", size=%d", msg.timestamp, msg.size); |
1334 | 1408 | ||
1335 | - srs_warn("Audio dts=%"PRId64", size=%d", msg.timestamp, msg.size); | 1409 | + if (!mix_correct) { |
1410 | + return on_audio_imp(&msg); | ||
1411 | + } | ||
1336 | 1412 | ||
1337 | - return on_audio_imp(&msg); | 1413 | + return do_mix_correct(&msg); |
1338 | } | 1414 | } |
1339 | 1415 | ||
1340 | int SrsSource::on_audio_imp(SrsSharedPtrMessage* msg) | 1416 | int SrsSource::on_audio_imp(SrsSharedPtrMessage* msg) |
1341 | { | 1417 | { |
1342 | int ret = ERROR_SUCCESS; | 1418 | int ret = ERROR_SUCCESS; |
1343 | 1419 | ||
1420 | + srs_info("Audio dts=%"PRId64", size=%d", msg->timestamp, msg->size); | ||
1421 | + | ||
1344 | #ifdef SRS_AUTO_HLS | 1422 | #ifdef SRS_AUTO_HLS |
1345 | if ((ret = hls->on_audio(msg)) != ERROR_SUCCESS) { | 1423 | if ((ret = hls->on_audio(msg)) != ERROR_SUCCESS) { |
1346 | // apply the error strategy for hls. | 1424 | // apply the error strategy for hls. |
@@ -1490,17 +1568,21 @@ int SrsSource::on_video(SrsCommonMessage* shared_video) | @@ -1490,17 +1568,21 @@ int SrsSource::on_video(SrsCommonMessage* shared_video) | ||
1490 | srs_error("initialize the video failed. ret=%d", ret); | 1568 | srs_error("initialize the video failed. ret=%d", ret); |
1491 | return ret; | 1569 | return ret; |
1492 | } | 1570 | } |
1493 | - srs_verbose("initialize shared ptr video success."); | 1571 | + srs_info("Video dts=%"PRId64", size=%d", msg.timestamp, msg.size); |
1494 | 1572 | ||
1495 | - srs_warn("Video dts=%"PRId64", size=%d", msg.timestamp, msg.size); | 1573 | + if (!mix_correct) { |
1574 | + return on_video_imp(&msg); | ||
1575 | + } | ||
1496 | 1576 | ||
1497 | - return on_video_imp(&msg); | 1577 | + return do_mix_correct(&msg); |
1498 | } | 1578 | } |
1499 | 1579 | ||
1500 | int SrsSource::on_video_imp(SrsSharedPtrMessage* msg) | 1580 | int SrsSource::on_video_imp(SrsSharedPtrMessage* msg) |
1501 | { | 1581 | { |
1502 | int ret = ERROR_SUCCESS; | 1582 | int ret = ERROR_SUCCESS; |
1503 | 1583 | ||
1584 | + srs_info("Video dts=%"PRId64", size=%d", msg->timestamp, msg->size); | ||
1585 | + | ||
1504 | #ifdef SRS_AUTO_HLS | 1586 | #ifdef SRS_AUTO_HLS |
1505 | if ((ret = hls->on_video(msg)) != ERROR_SUCCESS) { | 1587 | if ((ret = hls->on_video(msg)) != ERROR_SUCCESS) { |
1506 | // apply the error strategy for hls. | 1588 | // apply the error strategy for hls. |
@@ -1626,6 +1708,29 @@ int SrsSource::on_video_imp(SrsSharedPtrMessage* msg) | @@ -1626,6 +1708,29 @@ int SrsSource::on_video_imp(SrsSharedPtrMessage* msg) | ||
1626 | return ret; | 1708 | return ret; |
1627 | } | 1709 | } |
1628 | 1710 | ||
1711 | +int SrsSource::do_mix_correct(SrsSharedPtrMessage* msg) | ||
1712 | +{ | ||
1713 | + int ret = ERROR_SUCCESS; | ||
1714 | + | ||
1715 | + // insert msg to the queue. | ||
1716 | + mix_queue->push(msg->copy()); | ||
1717 | + | ||
1718 | + // fetch someone from mix queue. | ||
1719 | + SrsSharedPtrMessage* m = mix_queue->pop(); | ||
1720 | + if (!m) { | ||
1721 | + return ret; | ||
1722 | + } | ||
1723 | + SrsAutoFree(SrsSharedPtrMessage, m); | ||
1724 | + | ||
1725 | + // consume the monotonically increase message. | ||
1726 | + if (m->is_audio()) { | ||
1727 | + return on_audio_imp(m); | ||
1728 | + } | ||
1729 | + | ||
1730 | + srs_assert(m->is_video()); | ||
1731 | + return on_video_imp(m); | ||
1732 | +} | ||
1733 | + | ||
1629 | int SrsSource::on_aggregate(SrsCommonMessage* msg) | 1734 | int SrsSource::on_aggregate(SrsCommonMessage* msg) |
1630 | { | 1735 | { |
1631 | int ret = ERROR_SUCCESS; | 1736 | int ret = ERROR_SUCCESS; |
@@ -1766,6 +1871,9 @@ int SrsSource::on_publish() | @@ -1766,6 +1871,9 @@ int SrsSource::on_publish() | ||
1766 | // save its id to srouce id. | 1871 | // save its id to srouce id. |
1767 | on_source_id_changed(_srs_context->get_id()); | 1872 | on_source_id_changed(_srs_context->get_id()); |
1768 | 1873 | ||
1874 | + // reset the mix queue. | ||
1875 | + mix_queue->clear(); | ||
1876 | + | ||
1769 | // create forwarders | 1877 | // create forwarders |
1770 | if ((ret = create_forwarders()) != ERROR_SUCCESS) { | 1878 | if ((ret = create_forwarders()) != ERROR_SUCCESS) { |
1771 | srs_error("create forwarders failed. ret=%d", ret); | 1879 | srs_error("create forwarders failed. ret=%d", ret); |
@@ -369,6 +369,23 @@ public: | @@ -369,6 +369,23 @@ public: | ||
369 | }; | 369 | }; |
370 | 370 | ||
371 | /** | 371 | /** |
372 | + * the mix queue to correct the timestamp for mix_correct algorithm. | ||
373 | + */ | ||
374 | +class SrsMixQueue | ||
375 | +{ | ||
376 | +private: | ||
377 | + u_int32_t nb_videos; | ||
378 | + std::multimap<int64_t, SrsSharedPtrMessage*> msgs; | ||
379 | +public: | ||
380 | + SrsMixQueue(); | ||
381 | + virtual ~SrsMixQueue(); | ||
382 | +public: | ||
383 | + virtual void clear(); | ||
384 | + virtual void push(SrsSharedPtrMessage* msg); | ||
385 | + virtual SrsSharedPtrMessage* pop(); | ||
386 | +}; | ||
387 | + | ||
388 | +/** | ||
372 | * live streaming source. | 389 | * live streaming source. |
373 | */ | 390 | */ |
374 | class SrsSource : public ISrsReloadHandler | 391 | class SrsSource : public ISrsReloadHandler |
@@ -407,6 +424,9 @@ private: | @@ -407,6 +424,9 @@ private: | ||
407 | std::vector<SrsConsumer*> consumers; | 424 | std::vector<SrsConsumer*> consumers; |
408 | // the time jitter algorithm for vhost. | 425 | // the time jitter algorithm for vhost. |
409 | SrsRtmpJitterAlgorithm jitter_algorithm; | 426 | SrsRtmpJitterAlgorithm jitter_algorithm; |
427 | + // whether use interlaced/mixed algorithm to correct timestamp. | ||
428 | + bool mix_correct; | ||
429 | + SrsMixQueue* mix_queue; | ||
410 | // hls handler. | 430 | // hls handler. |
411 | #ifdef SRS_AUTO_HLS | 431 | #ifdef SRS_AUTO_HLS |
412 | SrsHls* hls; | 432 | SrsHls* hls; |
@@ -474,6 +494,7 @@ public: | @@ -474,6 +494,7 @@ public: | ||
474 | virtual int on_reload_vhost_gop_cache(std::string vhost); | 494 | virtual int on_reload_vhost_gop_cache(std::string vhost); |
475 | virtual int on_reload_vhost_queue_length(std::string vhost); | 495 | virtual int on_reload_vhost_queue_length(std::string vhost); |
476 | virtual int on_reload_vhost_time_jitter(std::string vhost); | 496 | virtual int on_reload_vhost_time_jitter(std::string vhost); |
497 | + virtual int on_reload_vhost_mix_correct(std::string vhost); | ||
477 | virtual int on_reload_vhost_forward(std::string vhost); | 498 | virtual int on_reload_vhost_forward(std::string vhost); |
478 | virtual int on_reload_vhost_hls(std::string vhost); | 499 | virtual int on_reload_vhost_hls(std::string vhost); |
479 | virtual int on_reload_vhost_hds(std::string vhost); | 500 | virtual int on_reload_vhost_hds(std::string vhost); |
@@ -503,6 +524,8 @@ public: | @@ -503,6 +524,8 @@ public: | ||
503 | virtual int on_video(SrsCommonMessage* video); | 524 | virtual int on_video(SrsCommonMessage* video); |
504 | private: | 525 | private: |
505 | virtual int on_video_imp(SrsSharedPtrMessage* video); | 526 | virtual int on_video_imp(SrsSharedPtrMessage* video); |
527 | +private: | ||
528 | + virtual int do_mix_correct(SrsSharedPtrMessage* msg); | ||
506 | public: | 529 | public: |
507 | virtual int on_aggregate(SrsCommonMessage* msg); | 530 | virtual int on_aggregate(SrsCommonMessage* msg); |
508 | /** | 531 | /** |
@@ -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 160 | 34 | +#define VERSION_REVISION 161 |
35 | 35 | ||
36 | // server info. | 36 | // server info. |
37 | #define RTMP_SIG_SRS_KEY "SRS" | 37 | #define RTMP_SIG_SRS_KEY "SRS" |
-
请 注册 或 登录 后发表评论