winlin

for #742, refine source, meta and origin hub. 3.0.16

@@ -184,6 +184,7 @@ Please select your language: @@ -184,6 +184,7 @@ Please select your language:
184 184
185 ### V3 changes 185 ### V3 changes
186 186
  187 +* v3.0, 2017-01-19, for [#742][bug #742] refine source, meta and origin hub. 3.0.16
187 * v3.0, 2017-01-17, for [#742][bug #742] refine source, timeout, live cycle. 3.0.15 188 * v3.0, 2017-01-17, for [#742][bug #742] refine source, timeout, live cycle. 3.0.15
188 * v3.0, 2017-01-11, fix [#735][bug #735] config transform refer_publish invalid. 3.0.14 189 * v3.0, 2017-01-11, fix [#735][bug #735] config transform refer_publish invalid. 3.0.14
189 * v3.0, 2017-01-06, for [#730][bug #730] support config in/out ack size. 3.0.13 190 * v3.0, 2017-01-06, for [#730][bug #730] support config in/out ack size. 3.0.13
@@ -872,13 +873,13 @@ Remark: @@ -872,13 +873,13 @@ Remark:
872 | Input | SRS(Simple RTMP Server) | Output | 873 | Input | SRS(Simple RTMP Server) | Output |
873 +----------------------+-------------------------+----------------+ 874 +----------------------+-------------------------+----------------+
874 | Encoder(1) | +-> RTMP/HDS --------+-> Flash player | 875 | Encoder(1) | +-> RTMP/HDS --------+-> Flash player |
875 -| (FMLE,FFMPEG, -rtmp-+->-+-> HLS/HTTP ---------+-> M3u8 player | 876 +| (FMLE,FFMPEG, -rtmp-+->-+-> HLS/HTTP ---------+-> M3U8 player |
876 | Flash,XSPLIT, | +-> FLV/MP3/Aac/Ts ---+-> HTTP player | 877 | Flash,XSPLIT, | +-> FLV/MP3/Aac/Ts ---+-> HTTP player |
877 | ......) | +-> Fowarder ---------+-> RTMP server | 878 | ......) | +-> Fowarder ---------+-> RTMP server |
878 | | +-> Transcoder -------+-> RTMP server | 879 | | +-> Transcoder -------+-> RTMP server |
879 | | +-> EXEC(5) ----------+-> External app | 880 | | +-> EXEC(5) ----------+-> External app |
880 -| | +-> DVR --------------+-> Flv file |  
881 -| | +-> BandwidthTest ----+-> flash | 881 +| | +-> DVR --------------+-> FLV file |
  882 +| | +-> BandwidthTest ----+-> Flash |
882 +----------------------+ | | 883 +----------------------+ | |
883 | MediaSource(2) | | | 884 | MediaSource(2) | | |
884 | (RTSP,FILE, | | | 885 | (RTSP,FILE, | | |
@@ -970,7 +970,7 @@ int SrsDvrSegmentPlan::update_duration(SrsSharedPtrMessage* msg) @@ -970,7 +970,7 @@ int SrsDvrSegmentPlan::update_duration(SrsSharedPtrMessage* msg)
970 970
971 SrsDvr::SrsDvr() 971 SrsDvr::SrsDvr()
972 { 972 {
973 - source = NULL; 973 + hub = NULL;
974 plan = NULL; 974 plan = NULL;
975 req = NULL; 975 req = NULL;
976 actived = false; 976 actived = false;
@@ -985,12 +985,12 @@ SrsDvr::~SrsDvr() @@ -985,12 +985,12 @@ SrsDvr::~SrsDvr()
985 srs_freep(plan); 985 srs_freep(plan);
986 } 986 }
987 987
988 -int SrsDvr::initialize(SrsSource* s, SrsRequest* r) 988 +int SrsDvr::initialize(SrsOriginHub* h, SrsRequest* r)
989 { 989 {
990 int ret = ERROR_SUCCESS; 990 int ret = ERROR_SUCCESS;
991 991
992 req = r; 992 req = r;
993 - source = s; 993 + hub = h;
994 994
995 SrsConfDirective* conf = _srs_config->get_dvr_apply(r->vhost); 995 SrsConfDirective* conf = _srs_config->get_dvr_apply(r->vhost);
996 actived = srs_config_apply_filter(conf, r); 996 actived = srs_config_apply_filter(conf, r);
@@ -1018,7 +1018,7 @@ int SrsDvr::on_publish(bool fetch_sequence_header) @@ -1018,7 +1018,7 @@ int SrsDvr::on_publish(bool fetch_sequence_header)
1018 return ret; 1018 return ret;
1019 } 1019 }
1020 1020
1021 - if (fetch_sequence_header && (ret = source->on_dvr_request_sh()) != ERROR_SUCCESS) { 1021 + if (fetch_sequence_header && (ret = hub->on_dvr_request_sh()) != ERROR_SUCCESS) {
1022 return ret; 1022 return ret;
1023 } 1023 }
1024 1024
@@ -35,6 +35,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -35,6 +35,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35 #ifdef SRS_AUTO_DVR 35 #ifdef SRS_AUTO_DVR
36 36
37 class SrsSource; 37 class SrsSource;
  38 +class SrsOriginHub;
38 class SrsRequest; 39 class SrsRequest;
39 class SrsBuffer; 40 class SrsBuffer;
40 class SrsRtmpJitter; 41 class SrsRtmpJitter;
@@ -300,7 +301,7 @@ private: @@ -300,7 +301,7 @@ private:
300 class SrsDvr : public ISrsReloadHandler 301 class SrsDvr : public ISrsReloadHandler
301 { 302 {
302 private: 303 private:
303 - SrsSource* source; 304 + SrsOriginHub* hub;
304 SrsDvrPlan* plan; 305 SrsDvrPlan* plan;
305 SrsRequest* req; 306 SrsRequest* req;
306 private: 307 private:
@@ -317,7 +318,7 @@ public: @@ -317,7 +318,7 @@ public:
317 * when system initialize(encoder publish at first time, or reload), 318 * when system initialize(encoder publish at first time, or reload),
318 * initialize the dvr will reinitialize the plan, the whole dvr framework. 319 * initialize the dvr will reinitialize the plan, the whole dvr framework.
319 */ 320 */
320 - virtual int initialize(SrsSource* s, SrsRequest* r); 321 + virtual int initialize(SrsOriginHub* h, SrsRequest* r);
321 /** 322 /**
322 * publish stream event, 323 * publish stream event,
323 * when encoder start to publish RTMP stream. 324 * when encoder start to publish RTMP stream.
@@ -50,9 +50,9 @@ using namespace std; @@ -50,9 +50,9 @@ using namespace std;
50 // when error, forwarder sleep for a while and retry. 50 // when error, forwarder sleep for a while and retry.
51 #define SRS_FORWARDER_CIMS (3000) 51 #define SRS_FORWARDER_CIMS (3000)
52 52
53 -SrsForwarder::SrsForwarder(SrsSource* s) 53 +SrsForwarder::SrsForwarder(SrsOriginHub* h)
54 { 54 {
55 - source = s; 55 + hub = h;
56 56
57 req = NULL; 57 req = NULL;
58 sh_video = sh_audio = NULL; 58 sh_video = sh_audio = NULL;
@@ -250,7 +250,7 @@ int SrsForwarder::cycle() @@ -250,7 +250,7 @@ int SrsForwarder::cycle()
250 return ret; 250 return ret;
251 } 251 }
252 252
253 - if ((ret = source->on_forwarder_start(this)) != ERROR_SUCCESS) { 253 + if ((ret = hub->on_forwarder_start(this)) != ERROR_SUCCESS) {
254 srs_error("callback the source to feed the sequence header failed. ret=%d", ret); 254 srs_error("callback the source to feed the sequence header failed. ret=%d", ret);
255 return ret; 255 return ret;
256 } 256 }
@@ -42,6 +42,7 @@ class SrsRtmpJitter; @@ -42,6 +42,7 @@ class SrsRtmpJitter;
42 class SrsRtmpClient; 42 class SrsRtmpClient;
43 class SrsRequest; 43 class SrsRequest;
44 class SrsSource; 44 class SrsSource;
  45 +class SrsOriginHub;
45 class SrsKbps; 46 class SrsKbps;
46 class SrsSimpleRtmpClient; 47 class SrsSimpleRtmpClient;
47 48
@@ -58,7 +59,7 @@ private: @@ -58,7 +59,7 @@ private:
58 private: 59 private:
59 SrsReusableThread2* pthread; 60 SrsReusableThread2* pthread;
60 private: 61 private:
61 - SrsSource* source; 62 + SrsOriginHub* hub;
62 SrsSimpleRtmpClient* sdk; 63 SrsSimpleRtmpClient* sdk;
63 SrsRtmpJitter* jitter; 64 SrsRtmpJitter* jitter;
64 SrsMessageQueue* queue; 65 SrsMessageQueue* queue;
@@ -69,7 +70,7 @@ private: @@ -69,7 +70,7 @@ private:
69 SrsSharedPtrMessage* sh_audio; 70 SrsSharedPtrMessage* sh_audio;
70 SrsSharedPtrMessage* sh_video; 71 SrsSharedPtrMessage* sh_video;
71 public: 72 public:
72 - SrsForwarder(SrsSource* _source); 73 + SrsForwarder(SrsOriginHub* h);
73 virtual ~SrsForwarder(); 74 virtual ~SrsForwarder();
74 public: 75 public:
75 virtual int initialize(SrsRequest* r, std::string ep); 76 virtual int initialize(SrsRequest* r, std::string ep);
@@ -1125,7 +1125,7 @@ int SrsHlsCache::reap_segment(string log_desc, SrsHlsMuxer* muxer, int64_t segme @@ -1125,7 +1125,7 @@ int SrsHlsCache::reap_segment(string log_desc, SrsHlsMuxer* muxer, int64_t segme
1125 SrsHls::SrsHls() 1125 SrsHls::SrsHls()
1126 { 1126 {
1127 req = NULL; 1127 req = NULL;
1128 - source = NULL; 1128 + hub = NULL;
1129 1129
1130 hls_enabled = false; 1130 hls_enabled = false;
1131 hls_can_dispose = false; 1131 hls_can_dispose = false;
@@ -1197,11 +1197,11 @@ int SrsHls::cycle() @@ -1197,11 +1197,11 @@ int SrsHls::cycle()
1197 return ret; 1197 return ret;
1198 } 1198 }
1199 1199
1200 -int SrsHls::initialize(SrsSource* s, SrsRequest* r) 1200 +int SrsHls::initialize(SrsOriginHub* h, SrsRequest* r)
1201 { 1201 {
1202 int ret = ERROR_SUCCESS; 1202 int ret = ERROR_SUCCESS;
1203 1203
1204 - source = s; 1204 + hub = h;
1205 req = r; 1205 req = r;
1206 1206
1207 if ((ret = muxer->initialize()) != ERROR_SUCCESS) { 1207 if ((ret = muxer->initialize()) != ERROR_SUCCESS) {
@@ -1244,7 +1244,7 @@ int SrsHls::on_publish(bool fetch_sequence_header) @@ -1244,7 +1244,7 @@ int SrsHls::on_publish(bool fetch_sequence_header)
1244 // notice the source to get the cached sequence header. 1244 // notice the source to get the cached sequence header.
1245 // when reload to start hls, hls will never get the sequence header in stream, 1245 // when reload to start hls, hls will never get the sequence header in stream,
1246 // use the SrsSource.on_hls_start to push the sequence header to HLS. 1246 // use the SrsSource.on_hls_start to push the sequence header to HLS.
1247 - if ((ret = source->on_hls_start()) != ERROR_SUCCESS) { 1247 + if ((ret = hub->on_hls_start()) != ERROR_SUCCESS) {
1248 srs_error("callback source hls start failed. ret=%d", ret); 1248 srs_error("callback source hls start failed. ret=%d", ret);
1249 return ret; 1249 return ret;
1250 } 1250 }
@@ -45,6 +45,7 @@ class SrsAvcAacCodec; @@ -45,6 +45,7 @@ class SrsAvcAacCodec;
45 class SrsRequest; 45 class SrsRequest;
46 class SrsPithyPrint; 46 class SrsPithyPrint;
47 class SrsSource; 47 class SrsSource;
  48 +class SrsOriginHub;
48 class SrsFileWriter; 49 class SrsFileWriter;
49 class SrsSimpleStream; 50 class SrsSimpleStream;
50 class SrsTsAacJitter; 51 class SrsTsAacJitter;
@@ -362,7 +363,7 @@ private: @@ -362,7 +363,7 @@ private:
362 bool hls_can_dispose; 363 bool hls_can_dispose;
363 int64_t last_update_time; 364 int64_t last_update_time;
364 private: 365 private:
365 - SrsSource* source; 366 + SrsOriginHub* hub;
366 SrsAvcAacCodec* codec; 367 SrsAvcAacCodec* codec;
367 SrsCodecSample* sample; 368 SrsCodecSample* sample;
368 SrsRtmpJitter* jitter; 369 SrsRtmpJitter* jitter;
@@ -391,7 +392,7 @@ public: @@ -391,7 +392,7 @@ public:
391 /** 392 /**
392 * initialize the hls by handler and source. 393 * initialize the hls by handler and source.
393 */ 394 */
394 - virtual int initialize(SrsSource* s, SrsRequest* r); 395 + virtual int initialize(SrsOriginHub* h, SrsRequest* r);
395 /** 396 /**
396 * publish stream event, continue to write the m3u8, 397 * publish stream event, continue to write the m3u8,
397 * for the muxer object not destroyed. 398 * for the muxer object not destroyed.
@@ -745,207 +745,29 @@ ISrsSourceHandler::~ISrsSourceHandler() @@ -745,207 +745,29 @@ ISrsSourceHandler::~ISrsSourceHandler()
745 { 745 {
746 } 746 }
747 747
748 -std::map<std::string, SrsSource*> SrsSource::pool;  
749 -  
750 -int SrsSource::fetch_or_create(SrsRequest* r, ISrsSourceHandler* h, SrsSource** pps)  
751 -{  
752 - int ret = ERROR_SUCCESS;  
753 -  
754 - SrsSource* source = NULL;  
755 - if ((source = fetch(r)) != NULL) {  
756 - *pps = source;  
757 - return ret;  
758 - }  
759 -  
760 - string stream_url = r->get_stream_url();  
761 - string vhost = r->vhost;  
762 -  
763 - // should always not exists for create a source.  
764 - srs_assert (pool.find(stream_url) == pool.end());  
765 -  
766 - source = new SrsSource();  
767 - if ((ret = source->initialize(r, h)) != ERROR_SUCCESS) {  
768 - srs_freep(source);  
769 - return ret;  
770 - }  
771 -  
772 - pool[stream_url] = source;  
773 - srs_info("create new source for url=%s, vhost=%s", stream_url.c_str(), vhost.c_str());  
774 -  
775 - *pps = source;  
776 -  
777 - return ret;  
778 -}  
779 -  
780 -SrsSource* SrsSource::fetch(SrsRequest* r)  
781 -{  
782 - SrsSource* source = NULL;  
783 -  
784 - string stream_url = r->get_stream_url();  
785 - if (pool.find(stream_url) == pool.end()) {  
786 - return NULL;  
787 - }  
788 -  
789 - source = pool[stream_url];  
790 -  
791 - // we always update the request of resource,  
792 - // for origin auth is on, the token in request maybe invalid,  
793 - // and we only need to update the token of request, it's simple.  
794 - source->req->update_auth(r);  
795 -  
796 - return source;  
797 -}  
798 -  
799 -void SrsSource::dispose_all()  
800 -{  
801 - std::map<std::string, SrsSource*>::iterator it;  
802 - for (it = pool.begin(); it != pool.end(); ++it) {  
803 - SrsSource* source = it->second;  
804 - source->dispose();  
805 - }  
806 - return;  
807 -}  
808 -  
809 -int SrsSource::cycle_all()  
810 -{  
811 - int ret = ERROR_SUCCESS;  
812 -  
813 - int cid = _srs_context->get_id();  
814 - ret = do_cycle_all();  
815 - _srs_context->set_id(cid);  
816 -  
817 - return ret;  
818 -}  
819 -  
820 -int SrsSource::do_cycle_all()  
821 -{  
822 - int ret = ERROR_SUCCESS;  
823 -  
824 - std::map<std::string, SrsSource*>::iterator it;  
825 - for (it = pool.begin(); it != pool.end();) {  
826 - SrsSource* source = it->second;  
827 -  
828 - // Do cycle source to cleanup components, such as hls dispose.  
829 - if ((ret = source->cycle()) != ERROR_SUCCESS) {  
830 - return ret;  
831 - }  
832 -  
833 - // TODO: FIXME: support source cleanup.  
834 - // @see https://github.com/ossrs/srs/issues/713  
835 - // @see https://github.com/ossrs/srs/issues/714  
836 -#if 0  
837 - // When source expired, remove it.  
838 - if (source->expired()) {  
839 - int cid = source->source_id();  
840 - if (cid == -1 && source->pre_source_id() > 0) {  
841 - cid = source->pre_source_id();  
842 - }  
843 - if (cid > 0) {  
844 - _srs_context->set_id(cid);  
845 - }  
846 - srs_trace("cleanup die source, total=%d", (int)pool.size());  
847 -  
848 - srs_freep(source);  
849 - pool.erase(it++);  
850 - } else {  
851 - ++it;  
852 - }  
853 -#else  
854 - ++it;  
855 -#endif  
856 - }  
857 -  
858 - return ret;  
859 -}  
860 -  
861 -void SrsSource::destroy()  
862 -{  
863 - std::map<std::string, SrsSource*>::iterator it;  
864 - for (it = pool.begin(); it != pool.end(); ++it) {  
865 - SrsSource* source = it->second;  
866 - srs_freep(source);  
867 - }  
868 - pool.clear();  
869 -}  
870 -  
871 -SrsMixQueue::SrsMixQueue()  
872 -{  
873 - nb_videos = 0;  
874 - nb_audios = 0;  
875 -}  
876 -  
877 -SrsMixQueue::~SrsMixQueue()  
878 -{  
879 - clear();  
880 -}  
881 -  
882 -void SrsMixQueue::clear()  
883 -{  
884 - std::multimap<int64_t, SrsSharedPtrMessage*>::iterator it;  
885 - for (it = msgs.begin(); it != msgs.end(); ++it) {  
886 - SrsSharedPtrMessage* msg = it->second;  
887 - srs_freep(msg);  
888 - }  
889 - msgs.clear();  
890 -  
891 - nb_videos = 0;  
892 - nb_audios = 0;  
893 -}  
894 -  
895 -void SrsMixQueue::push(SrsSharedPtrMessage* msg)  
896 -{  
897 - msgs.insert(std::make_pair(msg->timestamp, msg));  
898 -  
899 - if (msg->is_video()) {  
900 - nb_videos++;  
901 - } else {  
902 - nb_audios++;  
903 - }  
904 -}  
905 -  
906 -SrsSharedPtrMessage* SrsMixQueue::pop() 748 +// TODO: FIXME: Remove it?
  749 +bool srs_hls_can_continue(int ret, SrsSharedPtrMessage* sh, SrsSharedPtrMessage* msg)
907 { 750 {
908 - bool mix_ok = false;  
909 -  
910 - // pure video  
911 - if (nb_videos >= SRS_MIX_CORRECT_PURE_AV && nb_audios == 0) {  
912 - mix_ok = true;  
913 - }  
914 -  
915 - // pure audio  
916 - if (nb_audios >= SRS_MIX_CORRECT_PURE_AV && nb_videos == 0) {  
917 - mix_ok = true;  
918 - }  
919 -  
920 - // got 1 video and 1 audio, mix ok.  
921 - if (nb_videos >= 1 && nb_audios >= 1) {  
922 - mix_ok = true;  
923 - }  
924 -  
925 - if (!mix_ok) {  
926 - return NULL; 751 + // only continue for decode error.
  752 + if (ret != ERROR_HLS_DECODE_ERROR) {
  753 + return false;
927 } 754 }
928 755
929 - // pop the first msg.  
930 - std::multimap<int64_t, SrsSharedPtrMessage*>::iterator it = msgs.begin();  
931 - SrsSharedPtrMessage* msg = it->second;  
932 - msgs.erase(it);  
933 -  
934 - if (msg->is_video()) {  
935 - nb_videos--;  
936 - } else {  
937 - nb_audios--; 756 + // when video size equals to sequence header,
  757 + // the video actually maybe a sequence header,
  758 + // continue to make ffmpeg happy.
  759 + if (sh && sh->size == msg->size) {
  760 + srs_warn("the msg is actually a sequence header, ignore this packet.");
  761 + return true;
938 } 762 }
939 763
940 - return msg; 764 + return false;
941 } 765 }
942 766
943 -SrsSource::SrsSource() 767 +SrsOriginHub::SrsOriginHub(SrsSource* s)
944 { 768 {
  769 + source = s;
945 req = NULL; 770 req = NULL;
946 - jitter_algorithm = SrsRtmpJitterAlgorithmOFF;  
947 - mix_correct = false;  
948 - mix_queue = new SrsMixQueue();  
949 771
950 #ifdef SRS_AUTO_HLS 772 #ifdef SRS_AUTO_HLS
951 hls = new SrsHls(); 773 hls = new SrsHls();
@@ -957,36 +779,17 @@ SrsSource::SrsSource() @@ -957,36 +779,17 @@ SrsSource::SrsSource()
957 encoder = new SrsEncoder(); 779 encoder = new SrsEncoder();
958 #endif 780 #endif
959 #ifdef SRS_AUTO_HDS 781 #ifdef SRS_AUTO_HDS
960 - hds = new SrsHds(this); 782 + hds = new SrsHds(s);
961 #endif 783 #endif
962 -  
963 - cache_metadata = cache_sh_video = cache_sh_audio = NULL;  
964 -  
965 - _can_publish = true;  
966 - _pre_source_id = _source_id = -1;  
967 - die_at = -1;  
968 -  
969 - play_edge = new SrsPlayEdge();  
970 - publish_edge = new SrsPublishEdge();  
971 - gop_cache = new SrsGopCache();  
972 - aggregate_stream = new SrsBuffer();  
973 ng_exec = new SrsNgExec(); 784 ng_exec = new SrsNgExec();
974 785
975 - is_monotonically_increase = false;  
976 - last_packet_time = 0;  
977 -  
978 _srs_config->subscribe(this); 786 _srs_config->subscribe(this);
979 - atc = false;  
980 } 787 }
981 788
982 -SrsSource::~SrsSource() 789 +SrsOriginHub::~SrsOriginHub()
983 { 790 {
984 _srs_config->unsubscribe(this); 791 _srs_config->unsubscribe(this);
985 792
986 - // never free the consumers,  
987 - // for all consumers are auto free.  
988 - consumers.clear();  
989 -  
990 if (true) { 793 if (true) {
991 std::vector<SrsForwarder*>::iterator it; 794 std::vector<SrsForwarder*>::iterator it;
992 for (it = forwarders.begin(); it != forwarders.end(); ++it) { 795 for (it = forwarders.begin(); it != forwarders.end(); ++it) {
@@ -995,16 +798,6 @@ SrsSource::~SrsSource() @@ -995,16 +798,6 @@ SrsSource::~SrsSource()
995 } 798 }
996 forwarders.clear(); 799 forwarders.clear();
997 } 800 }
998 -  
999 - srs_freep(mix_queue);  
1000 - srs_freep(cache_metadata);  
1001 - srs_freep(cache_sh_video);  
1002 - srs_freep(cache_sh_audio);  
1003 -  
1004 - srs_freep(play_edge);  
1005 - srs_freep(publish_edge);  
1006 - srs_freep(gop_cache);  
1007 - srs_freep(aggregate_stream);  
1008 srs_freep(ng_exec); 801 srs_freep(ng_exec);
1009 802
1010 #ifdef SRS_AUTO_HLS 803 #ifdef SRS_AUTO_HLS
@@ -1019,208 +812,429 @@ SrsSource::~SrsSource() @@ -1019,208 +812,429 @@ SrsSource::~SrsSource()
1019 #ifdef SRS_AUTO_HDS 812 #ifdef SRS_AUTO_HDS
1020 srs_freep(hds); 813 srs_freep(hds);
1021 #endif 814 #endif
1022 -  
1023 - srs_freep(req);  
1024 -}  
1025 -  
1026 -void SrsSource::dispose()  
1027 -{  
1028 -#ifdef SRS_AUTO_HLS  
1029 - hls->dispose();  
1030 -#endif  
1031 -  
1032 - // cleaup the cached packets.  
1033 - srs_freep(cache_metadata);  
1034 - srs_freep(cache_sh_video);  
1035 - srs_freep(cache_sh_audio);  
1036 -  
1037 - // cleanup the gop cache.  
1038 - gop_cache->dispose();  
1039 } 815 }
1040 816
1041 -int SrsSource::cycle() 817 +int SrsOriginHub::initialize(SrsRequest* r)
1042 { 818 {
1043 int ret = ERROR_SUCCESS; 819 int ret = ERROR_SUCCESS;
1044 820
  821 + req = r;
  822 +
1045 #ifdef SRS_AUTO_HLS 823 #ifdef SRS_AUTO_HLS
1046 - if ((ret = hls->cycle()) != ERROR_SUCCESS) { 824 + if ((ret = hls->initialize(this, req)) != ERROR_SUCCESS) {
1047 return ret; 825 return ret;
1048 } 826 }
1049 #endif 827 #endif
1050 828
1051 - return ret;  
1052 -}  
1053 -  
1054 -bool SrsSource::expired()  
1055 -{  
1056 - // unknown state?  
1057 - if (die_at == -1) {  
1058 - return false;  
1059 - }  
1060 -  
1061 - // still publishing?  
1062 - if (!_can_publish || !publish_edge->can_publish()) {  
1063 - return false; 829 +#ifdef SRS_AUTO_DVR
  830 + if ((ret = dvr->initialize(this, req)) != ERROR_SUCCESS) {
  831 + return ret;
1064 } 832 }
  833 +#endif
1065 834
1066 - // has any consumers?  
1067 - if (!consumers.empty()) {  
1068 - return false;  
1069 - } 835 + return ret;
  836 +}
  837 +
  838 +void SrsOriginHub::dispose()
  839 +{
  840 +#ifdef SRS_AUTO_HLS
  841 + hls->dispose();
  842 +#endif
  843 +}
  844 +
  845 +int SrsOriginHub::cycle()
  846 +{
  847 + int ret = ERROR_SUCCESS;
1070 848
1071 - int64_t now = srs_get_system_time_ms();  
1072 - if (now > die_at + SRS_SOURCE_CLEANUP) {  
1073 - return true; 849 +#ifdef SRS_AUTO_HLS
  850 + if ((ret = hls->cycle()) != ERROR_SUCCESS) {
  851 + return ret;
1074 } 852 }
  853 +#endif
1075 854
1076 - return false; 855 + return ret;
1077 } 856 }
1078 857
1079 -int SrsSource::initialize(SrsRequest* r, ISrsSourceHandler* h) 858 +int SrsOriginHub::on_original_metadata(SrsOnMetaDataPacket* metadata)
1080 { 859 {
1081 int ret = ERROR_SUCCESS; 860 int ret = ERROR_SUCCESS;
1082 861
1083 - srs_assert(h);  
1084 - srs_assert(!req);  
1085 -  
1086 - handler = h;  
1087 - req = r->copy();  
1088 - atc = _srs_config->get_atc(req->vhost);  
1089 -  
1090 #ifdef SRS_AUTO_HLS 862 #ifdef SRS_AUTO_HLS
1091 - if ((ret = hls->initialize(this, req)) != ERROR_SUCCESS) { 863 + if (metadata && (ret = hls->on_meta_data(metadata->metadata)) != ERROR_SUCCESS) {
  864 + srs_error("hls process onMetaData message failed. ret=%d", ret);
1092 return ret; 865 return ret;
1093 } 866 }
1094 #endif 867 #endif
1095 868
1096 #ifdef SRS_AUTO_DVR 869 #ifdef SRS_AUTO_DVR
1097 - if ((ret = dvr->initialize(this, req)) != ERROR_SUCCESS) { 870 + if (metadata && (ret = dvr->on_meta_data(metadata)) != ERROR_SUCCESS) {
  871 + srs_error("dvr process onMetaData message failed. ret=%d", ret);
1098 return ret; 872 return ret;
1099 } 873 }
1100 #endif 874 #endif
1101 -  
1102 - if ((ret = play_edge->initialize(this, req)) != ERROR_SUCCESS) {  
1103 - return ret;  
1104 - }  
1105 - if ((ret = publish_edge->initialize(this, req)) != ERROR_SUCCESS) {  
1106 - return ret;  
1107 - }  
1108 -  
1109 - double queue_size = _srs_config->get_queue_length(req->vhost);  
1110 - publish_edge->set_queue_size(queue_size);  
1111 -  
1112 - jitter_algorithm = (SrsRtmpJitterAlgorithm)_srs_config->get_time_jitter(req->vhost);  
1113 - mix_correct = _srs_config->get_mix_correct(req->vhost);  
1114 875
1115 return ret; 876 return ret;
1116 } 877 }
1117 878
1118 -int SrsSource::on_reload_vhost_play(string vhost) 879 +int SrsOriginHub::on_meta_data(SrsSharedPtrMessage* shared_metadata)
1119 { 880 {
1120 int ret = ERROR_SUCCESS; 881 int ret = ERROR_SUCCESS;
1121 882
1122 - if (req->vhost != vhost) {  
1123 - return ret; 883 + // copy to all forwarders
  884 + if (true) {
  885 + std::vector<SrsForwarder*>::iterator it;
  886 + for (it = forwarders.begin(); it != forwarders.end(); ++it) {
  887 + SrsForwarder* forwarder = *it;
  888 + if ((ret = forwarder->on_meta_data(shared_metadata)) != ERROR_SUCCESS) {
  889 + srs_error("forwarder process onMetaData message failed. ret=%d", ret);
  890 + return ret;
  891 + }
  892 + }
1124 } 893 }
1125 894
1126 - // time_jitter  
1127 - jitter_algorithm = (SrsRtmpJitterAlgorithm)_srs_config->get_time_jitter(req->vhost); 895 + return ret;
  896 +}
  897 +
  898 +int SrsOriginHub::on_audio(SrsSharedPtrMessage* shared_audio)
  899 +{
  900 + int ret = ERROR_SUCCESS;
1128 901
1129 - // mix_correct  
1130 - if (true) {  
1131 - bool v = _srs_config->get_mix_correct(req->vhost);  
1132 -  
1133 - // when changed, clear the mix queue.  
1134 - if (v != mix_correct) {  
1135 - mix_queue->clear(); 902 + SrsSharedPtrMessage* msg = shared_audio;
  903 +
  904 +#ifdef SRS_AUTO_HLS
  905 + if ((ret = hls->on_audio(msg)) != ERROR_SUCCESS) {
  906 + // apply the error strategy for hls.
  907 + // @see https://github.com/ossrs/srs/issues/264
  908 + std::string hls_error_strategy = _srs_config->get_hls_on_error(req->vhost);
  909 + if (srs_config_hls_is_on_error_ignore(hls_error_strategy)) {
  910 + srs_warn("hls process audio message failed, ignore and disable hls. ret=%d", ret);
  911 +
  912 + // unpublish, ignore ret.
  913 + hls->on_unpublish();
  914 +
  915 + // ignore.
  916 + ret = ERROR_SUCCESS;
  917 + } else if (srs_config_hls_is_on_error_continue(hls_error_strategy)) {
  918 + if (srs_hls_can_continue(ret, source->meta->ash(), msg)) {
  919 + ret = ERROR_SUCCESS;
  920 + } else {
  921 + srs_warn("hls continue audio failed. ret=%d", ret);
  922 + return ret;
  923 + }
  924 + } else {
  925 + srs_warn("hls disconnect publisher for audio error. ret=%d", ret);
  926 + return ret;
1136 } 927 }
1137 - mix_correct = v;  
1138 } 928 }
  929 +#endif
1139 930
1140 - // atc changed.  
1141 - if (true) {  
1142 - bool v = _srs_config->get_atc(vhost); 931 +#ifdef SRS_AUTO_DVR
  932 + if ((ret = dvr->on_audio(msg)) != ERROR_SUCCESS) {
  933 + srs_warn("dvr process audio message failed, ignore and disable dvr. ret=%d", ret);
1143 934
1144 - if (v != atc) {  
1145 - srs_warn("vhost %s atc changed to %d, connected client may corrupt.", vhost.c_str(), v);  
1146 - gop_cache->clear();  
1147 - }  
1148 - atc = v; 935 + // unpublish, ignore ret.
  936 + dvr->on_unpublish();
  937 +
  938 + // ignore.
  939 + ret = ERROR_SUCCESS;
1149 } 940 }
  941 +#endif
1150 942
1151 - // gop cache changed.  
1152 - if (true) {  
1153 - bool v = _srs_config->get_gop_cache(vhost); 943 +#ifdef SRS_AUTO_HDS
  944 + if ((ret = hds->on_audio(msg)) != ERROR_SUCCESS) {
  945 + srs_warn("hds process audio message failed, ignore and disable dvr. ret=%d", ret);
1154 946
1155 - if (v != gop_cache->enabled()) {  
1156 - string url = req->get_stream_url();  
1157 - srs_trace("vhost %s gop_cache changed to %d, source url=%s", vhost.c_str(), v, url.c_str());  
1158 - gop_cache->set(v);  
1159 - } 947 + // unpublish, ignore ret.
  948 + hds->on_unpublish();
  949 + // ignore.
  950 + ret = ERROR_SUCCESS;
1160 } 951 }
  952 +#endif
1161 953
1162 - // queue length 954 + // copy to all forwarders.
1163 if (true) { 955 if (true) {
1164 - double v = _srs_config->get_queue_length(req->vhost);  
1165 -  
1166 - if (true) {  
1167 - std::vector<SrsConsumer*>::iterator it;  
1168 -  
1169 - for (it = consumers.begin(); it != consumers.end(); ++it) {  
1170 - SrsConsumer* consumer = *it;  
1171 - consumer->set_queue_size(v);  
1172 - }  
1173 -  
1174 - srs_trace("consumers reload queue size success.");  
1175 - }  
1176 -  
1177 - if (true) {  
1178 - std::vector<SrsForwarder*>::iterator it;  
1179 -  
1180 - for (it = forwarders.begin(); it != forwarders.end(); ++it) {  
1181 - SrsForwarder* forwarder = *it;  
1182 - forwarder->set_queue_size(v); 956 + std::vector<SrsForwarder*>::iterator it;
  957 + for (it = forwarders.begin(); it != forwarders.end(); ++it) {
  958 + SrsForwarder* forwarder = *it;
  959 + if ((ret = forwarder->on_audio(msg)) != ERROR_SUCCESS) {
  960 + srs_error("forwarder process audio message failed. ret=%d", ret);
  961 + return ret;
1183 } 962 }
1184 -  
1185 - srs_trace("forwarders reload queue size success.");  
1186 - }  
1187 -  
1188 - if (true) {  
1189 - publish_edge->set_queue_size(v);  
1190 - srs_trace("publish_edge reload queue size success.");  
1191 } 963 }
1192 } 964 }
1193 965
1194 return ret; 966 return ret;
1195 } 967 }
1196 968
1197 -int SrsSource::on_reload_vhost_forward(string vhost) 969 +int SrsOriginHub::on_video(SrsSharedPtrMessage* shared_video, bool is_sequence_header)
1198 { 970 {
1199 int ret = ERROR_SUCCESS; 971 int ret = ERROR_SUCCESS;
1200 972
1201 - if (req->vhost != vhost) {  
1202 - return ret; 973 + SrsSharedPtrMessage* msg = shared_video;
  974 +
  975 +#ifdef SRS_AUTO_HLS
  976 + if ((ret = hls->on_video(msg, is_sequence_header)) != ERROR_SUCCESS) {
  977 + // apply the error strategy for hls.
  978 + // @see https://github.com/ossrs/srs/issues/264
  979 + std::string hls_error_strategy = _srs_config->get_hls_on_error(req->vhost);
  980 + if (srs_config_hls_is_on_error_ignore(hls_error_strategy)) {
  981 + srs_warn("hls process video message failed, ignore and disable hls. ret=%d", ret);
  982 +
  983 + // unpublish, ignore ret.
  984 + hls->on_unpublish();
  985 +
  986 + // ignore.
  987 + ret = ERROR_SUCCESS;
  988 + } else if (srs_config_hls_is_on_error_continue(hls_error_strategy)) {
  989 + if (srs_hls_can_continue(ret, source->meta->vsh(), msg)) {
  990 + ret = ERROR_SUCCESS;
  991 + } else {
  992 + srs_warn("hls continue video failed. ret=%d", ret);
  993 + return ret;
  994 + }
  995 + } else {
  996 + srs_warn("hls disconnect publisher for video error. ret=%d", ret);
  997 + return ret;
  998 + }
1203 } 999 }
  1000 +#endif
1204 1001
1205 - // TODO: FIXME: maybe should ignore when publish already stopped?  
1206 -  
1207 - // forwarders  
1208 - destroy_forwarders();  
1209 - if ((ret = create_forwarders()) != ERROR_SUCCESS) {  
1210 - srs_error("create forwarders failed. ret=%d", ret);  
1211 - return ret; 1002 +#ifdef SRS_AUTO_DVR
  1003 + if ((ret = dvr->on_video(msg)) != ERROR_SUCCESS) {
  1004 + srs_warn("dvr process video message failed, ignore and disable dvr. ret=%d", ret);
  1005 +
  1006 + // unpublish, ignore ret.
  1007 + dvr->on_unpublish();
  1008 +
  1009 + // ignore.
  1010 + ret = ERROR_SUCCESS;
  1011 + }
  1012 +#endif
  1013 +
  1014 +#ifdef SRS_AUTO_HDS
  1015 + if ((ret = hds->on_video(msg)) != ERROR_SUCCESS) {
  1016 + srs_warn("hds process video message failed, ignore and disable dvr. ret=%d", ret);
  1017 +
  1018 + // unpublish, ignore ret.
  1019 + hds->on_unpublish();
  1020 + // ignore.
  1021 + ret = ERROR_SUCCESS;
  1022 + }
  1023 +#endif
  1024 +
  1025 + // copy to all forwarders.
  1026 + if (!forwarders.empty()) {
  1027 + std::vector<SrsForwarder*>::iterator it;
  1028 + for (it = forwarders.begin(); it != forwarders.end(); ++it) {
  1029 + SrsForwarder* forwarder = *it;
  1030 + if ((ret = forwarder->on_video(msg)) != ERROR_SUCCESS) {
  1031 + srs_error("forwarder process video message failed. ret=%d", ret);
  1032 + return ret;
  1033 + }
  1034 + }
1212 } 1035 }
1213 -  
1214 - srs_trace("vhost %s forwarders reload success", vhost.c_str());  
1215 1036
1216 return ret; 1037 return ret;
1217 } 1038 }
1218 1039
1219 -int SrsSource::on_reload_vhost_hls(string vhost) 1040 +int SrsOriginHub::on_publish()
1220 { 1041 {
1221 int ret = ERROR_SUCCESS; 1042 int ret = ERROR_SUCCESS;
1222 1043
1223 - if (req->vhost != vhost) { 1044 + // create forwarders
  1045 + if ((ret = create_forwarders()) != ERROR_SUCCESS) {
  1046 + srs_error("create forwarders failed. ret=%d", ret);
  1047 + return ret;
  1048 + }
  1049 +
  1050 + // TODO: FIXME: use initialize to set req.
  1051 +#ifdef SRS_AUTO_TRANSCODE
  1052 + if ((ret = encoder->on_publish(req)) != ERROR_SUCCESS) {
  1053 + srs_error("start encoder failed. ret=%d", ret);
  1054 + return ret;
  1055 + }
  1056 +#endif
  1057 +
  1058 +#ifdef SRS_AUTO_HLS
  1059 + if ((ret = hls->on_publish(false)) != ERROR_SUCCESS) {
  1060 + srs_error("start hls failed. ret=%d", ret);
  1061 + return ret;
  1062 + }
  1063 +#endif
  1064 +
  1065 +#ifdef SRS_AUTO_DVR
  1066 + if ((ret = dvr->on_publish(false)) != ERROR_SUCCESS) {
  1067 + srs_error("start dvr failed. ret=%d", ret);
  1068 + return ret;
  1069 + }
  1070 +#endif
  1071 +
  1072 + // TODO: FIXME: use initialize to set req.
  1073 +#ifdef SRS_AUTO_HDS
  1074 + if ((ret = hds->on_publish(req)) != ERROR_SUCCESS) {
  1075 + srs_error("start hds failed. ret=%d", ret);
  1076 + return ret;
  1077 + }
  1078 +#endif
  1079 +
  1080 + // TODO: FIXME: use initialize to set req.
  1081 + if ((ret = ng_exec->on_publish(req)) != ERROR_SUCCESS) {
  1082 + srs_error("start exec failed. ret=%d", ret);
  1083 + return ret;
  1084 + }
  1085 +
  1086 + return ret;
  1087 +}
  1088 +
  1089 +void SrsOriginHub::on_unpublish()
  1090 +{
  1091 + // destroy all forwarders
  1092 + destroy_forwarders();
  1093 +
  1094 +#ifdef SRS_AUTO_TRANSCODE
  1095 + encoder->on_unpublish();
  1096 +#endif
  1097 +
  1098 +#ifdef SRS_AUTO_HLS
  1099 + hls->on_unpublish();
  1100 +#endif
  1101 +
  1102 +#ifdef SRS_AUTO_DVR
  1103 + dvr->on_unpublish();
  1104 +#endif
  1105 +
  1106 +#ifdef SRS_AUTO_HDS
  1107 + hds->on_unpublish();
  1108 +#endif
  1109 +
  1110 + ng_exec->on_unpublish();
  1111 +}
  1112 +
  1113 +int SrsOriginHub::on_forwarder_start(SrsForwarder* forwarder)
  1114 +{
  1115 + int ret = ERROR_SUCCESS;
  1116 +
  1117 + SrsSharedPtrMessage* cache_metadata = source->meta->data();
  1118 + SrsSharedPtrMessage* cache_sh_video = source->meta->vsh();
  1119 + SrsSharedPtrMessage* cache_sh_audio = source->meta->ash();
  1120 +
  1121 + // feed the forwarder the metadata/sequence header,
  1122 + // when reload to enable the forwarder.
  1123 + if (cache_metadata && (ret = forwarder->on_meta_data(cache_metadata)) != ERROR_SUCCESS) {
  1124 + srs_error("forwarder process onMetaData message failed. ret=%d", ret);
  1125 + return ret;
  1126 + }
  1127 + if (cache_sh_video && (ret = forwarder->on_video(cache_sh_video)) != ERROR_SUCCESS) {
  1128 + srs_error("forwarder process video sequence header message failed. ret=%d", ret);
  1129 + return ret;
  1130 + }
  1131 + if (cache_sh_audio && (ret = forwarder->on_audio(cache_sh_audio)) != ERROR_SUCCESS) {
  1132 + srs_error("forwarder process audio sequence header message failed. ret=%d", ret);
  1133 + return ret;
  1134 + }
  1135 +
  1136 + return ret;
  1137 +}
  1138 +
  1139 +int SrsOriginHub::on_hls_start()
  1140 +{
  1141 + int ret = ERROR_SUCCESS;
  1142 +
  1143 + SrsSharedPtrMessage* cache_sh_video = source->meta->vsh();
  1144 + SrsSharedPtrMessage* cache_sh_audio = source->meta->ash();
  1145 +
  1146 +#ifdef SRS_AUTO_HLS
  1147 + // feed the hls the metadata/sequence header,
  1148 + // when reload to start hls, hls will never get the sequence header in stream,
  1149 + // use the SrsSource.on_hls_start to push the sequence header to HLS.
  1150 + // TODO: maybe need to decode the metadata?
  1151 + if (cache_sh_video && (ret = hls->on_video(cache_sh_video, true)) != ERROR_SUCCESS) {
  1152 + srs_error("hls process video sequence header message failed. ret=%d", ret);
  1153 + return ret;
  1154 + }
  1155 + if (cache_sh_audio && (ret = hls->on_audio(cache_sh_audio)) != ERROR_SUCCESS) {
  1156 + srs_error("hls process audio sequence header message failed. ret=%d", ret);
  1157 + return ret;
  1158 + }
  1159 +#endif
  1160 +
  1161 + return ret;
  1162 +}
  1163 +
  1164 +int SrsOriginHub::on_dvr_request_sh()
  1165 +{
  1166 + int ret = ERROR_SUCCESS;
  1167 +
  1168 + SrsSharedPtrMessage* cache_metadata = source->meta->data();
  1169 + SrsSharedPtrMessage* cache_sh_video = source->meta->vsh();
  1170 + SrsSharedPtrMessage* cache_sh_audio = source->meta->ash();
  1171 +
  1172 +#ifdef SRS_AUTO_DVR
  1173 + // feed the dvr the metadata/sequence header,
  1174 + // when reload to start dvr, dvr will never get the sequence header in stream,
  1175 + // use the SrsSource.on_dvr_request_sh to push the sequence header to DVR.
  1176 + if (cache_metadata) {
  1177 + char* payload = cache_metadata->payload;
  1178 + int size = cache_metadata->size;
  1179 +
  1180 + SrsBuffer stream;
  1181 + if ((ret = stream.initialize(payload, size)) != ERROR_SUCCESS) {
  1182 + srs_error("dvr decode metadata stream failed. ret=%d", ret);
  1183 + return ret;
  1184 + }
  1185 +
  1186 + SrsOnMetaDataPacket pkt;
  1187 + if ((ret = pkt.decode(&stream)) != ERROR_SUCCESS) {
  1188 + srs_error("dvr decode metadata packet failed.");
  1189 + return ret;
  1190 + }
  1191 +
  1192 + if ((ret = dvr->on_meta_data(&pkt)) != ERROR_SUCCESS) {
  1193 + srs_error("dvr process onMetaData message failed. ret=%d", ret);
  1194 + return ret;
  1195 + }
  1196 + }
  1197 +
  1198 + if (cache_sh_video && (ret = dvr->on_video(cache_sh_video)) != ERROR_SUCCESS) {
  1199 + srs_error("dvr process video sequence header message failed. ret=%d", ret);
  1200 + return ret;
  1201 + }
  1202 + if (cache_sh_audio && (ret = dvr->on_audio(cache_sh_audio)) != ERROR_SUCCESS) {
  1203 + srs_error("dvr process audio sequence header message failed. ret=%d", ret);
  1204 + return ret;
  1205 + }
  1206 +#endif
  1207 +
  1208 + return ret;
  1209 +}
  1210 +
  1211 +int SrsOriginHub::on_reload_vhost_forward(string vhost)
  1212 +{
  1213 + int ret = ERROR_SUCCESS;
  1214 +
  1215 + if (req->vhost != vhost) {
  1216 + return ret;
  1217 + }
  1218 +
  1219 + // TODO: FIXME: maybe should ignore when publish already stopped?
  1220 +
  1221 + // forwarders
  1222 + destroy_forwarders();
  1223 + if ((ret = create_forwarders()) != ERROR_SUCCESS) {
  1224 + srs_error("create forwarders failed. ret=%d", ret);
  1225 + return ret;
  1226 + }
  1227 +
  1228 + srs_trace("vhost %s forwarders reload success", vhost.c_str());
  1229 +
  1230 + return ret;
  1231 +}
  1232 +
  1233 +int SrsOriginHub::on_reload_vhost_hls(string vhost)
  1234 +{
  1235 + int ret = ERROR_SUCCESS;
  1236 +
  1237 + if (req->vhost != vhost) {
1224 return ret; 1238 return ret;
1225 } 1239 }
1226 1240
@@ -1238,16 +1252,16 @@ int SrsSource::on_reload_vhost_hls(string vhost) @@ -1238,16 +1252,16 @@ int SrsSource::on_reload_vhost_hls(string vhost)
1238 return ret; 1252 return ret;
1239 } 1253 }
1240 1254
1241 -int SrsSource::on_reload_vhost_hds(string vhost) 1255 +int SrsOriginHub::on_reload_vhost_hds(string vhost)
1242 { 1256 {
1243 int ret = ERROR_SUCCESS; 1257 int ret = ERROR_SUCCESS;
1244 - 1258 +
1245 if (req->vhost != vhost) { 1259 if (req->vhost != vhost) {
1246 return ret; 1260 return ret;
1247 } 1261 }
1248 1262
1249 // TODO: FIXME: maybe should ignore when publish already stopped? 1263 // TODO: FIXME: maybe should ignore when publish already stopped?
1250 - 1264 +
1251 #ifdef SRS_AUTO_HDS 1265 #ifdef SRS_AUTO_HDS
1252 hds->on_unpublish(); 1266 hds->on_unpublish();
1253 if ((ret = hds->on_publish(req)) != ERROR_SUCCESS) { 1267 if ((ret = hds->on_publish(req)) != ERROR_SUCCESS) {
@@ -1256,11 +1270,11 @@ int SrsSource::on_reload_vhost_hds(string vhost) @@ -1256,11 +1270,11 @@ int SrsSource::on_reload_vhost_hds(string vhost)
1256 } 1270 }
1257 srs_trace("vhost %s hds reload success", vhost.c_str()); 1271 srs_trace("vhost %s hds reload success", vhost.c_str());
1258 #endif 1272 #endif
1259 - 1273 +
1260 return ret; 1274 return ret;
1261 } 1275 }
1262 1276
1263 -int SrsSource::on_reload_vhost_dvr(string vhost) 1277 +int SrsOriginHub::on_reload_vhost_dvr(string vhost)
1264 { 1278 {
1265 int ret = ERROR_SUCCESS; 1279 int ret = ERROR_SUCCESS;
1266 1280
@@ -1273,12 +1287,12 @@ int SrsSource::on_reload_vhost_dvr(string vhost) @@ -1273,12 +1287,12 @@ int SrsSource::on_reload_vhost_dvr(string vhost)
1273 #ifdef SRS_AUTO_DVR 1287 #ifdef SRS_AUTO_DVR
1274 // cleanup dvr 1288 // cleanup dvr
1275 dvr->on_unpublish(); 1289 dvr->on_unpublish();
1276 - 1290 +
1277 // reinitialize the dvr, update plan. 1291 // reinitialize the dvr, update plan.
1278 if ((ret = dvr->initialize(this, req)) != ERROR_SUCCESS) { 1292 if ((ret = dvr->initialize(this, req)) != ERROR_SUCCESS) {
1279 return ret; 1293 return ret;
1280 } 1294 }
1281 - 1295 +
1282 // start to publish by new plan. 1296 // start to publish by new plan.
1283 if ((ret = dvr->on_publish(true)) != ERROR_SUCCESS) { 1297 if ((ret = dvr->on_publish(true)) != ERROR_SUCCESS) {
1284 srs_error("dvr publish failed. ret=%d", ret); 1298 srs_error("dvr publish failed. ret=%d", ret);
@@ -1291,131 +1305,624 @@ int SrsSource::on_reload_vhost_dvr(string vhost) @@ -1291,131 +1305,624 @@ int SrsSource::on_reload_vhost_dvr(string vhost)
1291 return ret; 1305 return ret;
1292 } 1306 }
1293 1307
1294 -int SrsSource::on_reload_vhost_transcode(string vhost) 1308 +int SrsOriginHub::on_reload_vhost_transcode(string vhost)
  1309 +{
  1310 + int ret = ERROR_SUCCESS;
  1311 +
  1312 + if (req->vhost != vhost) {
  1313 + return ret;
  1314 + }
  1315 +
  1316 + // TODO: FIXME: maybe should ignore when publish already stopped?
  1317 +
  1318 +#ifdef SRS_AUTO_TRANSCODE
  1319 + encoder->on_unpublish();
  1320 + if ((ret = encoder->on_publish(req)) != ERROR_SUCCESS) {
  1321 + srs_error("start encoder failed. ret=%d", ret);
  1322 + return ret;
  1323 + }
  1324 + srs_trace("vhost %s transcode reload success", vhost.c_str());
  1325 +#endif
  1326 +
  1327 + return ret;
  1328 +}
  1329 +
  1330 +int SrsOriginHub::on_reload_vhost_exec(string vhost)
  1331 +{
  1332 + int ret = ERROR_SUCCESS;
  1333 +
  1334 + if (req->vhost != vhost) {
  1335 + return ret;
  1336 + }
  1337 +
  1338 + // TODO: FIXME: maybe should ignore when publish already stopped?
  1339 +
  1340 + ng_exec->on_unpublish();
  1341 + if ((ret = ng_exec->on_publish(req)) != ERROR_SUCCESS) {
  1342 + srs_error("start exec failed. ret=%d", ret);
  1343 + return ret;
  1344 + }
  1345 + srs_trace("vhost %s exec reload success", vhost.c_str());
  1346 +
  1347 + return ret;
  1348 +}
  1349 +
  1350 +int SrsOriginHub::create_forwarders()
  1351 +{
  1352 + int ret = ERROR_SUCCESS;
  1353 +
  1354 + if (!_srs_config->get_forward_enabled(req->vhost)) {
  1355 + return ret;
  1356 + }
  1357 +
  1358 + SrsConfDirective* conf = _srs_config->get_forwards(req->vhost);
  1359 + for (int i = 0; conf && i < (int)conf->args.size(); i++) {
  1360 + std::string forward_server = conf->args.at(i);
  1361 +
  1362 + SrsForwarder* forwarder = new SrsForwarder(this);
  1363 + forwarders.push_back(forwarder);
  1364 +
  1365 + // initialize the forwarder with request.
  1366 + if ((ret = forwarder->initialize(req, forward_server)) != ERROR_SUCCESS) {
  1367 + return ret;
  1368 + }
  1369 +
  1370 + // TODO: FIXME: support queue size.
  1371 + //double queue_size = _srs_config->get_queue_length(req->vhost);
  1372 + //forwarder->set_queue_size(queue_size);
  1373 +
  1374 + if ((ret = forwarder->on_publish()) != ERROR_SUCCESS) {
  1375 + srs_error("start forwarder failed. "
  1376 + "vhost=%s, app=%s, stream=%s, forward-to=%s",
  1377 + req->vhost.c_str(), req->app.c_str(), req->stream.c_str(),
  1378 + forward_server.c_str());
  1379 + return ret;
  1380 + }
  1381 + }
  1382 +
  1383 + return ret;
  1384 +}
  1385 +
  1386 +void SrsOriginHub::destroy_forwarders()
  1387 +{
  1388 + std::vector<SrsForwarder*>::iterator it;
  1389 + for (it = forwarders.begin(); it != forwarders.end(); ++it) {
  1390 + SrsForwarder* forwarder = *it;
  1391 + forwarder->on_unpublish();
  1392 + srs_freep(forwarder);
  1393 + }
  1394 + forwarders.clear();
  1395 +}
  1396 +
  1397 +SrsMetaCache::SrsMetaCache()
  1398 +{
  1399 + cache_metadata = cache_sh_video = cache_sh_audio = NULL;
  1400 +}
  1401 +
  1402 +SrsMetaCache::~SrsMetaCache()
  1403 +{
  1404 + dispose();
  1405 +}
  1406 +
  1407 +void SrsMetaCache::dispose()
  1408 +{
  1409 + srs_freep(cache_metadata);
  1410 + srs_freep(cache_sh_video);
  1411 + srs_freep(cache_sh_audio);
  1412 +}
  1413 +
  1414 +SrsSharedPtrMessage* SrsMetaCache::data()
  1415 +{
  1416 + return cache_metadata;
  1417 +}
  1418 +
  1419 +SrsSharedPtrMessage* SrsMetaCache::vsh()
  1420 +{
  1421 + return cache_sh_video;
  1422 +}
  1423 +
  1424 +SrsSharedPtrMessage* SrsMetaCache::ash()
  1425 +{
  1426 + return cache_sh_audio;
  1427 +}
  1428 +
  1429 +int SrsMetaCache::dumps(SrsConsumer* consumer, bool atc, SrsRtmpJitterAlgorithm ag, bool dm, bool ds)
  1430 +{
  1431 + int ret = ERROR_SUCCESS;
  1432 +
  1433 + // copy metadata.
  1434 + if (dm && cache_metadata && (ret = consumer->enqueue(cache_metadata, atc, ag)) != ERROR_SUCCESS) {
  1435 + srs_error("dispatch metadata failed. ret=%d", ret);
  1436 + return ret;
  1437 + }
  1438 + srs_info("dispatch metadata success");
  1439 +
  1440 + // copy sequence header
  1441 + // copy audio sequence first, for hls to fast parse the "right" audio codec.
  1442 + // @see https://github.com/ossrs/srs/issues/301
  1443 + if (ds && cache_sh_audio && (ret = consumer->enqueue(cache_sh_audio, atc, ag)) != ERROR_SUCCESS) {
  1444 + srs_error("dispatch audio sequence header failed. ret=%d", ret);
  1445 + return ret;
  1446 + }
  1447 + srs_info("dispatch audio sequence header success");
  1448 +
  1449 + if (ds && cache_sh_video && (ret = consumer->enqueue(cache_sh_video, atc, ag)) != ERROR_SUCCESS) {
  1450 + srs_error("dispatch video sequence header failed. ret=%d", ret);
  1451 + return ret;
  1452 + }
  1453 + srs_info("dispatch video sequence header success");
  1454 +
  1455 + return ret;
  1456 +}
  1457 +
  1458 +int SrsMetaCache::update_data(SrsMessageHeader* header, SrsOnMetaDataPacket* metadata, bool& updated)
  1459 +{
  1460 + updated = false;
  1461 +
  1462 + int ret = ERROR_SUCCESS;
  1463 +
  1464 + SrsAmf0Any* prop = NULL;
  1465 +
  1466 + // when exists the duration, remove it to make ExoPlayer happy.
  1467 + if (metadata->metadata->get_property("duration") != NULL) {
  1468 + metadata->metadata->remove("duration");
  1469 + }
  1470 +
  1471 + // generate metadata info to print
  1472 + std::stringstream ss;
  1473 + if ((prop = metadata->metadata->ensure_property_number("width")) != NULL) {
  1474 + ss << ", width=" << (int)prop->to_number();
  1475 + }
  1476 + if ((prop = metadata->metadata->ensure_property_number("height")) != NULL) {
  1477 + ss << ", height=" << (int)prop->to_number();
  1478 + }
  1479 + if ((prop = metadata->metadata->ensure_property_number("videocodecid")) != NULL) {
  1480 + ss << ", vcodec=" << (int)prop->to_number();
  1481 + }
  1482 + if ((prop = metadata->metadata->ensure_property_number("audiocodecid")) != NULL) {
  1483 + ss << ", acodec=" << (int)prop->to_number();
  1484 + }
  1485 + srs_trace("got metadata%s", ss.str().c_str());
  1486 +
  1487 + // add server info to metadata
  1488 + metadata->metadata->set("server", SrsAmf0Any::str(RTMP_SIG_SRS_SERVER));
  1489 + metadata->metadata->set("srs_primary", SrsAmf0Any::str(RTMP_SIG_SRS_PRIMARY));
  1490 + metadata->metadata->set("srs_authors", SrsAmf0Any::str(RTMP_SIG_SRS_AUTHROS));
  1491 +
  1492 + // version, for example, 1.0.0
  1493 + // add version to metadata, please donot remove it, for debug.
  1494 + metadata->metadata->set("server_version", SrsAmf0Any::str(RTMP_SIG_SRS_VERSION));
  1495 +
  1496 + // encode the metadata to payload
  1497 + int size = 0;
  1498 + char* payload = NULL;
  1499 + if ((ret = metadata->encode(size, payload)) != ERROR_SUCCESS) {
  1500 + srs_error("encode metadata error. ret=%d", ret);
  1501 + srs_freep(payload);
  1502 + return ret;
  1503 + }
  1504 + srs_verbose("encode metadata success.");
  1505 +
  1506 + if (size <= 0) {
  1507 + srs_warn("ignore the invalid metadata. size=%d", size);
  1508 + return ret;
  1509 + }
  1510 +
  1511 + // create a shared ptr message.
  1512 + srs_freep(cache_metadata);
  1513 + cache_metadata = new SrsSharedPtrMessage();
  1514 + updated = true;
  1515 +
  1516 + // dump message to shared ptr message.
  1517 + // the payload/size managed by cache_metadata, user should not free it.
  1518 + if ((ret = cache_metadata->create(header, payload, size)) != ERROR_SUCCESS) {
  1519 + srs_error("initialize the cache metadata failed. ret=%d", ret);
  1520 + return ret;
  1521 + }
  1522 + srs_verbose("initialize shared ptr metadata success.");
  1523 +
  1524 + return ret;
  1525 +}
  1526 +
  1527 +void SrsMetaCache::update_ash(SrsSharedPtrMessage* msg)
  1528 +{
  1529 + srs_freep(cache_sh_audio);
  1530 + cache_sh_audio = msg->copy();
  1531 +}
  1532 +
  1533 +void SrsMetaCache::update_vsh(SrsSharedPtrMessage* msg)
  1534 +{
  1535 + srs_freep(cache_sh_video);
  1536 + cache_sh_video = msg->copy();
  1537 +}
  1538 +
  1539 +std::map<std::string, SrsSource*> SrsSource::pool;
  1540 +
  1541 +int SrsSource::fetch_or_create(SrsRequest* r, ISrsSourceHandler* h, SrsSource** pps)
  1542 +{
  1543 + int ret = ERROR_SUCCESS;
  1544 +
  1545 + SrsSource* source = NULL;
  1546 + if ((source = fetch(r)) != NULL) {
  1547 + *pps = source;
  1548 + return ret;
  1549 + }
  1550 +
  1551 + string stream_url = r->get_stream_url();
  1552 + string vhost = r->vhost;
  1553 +
  1554 + // should always not exists for create a source.
  1555 + srs_assert (pool.find(stream_url) == pool.end());
  1556 +
  1557 + source = new SrsSource();
  1558 + if ((ret = source->initialize(r, h)) != ERROR_SUCCESS) {
  1559 + srs_freep(source);
  1560 + return ret;
  1561 + }
  1562 +
  1563 + pool[stream_url] = source;
  1564 + srs_info("create new source for url=%s, vhost=%s", stream_url.c_str(), vhost.c_str());
  1565 +
  1566 + *pps = source;
  1567 +
  1568 + return ret;
  1569 +}
  1570 +
  1571 +SrsSource* SrsSource::fetch(SrsRequest* r)
  1572 +{
  1573 + SrsSource* source = NULL;
  1574 +
  1575 + string stream_url = r->get_stream_url();
  1576 + if (pool.find(stream_url) == pool.end()) {
  1577 + return NULL;
  1578 + }
  1579 +
  1580 + source = pool[stream_url];
  1581 +
  1582 + // we always update the request of resource,
  1583 + // for origin auth is on, the token in request maybe invalid,
  1584 + // and we only need to update the token of request, it's simple.
  1585 + source->req->update_auth(r);
  1586 +
  1587 + return source;
  1588 +}
  1589 +
  1590 +void SrsSource::dispose_all()
  1591 +{
  1592 + std::map<std::string, SrsSource*>::iterator it;
  1593 + for (it = pool.begin(); it != pool.end(); ++it) {
  1594 + SrsSource* source = it->second;
  1595 + source->dispose();
  1596 + }
  1597 + return;
  1598 +}
  1599 +
  1600 +int SrsSource::cycle_all()
  1601 +{
  1602 + int ret = ERROR_SUCCESS;
  1603 +
  1604 + int cid = _srs_context->get_id();
  1605 + ret = do_cycle_all();
  1606 + _srs_context->set_id(cid);
  1607 +
  1608 + return ret;
  1609 +}
  1610 +
  1611 +int SrsSource::do_cycle_all()
  1612 +{
  1613 + int ret = ERROR_SUCCESS;
  1614 +
  1615 + std::map<std::string, SrsSource*>::iterator it;
  1616 + for (it = pool.begin(); it != pool.end();) {
  1617 + SrsSource* source = it->second;
  1618 +
  1619 + // Do cycle source to cleanup components, such as hls dispose.
  1620 + if ((ret = source->cycle()) != ERROR_SUCCESS) {
  1621 + return ret;
  1622 + }
  1623 +
  1624 + // TODO: FIXME: support source cleanup.
  1625 + // @see https://github.com/ossrs/srs/issues/713
  1626 + // @see https://github.com/ossrs/srs/issues/714
  1627 +#if 0
  1628 + // When source expired, remove it.
  1629 + if (source->expired()) {
  1630 + int cid = source->source_id();
  1631 + if (cid == -1 && source->pre_source_id() > 0) {
  1632 + cid = source->pre_source_id();
  1633 + }
  1634 + if (cid > 0) {
  1635 + _srs_context->set_id(cid);
  1636 + }
  1637 + srs_trace("cleanup die source, total=%d", (int)pool.size());
  1638 +
  1639 + srs_freep(source);
  1640 + pool.erase(it++);
  1641 + } else {
  1642 + ++it;
  1643 + }
  1644 +#else
  1645 + ++it;
  1646 +#endif
  1647 + }
  1648 +
  1649 + return ret;
  1650 +}
  1651 +
  1652 +void SrsSource::destroy()
  1653 +{
  1654 + std::map<std::string, SrsSource*>::iterator it;
  1655 + for (it = pool.begin(); it != pool.end(); ++it) {
  1656 + SrsSource* source = it->second;
  1657 + srs_freep(source);
  1658 + }
  1659 + pool.clear();
  1660 +}
  1661 +
  1662 +SrsMixQueue::SrsMixQueue()
  1663 +{
  1664 + nb_videos = 0;
  1665 + nb_audios = 0;
  1666 +}
  1667 +
  1668 +SrsMixQueue::~SrsMixQueue()
  1669 +{
  1670 + clear();
  1671 +}
  1672 +
  1673 +void SrsMixQueue::clear()
  1674 +{
  1675 + std::multimap<int64_t, SrsSharedPtrMessage*>::iterator it;
  1676 + for (it = msgs.begin(); it != msgs.end(); ++it) {
  1677 + SrsSharedPtrMessage* msg = it->second;
  1678 + srs_freep(msg);
  1679 + }
  1680 + msgs.clear();
  1681 +
  1682 + nb_videos = 0;
  1683 + nb_audios = 0;
  1684 +}
  1685 +
  1686 +void SrsMixQueue::push(SrsSharedPtrMessage* msg)
  1687 +{
  1688 + msgs.insert(std::make_pair(msg->timestamp, msg));
  1689 +
  1690 + if (msg->is_video()) {
  1691 + nb_videos++;
  1692 + } else {
  1693 + nb_audios++;
  1694 + }
  1695 +}
  1696 +
  1697 +SrsSharedPtrMessage* SrsMixQueue::pop()
  1698 +{
  1699 + bool mix_ok = false;
  1700 +
  1701 + // pure video
  1702 + if (nb_videos >= SRS_MIX_CORRECT_PURE_AV && nb_audios == 0) {
  1703 + mix_ok = true;
  1704 + }
  1705 +
  1706 + // pure audio
  1707 + if (nb_audios >= SRS_MIX_CORRECT_PURE_AV && nb_videos == 0) {
  1708 + mix_ok = true;
  1709 + }
  1710 +
  1711 + // got 1 video and 1 audio, mix ok.
  1712 + if (nb_videos >= 1 && nb_audios >= 1) {
  1713 + mix_ok = true;
  1714 + }
  1715 +
  1716 + if (!mix_ok) {
  1717 + return NULL;
  1718 + }
  1719 +
  1720 + // pop the first msg.
  1721 + std::multimap<int64_t, SrsSharedPtrMessage*>::iterator it = msgs.begin();
  1722 + SrsSharedPtrMessage* msg = it->second;
  1723 + msgs.erase(it);
  1724 +
  1725 + if (msg->is_video()) {
  1726 + nb_videos--;
  1727 + } else {
  1728 + nb_audios--;
  1729 + }
  1730 +
  1731 + return msg;
  1732 +}
  1733 +
  1734 +SrsSource::SrsSource()
  1735 +{
  1736 + req = NULL;
  1737 + jitter_algorithm = SrsRtmpJitterAlgorithmOFF;
  1738 + mix_correct = false;
  1739 + mix_queue = new SrsMixQueue();
  1740 +
  1741 + _can_publish = true;
  1742 + _pre_source_id = _source_id = -1;
  1743 + die_at = -1;
  1744 +
  1745 + play_edge = new SrsPlayEdge();
  1746 + publish_edge = new SrsPublishEdge();
  1747 + gop_cache = new SrsGopCache();
  1748 + aggregate_stream = new SrsBuffer();
  1749 + hub = new SrsOriginHub(this);
  1750 + meta = new SrsMetaCache();
  1751 +
  1752 + is_monotonically_increase = false;
  1753 + last_packet_time = 0;
  1754 +
  1755 + _srs_config->subscribe(this);
  1756 + atc = false;
  1757 +}
  1758 +
  1759 +SrsSource::~SrsSource()
  1760 +{
  1761 + _srs_config->unsubscribe(this);
  1762 +
  1763 + // never free the consumers,
  1764 + // for all consumers are auto free.
  1765 + consumers.clear();
  1766 +
  1767 + srs_freep(hub);
  1768 + srs_freep(meta);
  1769 + srs_freep(mix_queue);
  1770 +
  1771 + srs_freep(play_edge);
  1772 + srs_freep(publish_edge);
  1773 + srs_freep(gop_cache);
  1774 + srs_freep(aggregate_stream);
  1775 +
  1776 + srs_freep(req);
  1777 +}
  1778 +
  1779 +void SrsSource::dispose()
  1780 +{
  1781 + hub->dispose();
  1782 + meta->dispose();
  1783 + gop_cache->dispose();
  1784 +}
  1785 +
  1786 +int SrsSource::cycle()
1295 { 1787 {
1296 - int ret = ERROR_SUCCESS;  
1297 -  
1298 - if (req->vhost != vhost) {  
1299 - return ret;  
1300 - }  
1301 -  
1302 - // TODO: FIXME: maybe should ignore when publish already stopped?  
1303 -  
1304 -#ifdef SRS_AUTO_TRANSCODE  
1305 - encoder->on_unpublish();  
1306 - if ((ret = encoder->on_publish(req)) != ERROR_SUCCESS) {  
1307 - srs_error("start encoder failed. ret=%d", ret);  
1308 - return ret;  
1309 - }  
1310 - srs_trace("vhost %s transcode reload success", vhost.c_str());  
1311 -#endif  
1312 -  
1313 - return ret; 1788 + return hub->cycle();
1314 } 1789 }
1315 1790
1316 -int SrsSource::on_reload_vhost_exec(string vhost) 1791 +bool SrsSource::expired()
1317 { 1792 {
1318 - int ret = ERROR_SUCCESS; 1793 + // unknown state?
  1794 + if (die_at == -1) {
  1795 + return false;
  1796 + }
1319 1797
1320 - if (req->vhost != vhost) {  
1321 - return ret; 1798 + // still publishing?
  1799 + if (!_can_publish || !publish_edge->can_publish()) {
  1800 + return false;
1322 } 1801 }
1323 1802
1324 - // TODO: FIXME: maybe should ignore when publish already stopped? 1803 + // has any consumers?
  1804 + if (!consumers.empty()) {
  1805 + return false;
  1806 + }
1325 1807
1326 - ng_exec->on_unpublish();  
1327 - if ((ret = ng_exec->on_publish(req)) != ERROR_SUCCESS) {  
1328 - srs_error("start exec failed. ret=%d", ret);  
1329 - return ret; 1808 + int64_t now = srs_get_system_time_ms();
  1809 + if (now > die_at + SRS_SOURCE_CLEANUP) {
  1810 + return true;
1330 } 1811 }
1331 - srs_trace("vhost %s exec reload success", vhost.c_str());  
1332 1812
1333 - return ret; 1813 + return false;
1334 } 1814 }
1335 1815
1336 -int SrsSource::on_forwarder_start(SrsForwarder* forwarder) 1816 +int SrsSource::initialize(SrsRequest* r, ISrsSourceHandler* h)
1337 { 1817 {
1338 int ret = ERROR_SUCCESS; 1818 int ret = ERROR_SUCCESS;
1339 -  
1340 - // feed the forwarder the metadata/sequence header,  
1341 - // when reload to enable the forwarder.  
1342 - if (cache_metadata && (ret = forwarder->on_meta_data(cache_metadata)) != ERROR_SUCCESS) {  
1343 - srs_error("forwarder process onMetaData message failed. ret=%d", ret); 1819 +
  1820 + srs_assert(h);
  1821 + srs_assert(!req);
  1822 +
  1823 + handler = h;
  1824 + req = r->copy();
  1825 + atc = _srs_config->get_atc(req->vhost);
  1826 +
  1827 + if ((ret = hub->initialize(req)) != ERROR_SUCCESS) {
1344 return ret; 1828 return ret;
1345 } 1829 }
1346 - if (cache_sh_video && (ret = forwarder->on_video(cache_sh_video)) != ERROR_SUCCESS) {  
1347 - srs_error("forwarder process video sequence header message failed. ret=%d", ret); 1830 +
  1831 + if ((ret = play_edge->initialize(this, req)) != ERROR_SUCCESS) {
1348 return ret; 1832 return ret;
1349 } 1833 }
1350 - if (cache_sh_audio && (ret = forwarder->on_audio(cache_sh_audio)) != ERROR_SUCCESS) {  
1351 - srs_error("forwarder process audio sequence header message failed. ret=%d", ret); 1834 + if ((ret = publish_edge->initialize(this, req)) != ERROR_SUCCESS) {
1352 return ret; 1835 return ret;
1353 } 1836 }
1354 1837
  1838 + double queue_size = _srs_config->get_queue_length(req->vhost);
  1839 + publish_edge->set_queue_size(queue_size);
  1840 +
  1841 + jitter_algorithm = (SrsRtmpJitterAlgorithm)_srs_config->get_time_jitter(req->vhost);
  1842 + mix_correct = _srs_config->get_mix_correct(req->vhost);
  1843 +
1355 return ret; 1844 return ret;
1356 } 1845 }
1357 1846
1358 -int SrsSource::on_hls_start() 1847 +int SrsSource::on_reload_vhost_play(string vhost)
1359 { 1848 {
1360 int ret = ERROR_SUCCESS; 1849 int ret = ERROR_SUCCESS;
1361 1850
1362 -#ifdef SRS_AUTO_HLS  
1363 - // feed the hls the metadata/sequence header,  
1364 - // when reload to start hls, hls will never get the sequence header in stream,  
1365 - // use the SrsSource.on_hls_start to push the sequence header to HLS.  
1366 - // TODO: maybe need to decode the metadata?  
1367 - if (cache_sh_video && (ret = hls->on_video(cache_sh_video, true)) != ERROR_SUCCESS) {  
1368 - srs_error("hls process video sequence header message failed. ret=%d", ret);  
1369 - return ret;  
1370 - }  
1371 - if (cache_sh_audio && (ret = hls->on_audio(cache_sh_audio)) != ERROR_SUCCESS) {  
1372 - srs_error("hls process audio sequence header message failed. ret=%d", ret); 1851 + if (req->vhost != vhost) {
1373 return ret; 1852 return ret;
1374 } 1853 }
1375 -#endif  
1376 1854
1377 - return ret;  
1378 -}  
1379 -  
1380 -int SrsSource::on_dvr_request_sh()  
1381 -{  
1382 - int ret = ERROR_SUCCESS; 1855 + // time_jitter
  1856 + jitter_algorithm = (SrsRtmpJitterAlgorithm)_srs_config->get_time_jitter(req->vhost);
1383 1857
1384 -#ifdef SRS_AUTO_DVR  
1385 - // feed the dvr the metadata/sequence header,  
1386 - // when reload to start dvr, dvr will never get the sequence header in stream,  
1387 - // use the SrsSource.on_dvr_request_sh to push the sequence header to DVR.  
1388 - if (cache_metadata) {  
1389 - char* payload = cache_metadata->payload;  
1390 - int size = cache_metadata->size; 1858 + // mix_correct
  1859 + if (true) {
  1860 + bool v = _srs_config->get_mix_correct(req->vhost);
1391 1861
1392 - SrsBuffer stream;  
1393 - if ((ret = stream.initialize(payload, size)) != ERROR_SUCCESS) {  
1394 - srs_error("dvr decode metadata stream failed. ret=%d", ret);  
1395 - return ret; 1862 + // when changed, clear the mix queue.
  1863 + if (v != mix_correct) {
  1864 + mix_queue->clear();
1396 } 1865 }
  1866 + mix_correct = v;
  1867 + }
  1868 +
  1869 + // atc changed.
  1870 + if (true) {
  1871 + bool v = _srs_config->get_atc(vhost);
1397 1872
1398 - SrsOnMetaDataPacket pkt;  
1399 - if ((ret = pkt.decode(&stream)) != ERROR_SUCCESS) {  
1400 - srs_error("dvr decode metadata packet failed.");  
1401 - return ret; 1873 + if (v != atc) {
  1874 + srs_warn("vhost %s atc changed to %d, connected client may corrupt.", vhost.c_str(), v);
  1875 + gop_cache->clear();
1402 } 1876 }
  1877 + atc = v;
  1878 + }
  1879 +
  1880 + // gop cache changed.
  1881 + if (true) {
  1882 + bool v = _srs_config->get_gop_cache(vhost);
1403 1883
1404 - if ((ret = dvr->on_meta_data(&pkt)) != ERROR_SUCCESS) {  
1405 - srs_error("dvr process onMetaData message failed. ret=%d", ret);  
1406 - return ret; 1884 + if (v != gop_cache->enabled()) {
  1885 + string url = req->get_stream_url();
  1886 + srs_trace("vhost %s gop_cache changed to %d, source url=%s", vhost.c_str(), v, url.c_str());
  1887 + gop_cache->set(v);
1407 } 1888 }
1408 } 1889 }
1409 1890
1410 - if (cache_sh_video && (ret = dvr->on_video(cache_sh_video)) != ERROR_SUCCESS) {  
1411 - srs_error("dvr process video sequence header message failed. ret=%d", ret);  
1412 - return ret;  
1413 - }  
1414 - if (cache_sh_audio && (ret = dvr->on_audio(cache_sh_audio)) != ERROR_SUCCESS) {  
1415 - srs_error("dvr process audio sequence header message failed. ret=%d", ret);  
1416 - return ret;  
1417 - } 1891 + // queue length
  1892 + if (true) {
  1893 + double v = _srs_config->get_queue_length(req->vhost);
  1894 +
  1895 + if (true) {
  1896 + std::vector<SrsConsumer*>::iterator it;
  1897 +
  1898 + for (it = consumers.begin(); it != consumers.end(); ++it) {
  1899 + SrsConsumer* consumer = *it;
  1900 + consumer->set_queue_size(v);
  1901 + }
  1902 +
  1903 + srs_trace("consumers reload queue size success.");
  1904 + }
  1905 +
  1906 + // TODO: FIXME: https://github.com/ossrs/srs/issues/742#issuecomment-273656897
  1907 + // TODO: FIXME: support queue size.
  1908 +#if 0
  1909 + if (true) {
  1910 + std::vector<SrsForwarder*>::iterator it;
  1911 +
  1912 + for (it = forwarders.begin(); it != forwarders.end(); ++it) {
  1913 + SrsForwarder* forwarder = *it;
  1914 + forwarder->set_queue_size(v);
  1915 + }
  1916 +
  1917 + srs_trace("forwarders reload queue size success.");
  1918 + }
  1919 +
  1920 + if (true) {
  1921 + publish_edge->set_queue_size(v);
  1922 + srs_trace("publish_edge reload queue size success.");
  1923 + }
1418 #endif 1924 #endif
  1925 + }
1419 1926
1420 return ret; 1927 return ret;
1421 } 1928 }
@@ -1469,53 +1976,13 @@ int SrsSource::on_meta_data(SrsCommonMessage* msg, SrsOnMetaDataPacket* metadata @@ -1469,53 +1976,13 @@ int SrsSource::on_meta_data(SrsCommonMessage* msg, SrsOnMetaDataPacket* metadata
1469 { 1976 {
1470 int ret = ERROR_SUCCESS; 1977 int ret = ERROR_SUCCESS;
1471 1978
1472 -#ifdef SRS_AUTO_HLS  
1473 - if (metadata && (ret = hls->on_meta_data(metadata->metadata)) != ERROR_SUCCESS) {  
1474 - srs_error("hls process onMetaData message failed. ret=%d", ret);  
1475 - return ret;  
1476 - }  
1477 -#endif  
1478 -  
1479 -#ifdef SRS_AUTO_DVR  
1480 - if (metadata && (ret = dvr->on_meta_data(metadata)) != ERROR_SUCCESS) {  
1481 - srs_error("dvr process onMetaData message failed. ret=%d", ret); 1979 + // Notify hub about the original metadata.
  1980 + if ((ret = hub->on_original_metadata(metadata)) != ERROR_SUCCESS) {
1482 return ret; 1981 return ret;
1483 } 1982 }
1484 -#endif  
1485 -  
1486 - SrsAmf0Any* prop = NULL;  
1487 -  
1488 - // when exists the duration, remove it to make ExoPlayer happy.  
1489 - if (metadata->metadata->get_property("duration") != NULL) {  
1490 - metadata->metadata->remove("duration");  
1491 - }  
1492 -  
1493 - // generate metadata info to print  
1494 - std::stringstream ss;  
1495 - if ((prop = metadata->metadata->ensure_property_number("width")) != NULL) {  
1496 - ss << ", width=" << (int)prop->to_number();  
1497 - }  
1498 - if ((prop = metadata->metadata->ensure_property_number("height")) != NULL) {  
1499 - ss << ", height=" << (int)prop->to_number();  
1500 - }  
1501 - if ((prop = metadata->metadata->ensure_property_number("videocodecid")) != NULL) {  
1502 - ss << ", vcodec=" << (int)prop->to_number();  
1503 - }  
1504 - if ((prop = metadata->metadata->ensure_property_number("audiocodecid")) != NULL) {  
1505 - ss << ", acodec=" << (int)prop->to_number();  
1506 - }  
1507 - srs_trace("got metadata%s", ss.str().c_str());  
1508 -  
1509 - // add server info to metadata  
1510 - metadata->metadata->set("server", SrsAmf0Any::str(RTMP_SIG_SRS_SERVER));  
1511 - metadata->metadata->set("srs_primary", SrsAmf0Any::str(RTMP_SIG_SRS_PRIMARY));  
1512 - metadata->metadata->set("srs_authors", SrsAmf0Any::str(RTMP_SIG_SRS_AUTHROS));  
1513 -  
1514 - // version, for example, 1.0.0  
1515 - // add version to metadata, please donot remove it, for debug.  
1516 - metadata->metadata->set("server_version", SrsAmf0Any::str(RTMP_SIG_SRS_VERSION));  
1517 1983
1518 // if allow atc_auto and bravo-atc detected, open atc for vhost. 1984 // if allow atc_auto and bravo-atc detected, open atc for vhost.
  1985 + SrsAmf0Any* prop = NULL;
1519 atc = _srs_config->get_atc(req->vhost); 1986 atc = _srs_config->get_atc(req->vhost);
1520 if (_srs_config->get_atc_auto(req->vhost)) { 1987 if (_srs_config->get_atc_auto(req->vhost)) {
1521 if ((prop = metadata->metadata->get_property("bravo_atc")) != NULL) { 1988 if ((prop = metadata->metadata->get_property("bravo_atc")) != NULL) {
@@ -1525,65 +1992,36 @@ int SrsSource::on_meta_data(SrsCommonMessage* msg, SrsOnMetaDataPacket* metadata @@ -1525,65 +1992,36 @@ int SrsSource::on_meta_data(SrsCommonMessage* msg, SrsOnMetaDataPacket* metadata
1525 } 1992 }
1526 } 1993 }
1527 1994
1528 - // encode the metadata to payload  
1529 - int size = 0;  
1530 - char* payload = NULL;  
1531 - if ((ret = metadata->encode(size, payload)) != ERROR_SUCCESS) {  
1532 - srs_error("encode metadata error. ret=%d", ret);  
1533 - srs_freep(payload); 1995 + // Update the meta cache.
  1996 + bool updated = false;
  1997 + if ((ret = meta->update_data(&msg->header, metadata, updated)) != ERROR_SUCCESS) {
1534 return ret; 1998 return ret;
1535 } 1999 }
1536 - srs_verbose("encode metadata success.");  
1537 -  
1538 - if (size <= 0) {  
1539 - srs_warn("ignore the invalid metadata. size=%d", size); 2000 + if (!updated) {
1540 return ret; 2001 return ret;
1541 } 2002 }
1542 2003
1543 // when already got metadata, drop when reduce sequence header. 2004 // when already got metadata, drop when reduce sequence header.
1544 bool drop_for_reduce = false; 2005 bool drop_for_reduce = false;
1545 - if (cache_metadata && _srs_config->get_reduce_sequence_header(req->vhost)) { 2006 + if (meta->data() && _srs_config->get_reduce_sequence_header(req->vhost)) {
1546 drop_for_reduce = true; 2007 drop_for_reduce = true;
1547 srs_warn("drop for reduce sh metadata, size=%d", msg->size); 2008 srs_warn("drop for reduce sh metadata, size=%d", msg->size);
1548 } 2009 }
1549 2010
1550 - // create a shared ptr message.  
1551 - srs_freep(cache_metadata);  
1552 - cache_metadata = new SrsSharedPtrMessage();  
1553 -  
1554 - // dump message to shared ptr message.  
1555 - // the payload/size managed by cache_metadata, user should not free it.  
1556 - if ((ret = cache_metadata->create(&msg->header, payload, size)) != ERROR_SUCCESS) {  
1557 - srs_error("initialize the cache metadata failed. ret=%d", ret);  
1558 - return ret;  
1559 - }  
1560 - srs_verbose("initialize shared ptr metadata success.");  
1561 -  
1562 // copy to all consumer 2011 // copy to all consumer
1563 if (!drop_for_reduce) { 2012 if (!drop_for_reduce) {
1564 std::vector<SrsConsumer*>::iterator it; 2013 std::vector<SrsConsumer*>::iterator it;
1565 - for (it = consumers.begin(); it != consumers.end(); ++it) {  
1566 - SrsConsumer* consumer = *it;  
1567 - if ((ret = consumer->enqueue(cache_metadata, atc, jitter_algorithm)) != ERROR_SUCCESS) {  
1568 - srs_error("dispatch the metadata failed. ret=%d", ret);  
1569 - return ret;  
1570 - }  
1571 - }  
1572 - }  
1573 -  
1574 - // copy to all forwarders  
1575 - if (true) {  
1576 - std::vector<SrsForwarder*>::iterator it;  
1577 - for (it = forwarders.begin(); it != forwarders.end(); ++it) {  
1578 - SrsForwarder* forwarder = *it;  
1579 - if ((ret = forwarder->on_meta_data(cache_metadata)) != ERROR_SUCCESS) {  
1580 - srs_error("forwarder process onMetaData message failed. ret=%d", ret); 2014 + for (it = consumers.begin(); it != consumers.end(); ++it) {
  2015 + SrsConsumer* consumer = *it;
  2016 + if ((ret = consumer->enqueue(meta->data(), atc, jitter_algorithm)) != ERROR_SUCCESS) {
  2017 + srs_error("dispatch the metadata failed. ret=%d", ret);
1581 return ret; 2018 return ret;
1582 } 2019 }
1583 } 2020 }
1584 } 2021 }
1585 2022
1586 - return ret; 2023 + // Copy to hub to all utilities.
  2024 + return hub->on_meta_data(meta->data());
1587 } 2025 }
1588 2026
1589 int SrsSource::on_audio(SrsCommonMessage* shared_audio) 2027 int SrsSource::on_audio(SrsCommonMessage* shared_audio)
@@ -1633,24 +2071,6 @@ int SrsSource::on_audio(SrsCommonMessage* shared_audio) @@ -1633,24 +2071,6 @@ int SrsSource::on_audio(SrsCommonMessage* shared_audio)
1633 return ret; 2071 return ret;
1634 } 2072 }
1635 2073
1636 -bool srs_hls_can_continue(int ret, SrsSharedPtrMessage* sh, SrsSharedPtrMessage* msg)  
1637 -{  
1638 - // only continue for decode error.  
1639 - if (ret != ERROR_HLS_DECODE_ERROR) {  
1640 - return false;  
1641 - }  
1642 -  
1643 - // when video size equals to sequence header,  
1644 - // the video actually maybe a sequence header,  
1645 - // continue to make ffmpeg happy.  
1646 - if (sh && sh->size == msg->size) {  
1647 - srs_warn("the msg is actually a sequence header, ignore this packet.");  
1648 - return true;  
1649 - }  
1650 -  
1651 - return false;  
1652 -}  
1653 -  
1654 int SrsSource::on_audio_imp(SrsSharedPtrMessage* msg) 2074 int SrsSource::on_audio_imp(SrsSharedPtrMessage* msg)
1655 { 2075 {
1656 int ret = ERROR_SUCCESS; 2076 int ret = ERROR_SUCCESS;
@@ -1661,9 +2081,9 @@ int SrsSource::on_audio_imp(SrsSharedPtrMessage* msg) @@ -1661,9 +2081,9 @@ int SrsSource::on_audio_imp(SrsSharedPtrMessage* msg)
1661 2081
1662 // whether consumer should drop for the duplicated sequence header. 2082 // whether consumer should drop for the duplicated sequence header.
1663 bool drop_for_reduce = false; 2083 bool drop_for_reduce = false;
1664 - if (is_sequence_header && cache_sh_audio && _srs_config->get_reduce_sequence_header(req->vhost)) {  
1665 - if (cache_sh_audio->size == msg->size) {  
1666 - drop_for_reduce = srs_bytes_equals(cache_sh_audio->payload, msg->payload, msg->size); 2084 + if (is_sequence_header && meta->ash() && _srs_config->get_reduce_sequence_header(req->vhost)) {
  2085 + if (meta->ash()->size == msg->size) {
  2086 + drop_for_reduce = srs_bytes_equals(meta->ash()->payload, msg->payload, msg->size);
1667 srs_warn("drop for reduce sh audio, size=%d", msg->size); 2087 srs_warn("drop for reduce sh audio, size=%d", msg->size);
1668 } 2088 }
1669 } 2089 }
@@ -1697,56 +2117,6 @@ int SrsSource::on_audio_imp(SrsSharedPtrMessage* msg) @@ -1697,56 +2117,6 @@ int SrsSource::on_audio_imp(SrsSharedPtrMessage* msg)
1697 flv_sample_rates[sample.sound_rate]); 2117 flv_sample_rates[sample.sound_rate]);
1698 } 2118 }
1699 2119
1700 -#ifdef SRS_AUTO_HLS  
1701 - if ((ret = hls->on_audio(msg)) != ERROR_SUCCESS) {  
1702 - // apply the error strategy for hls.  
1703 - // @see https://github.com/ossrs/srs/issues/264  
1704 - std::string hls_error_strategy = _srs_config->get_hls_on_error(req->vhost);  
1705 - if (srs_config_hls_is_on_error_ignore(hls_error_strategy)) {  
1706 - srs_warn("hls process audio message failed, ignore and disable hls. ret=%d", ret);  
1707 -  
1708 - // unpublish, ignore ret.  
1709 - hls->on_unpublish();  
1710 -  
1711 - // ignore.  
1712 - ret = ERROR_SUCCESS;  
1713 - } else if (srs_config_hls_is_on_error_continue(hls_error_strategy)) {  
1714 - if (srs_hls_can_continue(ret, cache_sh_audio, msg)) {  
1715 - ret = ERROR_SUCCESS;  
1716 - } else {  
1717 - srs_warn("hls continue audio failed. ret=%d", ret);  
1718 - return ret;  
1719 - }  
1720 - } else {  
1721 - srs_warn("hls disconnect publisher for audio error. ret=%d", ret);  
1722 - return ret;  
1723 - }  
1724 - }  
1725 -#endif  
1726 -  
1727 -#ifdef SRS_AUTO_DVR  
1728 - if ((ret = dvr->on_audio(msg)) != ERROR_SUCCESS) {  
1729 - srs_warn("dvr process audio message failed, ignore and disable dvr. ret=%d", ret);  
1730 -  
1731 - // unpublish, ignore ret.  
1732 - dvr->on_unpublish();  
1733 -  
1734 - // ignore.  
1735 - ret = ERROR_SUCCESS;  
1736 - }  
1737 -#endif  
1738 -  
1739 -#ifdef SRS_AUTO_HDS  
1740 - if ((ret = hds->on_audio(msg)) != ERROR_SUCCESS) {  
1741 - srs_warn("hds process audio message failed, ignore and disable dvr. ret=%d", ret);  
1742 -  
1743 - // unpublish, ignore ret.  
1744 - hds->on_unpublish();  
1745 - // ignore.  
1746 - ret = ERROR_SUCCESS;  
1747 - }  
1748 -#endif  
1749 -  
1750 // copy to all consumer 2120 // copy to all consumer
1751 if (!drop_for_reduce) { 2121 if (!drop_for_reduce) {
1752 for (int i = 0; i < (int)consumers.size(); i++) { 2122 for (int i = 0; i < (int)consumers.size(); i++) {
@@ -1759,24 +2129,16 @@ int SrsSource::on_audio_imp(SrsSharedPtrMessage* msg) @@ -1759,24 +2129,16 @@ int SrsSource::on_audio_imp(SrsSharedPtrMessage* msg)
1759 srs_info("dispatch audio success."); 2129 srs_info("dispatch audio success.");
1760 } 2130 }
1761 2131
1762 - // copy to all forwarders.  
1763 - if (true) {  
1764 - std::vector<SrsForwarder*>::iterator it;  
1765 - for (it = forwarders.begin(); it != forwarders.end(); ++it) {  
1766 - SrsForwarder* forwarder = *it;  
1767 - if ((ret = forwarder->on_audio(msg)) != ERROR_SUCCESS) {  
1768 - srs_error("forwarder process audio message failed. ret=%d", ret);  
1769 - return ret;  
1770 - }  
1771 - } 2132 + // Copy to hub to all utilities.
  2133 + if ((ret = hub->on_audio(msg)) != ERROR_SUCCESS) {
  2134 + return ret;
1772 } 2135 }
1773 2136
1774 // cache the sequence header of aac, or first packet of mp3. 2137 // cache the sequence header of aac, or first packet of mp3.
1775 // for example, the mp3 is used for hls to write the "right" audio codec. 2138 // for example, the mp3 is used for hls to write the "right" audio codec.
1776 // TODO: FIXME: to refine the stream info system. 2139 // TODO: FIXME: to refine the stream info system.
1777 - if (is_aac_sequence_header || !cache_sh_audio) {  
1778 - srs_freep(cache_sh_audio);  
1779 - cache_sh_audio = msg->copy(); 2140 + if (is_aac_sequence_header || !meta->ash()) {
  2141 + meta->update_ash(msg);
1780 } 2142 }
1781 2143
1782 // when sequence header, donot push to gop cache and adjust the timestamp. 2144 // when sequence header, donot push to gop cache and adjust the timestamp.
@@ -1793,11 +2155,11 @@ int SrsSource::on_audio_imp(SrsSharedPtrMessage* msg) @@ -1793,11 +2155,11 @@ int SrsSource::on_audio_imp(SrsSharedPtrMessage* msg)
1793 2155
1794 // if atc, update the sequence header to abs time. 2156 // if atc, update the sequence header to abs time.
1795 if (atc) { 2157 if (atc) {
1796 - if (cache_sh_audio) {  
1797 - cache_sh_audio->timestamp = msg->timestamp; 2158 + if (meta->ash()) {
  2159 + meta->ash()->timestamp = msg->timestamp;
1798 } 2160 }
1799 - if (cache_metadata) {  
1800 - cache_metadata->timestamp = msg->timestamp; 2161 + if (meta->data()) {
  2162 + meta->data()->timestamp = msg->timestamp;
1801 } 2163 }
1802 } 2164 }
1803 2165
@@ -1874,9 +2236,9 @@ int SrsSource::on_video_imp(SrsSharedPtrMessage* msg) @@ -1874,9 +2236,9 @@ int SrsSource::on_video_imp(SrsSharedPtrMessage* msg)
1874 2236
1875 // whether consumer should drop for the duplicated sequence header. 2237 // whether consumer should drop for the duplicated sequence header.
1876 bool drop_for_reduce = false; 2238 bool drop_for_reduce = false;
1877 - if (is_sequence_header && cache_sh_video && _srs_config->get_reduce_sequence_header(req->vhost)) {  
1878 - if (cache_sh_video->size == msg->size) {  
1879 - drop_for_reduce = srs_bytes_equals(cache_sh_video->payload, msg->payload, msg->size); 2239 + if (is_sequence_header && meta->vsh() && _srs_config->get_reduce_sequence_header(req->vhost)) {
  2240 + if (meta->vsh()->size == msg->size) {
  2241 + drop_for_reduce = srs_bytes_equals(meta->vsh()->payload, msg->payload, msg->size);
1880 srs_warn("drop for reduce sh video, size=%d", msg->size); 2242 srs_warn("drop for reduce sh video, size=%d", msg->size);
1881 } 2243 }
1882 } 2244 }
@@ -1884,8 +2246,7 @@ int SrsSource::on_video_imp(SrsSharedPtrMessage* msg) @@ -1884,8 +2246,7 @@ int SrsSource::on_video_imp(SrsSharedPtrMessage* msg)
1884 // cache the sequence header if h264 2246 // cache the sequence header if h264
1885 // donot cache the sequence header to gop_cache, return here. 2247 // donot cache the sequence header to gop_cache, return here.
1886 if (is_sequence_header) { 2248 if (is_sequence_header) {
1887 - srs_freep(cache_sh_video);  
1888 - cache_sh_video = msg->copy(); 2249 + meta->update_vsh(msg);
1889 2250
1890 // parse detail audio codec 2251 // parse detail audio codec
1891 SrsAvcAacCodec codec; 2252 SrsAvcAacCodec codec;
@@ -1913,55 +2274,10 @@ int SrsSource::on_video_imp(SrsSharedPtrMessage* msg) @@ -1913,55 +2274,10 @@ int SrsSource::on_video_imp(SrsSharedPtrMessage* msg)
1913 codec.video_data_rate / 1000, codec.frame_rate, codec.duration); 2274 codec.video_data_rate / 1000, codec.frame_rate, codec.duration);
1914 } 2275 }
1915 2276
1916 -#ifdef SRS_AUTO_HLS  
1917 - if ((ret = hls->on_video(msg, is_sequence_header)) != ERROR_SUCCESS) {  
1918 - // apply the error strategy for hls.  
1919 - // @see https://github.com/ossrs/srs/issues/264  
1920 - std::string hls_error_strategy = _srs_config->get_hls_on_error(req->vhost);  
1921 - if (srs_config_hls_is_on_error_ignore(hls_error_strategy)) {  
1922 - srs_warn("hls process video message failed, ignore and disable hls. ret=%d", ret);  
1923 -  
1924 - // unpublish, ignore ret.  
1925 - hls->on_unpublish();  
1926 -  
1927 - // ignore.  
1928 - ret = ERROR_SUCCESS;  
1929 - } else if (srs_config_hls_is_on_error_continue(hls_error_strategy)) {  
1930 - if (srs_hls_can_continue(ret, cache_sh_video, msg)) {  
1931 - ret = ERROR_SUCCESS;  
1932 - } else {  
1933 - srs_warn("hls continue video failed. ret=%d", ret);  
1934 - return ret;  
1935 - }  
1936 - } else {  
1937 - srs_warn("hls disconnect publisher for video error. ret=%d", ret);  
1938 - return ret;  
1939 - }  
1940 - }  
1941 -#endif  
1942 -  
1943 -#ifdef SRS_AUTO_DVR  
1944 - if ((ret = dvr->on_video(msg)) != ERROR_SUCCESS) {  
1945 - srs_warn("dvr process video message failed, ignore and disable dvr. ret=%d", ret);  
1946 -  
1947 - // unpublish, ignore ret.  
1948 - dvr->on_unpublish();  
1949 -  
1950 - // ignore.  
1951 - ret = ERROR_SUCCESS;  
1952 - }  
1953 -#endif  
1954 -  
1955 -#ifdef SRS_AUTO_HDS  
1956 - if ((ret = hds->on_video(msg)) != ERROR_SUCCESS) {  
1957 - srs_warn("hds process video message failed, ignore and disable dvr. ret=%d", ret);  
1958 -  
1959 - // unpublish, ignore ret.  
1960 - hds->on_unpublish();  
1961 - // ignore.  
1962 - ret = ERROR_SUCCESS; 2277 + // Copy to hub to all utilities.
  2278 + if ((ret = hub->on_video(msg, is_sequence_header)) != ERROR_SUCCESS) {
  2279 + return ret;
1963 } 2280 }
1964 -#endif  
1965 2281
1966 // copy to all consumer 2282 // copy to all consumer
1967 if (!drop_for_reduce) { 2283 if (!drop_for_reduce) {
@@ -1974,18 +2290,6 @@ int SrsSource::on_video_imp(SrsSharedPtrMessage* msg) @@ -1974,18 +2290,6 @@ int SrsSource::on_video_imp(SrsSharedPtrMessage* msg)
1974 } 2290 }
1975 srs_info("dispatch video success."); 2291 srs_info("dispatch video success.");
1976 } 2292 }
1977 -  
1978 - // copy to all forwarders.  
1979 - if (!forwarders.empty()) {  
1980 - std::vector<SrsForwarder*>::iterator it;  
1981 - for (it = forwarders.begin(); it != forwarders.end(); ++it) {  
1982 - SrsForwarder* forwarder = *it;  
1983 - if ((ret = forwarder->on_video(msg)) != ERROR_SUCCESS) {  
1984 - srs_error("forwarder process video message failed. ret=%d", ret);  
1985 - return ret;  
1986 - }  
1987 - }  
1988 - }  
1989 2293
1990 // when sequence header, donot push to gop cache and adjust the timestamp. 2294 // when sequence header, donot push to gop cache and adjust the timestamp.
1991 if (is_sequence_header) { 2295 if (is_sequence_header) {
@@ -2001,11 +2305,11 @@ int SrsSource::on_video_imp(SrsSharedPtrMessage* msg) @@ -2001,11 +2305,11 @@ int SrsSource::on_video_imp(SrsSharedPtrMessage* msg)
2001 2305
2002 // if atc, update the sequence header to abs time. 2306 // if atc, update the sequence header to abs time.
2003 if (atc) { 2307 if (atc) {
2004 - if (cache_sh_video) {  
2005 - cache_sh_video->timestamp = msg->timestamp; 2308 + if (meta->vsh()) {
  2309 + meta->vsh()->timestamp = msg->timestamp;
2006 } 2310 }
2007 - if (cache_metadata) {  
2008 - cache_metadata->timestamp = msg->timestamp; 2311 + if (meta->data()) {
  2312 + meta->data()->timestamp = msg->timestamp;
2009 } 2313 }
2010 } 2314 }
2011 2315
@@ -2142,45 +2446,8 @@ int SrsSource::on_publish() @@ -2142,45 +2446,8 @@ int SrsSource::on_publish()
2142 is_monotonically_increase = true; 2446 is_monotonically_increase = true;
2143 last_packet_time = 0; 2447 last_packet_time = 0;
2144 2448
2145 - // create forwarders  
2146 - if ((ret = create_forwarders()) != ERROR_SUCCESS) {  
2147 - srs_error("create forwarders failed. ret=%d", ret);  
2148 - return ret;  
2149 - }  
2150 -  
2151 - // TODO: FIXME: use initialize to set req.  
2152 -#ifdef SRS_AUTO_TRANSCODE  
2153 - if ((ret = encoder->on_publish(req)) != ERROR_SUCCESS) {  
2154 - srs_error("start encoder failed. ret=%d", ret);  
2155 - return ret;  
2156 - }  
2157 -#endif  
2158 -  
2159 -#ifdef SRS_AUTO_HLS  
2160 - if ((ret = hls->on_publish(false)) != ERROR_SUCCESS) {  
2161 - srs_error("start hls failed. ret=%d", ret);  
2162 - return ret;  
2163 - }  
2164 -#endif  
2165 -  
2166 -#ifdef SRS_AUTO_DVR  
2167 - if ((ret = dvr->on_publish(false)) != ERROR_SUCCESS) {  
2168 - srs_error("start dvr failed. ret=%d", ret);  
2169 - return ret;  
2170 - }  
2171 -#endif  
2172 -  
2173 - // TODO: FIXME: use initialize to set req.  
2174 -#ifdef SRS_AUTO_HDS  
2175 - if ((ret = hds->on_publish(req)) != ERROR_SUCCESS) {  
2176 - srs_error("start hds failed. ret=%d", ret);  
2177 - return ret;  
2178 - }  
2179 -#endif  
2180 -  
2181 - // TODO: FIXME: use initialize to set req.  
2182 - if ((ret = ng_exec->on_publish(req)) != ERROR_SUCCESS) {  
2183 - srs_error("start exec failed. ret=%d", ret); 2449 + // Notify the hub about the publish event.
  2450 + if ((ret = hub->on_publish()) != ERROR_SUCCESS) {
2184 return ret; 2451 return ret;
2185 } 2452 }
2186 2453
@@ -2203,26 +2470,8 @@ void SrsSource::on_unpublish() @@ -2203,26 +2470,8 @@ void SrsSource::on_unpublish()
2203 return; 2470 return;
2204 } 2471 }
2205 2472
2206 - // destroy all forwarders  
2207 - destroy_forwarders();  
2208 -  
2209 -#ifdef SRS_AUTO_TRANSCODE  
2210 - encoder->on_unpublish();  
2211 -#endif  
2212 -  
2213 -#ifdef SRS_AUTO_HLS  
2214 - hls->on_unpublish();  
2215 -#endif  
2216 -  
2217 -#ifdef SRS_AUTO_DVR  
2218 - dvr->on_unpublish();  
2219 -#endif  
2220 -  
2221 -#ifdef SRS_AUTO_HDS  
2222 - hds->on_unpublish();  
2223 -#endif  
2224 -  
2225 - ng_exec->on_unpublish(); 2473 + // Notify the hub about the unpublish event.
  2474 + hub->on_unpublish();
2226 2475
2227 // only clear the gop cache, 2476 // only clear the gop cache,
2228 // donot clear the sequence header, for it maybe not changed, 2477 // donot clear the sequence header, for it maybe not changed,
@@ -2259,38 +2508,21 @@ int SrsSource::create_consumer(SrsConnection* conn, SrsConsumer*& consumer, bool @@ -2259,38 +2508,21 @@ int SrsSource::create_consumer(SrsConnection* conn, SrsConsumer*& consumer, bool
2259 2508
2260 // if atc, update the sequence header to gop cache time. 2509 // if atc, update the sequence header to gop cache time.
2261 if (atc && !gop_cache->empty()) { 2510 if (atc && !gop_cache->empty()) {
2262 - if (cache_metadata) {  
2263 - cache_metadata->timestamp = gop_cache->start_time(); 2511 + if (meta->data()) {
  2512 + meta->data()->timestamp = gop_cache->start_time();
2264 } 2513 }
2265 - if (cache_sh_video) {  
2266 - cache_sh_video->timestamp = gop_cache->start_time(); 2514 + if (meta->vsh()) {
  2515 + meta->vsh()->timestamp = gop_cache->start_time();
2267 } 2516 }
2268 - if (cache_sh_audio) {  
2269 - cache_sh_audio->timestamp = gop_cache->start_time(); 2517 + if (meta->ash()) {
  2518 + meta->ash()->timestamp = gop_cache->start_time();
2270 } 2519 }
2271 } 2520 }
2272 2521
2273 - // copy metadata.  
2274 - if (dm && cache_metadata && (ret = consumer->enqueue(cache_metadata, atc, jitter_algorithm)) != ERROR_SUCCESS) {  
2275 - srs_error("dispatch metadata failed. ret=%d", ret);  
2276 - return ret;  
2277 - }  
2278 - srs_info("dispatch metadata success");  
2279 -  
2280 - // copy sequence header  
2281 - // copy audio sequence first, for hls to fast parse the "right" audio codec.  
2282 - // @see https://github.com/ossrs/srs/issues/301  
2283 - if (ds && cache_sh_audio && (ret = consumer->enqueue(cache_sh_audio, atc, jitter_algorithm)) != ERROR_SUCCESS) {  
2284 - srs_error("dispatch audio sequence header failed. ret=%d", ret);  
2285 - return ret;  
2286 - }  
2287 - srs_info("dispatch audio sequence header success");  
2288 -  
2289 - if (ds && cache_sh_video && (ret = consumer->enqueue(cache_sh_video, atc, jitter_algorithm)) != ERROR_SUCCESS) {  
2290 - srs_error("dispatch video sequence header failed. ret=%d", ret); 2522 + // Copy metadata and sequence header to consumer.
  2523 + if ((ret = meta->dumps(consumer, atc, jitter_algorithm, dm, ds)) != ERROR_SUCCESS) {
2291 return ret; 2524 return ret;
2292 } 2525 }
2293 - srs_info("dispatch video sequence header success");  
2294 2526
2295 // copy gop cache to client. 2527 // copy gop cache to client.
2296 if (dg && (ret = gop_cache->dump(consumer, atc, jitter_algorithm)) != ERROR_SUCCESS) { 2528 if (dg && (ret = gop_cache->dump(consumer, atc, jitter_algorithm)) != ERROR_SUCCESS) {
@@ -2356,52 +2588,6 @@ void SrsSource::on_edge_proxy_unpublish() @@ -2356,52 +2588,6 @@ void SrsSource::on_edge_proxy_unpublish()
2356 publish_edge->on_proxy_unpublish(); 2588 publish_edge->on_proxy_unpublish();
2357 } 2589 }
2358 2590
2359 -int SrsSource::create_forwarders()  
2360 -{  
2361 - int ret = ERROR_SUCCESS;  
2362 -  
2363 - if (!_srs_config->get_forward_enabled(req->vhost)) {  
2364 - return ret;  
2365 - }  
2366 -  
2367 - SrsConfDirective* conf = _srs_config->get_forwards(req->vhost);  
2368 - for (int i = 0; conf && i < (int)conf->args.size(); i++) {  
2369 - std::string forward_server = conf->args.at(i);  
2370 -  
2371 - SrsForwarder* forwarder = new SrsForwarder(this);  
2372 - forwarders.push_back(forwarder);  
2373 -  
2374 - // initialize the forwarder with request.  
2375 - if ((ret = forwarder->initialize(req, forward_server)) != ERROR_SUCCESS) {  
2376 - return ret;  
2377 - }  
2378 -  
2379 - double queue_size = _srs_config->get_queue_length(req->vhost);  
2380 - forwarder->set_queue_size(queue_size);  
2381 -  
2382 - if ((ret = forwarder->on_publish()) != ERROR_SUCCESS) {  
2383 - srs_error("start forwarder failed. "  
2384 - "vhost=%s, app=%s, stream=%s, forward-to=%s",  
2385 - req->vhost.c_str(), req->app.c_str(), req->stream.c_str(),  
2386 - forward_server.c_str());  
2387 - return ret;  
2388 - }  
2389 - }  
2390 -  
2391 - return ret;  
2392 -}  
2393 -  
2394 -void SrsSource::destroy_forwarders()  
2395 -{  
2396 - std::vector<SrsForwarder*>::iterator it;  
2397 - for (it = forwarders.begin(); it != forwarders.end(); ++it) {  
2398 - SrsForwarder* forwarder = *it;  
2399 - forwarder->on_unpublish();  
2400 - srs_freep(forwarder);  
2401 - }  
2402 - forwarders.clear();  
2403 -}  
2404 -  
2405 string SrsSource::get_curr_origin() 2591 string SrsSource::get_curr_origin()
2406 { 2592 {
2407 return play_edge->get_curr_origin(); 2593 return play_edge->get_curr_origin();
@@ -53,6 +53,7 @@ class SrsEdgeProxyContext; @@ -53,6 +53,7 @@ class SrsEdgeProxyContext;
53 class SrsMessageArray; 53 class SrsMessageArray;
54 class SrsNgExec; 54 class SrsNgExec;
55 class SrsConnection; 55 class SrsConnection;
  56 +class SrsMessageHeader;
56 #ifdef SRS_AUTO_HLS 57 #ifdef SRS_AUTO_HLS
57 class SrsHls; 58 class SrsHls;
58 #endif 59 #endif
@@ -411,10 +412,128 @@ public: @@ -411,10 +412,128 @@ public:
411 }; 412 };
412 413
413 /** 414 /**
  415 + * The hub for origin is a collection of utilities for origin only,
  416 + * for example, DVR, HLS, Forward and Transcode are only available for origin,
  417 + * they are meanless for edge server.
  418 + */
  419 +class SrsOriginHub : public ISrsReloadHandler
  420 +{
  421 +private:
  422 + SrsSource* source;
  423 + SrsRequest* req;
  424 +private:
  425 + // hls handler.
  426 +#ifdef SRS_AUTO_HLS
  427 + SrsHls* hls;
  428 +#endif
  429 + // dvr handler.
  430 +#ifdef SRS_AUTO_DVR
  431 + SrsDvr* dvr;
  432 +#endif
  433 + // transcoding handler.
  434 +#ifdef SRS_AUTO_TRANSCODE
  435 + SrsEncoder* encoder;
  436 +#endif
  437 +#ifdef SRS_AUTO_HDS
  438 + // adobe hds(http dynamic streaming).
  439 + SrsHds *hds;
  440 +#endif
  441 + // nginx-rtmp exec feature.
  442 + SrsNgExec* ng_exec;
  443 + // to forward stream to other servers
  444 + std::vector<SrsForwarder*> forwarders;
  445 +public:
  446 + SrsOriginHub(SrsSource* s);
  447 + virtual ~SrsOriginHub();
  448 +public:
  449 + // Initialize the hub with source and request.
  450 + // @param r The request object, managed by source.
  451 + virtual int initialize(SrsRequest* r);
  452 + // Dispose the hub, release utilities resource,
  453 + // for example, delete all HLS pieces.
  454 + virtual void dispose();
  455 + // Cycle the hub, process some regular events,
  456 + // for example, dispose hls in cycle.
  457 + virtual int cycle();
  458 +public:
  459 + // When got a original metadata.
  460 + virtual int on_original_metadata(SrsOnMetaDataPacket* metadata);
  461 + // When got a parsed metadata.
  462 + virtual int on_meta_data(SrsSharedPtrMessage* shared_metadata);
  463 + // When got a parsed audio packet.
  464 + virtual int on_audio(SrsSharedPtrMessage* shared_audio);
  465 + // When got a parsed video packet.
  466 + virtual int on_video(SrsSharedPtrMessage* shared_video, bool is_sequence_header);
  467 +public:
  468 + // When start publish stream.
  469 + virtual int on_publish();
  470 + // When stop publish stream.
  471 + virtual void on_unpublish();
  472 +// for the tools callback
  473 +public:
  474 + // for the SrsForwarder to callback to request the sequence headers.
  475 + virtual int on_forwarder_start(SrsForwarder* forwarder);
  476 + // for the SrsHls to callback to request the sequence headers.
  477 + virtual int on_hls_start();
  478 + // for the SrsDvr to callback to request the sequence headers.
  479 + virtual int on_dvr_request_sh();
  480 +// interface ISrsReloadHandler
  481 +public:
  482 + virtual int on_reload_vhost_forward(std::string vhost);
  483 + virtual int on_reload_vhost_hls(std::string vhost);
  484 + virtual int on_reload_vhost_hds(std::string vhost);
  485 + virtual int on_reload_vhost_dvr(std::string vhost);
  486 + virtual int on_reload_vhost_transcode(std::string vhost);
  487 + virtual int on_reload_vhost_exec(std::string vhost);
  488 +private:
  489 + virtual int create_forwarders();
  490 + virtual void destroy_forwarders();
  491 +};
  492 +
  493 +/**
  494 + * Each stream have optional meta(sps/pps in sequence header and metadata).
  495 + * This class cache and update the meta.
  496 + */
  497 +class SrsMetaCache
  498 +{
  499 +private:
  500 + SrsSharedPtrMessage* cache_metadata;
  501 + // the cached video sequence header.
  502 + SrsSharedPtrMessage* cache_sh_video;
  503 + // the cached audio sequence header.
  504 + SrsSharedPtrMessage* cache_sh_audio;
  505 +public:
  506 + SrsMetaCache();
  507 + virtual ~SrsMetaCache();
  508 +public:
  509 + // Dispose the metadata cache.
  510 + virtual void dispose();
  511 +public:
  512 + // Get the cached metadata.
  513 + virtual SrsSharedPtrMessage* data();
  514 + // Get the cached vsh(video sequence header).
  515 + virtual SrsSharedPtrMessage* vsh();
  516 + // Get the cached ash(audio sequence header).
  517 + virtual SrsSharedPtrMessage* ash();
  518 + // Dumps cached metadata to consumer.
  519 + // @param dm Whether dumps the metadata.
  520 + // @param ds Whether dumps the sequence header.
  521 + virtual int dumps(SrsConsumer* consumer, bool atc, SrsRtmpJitterAlgorithm ag, bool dm, bool ds);
  522 +public:
  523 + // Update the cached metadata by packet.
  524 + virtual int update_data(SrsMessageHeader* header, SrsOnMetaDataPacket* metadata, bool& updated);
  525 + // Update the cached audio sequence header.
  526 + virtual void update_ash(SrsSharedPtrMessage* msg);
  527 + // Update the cached video sequence header.
  528 + virtual void update_vsh(SrsSharedPtrMessage* msg);
  529 +};
  530 +
  531 +/**
414 * live streaming source. 532 * live streaming source.
415 */ 533 */
416 class SrsSource : public ISrsReloadHandler 534 class SrsSource : public ISrsReloadHandler
417 { 535 {
  536 + friend class SrsOriginHub;
418 private: 537 private:
419 static std::map<std::string, SrsSource*> pool; 538 static std::map<std::string, SrsSource*> pool;
420 public: 539 public:
@@ -475,35 +594,19 @@ private: @@ -475,35 +594,19 @@ private:
475 bool is_monotonically_increase; 594 bool is_monotonically_increase;
476 // the time of the packet we just got. 595 // the time of the packet we just got.
477 int64_t last_packet_time; 596 int64_t last_packet_time;
478 - // hls handler.  
479 -#ifdef SRS_AUTO_HLS  
480 - SrsHls* hls;  
481 -#endif  
482 - // dvr handler.  
483 -#ifdef SRS_AUTO_DVR  
484 - SrsDvr* dvr;  
485 -#endif  
486 - // transcoding handler.  
487 -#ifdef SRS_AUTO_TRANSCODE  
488 - SrsEncoder* encoder;  
489 -#endif  
490 -#ifdef SRS_AUTO_HDS  
491 - // adobe hds(http dynamic streaming).  
492 - SrsHds *hds;  
493 -#endif  
494 - // nginx-rtmp exec feature.  
495 - SrsNgExec* ng_exec; 597 + // for aggregate message
  598 + SrsBuffer* aggregate_stream;
  599 + // the event handler.
  600 + ISrsSourceHandler* handler;
496 // edge control service 601 // edge control service
497 SrsPlayEdge* play_edge; 602 SrsPlayEdge* play_edge;
498 SrsPublishEdge* publish_edge; 603 SrsPublishEdge* publish_edge;
499 // gop cache for client fast startup. 604 // gop cache for client fast startup.
500 SrsGopCache* gop_cache; 605 SrsGopCache* gop_cache;
501 - // to forward stream to other servers  
502 - std::vector<SrsForwarder*> forwarders;  
503 - // for aggregate message  
504 - SrsBuffer* aggregate_stream;  
505 - // the event handler.  
506 - ISrsSourceHandler* handler; 606 + // The hub for origin server.
  607 + SrsOriginHub* hub;
  608 + // The metadata cache.
  609 + SrsMetaCache* meta;
507 private: 610 private:
508 /** 611 /**
509 * can publish, true when is not streaming 612 * can publish, true when is not streaming
@@ -512,12 +615,6 @@ private: @@ -512,12 +615,6 @@ private:
512 // last die time, when all consumers quit and no publisher, 615 // last die time, when all consumers quit and no publisher,
513 // we will remove the source when source die. 616 // we will remove the source when source die.
514 int64_t die_at; 617 int64_t die_at;
515 -private:  
516 - SrsSharedPtrMessage* cache_metadata;  
517 - // the cached video sequence header.  
518 - SrsSharedPtrMessage* cache_sh_video;  
519 - // the cached audio sequence header.  
520 - SrsSharedPtrMessage* cache_sh_audio;  
521 public: 618 public:
522 SrsSource(); 619 SrsSource();
523 virtual ~SrsSource(); 620 virtual ~SrsSource();
@@ -535,20 +632,8 @@ public: @@ -535,20 +632,8 @@ public:
535 // interface ISrsReloadHandler 632 // interface ISrsReloadHandler
536 public: 633 public:
537 virtual int on_reload_vhost_play(std::string vhost); 634 virtual int on_reload_vhost_play(std::string vhost);
538 - virtual int on_reload_vhost_forward(std::string vhost);  
539 - virtual int on_reload_vhost_hls(std::string vhost);  
540 - virtual int on_reload_vhost_hds(std::string vhost);  
541 - virtual int on_reload_vhost_dvr(std::string vhost);  
542 - virtual int on_reload_vhost_transcode(std::string vhost);  
543 - virtual int on_reload_vhost_exec(std::string vhost);  
544 // for the tools callback 635 // for the tools callback
545 public: 636 public:
546 - // for the SrsForwarder to callback to request the sequence headers.  
547 - virtual int on_forwarder_start(SrsForwarder* forwarder);  
548 - // for the SrsHls to callback to request the sequence headers.  
549 - virtual int on_hls_start();  
550 - // for the SrsDvr to callback to request the sequence headers.  
551 - virtual int on_dvr_request_sh();  
552 // source id changed. 637 // source id changed.
553 virtual int on_source_id_changed(int id); 638 virtual int on_source_id_changed(int id);
554 // get current source id. 639 // get current source id.
@@ -599,9 +684,6 @@ public: @@ -599,9 +684,6 @@ public:
599 virtual int on_edge_proxy_publish(SrsCommonMessage* msg); 684 virtual int on_edge_proxy_publish(SrsCommonMessage* msg);
600 // for edge, proxy stop publish 685 // for edge, proxy stop publish
601 virtual void on_edge_proxy_unpublish(); 686 virtual void on_edge_proxy_unpublish();
602 -private:  
603 - virtual int create_forwarders();  
604 - virtual void destroy_forwarders();  
605 public: 687 public:
606 virtual std::string get_curr_origin(); 688 virtual std::string get_curr_origin();
607 }; 689 };
@@ -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 3 32 #define VERSION_MAJOR 3
33 #define VERSION_MINOR 0 33 #define VERSION_MINOR 0
34 -#define VERSION_REVISION 15 34 +#define VERSION_REVISION 16
35 35
36 // generated by configure, only macros. 36 // generated by configure, only macros.
37 #include <srs_auto_headers.hpp> 37 #include <srs_auto_headers.hpp>