正在显示
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"); | ||
| 2140 | - | ||
| 2141 | if (conf) { | 2149 | if (conf) { |
| 2150 | + conf = conf->get("time_jitter"); | ||
| 2151 | + | ||
| 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."); | ||
| 1334 | - | ||
| 1335 | - srs_warn("Audio dts=%"PRId64", size=%d", msg.timestamp, msg.size); | 1407 | + srs_info("Audio dts=%"PRId64", size=%d", msg.timestamp, msg.size); |
| 1336 | 1408 | ||
| 1409 | + if (!mix_correct) { | ||
| 1337 | return on_audio_imp(&msg); | 1410 | return on_audio_imp(&msg); |
| 1411 | + } | ||
| 1412 | + | ||
| 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."); | ||
| 1494 | - | ||
| 1495 | - srs_warn("Video dts=%"PRId64", size=%d", msg.timestamp, msg.size); | 1571 | + srs_info("Video dts=%"PRId64", size=%d", msg.timestamp, msg.size); |
| 1496 | 1572 | ||
| 1573 | + if (!mix_correct) { | ||
| 1497 | return on_video_imp(&msg); | 1574 | return on_video_imp(&msg); |
| 1575 | + } | ||
| 1576 | + | ||
| 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" |
-
请 注册 或 登录 后发表评论