正在显示
12 个修改的文件
包含
269 行增加
和
39 行删除
| @@ -566,6 +566,7 @@ Supported operating systems and hardware: | @@ -566,6 +566,7 @@ Supported operating systems and hardware: | ||
| 566 | 566 | ||
| 567 | ### SRS 2.0 history | 567 | ### SRS 2.0 history |
| 568 | 568 | ||
| 569 | +* v2.0, 2015-04-15, for [#383](https://github.com/winlinvip/simple-rtmp-server/issues/383), support mix_correct algorithm. 2.0.161. | ||
| 569 | * 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. | 570 | * 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. |
| 570 | * v2.0, 2015-04-10, enhanced on_hls_notify, support HTTP GET when reap ts. | 571 | * v2.0, 2015-04-10, enhanced on_hls_notify, support HTTP GET when reap ts. |
| 571 | * v2.0, 2015-04-10, refine the hls deviation for floor algorithm. | 572 | * v2.0, 2015-04-10, refine the hls deviation for floor algorithm. |
| @@ -75,7 +75,7 @@ heartbeat { | @@ -75,7 +75,7 @@ heartbeat { | ||
| 75 | # the id of devide. | 75 | # the id of devide. |
| 76 | device_id "my-srs-device"; | 76 | device_id "my-srs-device"; |
| 77 | # whether report with summaries | 77 | # whether report with summaries |
| 78 | - # if true, put /api/v1/summaries to the request data: | 78 | + # if on, put /api/v1/summaries to the request data: |
| 79 | # { | 79 | # { |
| 80 | # "summaries": summaries object. | 80 | # "summaries": summaries object. |
| 81 | # } | 81 | # } |
| @@ -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,6 +1338,11 @@ vhost jitter.srs.com { | @@ -1338,6 +1338,11 @@ 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 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. | ||
| 1344 | + # default: off | ||
| 1345 | + mix_correct off; | ||
| 1341 | } | 1346 | } |
| 1342 | 1347 | ||
| 1343 | # vhost for atc. | 1348 | # vhost for atc. |
| @@ -171,7 +171,7 @@ int do_proxy(srs_flv_t flv, srs_rtmp_t ortmp, int64_t re, int32_t* pstarttime, u | @@ -171,7 +171,7 @@ int do_proxy(srs_flv_t flv, srs_rtmp_t ortmp, int64_t re, int32_t* pstarttime, u | ||
| 171 | return ret; | 171 | return ret; |
| 172 | } | 172 | } |
| 173 | 173 | ||
| 174 | - if (*pstarttime < 0) { | 174 | + if (*pstarttime < 0 && srs_utils_flv_tag_is_av(type)) { |
| 175 | *pstarttime = *ptimestamp; | 175 | *pstarttime = *ptimestamp; |
| 176 | } | 176 | } |
| 177 | 177 |
| @@ -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. |
| @@ -358,8 +358,18 @@ int SrsHttpHooks::on_hls_notify(std::string url, SrsRequest* req, std::string ts | @@ -358,8 +358,18 @@ int SrsHttpHooks::on_hls_notify(std::string url, SrsRequest* req, std::string ts | ||
| 358 | return ret; | 358 | return ret; |
| 359 | } | 359 | } |
| 360 | 360 | ||
| 361 | + std::string path = uri.get_query(); | ||
| 362 | + if (path.empty()) { | ||
| 363 | + path = uri.get_path(); | ||
| 364 | + } else { | ||
| 365 | + path = uri.get_path(); | ||
| 366 | + path += "?"; | ||
| 367 | + path += uri.get_query(); | ||
| 368 | + } | ||
| 369 | + srs_warn("GET %s", path.c_str()); | ||
| 370 | + | ||
| 361 | SrsHttpMessage* msg = NULL; | 371 | SrsHttpMessage* msg = NULL; |
| 362 | - if ((ret = http.get(uri.get_path(), "", &msg)) != ERROR_SUCCESS) { | 372 | + if ((ret = http.get(path.c_str(), "", &msg)) != ERROR_SUCCESS) { |
| 363 | return ret; | 373 | return ret; |
| 364 | } | 374 | } |
| 365 | SrsAutoFree(SrsHttpMessage, msg); | 375 | SrsAutoFree(SrsHttpMessage, msg); |
| @@ -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,10 +1404,23 @@ int SrsSource::on_audio(SrsCommonMessage* shared_audio) | @@ -1330,10 +1404,23 @@ 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); |
| 1408 | + | ||
| 1409 | + if (!mix_correct) { | ||
| 1410 | + return on_audio_imp(&msg); | ||
| 1411 | + } | ||
| 1412 | + | ||
| 1413 | + return do_mix_correct(&msg); | ||
| 1414 | +} | ||
| 1415 | + | ||
| 1416 | +int SrsSource::on_audio_imp(SrsSharedPtrMessage* msg) | ||
| 1417 | +{ | ||
| 1418 | + int ret = ERROR_SUCCESS; | ||
| 1419 | + | ||
| 1420 | + srs_info("Audio dts=%"PRId64", size=%d", msg->timestamp, msg->size); | ||
| 1334 | 1421 | ||
| 1335 | #ifdef SRS_AUTO_HLS | 1422 | #ifdef SRS_AUTO_HLS |
| 1336 | - if ((ret = hls->on_audio(&msg)) != ERROR_SUCCESS) { | 1423 | + if ((ret = hls->on_audio(msg)) != ERROR_SUCCESS) { |
| 1337 | // apply the error strategy for hls. | 1424 | // apply the error strategy for hls. |
| 1338 | // @see https://github.com/winlinvip/simple-rtmp-server/issues/264 | 1425 | // @see https://github.com/winlinvip/simple-rtmp-server/issues/264 |
| 1339 | std::string hls_error_strategy = _srs_config->get_hls_on_error(_req->vhost); | 1426 | std::string hls_error_strategy = _srs_config->get_hls_on_error(_req->vhost); |
| @@ -1347,7 +1434,7 @@ int SrsSource::on_audio(SrsCommonMessage* shared_audio) | @@ -1347,7 +1434,7 @@ int SrsSource::on_audio(SrsCommonMessage* shared_audio) | ||
| 1347 | ret = ERROR_SUCCESS; | 1434 | ret = ERROR_SUCCESS; |
| 1348 | } else if (hls_error_strategy == SRS_CONF_DEFAULT_HLS_ON_ERROR_CONTINUE) { | 1435 | } else if (hls_error_strategy == SRS_CONF_DEFAULT_HLS_ON_ERROR_CONTINUE) { |
| 1349 | // compare the sequence header with audio, continue when it's actually an sequence header. | 1436 | // compare the sequence header with audio, continue when it's actually an sequence header. |
| 1350 | - if (ret == ERROR_HLS_DECODE_ERROR && cache_sh_audio && cache_sh_audio->size == msg.size) { | 1437 | + if (ret == ERROR_HLS_DECODE_ERROR && cache_sh_audio && cache_sh_audio->size == msg->size) { |
| 1351 | srs_warn("the audio is actually a sequence header, ignore this packet."); | 1438 | srs_warn("the audio is actually a sequence header, ignore this packet."); |
| 1352 | ret = ERROR_SUCCESS; | 1439 | ret = ERROR_SUCCESS; |
| 1353 | } else { | 1440 | } else { |
| @@ -1362,7 +1449,7 @@ int SrsSource::on_audio(SrsCommonMessage* shared_audio) | @@ -1362,7 +1449,7 @@ int SrsSource::on_audio(SrsCommonMessage* shared_audio) | ||
| 1362 | #endif | 1449 | #endif |
| 1363 | 1450 | ||
| 1364 | #ifdef SRS_AUTO_DVR | 1451 | #ifdef SRS_AUTO_DVR |
| 1365 | - if ((ret = dvr->on_audio(&msg)) != ERROR_SUCCESS) { | 1452 | + if ((ret = dvr->on_audio(msg)) != ERROR_SUCCESS) { |
| 1366 | srs_warn("dvr process audio message failed, ignore and disable dvr. ret=%d", ret); | 1453 | srs_warn("dvr process audio message failed, ignore and disable dvr. ret=%d", ret); |
| 1367 | 1454 | ||
| 1368 | // unpublish, ignore ret. | 1455 | // unpublish, ignore ret. |
| @@ -1374,7 +1461,7 @@ int SrsSource::on_audio(SrsCommonMessage* shared_audio) | @@ -1374,7 +1461,7 @@ int SrsSource::on_audio(SrsCommonMessage* shared_audio) | ||
| 1374 | #endif | 1461 | #endif |
| 1375 | 1462 | ||
| 1376 | #ifdef SRS_AUTO_HDS | 1463 | #ifdef SRS_AUTO_HDS |
| 1377 | - if ((ret = hds->on_audio(&msg)) != ERROR_SUCCESS) { | 1464 | + if ((ret = hds->on_audio(msg)) != ERROR_SUCCESS) { |
| 1378 | srs_warn("hds process audio message failed, ignore and disable dvr. ret=%d", ret); | 1465 | srs_warn("hds process audio message failed, ignore and disable dvr. ret=%d", ret); |
| 1379 | 1466 | ||
| 1380 | // unpublish, ignore ret. | 1467 | // unpublish, ignore ret. |
| @@ -1390,7 +1477,7 @@ int SrsSource::on_audio(SrsCommonMessage* shared_audio) | @@ -1390,7 +1477,7 @@ int SrsSource::on_audio(SrsCommonMessage* shared_audio) | ||
| 1390 | SrsConsumer** pconsumer = consumers.data(); | 1477 | SrsConsumer** pconsumer = consumers.data(); |
| 1391 | for (int i = 0; i < nb_consumers; i++) { | 1478 | for (int i = 0; i < nb_consumers; i++) { |
| 1392 | SrsConsumer* consumer = pconsumer[i]; | 1479 | SrsConsumer* consumer = pconsumer[i]; |
| 1393 | - if ((ret = consumer->enqueue(&msg, atc, sample_rate, frame_rate, jitter_algorithm)) != ERROR_SUCCESS) { | 1480 | + if ((ret = consumer->enqueue(msg, atc, sample_rate, frame_rate, jitter_algorithm)) != ERROR_SUCCESS) { |
| 1394 | srs_error("dispatch the audio failed. ret=%d", ret); | 1481 | srs_error("dispatch the audio failed. ret=%d", ret); |
| 1395 | return ret; | 1482 | return ret; |
| 1396 | } | 1483 | } |
| @@ -1403,7 +1490,7 @@ int SrsSource::on_audio(SrsCommonMessage* shared_audio) | @@ -1403,7 +1490,7 @@ int SrsSource::on_audio(SrsCommonMessage* shared_audio) | ||
| 1403 | std::vector<SrsForwarder*>::iterator it; | 1490 | std::vector<SrsForwarder*>::iterator it; |
| 1404 | for (it = forwarders.begin(); it != forwarders.end(); ++it) { | 1491 | for (it = forwarders.begin(); it != forwarders.end(); ++it) { |
| 1405 | SrsForwarder* forwarder = *it; | 1492 | SrsForwarder* forwarder = *it; |
| 1406 | - if ((ret = forwarder->on_audio(&msg)) != ERROR_SUCCESS) { | 1493 | + if ((ret = forwarder->on_audio(msg)) != ERROR_SUCCESS) { |
| 1407 | srs_error("forwarder process audio message failed. ret=%d", ret); | 1494 | srs_error("forwarder process audio message failed. ret=%d", ret); |
| 1408 | return ret; | 1495 | return ret; |
| 1409 | } | 1496 | } |
| @@ -1413,10 +1500,10 @@ int SrsSource::on_audio(SrsCommonMessage* shared_audio) | @@ -1413,10 +1500,10 @@ int SrsSource::on_audio(SrsCommonMessage* shared_audio) | ||
| 1413 | // cache the sequence header of aac, or first packet of mp3. | 1500 | // cache the sequence header of aac, or first packet of mp3. |
| 1414 | // for example, the mp3 is used for hls to write the "right" audio codec. | 1501 | // for example, the mp3 is used for hls to write the "right" audio codec. |
| 1415 | // TODO: FIXME: to refine the stream info system. | 1502 | // TODO: FIXME: to refine the stream info system. |
| 1416 | - bool is_aac_sequence_header = SrsFlvCodec::audio_is_sequence_header(msg.payload, msg.size); | 1503 | + bool is_aac_sequence_header = SrsFlvCodec::audio_is_sequence_header(msg->payload, msg->size); |
| 1417 | if (is_aac_sequence_header || !cache_sh_audio) { | 1504 | if (is_aac_sequence_header || !cache_sh_audio) { |
| 1418 | srs_freep(cache_sh_audio); | 1505 | srs_freep(cache_sh_audio); |
| 1419 | - cache_sh_audio = msg.copy(); | 1506 | + cache_sh_audio = msg->copy(); |
| 1420 | } | 1507 | } |
| 1421 | 1508 | ||
| 1422 | // cache the sequence header if aac | 1509 | // cache the sequence header if aac |
| @@ -1425,7 +1512,7 @@ int SrsSource::on_audio(SrsCommonMessage* shared_audio) | @@ -1425,7 +1512,7 @@ int SrsSource::on_audio(SrsCommonMessage* shared_audio) | ||
| 1425 | // parse detail audio codec | 1512 | // parse detail audio codec |
| 1426 | SrsAvcAacCodec codec; | 1513 | SrsAvcAacCodec codec; |
| 1427 | SrsCodecSample sample; | 1514 | SrsCodecSample sample; |
| 1428 | - if ((ret = codec.audio_aac_demux(msg.payload, msg.size, &sample)) != ERROR_SUCCESS) { | 1515 | + if ((ret = codec.audio_aac_demux(msg->payload, msg->size, &sample)) != ERROR_SUCCESS) { |
| 1429 | srs_error("source codec demux audio failed. ret=%d", ret); | 1516 | srs_error("source codec demux audio failed. ret=%d", ret); |
| 1430 | return ret; | 1517 | return ret; |
| 1431 | } | 1518 | } |
| @@ -1442,7 +1529,7 @@ int SrsSource::on_audio(SrsCommonMessage* shared_audio) | @@ -1442,7 +1529,7 @@ int SrsSource::on_audio(SrsCommonMessage* shared_audio) | ||
| 1442 | srs_trace("%dB audio sh, " | 1529 | srs_trace("%dB audio sh, " |
| 1443 | "codec(%d, profile=%s, %dchannels, %dkbps, %dHZ), " | 1530 | "codec(%d, profile=%s, %dchannels, %dkbps, %dHZ), " |
| 1444 | "flv(%dbits, %dchannels, %dHZ)", | 1531 | "flv(%dbits, %dchannels, %dHZ)", |
| 1445 | - msg.size, codec.audio_codec_id, | 1532 | + msg->size, codec.audio_codec_id, |
| 1446 | srs_codec_aac_object2str(codec.aac_object).c_str(), codec.aac_channels, | 1533 | srs_codec_aac_object2str(codec.aac_object).c_str(), codec.aac_channels, |
| 1447 | codec.audio_data_rate / 1000, aac_sample_rates[codec.aac_sample_rate], | 1534 | codec.audio_data_rate / 1000, aac_sample_rates[codec.aac_sample_rate], |
| 1448 | flv_sample_sizes[sample.sound_size], flv_sound_types[sample.sound_type], | 1535 | flv_sample_sizes[sample.sound_size], flv_sound_types[sample.sound_type], |
| @@ -1451,7 +1538,7 @@ int SrsSource::on_audio(SrsCommonMessage* shared_audio) | @@ -1451,7 +1538,7 @@ int SrsSource::on_audio(SrsCommonMessage* shared_audio) | ||
| 1451 | } | 1538 | } |
| 1452 | 1539 | ||
| 1453 | // cache the last gop packets | 1540 | // cache the last gop packets |
| 1454 | - if ((ret = gop_cache->cache(&msg)) != ERROR_SUCCESS) { | 1541 | + if ((ret = gop_cache->cache(msg)) != ERROR_SUCCESS) { |
| 1455 | srs_error("shrink gop cache failed. ret=%d", ret); | 1542 | srs_error("shrink gop cache failed. ret=%d", ret); |
| 1456 | return ret; | 1543 | return ret; |
| 1457 | } | 1544 | } |
| @@ -1460,10 +1547,10 @@ int SrsSource::on_audio(SrsCommonMessage* shared_audio) | @@ -1460,10 +1547,10 @@ int SrsSource::on_audio(SrsCommonMessage* shared_audio) | ||
| 1460 | // if atc, update the sequence header to abs time. | 1547 | // if atc, update the sequence header to abs time. |
| 1461 | if (atc) { | 1548 | if (atc) { |
| 1462 | if (cache_sh_audio) { | 1549 | if (cache_sh_audio) { |
| 1463 | - cache_sh_audio->timestamp = msg.timestamp; | 1550 | + cache_sh_audio->timestamp = msg->timestamp; |
| 1464 | } | 1551 | } |
| 1465 | if (cache_metadata) { | 1552 | if (cache_metadata) { |
| 1466 | - cache_metadata->timestamp = msg.timestamp; | 1553 | + cache_metadata->timestamp = msg->timestamp; |
| 1467 | } | 1554 | } |
| 1468 | } | 1555 | } |
| 1469 | 1556 | ||
| @@ -1481,10 +1568,23 @@ int SrsSource::on_video(SrsCommonMessage* shared_video) | @@ -1481,10 +1568,23 @@ int SrsSource::on_video(SrsCommonMessage* shared_video) | ||
| 1481 | srs_error("initialize the video failed. ret=%d", ret); | 1568 | srs_error("initialize the video failed. ret=%d", ret); |
| 1482 | return ret; | 1569 | return ret; |
| 1483 | } | 1570 | } |
| 1484 | - srs_verbose("initialize shared ptr video success."); | 1571 | + srs_info("Video dts=%"PRId64", size=%d", msg.timestamp, msg.size); |
| 1572 | + | ||
| 1573 | + if (!mix_correct) { | ||
| 1574 | + return on_video_imp(&msg); | ||
| 1575 | + } | ||
| 1576 | + | ||
| 1577 | + return do_mix_correct(&msg); | ||
| 1578 | +} | ||
| 1579 | + | ||
| 1580 | +int SrsSource::on_video_imp(SrsSharedPtrMessage* msg) | ||
| 1581 | +{ | ||
| 1582 | + int ret = ERROR_SUCCESS; | ||
| 1583 | + | ||
| 1584 | + srs_info("Video dts=%"PRId64", size=%d", msg->timestamp, msg->size); | ||
| 1485 | 1585 | ||
| 1486 | #ifdef SRS_AUTO_HLS | 1586 | #ifdef SRS_AUTO_HLS |
| 1487 | - if ((ret = hls->on_video(&msg)) != ERROR_SUCCESS) { | 1587 | + if ((ret = hls->on_video(msg)) != ERROR_SUCCESS) { |
| 1488 | // apply the error strategy for hls. | 1588 | // apply the error strategy for hls. |
| 1489 | // @see https://github.com/winlinvip/simple-rtmp-server/issues/264 | 1589 | // @see https://github.com/winlinvip/simple-rtmp-server/issues/264 |
| 1490 | std::string hls_error_strategy = _srs_config->get_hls_on_error(_req->vhost); | 1590 | std::string hls_error_strategy = _srs_config->get_hls_on_error(_req->vhost); |
| @@ -1498,7 +1598,7 @@ int SrsSource::on_video(SrsCommonMessage* shared_video) | @@ -1498,7 +1598,7 @@ int SrsSource::on_video(SrsCommonMessage* shared_video) | ||
| 1498 | ret = ERROR_SUCCESS; | 1598 | ret = ERROR_SUCCESS; |
| 1499 | } else if (hls_error_strategy == SRS_CONF_DEFAULT_HLS_ON_ERROR_CONTINUE) { | 1599 | } else if (hls_error_strategy == SRS_CONF_DEFAULT_HLS_ON_ERROR_CONTINUE) { |
| 1500 | // compare the sequence header with video, continue when it's actually an sequence header. | 1600 | // compare the sequence header with video, continue when it's actually an sequence header. |
| 1501 | - if (ret == ERROR_HLS_DECODE_ERROR && cache_sh_video && cache_sh_video->size == msg.size) { | 1601 | + if (ret == ERROR_HLS_DECODE_ERROR && cache_sh_video && cache_sh_video->size == msg->size) { |
| 1502 | srs_warn("the video is actually a sequence header, ignore this packet."); | 1602 | srs_warn("the video is actually a sequence header, ignore this packet."); |
| 1503 | ret = ERROR_SUCCESS; | 1603 | ret = ERROR_SUCCESS; |
| 1504 | } else { | 1604 | } else { |
| @@ -1513,7 +1613,7 @@ int SrsSource::on_video(SrsCommonMessage* shared_video) | @@ -1513,7 +1613,7 @@ int SrsSource::on_video(SrsCommonMessage* shared_video) | ||
| 1513 | #endif | 1613 | #endif |
| 1514 | 1614 | ||
| 1515 | #ifdef SRS_AUTO_DVR | 1615 | #ifdef SRS_AUTO_DVR |
| 1516 | - if ((ret = dvr->on_video(&msg)) != ERROR_SUCCESS) { | 1616 | + if ((ret = dvr->on_video(msg)) != ERROR_SUCCESS) { |
| 1517 | srs_warn("dvr process video message failed, ignore and disable dvr. ret=%d", ret); | 1617 | srs_warn("dvr process video message failed, ignore and disable dvr. ret=%d", ret); |
| 1518 | 1618 | ||
| 1519 | // unpublish, ignore ret. | 1619 | // unpublish, ignore ret. |
| @@ -1525,7 +1625,7 @@ int SrsSource::on_video(SrsCommonMessage* shared_video) | @@ -1525,7 +1625,7 @@ int SrsSource::on_video(SrsCommonMessage* shared_video) | ||
| 1525 | #endif | 1625 | #endif |
| 1526 | 1626 | ||
| 1527 | #ifdef SRS_AUTO_HDS | 1627 | #ifdef SRS_AUTO_HDS |
| 1528 | - if ((ret = hds->on_video(&msg)) != ERROR_SUCCESS) { | 1628 | + if ((ret = hds->on_video(msg)) != ERROR_SUCCESS) { |
| 1529 | srs_warn("hds process video message failed, ignore and disable dvr. ret=%d", ret); | 1629 | srs_warn("hds process video message failed, ignore and disable dvr. ret=%d", ret); |
| 1530 | 1630 | ||
| 1531 | // unpublish, ignore ret. | 1631 | // unpublish, ignore ret. |
| @@ -1539,7 +1639,7 @@ int SrsSource::on_video(SrsCommonMessage* shared_video) | @@ -1539,7 +1639,7 @@ int SrsSource::on_video(SrsCommonMessage* shared_video) | ||
| 1539 | if (true) { | 1639 | if (true) { |
| 1540 | for (int i = 0; i < (int)consumers.size(); i++) { | 1640 | for (int i = 0; i < (int)consumers.size(); i++) { |
| 1541 | SrsConsumer* consumer = consumers.at(i); | 1641 | SrsConsumer* consumer = consumers.at(i); |
| 1542 | - if ((ret = consumer->enqueue(&msg, atc, sample_rate, frame_rate, jitter_algorithm)) != ERROR_SUCCESS) { | 1642 | + if ((ret = consumer->enqueue(msg, atc, sample_rate, frame_rate, jitter_algorithm)) != ERROR_SUCCESS) { |
| 1543 | srs_error("dispatch the video failed. ret=%d", ret); | 1643 | srs_error("dispatch the video failed. ret=%d", ret); |
| 1544 | return ret; | 1644 | return ret; |
| 1545 | } | 1645 | } |
| @@ -1552,7 +1652,7 @@ int SrsSource::on_video(SrsCommonMessage* shared_video) | @@ -1552,7 +1652,7 @@ int SrsSource::on_video(SrsCommonMessage* shared_video) | ||
| 1552 | std::vector<SrsForwarder*>::iterator it; | 1652 | std::vector<SrsForwarder*>::iterator it; |
| 1553 | for (it = forwarders.begin(); it != forwarders.end(); ++it) { | 1653 | for (it = forwarders.begin(); it != forwarders.end(); ++it) { |
| 1554 | SrsForwarder* forwarder = *it; | 1654 | SrsForwarder* forwarder = *it; |
| 1555 | - if ((ret = forwarder->on_video(&msg)) != ERROR_SUCCESS) { | 1655 | + if ((ret = forwarder->on_video(msg)) != ERROR_SUCCESS) { |
| 1556 | srs_error("forwarder process video message failed. ret=%d", ret); | 1656 | srs_error("forwarder process video message failed. ret=%d", ret); |
| 1557 | return ret; | 1657 | return ret; |
| 1558 | } | 1658 | } |
| @@ -1561,14 +1661,14 @@ int SrsSource::on_video(SrsCommonMessage* shared_video) | @@ -1561,14 +1661,14 @@ int SrsSource::on_video(SrsCommonMessage* shared_video) | ||
| 1561 | 1661 | ||
| 1562 | // cache the sequence header if h264 | 1662 | // cache the sequence header if h264 |
| 1563 | // donot cache the sequence header to gop_cache, return here. | 1663 | // donot cache the sequence header to gop_cache, return here. |
| 1564 | - if (SrsFlvCodec::video_is_sequence_header(msg.payload, msg.size)) { | 1664 | + if (SrsFlvCodec::video_is_sequence_header(msg->payload, msg->size)) { |
| 1565 | srs_freep(cache_sh_video); | 1665 | srs_freep(cache_sh_video); |
| 1566 | - cache_sh_video = msg.copy(); | 1666 | + cache_sh_video = msg->copy(); |
| 1567 | 1667 | ||
| 1568 | // parse detail audio codec | 1668 | // parse detail audio codec |
| 1569 | SrsAvcAacCodec codec; | 1669 | SrsAvcAacCodec codec; |
| 1570 | SrsCodecSample sample; | 1670 | SrsCodecSample sample; |
| 1571 | - if ((ret = codec.video_avc_demux(msg.payload, msg.size, &sample)) != ERROR_SUCCESS) { | 1671 | + if ((ret = codec.video_avc_demux(msg->payload, msg->size, &sample)) != ERROR_SUCCESS) { |
| 1572 | srs_error("source codec demux video failed. ret=%d", ret); | 1672 | srs_error("source codec demux video failed. ret=%d", ret); |
| 1573 | return ret; | 1673 | return ret; |
| 1574 | } | 1674 | } |
| @@ -1581,7 +1681,7 @@ int SrsSource::on_video(SrsCommonMessage* shared_video) | @@ -1581,7 +1681,7 @@ int SrsSource::on_video(SrsCommonMessage* shared_video) | ||
| 1581 | 1681 | ||
| 1582 | srs_trace("%dB video sh, " | 1682 | srs_trace("%dB video sh, " |
| 1583 | "codec(%d, profile=%s, level=%s, %dx%d, %dkbps, %dfps, %ds)", | 1683 | "codec(%d, profile=%s, level=%s, %dx%d, %dkbps, %dfps, %ds)", |
| 1584 | - msg.size, codec.video_codec_id, | 1684 | + msg->size, codec.video_codec_id, |
| 1585 | srs_codec_avc_profile2str(codec.avc_profile).c_str(), | 1685 | srs_codec_avc_profile2str(codec.avc_profile).c_str(), |
| 1586 | srs_codec_avc_level2str(codec.avc_level).c_str(), codec.width, codec.height, | 1686 | srs_codec_avc_level2str(codec.avc_level).c_str(), codec.width, codec.height, |
| 1587 | codec.video_data_rate / 1000, codec.frame_rate, codec.duration); | 1687 | codec.video_data_rate / 1000, codec.frame_rate, codec.duration); |
| @@ -1589,7 +1689,7 @@ int SrsSource::on_video(SrsCommonMessage* shared_video) | @@ -1589,7 +1689,7 @@ int SrsSource::on_video(SrsCommonMessage* shared_video) | ||
| 1589 | } | 1689 | } |
| 1590 | 1690 | ||
| 1591 | // cache the last gop packets | 1691 | // cache the last gop packets |
| 1592 | - if ((ret = gop_cache->cache(&msg)) != ERROR_SUCCESS) { | 1692 | + if ((ret = gop_cache->cache(msg)) != ERROR_SUCCESS) { |
| 1593 | srs_error("gop cache msg failed. ret=%d", ret); | 1693 | srs_error("gop cache msg failed. ret=%d", ret); |
| 1594 | return ret; | 1694 | return ret; |
| 1595 | } | 1695 | } |
| @@ -1598,16 +1698,39 @@ int SrsSource::on_video(SrsCommonMessage* shared_video) | @@ -1598,16 +1698,39 @@ int SrsSource::on_video(SrsCommonMessage* shared_video) | ||
| 1598 | // if atc, update the sequence header to abs time. | 1698 | // if atc, update the sequence header to abs time. |
| 1599 | if (atc) { | 1699 | if (atc) { |
| 1600 | if (cache_sh_video) { | 1700 | if (cache_sh_video) { |
| 1601 | - cache_sh_video->timestamp = msg.timestamp; | 1701 | + cache_sh_video->timestamp = msg->timestamp; |
| 1602 | } | 1702 | } |
| 1603 | if (cache_metadata) { | 1703 | if (cache_metadata) { |
| 1604 | - cache_metadata->timestamp = msg.timestamp; | 1704 | + cache_metadata->timestamp = msg->timestamp; |
| 1605 | } | 1705 | } |
| 1606 | } | 1706 | } |
| 1607 | 1707 | ||
| 1608 | return ret; | 1708 | return ret; |
| 1609 | } | 1709 | } |
| 1610 | 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 | + | ||
| 1611 | int SrsSource::on_aggregate(SrsCommonMessage* msg) | 1734 | int SrsSource::on_aggregate(SrsCommonMessage* msg) |
| 1612 | { | 1735 | { |
| 1613 | int ret = ERROR_SUCCESS; | 1736 | int ret = ERROR_SUCCESS; |
| @@ -1748,6 +1871,9 @@ int SrsSource::on_publish() | @@ -1748,6 +1871,9 @@ int SrsSource::on_publish() | ||
| 1748 | // save its id to srouce id. | 1871 | // save its id to srouce id. |
| 1749 | on_source_id_changed(_srs_context->get_id()); | 1872 | on_source_id_changed(_srs_context->get_id()); |
| 1750 | 1873 | ||
| 1874 | + // reset the mix queue. | ||
| 1875 | + mix_queue->clear(); | ||
| 1876 | + | ||
| 1751 | // create forwarders | 1877 | // create forwarders |
| 1752 | if ((ret = create_forwarders()) != ERROR_SUCCESS) { | 1878 | if ((ret = create_forwarders()) != ERROR_SUCCESS) { |
| 1753 | 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); |
| @@ -495,8 +516,17 @@ public: | @@ -495,8 +516,17 @@ public: | ||
| 495 | public: | 516 | public: |
| 496 | virtual bool can_publish(); | 517 | virtual bool can_publish(); |
| 497 | virtual int on_meta_data(SrsCommonMessage* msg, SrsOnMetaDataPacket* metadata); | 518 | virtual int on_meta_data(SrsCommonMessage* msg, SrsOnMetaDataPacket* metadata); |
| 519 | +public: | ||
| 498 | virtual int on_audio(SrsCommonMessage* audio); | 520 | virtual int on_audio(SrsCommonMessage* audio); |
| 521 | +private: | ||
| 522 | + virtual int on_audio_imp(SrsSharedPtrMessage* audio); | ||
| 523 | +public: | ||
| 499 | virtual int on_video(SrsCommonMessage* video); | 524 | virtual int on_video(SrsCommonMessage* video); |
| 525 | +private: | ||
| 526 | + virtual int on_video_imp(SrsSharedPtrMessage* video); | ||
| 527 | +private: | ||
| 528 | + virtual int do_mix_correct(SrsSharedPtrMessage* msg); | ||
| 529 | +public: | ||
| 500 | virtual int on_aggregate(SrsCommonMessage* msg); | 530 | virtual int on_aggregate(SrsCommonMessage* msg); |
| 501 | /** | 531 | /** |
| 502 | * the pre-publish is we are very sure we are | 532 | * the pre-publish is we are very sure we are |
| @@ -1979,6 +1979,21 @@ srs_bool srs_utils_flv_tag_is_ok(char type) | @@ -1979,6 +1979,21 @@ srs_bool srs_utils_flv_tag_is_ok(char type) | ||
| 1979 | return type == SRS_RTMP_TYPE_AUDIO || type == SRS_RTMP_TYPE_VIDEO || type == SRS_RTMP_TYPE_SCRIPT; | 1979 | return type == SRS_RTMP_TYPE_AUDIO || type == SRS_RTMP_TYPE_VIDEO || type == SRS_RTMP_TYPE_SCRIPT; |
| 1980 | } | 1980 | } |
| 1981 | 1981 | ||
| 1982 | +srs_bool srs_utils_flv_tag_is_audio(char type) | ||
| 1983 | +{ | ||
| 1984 | + return type == SRS_RTMP_TYPE_AUDIO; | ||
| 1985 | +} | ||
| 1986 | + | ||
| 1987 | +srs_bool srs_utils_flv_tag_is_video(char type) | ||
| 1988 | +{ | ||
| 1989 | + return type == SRS_RTMP_TYPE_VIDEO; | ||
| 1990 | +} | ||
| 1991 | + | ||
| 1992 | +srs_bool srs_utils_flv_tag_is_av(char type) | ||
| 1993 | +{ | ||
| 1994 | + return type == SRS_RTMP_TYPE_AUDIO || type == SRS_RTMP_TYPE_VIDEO; | ||
| 1995 | +} | ||
| 1996 | + | ||
| 1982 | char srs_utils_flv_video_codec_id(char* data, int size) | 1997 | char srs_utils_flv_video_codec_id(char* data, int size) |
| 1983 | { | 1998 | { |
| 1984 | if (size < 1) { | 1999 | if (size < 1) { |
| @@ -661,6 +661,9 @@ extern int srs_utils_parse_timestamp( | @@ -661,6 +661,9 @@ extern int srs_utils_parse_timestamp( | ||
| 661 | * @return true when tag is video/audio/script-data; otherwise, false. | 661 | * @return true when tag is video/audio/script-data; otherwise, false. |
| 662 | */ | 662 | */ |
| 663 | extern srs_bool srs_utils_flv_tag_is_ok(char type); | 663 | extern srs_bool srs_utils_flv_tag_is_ok(char type); |
| 664 | +extern srs_bool srs_utils_flv_tag_is_audio(char type); | ||
| 665 | +extern srs_bool srs_utils_flv_tag_is_video(char type); | ||
| 666 | +extern srs_bool srs_utils_flv_tag_is_av(char type); | ||
| 664 | 667 | ||
| 665 | /** | 668 | /** |
| 666 | * get the CodecID of video tag. | 669 | * get the CodecID of video tag. |
-
请 注册 或 登录 后发表评论