正在显示
5 个修改的文件
包含
56 行增加
和
14 行删除
| @@ -342,6 +342,7 @@ Remark: | @@ -342,6 +342,7 @@ Remark: | ||
| 342 | 342 | ||
| 343 | ## History | 343 | ## History |
| 344 | 344 | ||
| 345 | +* v2.0, 2015-08-14, use reduce_sequence_header for stream control. | ||
| 345 | * v2.0, 2015-08-14, use send_min_interval for stream control. 2.0.183 | 346 | * v2.0, 2015-08-14, use send_min_interval for stream control. 2.0.183 |
| 346 | * v2.0, 2015-08-12, enable the SRS_PERF_TCP_NODELAY and add config tcp_nodelay. 2.0.182 | 347 | * v2.0, 2015-08-12, enable the SRS_PERF_TCP_NODELAY and add config tcp_nodelay. 2.0.182 |
| 347 | * v2.0, 2015-08-11, for [#442](https://github.com/simple-rtmp-server/srs/issues/442) support kickoff connected client. 2.0.181 | 348 | * v2.0, 2015-08-11, for [#442](https://github.com/simple-rtmp-server/srs/issues/442) support kickoff connected client. 2.0.181 |
| @@ -876,7 +876,12 @@ vhost stream.control.com { | @@ -876,7 +876,12 @@ vhost stream.control.com { | ||
| 876 | # @remark 0 to disable the minimal interval. | 876 | # @remark 0 to disable the minimal interval. |
| 877 | # @remark >0 to make the srs to send message one by one. | 877 | # @remark >0 to make the srs to send message one by one. |
| 878 | # default: 0 | 878 | # default: 0 |
| 879 | - send_min_interval 10; | 879 | + send_min_interval 10; |
| 880 | + # whether reduce the sequence header, | ||
| 881 | + # for some client which cannot got duplicated sequence header, | ||
| 882 | + # while the sequence header is not changed yet. | ||
| 883 | + # default: off | ||
| 884 | + reduce_sequence_header on; | ||
| 880 | } | 885 | } |
| 881 | 886 | ||
| 882 | # the vhost for antisuck. | 887 | # the vhost for antisuck. |
| @@ -1761,7 +1761,8 @@ int SrsConfig::check_config() | @@ -1761,7 +1761,8 @@ int SrsConfig::check_config() | ||
| 1761 | && n != "time_jitter" && n != "mix_correct" | 1761 | && n != "time_jitter" && n != "mix_correct" |
| 1762 | && n != "atc" && n != "atc_auto" | 1762 | && n != "atc" && n != "atc_auto" |
| 1763 | && n != "debug_srs_upnode" | 1763 | && n != "debug_srs_upnode" |
| 1764 | - && n != "mr" && n != "mw_latency" && n != "min_latency" && n != "tcp_nodelay" && n != "send_min_interval" | 1764 | + && n != "mr" && n != "mw_latency" && n != "min_latency" |
| 1765 | + && n != "tcp_nodelay" && n != "send_min_interval" && n != "reduce_sequence_header" | ||
| 1765 | && n != "security" && n != "http_remux" | 1766 | && n != "security" && n != "http_remux" |
| 1766 | && n != "http" && n != "http_static" | 1767 | && n != "http" && n != "http_static" |
| 1767 | && n != "hds" | 1768 | && n != "hds" |
| @@ -2534,6 +2535,23 @@ int SrsConfig::get_send_min_interval(string vhost) | @@ -2534,6 +2535,23 @@ int SrsConfig::get_send_min_interval(string vhost) | ||
| 2534 | return ::atoi(conf->arg0().c_str()); | 2535 | return ::atoi(conf->arg0().c_str()); |
| 2535 | } | 2536 | } |
| 2536 | 2537 | ||
| 2538 | +bool SrsConfig::get_reduce_sequence_header(string vhost) | ||
| 2539 | +{ | ||
| 2540 | + static bool DEFAULT = false; | ||
| 2541 | + | ||
| 2542 | + SrsConfDirective* conf = get_vhost(vhost); | ||
| 2543 | + if (!conf) { | ||
| 2544 | + return DEFAULT; | ||
| 2545 | + } | ||
| 2546 | + | ||
| 2547 | + conf = conf->get("reduce_sequence_header"); | ||
| 2548 | + if (!conf || conf->arg0().empty()) { | ||
| 2549 | + return DEFAULT; | ||
| 2550 | + } | ||
| 2551 | + | ||
| 2552 | + return SRS_CONF_PERFER_FALSE(conf->arg0()); | ||
| 2553 | +} | ||
| 2554 | + | ||
| 2537 | int SrsConfig::get_global_chunk_size() | 2555 | int SrsConfig::get_global_chunk_size() |
| 2538 | { | 2556 | { |
| 2539 | SrsConfDirective* conf = root->get("chunk_size"); | 2557 | SrsConfDirective* conf = root->get("chunk_size"); |
| @@ -530,6 +530,10 @@ public: | @@ -530,6 +530,10 @@ public: | ||
| 530 | * the minimal send interval in ms. | 530 | * the minimal send interval in ms. |
| 531 | */ | 531 | */ |
| 532 | virtual int get_send_min_interval(std::string vhost); | 532 | virtual int get_send_min_interval(std::string vhost); |
| 533 | + /** | ||
| 534 | + * whether reduce the sequence header. | ||
| 535 | + */ | ||
| 536 | + virtual bool get_reduce_sequence_header(std::string vhost); | ||
| 533 | private: | 537 | private: |
| 534 | /** | 538 | /** |
| 535 | * get the global chunk size. | 539 | * get the global chunk size. |
| @@ -1535,6 +1535,8 @@ int SrsSource::on_audio_imp(SrsSharedPtrMessage* msg) | @@ -1535,6 +1535,8 @@ int SrsSource::on_audio_imp(SrsSharedPtrMessage* msg) | ||
| 1535 | int ret = ERROR_SUCCESS; | 1535 | int ret = ERROR_SUCCESS; |
| 1536 | 1536 | ||
| 1537 | srs_info("Audio dts=%"PRId64", size=%d", msg->timestamp, msg->size); | 1537 | srs_info("Audio dts=%"PRId64", size=%d", msg->timestamp, msg->size); |
| 1538 | + bool is_aac_sequence_header = SrsFlvCodec::audio_is_sequence_header(msg->payload, msg->size); | ||
| 1539 | + bool is_sequence_header = is_aac_sequence_header; | ||
| 1538 | 1540 | ||
| 1539 | #ifdef SRS_AUTO_HLS | 1541 | #ifdef SRS_AUTO_HLS |
| 1540 | if ((ret = hls->on_audio(msg)) != ERROR_SUCCESS) { | 1542 | if ((ret = hls->on_audio(msg)) != ERROR_SUCCESS) { |
| @@ -1589,11 +1591,16 @@ int SrsSource::on_audio_imp(SrsSharedPtrMessage* msg) | @@ -1589,11 +1591,16 @@ int SrsSource::on_audio_imp(SrsSharedPtrMessage* msg) | ||
| 1589 | #endif | 1591 | #endif |
| 1590 | 1592 | ||
| 1591 | // copy to all consumer | 1593 | // copy to all consumer |
| 1592 | - int nb_consumers = (int)consumers.size(); | ||
| 1593 | - if (nb_consumers > 0) { | ||
| 1594 | - SrsConsumer** pconsumer = consumers.data(); | ||
| 1595 | - for (int i = 0; i < nb_consumers; i++) { | ||
| 1596 | - SrsConsumer* consumer = pconsumer[i]; | 1594 | + bool drop_for_reduce = false; |
| 1595 | + if (is_sequence_header && cache_sh_audio && _srs_config->get_reduce_sequence_header(_req->vhost)) { | ||
| 1596 | + if (cache_sh_audio->size == msg->size) { | ||
| 1597 | + drop_for_reduce = srs_bytes_equals(cache_sh_audio->payload, msg->payload, msg->size); | ||
| 1598 | + srs_warn("drop for reduce sh audio, size=%d", msg->size); | ||
| 1599 | + } | ||
| 1600 | + } | ||
| 1601 | + if (!drop_for_reduce) { | ||
| 1602 | + for (int i = 0; i < (int)consumers.size(); i++) { | ||
| 1603 | + SrsConsumer* consumer = consumers.at(i); | ||
| 1597 | if ((ret = consumer->enqueue(msg, atc, jitter_algorithm)) != ERROR_SUCCESS) { | 1604 | if ((ret = consumer->enqueue(msg, atc, jitter_algorithm)) != ERROR_SUCCESS) { |
| 1598 | srs_error("dispatch the audio failed. ret=%d", ret); | 1605 | srs_error("dispatch the audio failed. ret=%d", ret); |
| 1599 | return ret; | 1606 | return ret; |
| @@ -1617,7 +1624,6 @@ int SrsSource::on_audio_imp(SrsSharedPtrMessage* msg) | @@ -1617,7 +1624,6 @@ int SrsSource::on_audio_imp(SrsSharedPtrMessage* msg) | ||
| 1617 | // cache the sequence header of aac, or first packet of mp3. | 1624 | // cache the sequence header of aac, or first packet of mp3. |
| 1618 | // for example, the mp3 is used for hls to write the "right" audio codec. | 1625 | // for example, the mp3 is used for hls to write the "right" audio codec. |
| 1619 | // TODO: FIXME: to refine the stream info system. | 1626 | // TODO: FIXME: to refine the stream info system. |
| 1620 | - bool is_aac_sequence_header = SrsFlvCodec::audio_is_sequence_header(msg->payload, msg->size); | ||
| 1621 | if (is_aac_sequence_header || !cache_sh_audio) { | 1627 | if (is_aac_sequence_header || !cache_sh_audio) { |
| 1622 | srs_freep(cache_sh_audio); | 1628 | srs_freep(cache_sh_audio); |
| 1623 | cache_sh_audio = msg->copy(); | 1629 | cache_sh_audio = msg->copy(); |
| @@ -1740,6 +1746,8 @@ int SrsSource::on_video_imp(SrsSharedPtrMessage* msg) | @@ -1740,6 +1746,8 @@ int SrsSource::on_video_imp(SrsSharedPtrMessage* msg) | ||
| 1740 | 1746 | ||
| 1741 | srs_info("Video dts=%"PRId64", size=%d", msg->timestamp, msg->size); | 1747 | srs_info("Video dts=%"PRId64", size=%d", msg->timestamp, msg->size); |
| 1742 | 1748 | ||
| 1749 | + bool is_sequence_header = SrsFlvCodec::video_is_sequence_header(msg->payload, msg->size); | ||
| 1750 | + | ||
| 1743 | #ifdef SRS_AUTO_HLS | 1751 | #ifdef SRS_AUTO_HLS |
| 1744 | if ((ret = hls->on_video(msg)) != ERROR_SUCCESS) { | 1752 | if ((ret = hls->on_video(msg)) != ERROR_SUCCESS) { |
| 1745 | // apply the error strategy for hls. | 1753 | // apply the error strategy for hls. |
| @@ -1793,7 +1801,14 @@ int SrsSource::on_video_imp(SrsSharedPtrMessage* msg) | @@ -1793,7 +1801,14 @@ int SrsSource::on_video_imp(SrsSharedPtrMessage* msg) | ||
| 1793 | #endif | 1801 | #endif |
| 1794 | 1802 | ||
| 1795 | // copy to all consumer | 1803 | // copy to all consumer |
| 1796 | - if (true) { | 1804 | + bool drop_for_reduce = false; |
| 1805 | + if (is_sequence_header && cache_sh_video && _srs_config->get_reduce_sequence_header(_req->vhost)) { | ||
| 1806 | + if (cache_sh_video->size == msg->size) { | ||
| 1807 | + drop_for_reduce = srs_bytes_equals(cache_sh_video->payload, msg->payload, msg->size); | ||
| 1808 | + srs_warn("drop for reduce sh video, size=%d", msg->size); | ||
| 1809 | + } | ||
| 1810 | + } | ||
| 1811 | + if (!drop_for_reduce) { | ||
| 1797 | for (int i = 0; i < (int)consumers.size(); i++) { | 1812 | for (int i = 0; i < (int)consumers.size(); i++) { |
| 1798 | SrsConsumer* consumer = consumers.at(i); | 1813 | SrsConsumer* consumer = consumers.at(i); |
| 1799 | if ((ret = consumer->enqueue(msg, atc, jitter_algorithm)) != ERROR_SUCCESS) { | 1814 | if ((ret = consumer->enqueue(msg, atc, jitter_algorithm)) != ERROR_SUCCESS) { |
| @@ -1818,7 +1833,7 @@ int SrsSource::on_video_imp(SrsSharedPtrMessage* msg) | @@ -1818,7 +1833,7 @@ int SrsSource::on_video_imp(SrsSharedPtrMessage* msg) | ||
| 1818 | 1833 | ||
| 1819 | // cache the sequence header if h264 | 1834 | // cache the sequence header if h264 |
| 1820 | // donot cache the sequence header to gop_cache, return here. | 1835 | // donot cache the sequence header to gop_cache, return here. |
| 1821 | - if (SrsFlvCodec::video_is_sequence_header(msg->payload, msg->size)) { | 1836 | + if (is_sequence_header) { |
| 1822 | srs_freep(cache_sh_video); | 1837 | srs_freep(cache_sh_video); |
| 1823 | cache_sh_video = msg->copy(); | 1838 | cache_sh_video = msg->copy(); |
| 1824 | 1839 | ||
| @@ -2062,13 +2077,12 @@ void SrsSource::on_unpublish() | @@ -2062,13 +2077,12 @@ void SrsSource::on_unpublish() | ||
| 2062 | hds->on_unpublish(); | 2077 | hds->on_unpublish(); |
| 2063 | #endif | 2078 | #endif |
| 2064 | 2079 | ||
| 2080 | + // only clear the gop cache metadata, | ||
| 2081 | + // donot clear the sequence header, for it maybe not changed. | ||
| 2065 | gop_cache->clear(); | 2082 | gop_cache->clear(); |
| 2066 | - | ||
| 2067 | srs_freep(cache_metadata); | 2083 | srs_freep(cache_metadata); |
| 2068 | - srs_freep(cache_sh_video); | ||
| 2069 | - srs_freep(cache_sh_audio); | ||
| 2070 | 2084 | ||
| 2071 | - srs_info("clear cache/metadata/sequence-headers when unpublish."); | 2085 | + srs_info("clear cache/metadata when unpublish."); |
| 2072 | srs_trace("cleanup when unpublish"); | 2086 | srs_trace("cleanup when unpublish"); |
| 2073 | 2087 | ||
| 2074 | _can_publish = true; | 2088 | _can_publish = true; |
-
请 注册 或 登录 后发表评论