winlin

fix #474, config to donot parse width/height from sps. 2.0.189

@@ -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: