fix #474, config to donot parse width/height from sps. 2.0.189
正在显示
10 个修改的文件
包含
94 行增加
和
11 行删除
@@ -343,6 +343,7 @@ Remark: | @@ -343,6 +343,7 @@ Remark: | ||
343 | 343 | ||
344 | ## History | 344 | ## History |
345 | 345 | ||
346 | +* v2.0, 2015-09-14, fix [#474][bug #474] config to donot parse width/height from sps. 2.0.189 | ||
346 | * v2.0, 2015-09-14, for [#474][bug #474] always release publish for source. | 347 | * v2.0, 2015-09-14, for [#474][bug #474] always release publish for source. |
347 | * v2.0, 2015-09-14, for [#458][bug #458] http hooks use source thread cid. 2.0.188 | 348 | * v2.0, 2015-09-14, for [#458][bug #458] http hooks use source thread cid. 2.0.188 |
348 | * v2.0, 2015-09-14, for [#475][bug #475] fix http hooks crash for st context switch. 2.0.187 | 349 | * v2.0, 2015-09-14, for [#475][bug #475] fix http hooks crash for st context switch. 2.0.187 |
@@ -858,6 +858,17 @@ vhost min.delay.com { | @@ -858,6 +858,17 @@ vhost min.delay.com { | ||
858 | tcp_nodelay on; | 858 | tcp_nodelay on; |
859 | } | 859 | } |
860 | 860 | ||
861 | +# whether disable the sps parse, for the resolution of video. | ||
862 | +vhost no.parse.sps.com { | ||
863 | + publish { | ||
864 | + # whether parse the sps when publish stream. | ||
865 | + # we can got the resolution of video for stat api. | ||
866 | + # but we may failed to cause publish failed. | ||
867 | + # default: on | ||
868 | + parse_sps on; | ||
869 | + } | ||
870 | +} | ||
871 | + | ||
861 | # the vhost to control the stream delivery feature | 872 | # the vhost to control the stream delivery feature |
862 | vhost stream.control.com { | 873 | vhost stream.control.com { |
863 | # @see vhost mrw.srs.com for detail. | 874 | # @see vhost mrw.srs.com for detail. |
@@ -618,6 +618,9 @@ int SrsConfig::reload_vhost(SrsConfDirective* old_root) | @@ -618,6 +618,9 @@ int SrsConfig::reload_vhost(SrsConfDirective* old_root) | ||
618 | srs_error("reload never supports mode changed. ret=%d", ret); | 618 | srs_error("reload never supports mode changed. ret=%d", ret); |
619 | return ret; | 619 | return ret; |
620 | } | 620 | } |
621 | + | ||
622 | + // the auto reload configs: | ||
623 | + // publish.parse_sps | ||
621 | 624 | ||
622 | // ENABLED => ENABLED (modified) | 625 | // ENABLED => ENABLED (modified) |
623 | if (get_vhost_enabled(new_vhost) && get_vhost_enabled(old_vhost)) { | 626 | if (get_vhost_enabled(new_vhost) && get_vhost_enabled(old_vhost)) { |
@@ -1806,7 +1809,7 @@ int SrsConfig::check_config() | @@ -1806,7 +1809,7 @@ int SrsConfig::check_config() | ||
1806 | && n != "time_jitter" && n != "mix_correct" | 1809 | && n != "time_jitter" && n != "mix_correct" |
1807 | && n != "atc" && n != "atc_auto" | 1810 | && n != "atc" && n != "atc_auto" |
1808 | && n != "debug_srs_upnode" | 1811 | && n != "debug_srs_upnode" |
1809 | - && n != "mr" && n != "mw_latency" && n != "min_latency" | 1812 | + && n != "mr" && n != "mw_latency" && n != "min_latency" && n != "publish" |
1810 | && n != "tcp_nodelay" && n != "send_min_interval" && n != "reduce_sequence_header" | 1813 | && n != "tcp_nodelay" && n != "send_min_interval" && n != "reduce_sequence_header" |
1811 | && n != "publish_1stpkt_timeout" && n != "publish_normal_timeout" | 1814 | && n != "publish_1stpkt_timeout" && n != "publish_normal_timeout" |
1812 | && n != "security" && n != "http_remux" | 1815 | && n != "security" && n != "http_remux" |
@@ -1839,6 +1842,16 @@ int SrsConfig::check_config() | @@ -1839,6 +1842,16 @@ int SrsConfig::check_config() | ||
1839 | return ret; | 1842 | return ret; |
1840 | } | 1843 | } |
1841 | } | 1844 | } |
1845 | + } else if (n == "publish") { | ||
1846 | + for (int j = 0; j < (int)conf->directives.size(); j++) { | ||
1847 | + string m = conf->at(j)->name.c_str(); | ||
1848 | + if (m != "parse_sps" | ||
1849 | + ) { | ||
1850 | + ret = ERROR_SYSTEM_CONFIG_INVALID; | ||
1851 | + srs_error("unsupported vhost publish directive %s, ret=%d", m.c_str(), ret); | ||
1852 | + return ret; | ||
1853 | + } | ||
1854 | + } | ||
1842 | } else if (n == "ingest") { | 1855 | } else if (n == "ingest") { |
1843 | for (int j = 0; j < (int)conf->directives.size(); j++) { | 1856 | for (int j = 0; j < (int)conf->directives.size(); j++) { |
1844 | string m = conf->at(j)->name.c_str(); | 1857 | string m = conf->at(j)->name.c_str(); |
@@ -2473,6 +2486,29 @@ int SrsConfig::get_chunk_size(string vhost) | @@ -2473,6 +2486,29 @@ int SrsConfig::get_chunk_size(string vhost) | ||
2473 | return ::atoi(conf->arg0().c_str()); | 2486 | return ::atoi(conf->arg0().c_str()); |
2474 | } | 2487 | } |
2475 | 2488 | ||
2489 | +bool SrsConfig::get_parse_sps(string vhost) | ||
2490 | +{ | ||
2491 | + static bool DEFAULT = true; | ||
2492 | + | ||
2493 | + SrsConfDirective* conf = get_vhost(vhost); | ||
2494 | + | ||
2495 | + if (!conf) { | ||
2496 | + return DEFAULT; | ||
2497 | + } | ||
2498 | + | ||
2499 | + conf = conf->get("publish"); | ||
2500 | + if (!conf) { | ||
2501 | + return DEFAULT; | ||
2502 | + } | ||
2503 | + | ||
2504 | + conf = conf->get("parse_sps"); | ||
2505 | + if (!conf || conf->arg0().empty()) { | ||
2506 | + return DEFAULT; | ||
2507 | + } | ||
2508 | + | ||
2509 | + return SRS_CONF_PERFER_TRUE(conf->arg0()); | ||
2510 | +} | ||
2511 | + | ||
2476 | bool SrsConfig::get_mr_enabled(string vhost) | 2512 | bool SrsConfig::get_mr_enabled(string vhost) |
2477 | { | 2513 | { |
2478 | SrsConfDirective* conf = get_vhost(vhost); | 2514 | SrsConfDirective* conf = get_vhost(vhost); |
@@ -500,6 +500,10 @@ public: | @@ -500,6 +500,10 @@ public: | ||
500 | */ | 500 | */ |
501 | virtual int get_chunk_size(std::string vhost); | 501 | virtual int get_chunk_size(std::string vhost); |
502 | /** | 502 | /** |
503 | + * whether parse the sps when publish stream to SRS. | ||
504 | + */ | ||
505 | + virtual bool get_parse_sps(std::string vhost); | ||
506 | + /** | ||
503 | * whether mr is enabled for vhost. | 507 | * whether mr is enabled for vhost. |
504 | * @param vhost, the vhost to get the mr. | 508 | * @param vhost, the vhost to get the mr. |
505 | */ | 509 | */ |
@@ -1395,7 +1395,7 @@ int SrsHls::on_audio(SrsSharedPtrMessage* shared_audio) | @@ -1395,7 +1395,7 @@ int SrsHls::on_audio(SrsSharedPtrMessage* shared_audio) | ||
1395 | return ret; | 1395 | return ret; |
1396 | } | 1396 | } |
1397 | 1397 | ||
1398 | -int SrsHls::on_video(SrsSharedPtrMessage* shared_video) | 1398 | +int SrsHls::on_video(SrsSharedPtrMessage* shared_video, bool is_sps_pps) |
1399 | { | 1399 | { |
1400 | int ret = ERROR_SUCCESS; | 1400 | int ret = ERROR_SUCCESS; |
1401 | 1401 | ||
@@ -1409,6 +1409,12 @@ int SrsHls::on_video(SrsSharedPtrMessage* shared_video) | @@ -1409,6 +1409,12 @@ int SrsHls::on_video(SrsSharedPtrMessage* shared_video) | ||
1409 | SrsSharedPtrMessage* video = shared_video->copy(); | 1409 | SrsSharedPtrMessage* video = shared_video->copy(); |
1410 | SrsAutoFree(SrsSharedPtrMessage, video); | 1410 | SrsAutoFree(SrsSharedPtrMessage, video); |
1411 | 1411 | ||
1412 | + // user can disable the sps parse to workaround when parse sps failed. | ||
1413 | + // @see https://github.com/simple-rtmp-server/srs/issues/474 | ||
1414 | + if (is_sps_pps) { | ||
1415 | + codec->avc_parse_sps = _srs_config->get_parse_sps(_req->vhost); | ||
1416 | + } | ||
1417 | + | ||
1412 | sample->clear(); | 1418 | sample->clear(); |
1413 | if ((ret = codec->video_avc_demux(video->payload, video->size, sample)) != ERROR_SUCCESS) { | 1419 | if ((ret = codec->video_avc_demux(video->payload, video->size, sample)) != ERROR_SUCCESS) { |
1414 | srs_error("hls codec demux video failed. ret=%d", ret); | 1420 | srs_error("hls codec demux video failed. ret=%d", ret); |
@@ -444,10 +444,11 @@ public: | @@ -444,10 +444,11 @@ public: | ||
444 | */ | 444 | */ |
445 | virtual int on_audio(SrsSharedPtrMessage* shared_audio); | 445 | virtual int on_audio(SrsSharedPtrMessage* shared_audio); |
446 | /** | 446 | /** |
447 | - * mux the video packets to ts. | ||
448 | - * @param shared_video, directly ptr, copy it if need to save it. | ||
449 | - */ | ||
450 | - virtual int on_video(SrsSharedPtrMessage* shared_video); | 447 | + * mux the video packets to ts. |
448 | + * @param shared_video, directly ptr, copy it if need to save it. | ||
449 | + * @param is_sps_pps whether the video is h.264 sps/pps. | ||
450 | + */ | ||
451 | + virtual int on_video(SrsSharedPtrMessage* shared_video, bool is_sps_pps); | ||
451 | private: | 452 | private: |
452 | virtual void hls_show_mux_log(); | 453 | virtual void hls_show_mux_log(); |
453 | }; | 454 | }; |
@@ -1290,7 +1290,7 @@ int SrsSource::on_hls_start() | @@ -1290,7 +1290,7 @@ int SrsSource::on_hls_start() | ||
1290 | // when reload to start hls, hls will never get the sequence header in stream, | 1290 | // when reload to start hls, hls will never get the sequence header in stream, |
1291 | // use the SrsSource.on_hls_start to push the sequence header to HLS. | 1291 | // use the SrsSource.on_hls_start to push the sequence header to HLS. |
1292 | // TODO: maybe need to decode the metadata? | 1292 | // TODO: maybe need to decode the metadata? |
1293 | - if (cache_sh_video && (ret = hls->on_video(cache_sh_video)) != ERROR_SUCCESS) { | 1293 | + if (cache_sh_video && (ret = hls->on_video(cache_sh_video, true)) != ERROR_SUCCESS) { |
1294 | srs_error("hls process video sequence header message failed. ret=%d", ret); | 1294 | srs_error("hls process video sequence header message failed. ret=%d", ret); |
1295 | return ret; | 1295 | return ret; |
1296 | } | 1296 | } |
@@ -1587,7 +1587,6 @@ int SrsSource::on_audio_imp(SrsSharedPtrMessage* msg) | @@ -1587,7 +1587,6 @@ int SrsSource::on_audio_imp(SrsSharedPtrMessage* msg) | ||
1587 | codec.audio_data_rate / 1000, aac_sample_rates[codec.aac_sample_rate], | 1587 | codec.audio_data_rate / 1000, aac_sample_rates[codec.aac_sample_rate], |
1588 | flv_sample_sizes[sample.sound_size], flv_sound_types[sample.sound_type], | 1588 | flv_sample_sizes[sample.sound_size], flv_sound_types[sample.sound_type], |
1589 | flv_sample_rates[sample.sound_rate]); | 1589 | flv_sample_rates[sample.sound_rate]); |
1590 | - return ret; | ||
1591 | } | 1590 | } |
1592 | 1591 | ||
1593 | #ifdef SRS_AUTO_HLS | 1592 | #ifdef SRS_AUTO_HLS |
@@ -1674,6 +1673,11 @@ int SrsSource::on_audio_imp(SrsSharedPtrMessage* msg) | @@ -1674,6 +1673,11 @@ int SrsSource::on_audio_imp(SrsSharedPtrMessage* msg) | ||
1674 | cache_sh_audio = msg->copy(); | 1673 | cache_sh_audio = msg->copy(); |
1675 | } | 1674 | } |
1676 | 1675 | ||
1676 | + // when sequence header, donot push to gop cache and adjust the timestamp. | ||
1677 | + if (is_sequence_header) { | ||
1678 | + return ret; | ||
1679 | + } | ||
1680 | + | ||
1677 | // cache the last gop packets | 1681 | // cache the last gop packets |
1678 | if ((ret = gop_cache->cache(msg)) != ERROR_SUCCESS) { | 1682 | if ((ret = gop_cache->cache(msg)) != ERROR_SUCCESS) { |
1679 | srs_error("shrink gop cache failed. ret=%d", ret); | 1683 | srs_error("shrink gop cache failed. ret=%d", ret); |
@@ -1779,6 +1783,11 @@ int SrsSource::on_video_imp(SrsSharedPtrMessage* msg) | @@ -1779,6 +1783,11 @@ int SrsSource::on_video_imp(SrsSharedPtrMessage* msg) | ||
1779 | 1783 | ||
1780 | // parse detail audio codec | 1784 | // parse detail audio codec |
1781 | SrsAvcAacCodec codec; | 1785 | SrsAvcAacCodec codec; |
1786 | + | ||
1787 | + // user can disable the sps parse to workaround when parse sps failed. | ||
1788 | + // @see https://github.com/simple-rtmp-server/srs/issues/474 | ||
1789 | + codec.avc_parse_sps = _srs_config->get_parse_sps(_req->vhost); | ||
1790 | + | ||
1782 | SrsCodecSample sample; | 1791 | SrsCodecSample sample; |
1783 | if ((ret = codec.video_avc_demux(msg->payload, msg->size, &sample)) != ERROR_SUCCESS) { | 1792 | if ((ret = codec.video_avc_demux(msg->payload, msg->size, &sample)) != ERROR_SUCCESS) { |
1784 | srs_error("source codec demux video failed. ret=%d", ret); | 1793 | srs_error("source codec demux video failed. ret=%d", ret); |
@@ -1796,11 +1805,10 @@ int SrsSource::on_video_imp(SrsSharedPtrMessage* msg) | @@ -1796,11 +1805,10 @@ int SrsSource::on_video_imp(SrsSharedPtrMessage* msg) | ||
1796 | srs_codec_avc_profile2str(codec.avc_profile).c_str(), | 1805 | srs_codec_avc_profile2str(codec.avc_profile).c_str(), |
1797 | srs_codec_avc_level2str(codec.avc_level).c_str(), codec.width, codec.height, | 1806 | srs_codec_avc_level2str(codec.avc_level).c_str(), codec.width, codec.height, |
1798 | codec.video_data_rate / 1000, codec.frame_rate, codec.duration); | 1807 | codec.video_data_rate / 1000, codec.frame_rate, codec.duration); |
1799 | - return ret; | ||
1800 | } | 1808 | } |
1801 | 1809 | ||
1802 | #ifdef SRS_AUTO_HLS | 1810 | #ifdef SRS_AUTO_HLS |
1803 | - if ((ret = hls->on_video(msg)) != ERROR_SUCCESS) { | 1811 | + if ((ret = hls->on_video(msg, is_sequence_header)) != ERROR_SUCCESS) { |
1804 | // apply the error strategy for hls. | 1812 | // apply the error strategy for hls. |
1805 | // @see https://github.com/simple-rtmp-server/srs/issues/264 | 1813 | // @see https://github.com/simple-rtmp-server/srs/issues/264 |
1806 | std::string hls_error_strategy = _srs_config->get_hls_on_error(_req->vhost); | 1814 | std::string hls_error_strategy = _srs_config->get_hls_on_error(_req->vhost); |
@@ -1874,6 +1882,11 @@ int SrsSource::on_video_imp(SrsSharedPtrMessage* msg) | @@ -1874,6 +1882,11 @@ int SrsSource::on_video_imp(SrsSharedPtrMessage* msg) | ||
1874 | } | 1882 | } |
1875 | } | 1883 | } |
1876 | } | 1884 | } |
1885 | + | ||
1886 | + // when sequence header, donot push to gop cache and adjust the timestamp. | ||
1887 | + if (is_sequence_header) { | ||
1888 | + return ret; | ||
1889 | + } | ||
1877 | 1890 | ||
1878 | // cache the last gop packets | 1891 | // cache the last gop packets |
1879 | if ((ret = gop_cache->cache(msg)) != ERROR_SUCCESS) { | 1892 | if ((ret = gop_cache->cache(msg)) != ERROR_SUCCESS) { |
@@ -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 188 | 34 | +#define VERSION_REVISION 189 |
35 | 35 | ||
36 | // server info. | 36 | // server info. |
37 | #define RTMP_SIG_SRS_KEY "SRS" | 37 | #define RTMP_SIG_SRS_KEY "SRS" |
@@ -382,6 +382,8 @@ int SrsCodecSample::add_sample_unit(char* bytes, int size) | @@ -382,6 +382,8 @@ int SrsCodecSample::add_sample_unit(char* bytes, int size) | ||
382 | 382 | ||
383 | SrsAvcAacCodec::SrsAvcAacCodec() | 383 | SrsAvcAacCodec::SrsAvcAacCodec() |
384 | { | 384 | { |
385 | + avc_parse_sps = true; | ||
386 | + | ||
385 | width = 0; | 387 | width = 0; |
386 | height = 0; | 388 | height = 0; |
387 | duration = 0; | 389 | duration = 0; |
@@ -939,6 +941,12 @@ int SrsAvcAacCodec::avc_demux_sps_rbsp(char* rbsp, int nb_rbsp) | @@ -939,6 +941,12 @@ int SrsAvcAacCodec::avc_demux_sps_rbsp(char* rbsp, int nb_rbsp) | ||
939 | { | 941 | { |
940 | int ret = ERROR_SUCCESS; | 942 | int ret = ERROR_SUCCESS; |
941 | 943 | ||
944 | + // we donot parse the detail of sps. | ||
945 | + // @see https://github.com/simple-rtmp-server/srs/issues/474 | ||
946 | + if (!avc_parse_sps) { | ||
947 | + return ret; | ||
948 | + } | ||
949 | + | ||
942 | // reparse the rbsp. | 950 | // reparse the rbsp. |
943 | SrsStream stream; | 951 | SrsStream stream; |
944 | if ((ret = stream.initialize(rbsp, nb_rbsp)) != ERROR_SUCCESS) { | 952 | if ((ret = stream.initialize(rbsp, nb_rbsp)) != ERROR_SUCCESS) { |
@@ -606,6 +606,9 @@ public: | @@ -606,6 +606,9 @@ public: | ||
606 | int aac_extra_size; | 606 | int aac_extra_size; |
607 | char* aac_extra_data; | 607 | char* aac_extra_data; |
608 | public: | 608 | public: |
609 | + // for sequence header, whether parse the h.264 sps. | ||
610 | + bool avc_parse_sps; | ||
611 | +public: | ||
609 | SrsAvcAacCodec(); | 612 | SrsAvcAacCodec(); |
610 | virtual ~SrsAvcAacCodec(); | 613 | virtual ~SrsAvcAacCodec(); |
611 | public: | 614 | public: |
-
请 注册 或 登录 后发表评论