winlin

for #179, refine dvr, support POST create dvr when publish not start. 2.0.126

@@ -310,7 +310,7 @@ vhost dvr.srs.com { @@ -310,7 +310,7 @@ vhost dvr.srs.com {
310 # vhost:"__defaultVhost", app:"live", stream:"livestream", 310 # vhost:"__defaultVhost", app:"live", stream:"livestream",
311 # wait_keyframe:true, callback:"http://127.0.0.1:8085/api/v1/dvrs" 311 # wait_keyframe:true, callback:"http://127.0.0.1:8085/api/v1/dvrs"
312 # } 312 # }
313 - # @remark, the app and stream is optional. 313 + # @remark, the app and stream is required for POST.
314 # response in json, where: 314 # response in json, where:
315 # {code:0} 315 # {code:0}
316 # method=DELETE, to stop dvr 316 # method=DELETE, to stop dvr
@@ -1983,6 +1983,7 @@ SrsConfDirective* SrsConfig::create_directive(string vhost, string directive, st @@ -1983,6 +1983,7 @@ SrsConfDirective* SrsConfig::create_directive(string vhost, string directive, st
1983 1983
1984 if (!vhost_conf) { 1984 if (!vhost_conf) {
1985 vhost_conf = new SrsConfDirective(); 1985 vhost_conf = new SrsConfDirective();
  1986 + vhost_conf->name = vhost;
1986 root->directives.push_back(vhost_conf); 1987 root->directives.push_back(vhost_conf);
1987 } 1988 }
1988 1989
@@ -1993,6 +1994,7 @@ SrsConfDirective* SrsConfig::create_directive(string vhost, string directive, st @@ -1993,6 +1994,7 @@ SrsConfDirective* SrsConfig::create_directive(string vhost, string directive, st
1993 SrsConfDirective* dir = vhost_conf->get(directive); 1994 SrsConfDirective* dir = vhost_conf->get(directive);
1994 if (!dir) { 1995 if (!dir) {
1995 dir = new SrsConfDirective(); 1996 dir = new SrsConfDirective();
  1997 + dir->name = directive;
1996 vhost_conf->directives.push_back(dir); 1998 vhost_conf->directives.push_back(dir);
1997 } 1999 }
1998 2000
@@ -2003,6 +2005,7 @@ SrsConfDirective* SrsConfig::create_directive(string vhost, string directive, st @@ -2003,6 +2005,7 @@ SrsConfDirective* SrsConfig::create_directive(string vhost, string directive, st
2003 SrsConfDirective* sdir = dir->get(sub_directive); 2005 SrsConfDirective* sdir = dir->get(sub_directive);
2004 if (!sdir) { 2006 if (!sdir) {
2005 sdir = new SrsConfDirective(); 2007 sdir = new SrsConfDirective();
  2008 + sdir->name = sub_directive;
2006 dir->directives.push_back(sdir); 2009 dir->directives.push_back(sdir);
2007 } 2010 }
2008 2011
@@ -2352,6 +2355,13 @@ bool SrsConfig::get_vhost_http_hooks_enabled(string vhost) @@ -2352,6 +2355,13 @@ bool SrsConfig::get_vhost_http_hooks_enabled(string vhost)
2352 return true; 2355 return true;
2353 } 2356 }
2354 2357
  2358 +void SrsConfig::set_vhost_http_hooks_enabled(string vhost, bool enabled)
  2359 +{
  2360 + SrsConfDirective* conf = create_directive(vhost, "http_hooks", "enabled");
  2361 + conf->args.clear();
  2362 + conf->args.push_back(enabled? "on":"off");
  2363 +}
  2364 +
2355 SrsConfDirective* SrsConfig::get_vhost_on_connect(string vhost) 2365 SrsConfDirective* SrsConfig::get_vhost_on_connect(string vhost)
2356 { 2366 {
2357 SrsConfDirective* conf = get_vhost_http_hooks(vhost); 2367 SrsConfDirective* conf = get_vhost_http_hooks(vhost);
@@ -2429,6 +2439,13 @@ SrsConfDirective* SrsConfig::get_vhost_on_dvr(string vhost) @@ -2429,6 +2439,13 @@ SrsConfDirective* SrsConfig::get_vhost_on_dvr(string vhost)
2429 return conf->get("on_dvr"); 2439 return conf->get("on_dvr");
2430 } 2440 }
2431 2441
  2442 +void SrsConfig::set_vhost_on_dvr(string vhost, string callback)
  2443 +{
  2444 + SrsConfDirective* conf = create_directive(vhost, "http_hooks", "on_dvr");
  2445 + conf->args.clear();
  2446 + conf->args.push_back(callback);
  2447 +}
  2448 +
2432 bool SrsConfig::get_bw_check_enabled(string vhost) 2449 bool SrsConfig::get_bw_check_enabled(string vhost)
2433 { 2450 {
2434 SrsConfDirective* conf = get_vhost(vhost); 2451 SrsConfDirective* conf = get_vhost(vhost);
@@ -3390,6 +3407,13 @@ string SrsConfig::get_dvr_plan(string vhost) @@ -3390,6 +3407,13 @@ string SrsConfig::get_dvr_plan(string vhost)
3390 return conf->arg0(); 3407 return conf->arg0();
3391 } 3408 }
3392 3409
  3410 +void SrsConfig::set_dvr_plan(string vhost, string plan)
  3411 +{
  3412 + SrsConfDirective* conf = create_directive(vhost, "dvr", "dvr_plan");
  3413 + conf->args.clear();
  3414 + conf->args.push_back(plan);
  3415 +}
  3416 +
3393 int SrsConfig::get_dvr_duration(string vhost) 3417 int SrsConfig::get_dvr_duration(string vhost)
3394 { 3418 {
3395 SrsConfDirective* dvr = get_dvr(vhost); 3419 SrsConfDirective* dvr = get_dvr(vhost);
@@ -596,6 +596,7 @@ public: @@ -596,6 +596,7 @@ public:
596 * @remark, if not enabled, donot callback all http hooks. 596 * @remark, if not enabled, donot callback all http hooks.
597 */ 597 */
598 virtual bool get_vhost_http_hooks_enabled(std::string vhost); 598 virtual bool get_vhost_http_hooks_enabled(std::string vhost);
  599 + virtual void set_vhost_http_hooks_enabled(std::string vhost, bool enabled);
599 /** 600 /**
600 * get the on_connect callbacks of vhost. 601 * get the on_connect callbacks of vhost.
601 * @return the on_connect callback directive, the args is the url to callback. 602 * @return the on_connect callback directive, the args is the url to callback.
@@ -631,6 +632,7 @@ public: @@ -631,6 +632,7 @@ public:
631 * @return the on_dvr callback directive, the args is the url to callback. 632 * @return the on_dvr callback directive, the args is the url to callback.
632 */ 633 */
633 virtual SrsConfDirective* get_vhost_on_dvr(std::string vhost); 634 virtual SrsConfDirective* get_vhost_on_dvr(std::string vhost);
  635 + virtual void set_vhost_on_dvr(std::string vhost, std::string callback);
634 // bwct(bandwidth check tool) section 636 // bwct(bandwidth check tool) section
635 public: 637 public:
636 /** 638 /**
@@ -933,6 +935,7 @@ public: @@ -933,6 +935,7 @@ public:
933 * get the plan of dvr, how to reap the flv file. 935 * get the plan of dvr, how to reap the flv file.
934 */ 936 */
935 virtual std::string get_dvr_plan(std::string vhost); 937 virtual std::string get_dvr_plan(std::string vhost);
  938 + virtual void set_dvr_plan(std::string vhost, std::string plan);
936 /** 939 /**
937 * get the duration of dvr flv. 940 * get the duration of dvr flv.
938 */ 941 */
@@ -28,6 +28,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -28,6 +28,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 #include <fcntl.h> 28 #include <fcntl.h>
29 #include <sstream> 29 #include <sstream>
30 #include <sys/time.h> 30 #include <sys/time.h>
  31 +#include <algorithm>
31 using namespace std; 32 using namespace std;
32 33
33 #include <srs_app_config.hpp> 34 #include <srs_app_config.hpp>
@@ -54,7 +55,6 @@ using namespace std; @@ -54,7 +55,6 @@ using namespace std;
54 SrsFlvSegment::SrsFlvSegment(SrsDvrPlan* p) 55 SrsFlvSegment::SrsFlvSegment(SrsDvrPlan* p)
55 { 56 {
56 req = NULL; 57 req = NULL;
57 - source = NULL;  
58 jitter = NULL; 58 jitter = NULL;
59 plan = p; 59 plan = p;
60 60
@@ -85,11 +85,10 @@ SrsFlvSegment::~SrsFlvSegment() @@ -85,11 +85,10 @@ SrsFlvSegment::~SrsFlvSegment()
85 srs_freep(enc); 85 srs_freep(enc);
86 } 86 }
87 87
88 -int SrsFlvSegment::initialize(SrsSource* s, SrsRequest* r) 88 +int SrsFlvSegment::initialize(SrsRequest* r)
89 { 89 {
90 int ret = ERROR_SUCCESS; 90 int ret = ERROR_SUCCESS;
91 91
92 - source = s;  
93 req = r; 92 req = r;
94 jitter_algorithm = (SrsRtmpJitterAlgorithm)_srs_config->get_dvr_time_jitter(req->vhost); 93 jitter_algorithm = (SrsRtmpJitterAlgorithm)_srs_config->get_dvr_time_jitter(req->vhost);
95 94
@@ -617,48 +616,6 @@ string SrsDvrAsyncCallOnDvr::to_string() @@ -617,48 +616,6 @@ string SrsDvrAsyncCallOnDvr::to_string()
617 return ss.str(); 616 return ss.str();
618 } 617 }
619 618
620 -SrsDvrAsyncCallOnSegment::SrsDvrAsyncCallOnSegment(SrsRequest* r, string c, string p)  
621 -{  
622 - req = r;  
623 - callback = c;  
624 - path = p;  
625 -}  
626 -  
627 -SrsDvrAsyncCallOnSegment::~SrsDvrAsyncCallOnSegment()  
628 -{  
629 -}  
630 -  
631 -int SrsDvrAsyncCallOnSegment::call()  
632 -{  
633 - int ret = ERROR_SUCCESS;  
634 -  
635 -#ifdef SRS_AUTO_HTTP_CALLBACK  
636 - // HTTP: callback  
637 - if (callback.empty()) {  
638 - srs_warn("dvr: ignore for callback empty, vhost=%s", req->vhost.c_str());  
639 - return ret;  
640 - }  
641 -  
642 - int connection_id = _srs_context->get_id();  
643 - std::string cwd = _srs_config->cwd();  
644 - std::string file = path;  
645 - std::string url = callback;  
646 - if ((ret = SrsHttpHooks::on_dvr_reap_segment(url, connection_id, req, cwd, file)) != ERROR_SUCCESS) {  
647 - srs_error("hook client on_dvr_reap_segment failed. url=%s, ret=%d", url.c_str(), ret);  
648 - return ret;  
649 - }  
650 -#endif  
651 -  
652 - return ret;  
653 -}  
654 -  
655 -string SrsDvrAsyncCallOnSegment::to_string()  
656 -{  
657 - std::stringstream ss;  
658 - ss << "vhost=" << req->vhost << ", file=" << path << "callback=" << callback;  
659 - return ss.str();  
660 -}  
661 -  
662 SrsDvrAsyncCallThread::SrsDvrAsyncCallThread() 619 SrsDvrAsyncCallThread::SrsDvrAsyncCallThread()
663 { 620 {
664 pthread = new SrsThread("async", this, SRS_AUTO_ASYNC_CALLBACL_SLEEP_US, true); 621 pthread = new SrsThread("async", this, SRS_AUTO_ASYNC_CALLBACL_SLEEP_US, true);
@@ -717,7 +674,6 @@ int SrsDvrAsyncCallThread::cycle() @@ -717,7 +674,6 @@ int SrsDvrAsyncCallThread::cycle()
717 674
718 SrsDvrPlan::SrsDvrPlan() 675 SrsDvrPlan::SrsDvrPlan()
719 { 676 {
720 - source = NULL;  
721 req = NULL; 677 req = NULL;
722 678
723 dvr_enabled = false; 679 dvr_enabled = false;
@@ -731,14 +687,13 @@ SrsDvrPlan::~SrsDvrPlan() @@ -731,14 +687,13 @@ SrsDvrPlan::~SrsDvrPlan()
731 srs_freep(async); 687 srs_freep(async);
732 } 688 }
733 689
734 -int SrsDvrPlan::initialize(SrsSource* s, SrsRequest* r) 690 +int SrsDvrPlan::initialize(SrsRequest* r)
735 { 691 {
736 int ret = ERROR_SUCCESS; 692 int ret = ERROR_SUCCESS;
737 -  
738 - source = s; 693 +
739 req = r; 694 req = r;
740 695
741 - if ((ret = segment->initialize(s, r)) != ERROR_SUCCESS) { 696 + if ((ret = segment->initialize(r)) != ERROR_SUCCESS) {
742 return ret; 697 return ret;
743 } 698 }
744 699
@@ -749,18 +704,6 @@ int SrsDvrPlan::initialize(SrsSource* s, SrsRequest* r) @@ -749,18 +704,6 @@ int SrsDvrPlan::initialize(SrsSource* s, SrsRequest* r)
749 return ret; 704 return ret;
750 } 705 }
751 706
752 -int SrsDvrPlan::on_dvr_request_sh()  
753 -{  
754 - int ret = ERROR_SUCCESS;  
755 -  
756 - // the dvr is enabled, notice the source to push the data.  
757 - if ((ret = source->on_dvr_request_sh()) != ERROR_SUCCESS) {  
758 - return ret;  
759 - }  
760 -  
761 - return ret;  
762 -}  
763 -  
764 int SrsDvrPlan::on_video_keyframe() 707 int SrsDvrPlan::on_video_keyframe()
765 { 708 {
766 return ERROR_SUCCESS; 709 return ERROR_SUCCESS;
@@ -833,6 +776,15 @@ SrsDvrPlan* SrsDvrPlan::create_plan(string vhost) @@ -833,6 +776,15 @@ SrsDvrPlan* SrsDvrPlan::create_plan(string vhost)
833 } else if (plan == SRS_CONF_DEFAULT_DVR_PLAN_APPEND) { 776 } else if (plan == SRS_CONF_DEFAULT_DVR_PLAN_APPEND) {
834 return new SrsDvrAppendPlan(); 777 return new SrsDvrAppendPlan();
835 } else if (plan == SRS_CONF_DEFAULT_DVR_PLAN_API) { 778 } else if (plan == SRS_CONF_DEFAULT_DVR_PLAN_API) {
  779 + /**
  780 + * @remark the api plan maybe create by publish event or http api post create dvr event.
  781 + * so when we got from pool first when create it.
  782 + */
  783 + SrsApiDvrPool* pool = SrsApiDvrPool::instance();
  784 + SrsDvrApiPlan* plan = pool->get_dvr(vhost);
  785 + if (plan) {
  786 + return plan;
  787 + }
836 return new SrsDvrApiPlan(); 788 return new SrsDvrApiPlan();
837 } else { 789 } else {
838 srs_error("invalid dvr plan=%s, vhost=%s", plan.c_str(), vhost.c_str()); 790 srs_error("invalid dvr plan=%s, vhost=%s", plan.c_str(), vhost.c_str());
@@ -900,16 +852,19 @@ SrsDvrApiPlan::SrsDvrApiPlan() @@ -900,16 +852,19 @@ SrsDvrApiPlan::SrsDvrApiPlan()
900 852
901 SrsDvrApiPlan::~SrsDvrApiPlan() 853 SrsDvrApiPlan::~SrsDvrApiPlan()
902 { 854 {
  855 + SrsApiDvrPool* pool = SrsApiDvrPool::instance();
  856 + pool->detach_dvr(this);
  857 +
903 srs_freep(metadata); 858 srs_freep(metadata);
904 srs_freep(sh_audio); 859 srs_freep(sh_audio);
905 srs_freep(sh_video); 860 srs_freep(sh_video);
906 } 861 }
907 862
908 -int SrsDvrApiPlan::initialize(SrsSource* s, SrsRequest* r) 863 +int SrsDvrApiPlan::initialize(SrsRequest* r)
909 { 864 {
910 int ret = ERROR_SUCCESS; 865 int ret = ERROR_SUCCESS;
911 866
912 - if ((ret = SrsDvrPlan::initialize(s, r)) != ERROR_SUCCESS) { 867 + if ((ret = SrsDvrPlan::initialize(r)) != ERROR_SUCCESS) {
913 return ret; 868 return ret;
914 } 869 }
915 870
@@ -1017,6 +972,12 @@ int SrsDvrApiPlan::on_video(SrsSharedPtrMessage* __video) @@ -1017,6 +972,12 @@ int SrsDvrApiPlan::on_video(SrsSharedPtrMessage* __video)
1017 return ret; 972 return ret;
1018 } 973 }
1019 974
  975 +int SrsDvrApiPlan::set_plan()
  976 +{
  977 + _srs_config->set_dvr_plan(req->vhost, SRS_CONF_DEFAULT_DVR_PLAN_API);
  978 + return ERROR_SUCCESS;
  979 +}
  980 +
1020 int SrsDvrApiPlan::set_path_tmpl(string path_tmpl) 981 int SrsDvrApiPlan::set_path_tmpl(string path_tmpl)
1021 { 982 {
1022 _srs_config->set_dvr_path(req->vhost, path_tmpl); 983 _srs_config->set_dvr_path(req->vhost, path_tmpl);
@@ -1025,7 +986,8 @@ int SrsDvrApiPlan::set_path_tmpl(string path_tmpl) @@ -1025,7 +986,8 @@ int SrsDvrApiPlan::set_path_tmpl(string path_tmpl)
1025 986
1026 int SrsDvrApiPlan::set_callback(string value) 987 int SrsDvrApiPlan::set_callback(string value)
1027 { 988 {
1028 - callback = value; 989 + _srs_config->set_vhost_http_hooks_enabled(req->vhost, true);
  990 + _srs_config->set_vhost_on_dvr(req->vhost, value);
1029 return ERROR_SUCCESS; 991 return ERROR_SUCCESS;
1030 } 992 }
1031 993
@@ -1072,6 +1034,7 @@ int SrsDvrApiPlan::dumps(stringstream& ss) @@ -1072,6 +1034,7 @@ int SrsDvrApiPlan::dumps(stringstream& ss)
1072 1034
1073 bool wait_keyframe = _srs_config->get_dvr_wait_keyframe(req->vhost); 1035 bool wait_keyframe = _srs_config->get_dvr_wait_keyframe(req->vhost);
1074 std::string path_template = _srs_config->get_dvr_path(req->vhost); 1036 std::string path_template = _srs_config->get_dvr_path(req->vhost);
  1037 + SrsConfDirective* callbacks = _srs_config->get_vhost_on_dvr(req->vhost);
1075 1038
1076 ss << __SRS_JOBJECT_START 1039 ss << __SRS_JOBJECT_START
1077 << __SRS_JFIELD_STR("path_tmpl", path_template) << __SRS_JFIELD_CONT 1040 << __SRS_JFIELD_STR("path_tmpl", path_template) << __SRS_JFIELD_CONT
@@ -1080,7 +1043,7 @@ int SrsDvrApiPlan::dumps(stringstream& ss) @@ -1080,7 +1043,7 @@ int SrsDvrApiPlan::dumps(stringstream& ss)
1080 << __SRS_JFIELD_STR("vhost", req->vhost) << __SRS_JFIELD_CONT 1043 << __SRS_JFIELD_STR("vhost", req->vhost) << __SRS_JFIELD_CONT
1081 << __SRS_JFIELD_STR("app", req->app) << __SRS_JFIELD_CONT 1044 << __SRS_JFIELD_STR("app", req->app) << __SRS_JFIELD_CONT
1082 << __SRS_JFIELD_STR("stream", req->stream) << __SRS_JFIELD_CONT 1045 << __SRS_JFIELD_STR("stream", req->stream) << __SRS_JFIELD_CONT
1083 - << __SRS_JFIELD_STR("callback", callback) << __SRS_JFIELD_CONT 1046 + << __SRS_JFIELD_STR("callback", callbacks->arg0()) << __SRS_JFIELD_CONT
1084 << __SRS_JFIELD_STR("status", (dvr_enabled? "start":"stop")) 1047 << __SRS_JFIELD_STR("status", (dvr_enabled? "start":"stop"))
1085 << __SRS_JOBJECT_END; 1048 << __SRS_JOBJECT_END;
1086 1049
@@ -1133,21 +1096,6 @@ int SrsDvrApiPlan::rpc(SrsJsonObject* obj) @@ -1133,21 +1096,6 @@ int SrsDvrApiPlan::rpc(SrsJsonObject* obj)
1133 return ret; 1096 return ret;
1134 } 1097 }
1135 1098
1136 -int SrsDvrApiPlan::on_reap_segment()  
1137 -{  
1138 - int ret = ERROR_SUCCESS;  
1139 -  
1140 - if ((ret = SrsDvrPlan::on_reap_segment()) != ERROR_SUCCESS) {  
1141 - return ret;  
1142 - }  
1143 -  
1144 - if ((ret = async->call(new SrsDvrAsyncCallOnSegment(req, callback, segment->get_path()))) != ERROR_SUCCESS) {  
1145 - return ret;  
1146 - }  
1147 -  
1148 - return ret;  
1149 -}  
1150 -  
1151 int SrsDvrApiPlan::check_user_actions(SrsSharedPtrMessage* msg) 1099 int SrsDvrApiPlan::check_user_actions(SrsSharedPtrMessage* msg)
1152 { 1100 {
1153 int ret = ERROR_SUCCESS; 1101 int ret = ERROR_SUCCESS;
@@ -1311,11 +1259,11 @@ SrsDvrSegmentPlan::~SrsDvrSegmentPlan() @@ -1311,11 +1259,11 @@ SrsDvrSegmentPlan::~SrsDvrSegmentPlan()
1311 srs_freep(metadata); 1259 srs_freep(metadata);
1312 } 1260 }
1313 1261
1314 -int SrsDvrSegmentPlan::initialize(SrsSource* source, SrsRequest* req) 1262 +int SrsDvrSegmentPlan::initialize(SrsRequest* req)
1315 { 1263 {
1316 int ret = ERROR_SUCCESS; 1264 int ret = ERROR_SUCCESS;
1317 1265
1318 - if ((ret = SrsDvrPlan::initialize(source, req)) != ERROR_SUCCESS) { 1266 + if ((ret = SrsDvrPlan::initialize(req)) != ERROR_SUCCESS) {
1319 return ret; 1267 return ret;
1320 } 1268 }
1321 1269
@@ -1478,12 +1426,35 @@ SrsApiDvrPool::~SrsApiDvrPool() @@ -1478,12 +1426,35 @@ SrsApiDvrPool::~SrsApiDvrPool()
1478 dvrs.clear(); 1426 dvrs.clear();
1479 } 1427 }
1480 1428
  1429 +SrsDvrApiPlan* SrsApiDvrPool::get_dvr(string vhost)
  1430 +{
  1431 + std::vector<SrsDvrApiPlan*>::iterator it;
  1432 + for (it = dvrs.begin(); it != dvrs.end(); ++it) {
  1433 + SrsDvrApiPlan* plan = *it;
  1434 + if (plan->req->vhost == vhost) {
  1435 + return plan;
  1436 + }
  1437 + }
  1438 +
  1439 + return NULL;
  1440 +}
  1441 +
1481 int SrsApiDvrPool::add_dvr(SrsDvrApiPlan* dvr) 1442 int SrsApiDvrPool::add_dvr(SrsDvrApiPlan* dvr)
1482 { 1443 {
1483 dvrs.push_back(dvr); 1444 dvrs.push_back(dvr);
1484 return ERROR_SUCCESS; 1445 return ERROR_SUCCESS;
1485 } 1446 }
1486 1447
  1448 +void SrsApiDvrPool::detach_dvr(SrsDvrApiPlan* dvr)
  1449 +{
  1450 + std::vector<SrsDvrApiPlan*>::iterator it;
  1451 + it = ::find(dvrs.begin(), dvrs.end(), dvr);
  1452 +
  1453 + if (it != dvrs.end()) {
  1454 + dvrs.erase(it);
  1455 + }
  1456 +}
  1457 +
1487 int SrsApiDvrPool::dumps(string vhost, string app, string stream, stringstream& ss) 1458 int SrsApiDvrPool::dumps(string vhost, string app, string stream, stringstream& ss)
1488 { 1459 {
1489 int ret = ERROR_SUCCESS; 1460 int ret = ERROR_SUCCESS;
@@ -1540,39 +1511,69 @@ int SrsApiDvrPool::create(SrsJsonAny* json) @@ -1540,39 +1511,69 @@ int SrsApiDvrPool::create(SrsJsonAny* json)
1540 srs_error("dvr: api create dvr request requires vhost. ret=%d", ret); 1511 srs_error("dvr: api create dvr request requires vhost. ret=%d", ret);
1541 return ret; 1512 return ret;
1542 } 1513 }
1543 -  
1544 std::string vhost = prop->to_str(); 1514 std::string vhost = prop->to_str();
1545 - std::string app, stream;  
1546 - if ((prop = obj->ensure_property_string("app")) != NULL) {  
1547 - app = prop->to_str(); 1515 +
  1516 + if ((prop = obj->ensure_property_string("app")) == NULL) {
  1517 + ret = ERROR_HTTP_DVR_CREATE_REQUEST;
  1518 + srs_error("dvr: api create dvr request requires app. ret=%d", ret);
  1519 + return ret;
1548 } 1520 }
1549 - if ((prop = obj->ensure_property_string("stream")) != NULL) {  
1550 - stream = prop->to_str(); 1521 + std::string app = prop->to_str();
  1522 +
  1523 + if ((prop = obj->ensure_property_string("stream")) == NULL) {
  1524 + ret = ERROR_HTTP_DVR_CREATE_REQUEST;
  1525 + srs_error("dvr: api create dvr request requires stream. ret=%d", ret);
  1526 + return ret;
  1527 + }
  1528 + std::string stream = prop->to_str();
  1529 +
  1530 + if (vhost.empty() || app.empty() || stream.empty()) {
  1531 + ret = ERROR_HTTP_DVR_CREATE_REQUEST;
  1532 + srs_error("dvr: api create dvr request requires vhost/app/stream. ret=%d", ret);
  1533 + return ret;
1551 } 1534 }
1552 1535
1553 SrsDvrApiPlan* dvr = NULL; 1536 SrsDvrApiPlan* dvr = NULL;
1554 for (int i = 0; i < (int)dvrs.size(); i++) { 1537 for (int i = 0; i < (int)dvrs.size(); i++) {
1555 SrsDvrApiPlan* plan = dvrs.at(i); 1538 SrsDvrApiPlan* plan = dvrs.at(i);
1556 - if (!vhost.empty() && plan->req->vhost != vhost) {  
1557 - continue;  
1558 - }  
1559 - if (!app.empty() && plan->req->app != app) {  
1560 - continue;  
1561 - }  
1562 - if (!stream.empty() && plan->req->stream != stream) { 1539 + if (plan->req->vhost != vhost || plan->req->app != app || plan->req->stream != stream) {
1563 continue; 1540 continue;
1564 } 1541 }
1565 dvr = plan; 1542 dvr = plan;
1566 break; 1543 break;
1567 } 1544 }
1568 1545
  1546 + // mock the client request for dvr.
  1547 + SrsRequest* req = new SrsRequest();
  1548 + SrsAutoFree(SrsRequest, req);
  1549 +
  1550 + // should notice the source to reload dvr when already publishing.
  1551 + SrsSource* source = NULL;
  1552 +
  1553 + // create if not exists
1569 if (!dvr) { 1554 if (!dvr) {
1570 - ret = ERROR_HTTP_DVR_NO_TAEGET;  
1571 - srs_error("dvr: create not found for url=%s/%s/%s, ret=%d", vhost.c_str(), app.c_str(), stream.c_str(), ret);  
1572 - return ret; 1555 + dvr = new SrsDvrApiPlan();
  1556 +
  1557 + req->vhost = vhost;
  1558 + req->app = app;
  1559 + req->stream = stream;
  1560 + req->tcUrl = "rtmp://" + vhost + "/" + app + "/" + stream;
  1561 +
  1562 + // fetch source from pool.
  1563 + // NULL, create without source, ignore.
  1564 + // start dvr when already publishing.
  1565 + source = SrsSource::fetch(req);
  1566 +
  1567 + // initialize for dvr pool to create it.
  1568 + if ((ret = dvr->initialize(req)) != ERROR_SUCCESS) {
  1569 + return ret;
  1570 + }
1573 } 1571 }
1574 1572
1575 // update optional parameters for plan. 1573 // update optional parameters for plan.
  1574 + if ((ret = dvr->set_plan()) != ERROR_SUCCESS) {
  1575 + return ret;
  1576 + }
1576 if ((prop = obj->ensure_property_string("path_tmpl")) != NULL) { 1577 if ((prop = obj->ensure_property_string("path_tmpl")) != NULL) {
1577 if ((ret = dvr->set_path_tmpl(prop->to_str())) != ERROR_SUCCESS) { 1578 if ((ret = dvr->set_path_tmpl(prop->to_str())) != ERROR_SUCCESS) {
1578 return ret; 1579 return ret;
@@ -1589,7 +1590,19 @@ int SrsApiDvrPool::create(SrsJsonAny* json) @@ -1589,7 +1590,19 @@ int SrsApiDvrPool::create(SrsJsonAny* json)
1589 } 1590 }
1590 } 1591 }
1591 1592
1592 - return dvr->start(); 1593 + if ((ret = dvr->start()) != ERROR_SUCCESS) {
  1594 + return ret;
  1595 + }
  1596 +
  1597 + // do reload for source when already publishing.
  1598 + // when reload, the source will use the request instead.
  1599 + if (source) {
  1600 + if ((ret = source->on_reload_vhost_dvr(vhost)) != ERROR_SUCCESS) {
  1601 + return ret;
  1602 + }
  1603 + }
  1604 +
  1605 + return ret;
1593 } 1606 }
1594 1607
1595 int SrsApiDvrPool::stop(string vhost, string app, string stream) 1608 int SrsApiDvrPool::stop(string vhost, string app, string stream)
@@ -1681,9 +1694,9 @@ int SrsApiDvrPool::rpc(SrsJsonAny* json) @@ -1681,9 +1694,9 @@ int SrsApiDvrPool::rpc(SrsJsonAny* json)
1681 return ret; 1694 return ret;
1682 } 1695 }
1683 1696
1684 -SrsDvr::SrsDvr(SrsSource* s) 1697 +SrsDvr::SrsDvr()
1685 { 1698 {
1686 - source = s; 1699 + source = NULL;
1687 plan = NULL; 1700 plan = NULL;
1688 } 1701 }
1689 1702
@@ -1692,14 +1705,20 @@ SrsDvr::~SrsDvr() @@ -1692,14 +1705,20 @@ SrsDvr::~SrsDvr()
1692 srs_freep(plan); 1705 srs_freep(plan);
1693 } 1706 }
1694 1707
1695 -int SrsDvr::initialize(SrsRequest* r) 1708 +int SrsDvr::initialize(SrsSource* s, SrsRequest* r)
1696 { 1709 {
1697 int ret = ERROR_SUCCESS; 1710 int ret = ERROR_SUCCESS;
  1711 +
  1712 + source = s;
1698 1713
1699 srs_freep(plan); 1714 srs_freep(plan);
1700 plan = SrsDvrPlan::create_plan(r->vhost); 1715 plan = SrsDvrPlan::create_plan(r->vhost);
1701 1716
1702 - if ((ret = plan->initialize(source, r)) != ERROR_SUCCESS) { 1717 + if ((ret = plan->initialize(r)) != ERROR_SUCCESS) {
  1718 + return ret;
  1719 + }
  1720 +
  1721 + if ((ret = source->on_dvr_request_sh()) != ERROR_SUCCESS) {
1703 return ret; 1722 return ret;
1704 } 1723 }
1705 1724
@@ -1722,6 +1741,7 @@ void SrsDvr::on_unpublish() @@ -1722,6 +1741,7 @@ void SrsDvr::on_unpublish()
1722 plan->on_unpublish(); 1741 plan->on_unpublish();
1723 } 1742 }
1724 1743
  1744 +// TODO: FIXME: source should use shared message instead.
1725 int SrsDvr::on_meta_data(SrsOnMetaDataPacket* m) 1745 int SrsDvr::on_meta_data(SrsOnMetaDataPacket* m)
1726 { 1746 {
1727 int ret = ERROR_SUCCESS; 1747 int ret = ERROR_SUCCESS;
@@ -58,7 +58,6 @@ class SrsThread; @@ -58,7 +58,6 @@ class SrsThread;
58 class SrsFlvSegment : public ISrsReloadHandler 58 class SrsFlvSegment : public ISrsReloadHandler
59 { 59 {
60 private: 60 private:
61 - SrsSource* source;  
62 SrsRequest* req; 61 SrsRequest* req;
63 SrsDvrPlan* plan; 62 SrsDvrPlan* plan;
64 private: 63 private:
@@ -121,7 +120,7 @@ public: @@ -121,7 +120,7 @@ public:
121 /** 120 /**
122 * initialize the segment. 121 * initialize the segment.
123 */ 122 */
124 - virtual int initialize(SrsSource* s, SrsRequest* r); 123 + virtual int initialize(SrsRequest* r);
125 /** 124 /**
126 * whether segment is overflow. 125 * whether segment is overflow.
127 */ 126 */
@@ -200,19 +199,6 @@ public: @@ -200,19 +199,6 @@ public:
200 virtual int call(); 199 virtual int call();
201 virtual std::string to_string(); 200 virtual std::string to_string();
202 }; 201 };
203 -class SrsDvrAsyncCallOnSegment : public ISrsDvrAsyncCall  
204 -{  
205 -private:  
206 - std::string callback;  
207 - std::string path;  
208 - SrsRequest* req;  
209 -public:  
210 - SrsDvrAsyncCallOnSegment(SrsRequest* r, std::string c, std::string p);  
211 - virtual ~SrsDvrAsyncCallOnSegment();  
212 -public:  
213 - virtual int call();  
214 - virtual std::string to_string();  
215 -};  
216 202
217 /** 203 /**
218 * the async callback for dvr. 204 * the async callback for dvr.
@@ -247,7 +233,6 @@ public: @@ -247,7 +233,6 @@ public:
247 public: 233 public:
248 SrsRequest* req; 234 SrsRequest* req;
249 protected: 235 protected:
250 - SrsSource* source;  
251 SrsFlvSegment* segment; 236 SrsFlvSegment* segment;
252 SrsDvrAsyncCallThread* async; 237 SrsDvrAsyncCallThread* async;
253 bool dvr_enabled; 238 bool dvr_enabled;
@@ -255,7 +240,7 @@ public: @@ -255,7 +240,7 @@ public:
255 SrsDvrPlan(); 240 SrsDvrPlan();
256 virtual ~SrsDvrPlan(); 241 virtual ~SrsDvrPlan();
257 public: 242 public:
258 - virtual int initialize(SrsSource* s, SrsRequest* r); 243 + virtual int initialize(SrsRequest* r);
259 virtual int on_publish() = 0; 244 virtual int on_publish() = 0;
260 virtual void on_unpublish() = 0; 245 virtual void on_unpublish() = 0;
261 /** 246 /**
@@ -272,7 +257,6 @@ public: @@ -272,7 +257,6 @@ public:
272 virtual int on_video(SrsSharedPtrMessage* __video); 257 virtual int on_video(SrsSharedPtrMessage* __video);
273 protected: 258 protected:
274 virtual int on_reap_segment(); 259 virtual int on_reap_segment();
275 - virtual int on_dvr_request_sh();  
276 virtual int on_video_keyframe(); 260 virtual int on_video_keyframe();
277 virtual int64_t filter_timestamp(int64_t timestamp); 261 virtual int64_t filter_timestamp(int64_t timestamp);
278 public: 262 public:
@@ -294,6 +278,8 @@ public: @@ -294,6 +278,8 @@ public:
294 278
295 /** 279 /**
296 * api plan: reap flv by api. 280 * api plan: reap flv by api.
  281 +* @remark the api plan maybe create by publish event or http api post create dvr event.
  282 +* so when we got from pool first when create it.
297 */ 283 */
298 class SrsDvrApiPlan : public SrsDvrPlan 284 class SrsDvrApiPlan : public SrsDvrPlan
299 { 285 {
@@ -303,7 +289,6 @@ private: @@ -303,7 +289,6 @@ private:
303 SrsSharedPtrMessage* sh_video; 289 SrsSharedPtrMessage* sh_video;
304 SrsSharedPtrMessage* metadata; 290 SrsSharedPtrMessage* metadata;
305 private: 291 private:
306 - std::string callback;  
307 bool autostart; 292 bool autostart;
308 bool started; 293 bool started;
309 private: 294 private:
@@ -314,13 +299,14 @@ public: @@ -314,13 +299,14 @@ public:
314 SrsDvrApiPlan(); 299 SrsDvrApiPlan();
315 virtual ~SrsDvrApiPlan(); 300 virtual ~SrsDvrApiPlan();
316 public: 301 public:
317 - virtual int initialize(SrsSource* s, SrsRequest* r); 302 + virtual int initialize(SrsRequest* r);
318 virtual int on_publish(); 303 virtual int on_publish();
319 virtual void on_unpublish(); 304 virtual void on_unpublish();
320 virtual int on_meta_data(SrsSharedPtrMessage* __metadata); 305 virtual int on_meta_data(SrsSharedPtrMessage* __metadata);
321 virtual int on_audio(SrsSharedPtrMessage* __audio); 306 virtual int on_audio(SrsSharedPtrMessage* __audio);
322 virtual int on_video(SrsSharedPtrMessage* __video); 307 virtual int on_video(SrsSharedPtrMessage* __video);
323 public: 308 public:
  309 + virtual int set_plan();
324 virtual int set_path_tmpl(std::string path_tmpl); 310 virtual int set_path_tmpl(std::string path_tmpl);
325 virtual int set_callback(std::string value); 311 virtual int set_callback(std::string value);
326 virtual int set_wait_keyframe(bool wait_keyframe); 312 virtual int set_wait_keyframe(bool wait_keyframe);
@@ -328,8 +314,6 @@ public: @@ -328,8 +314,6 @@ public:
328 virtual int dumps(std::stringstream& ss); 314 virtual int dumps(std::stringstream& ss);
329 virtual int stop(); 315 virtual int stop();
330 virtual int rpc(SrsJsonObject* obj); 316 virtual int rpc(SrsJsonObject* obj);
331 -protected:  
332 - virtual int on_reap_segment();  
333 private: 317 private:
334 virtual int check_user_actions(SrsSharedPtrMessage* msg); 318 virtual int check_user_actions(SrsSharedPtrMessage* msg);
335 }; 319 };
@@ -368,7 +352,7 @@ public: @@ -368,7 +352,7 @@ public:
368 SrsDvrSegmentPlan(); 352 SrsDvrSegmentPlan();
369 virtual ~SrsDvrSegmentPlan(); 353 virtual ~SrsDvrSegmentPlan();
370 public: 354 public:
371 - virtual int initialize(SrsSource* source, SrsRequest* req); 355 + virtual int initialize(SrsRequest* req);
372 virtual int on_publish(); 356 virtual int on_publish();
373 virtual void on_unpublish(); 357 virtual void on_unpublish();
374 virtual int on_meta_data(SrsSharedPtrMessage* __metadata); 358 virtual int on_meta_data(SrsSharedPtrMessage* __metadata);
@@ -392,7 +376,9 @@ public: @@ -392,7 +376,9 @@ public:
392 static SrsApiDvrPool* instance(); 376 static SrsApiDvrPool* instance();
393 virtual ~SrsApiDvrPool(); 377 virtual ~SrsApiDvrPool();
394 public: 378 public:
  379 + virtual SrsDvrApiPlan* get_dvr(std::string vhost);
395 virtual int add_dvr(SrsDvrApiPlan* dvr); 380 virtual int add_dvr(SrsDvrApiPlan* dvr);
  381 + virtual void detach_dvr(SrsDvrApiPlan* dvr);
396 public: 382 public:
397 virtual int dumps(std::string vhost, std::string app, std::string stream, std::stringstream& ss); 383 virtual int dumps(std::string vhost, std::string app, std::string stream, std::stringstream& ss);
398 virtual int create(SrsJsonAny* json); 384 virtual int create(SrsJsonAny* json);
@@ -411,7 +397,7 @@ private: @@ -411,7 +397,7 @@ private:
411 private: 397 private:
412 SrsDvrPlan* plan; 398 SrsDvrPlan* plan;
413 public: 399 public:
414 - SrsDvr(SrsSource* s); 400 + SrsDvr();
415 virtual ~SrsDvr(); 401 virtual ~SrsDvr();
416 public: 402 public:
417 /** 403 /**
@@ -419,7 +405,7 @@ public: @@ -419,7 +405,7 @@ public:
419 * when system initialize(encoder publish at first time, or reload), 405 * when system initialize(encoder publish at first time, or reload),
420 * initialize the dvr will reinitialize the plan, the whole dvr framework. 406 * initialize the dvr will reinitialize the plan, the whole dvr framework.
421 */ 407 */
422 - virtual int initialize(SrsRequest* r); 408 + virtual int initialize(SrsSource* s, SrsRequest* r);
423 /** 409 /**
424 * publish stream event, 410 * publish stream event,
425 * when encoder start to publish RTMP stream. 411 * when encoder start to publish RTMP stream.
@@ -163,10 +163,10 @@ void SrsHlsSegment::update_duration(int64_t current_frame_dts) @@ -163,10 +163,10 @@ void SrsHlsSegment::update_duration(int64_t current_frame_dts)
163 return; 163 return;
164 } 164 }
165 165
166 -SrsHlsMuxer::SrsHlsMuxer(ISrsHlsHandler* h) 166 +SrsHlsMuxer::SrsHlsMuxer()
167 { 167 {
168 req = NULL; 168 req = NULL;
169 - handler = h; 169 + handler = NULL;
170 hls_fragment = hls_window = 0; 170 hls_fragment = hls_window = 0;
171 target_duration = 0; 171 target_duration = 0;
172 _sequence_no = 0; 172 _sequence_no = 0;
@@ -189,6 +189,15 @@ SrsHlsMuxer::~SrsHlsMuxer() @@ -189,6 +189,15 @@ SrsHlsMuxer::~SrsHlsMuxer()
189 srs_freep(req); 189 srs_freep(req);
190 } 190 }
191 191
  192 +int SrsHlsMuxer::initialize(ISrsHlsHandler* h)
  193 +{
  194 + int ret = ERROR_SUCCESS;
  195 +
  196 + handler = h;
  197 +
  198 + return ret;
  199 +}
  200 +
192 int SrsHlsMuxer::sequence_no() 201 int SrsHlsMuxer::sequence_no()
193 { 202 {
194 return _sequence_no; 203 return _sequence_no;
@@ -811,10 +820,10 @@ int SrsHlsCache::reap_segment(string log_desc, SrsHlsMuxer* muxer, int64_t segme @@ -811,10 +820,10 @@ int SrsHlsCache::reap_segment(string log_desc, SrsHlsMuxer* muxer, int64_t segme
811 return ret; 820 return ret;
812 } 821 }
813 822
814 -SrsHls::SrsHls(SrsSource* s, ISrsHlsHandler* h) 823 +SrsHls::SrsHls()
815 { 824 {
816 - source = s;  
817 - handler = h; 825 + source = NULL;
  826 + handler = NULL;
818 827
819 hls_enabled = false; 828 hls_enabled = false;
820 829
@@ -822,7 +831,7 @@ SrsHls::SrsHls(SrsSource* s, ISrsHlsHandler* h) @@ -822,7 +831,7 @@ SrsHls::SrsHls(SrsSource* s, ISrsHlsHandler* h)
822 sample = new SrsCodecSample(); 831 sample = new SrsCodecSample();
823 jitter = new SrsRtmpJitter(); 832 jitter = new SrsRtmpJitter();
824 833
825 - muxer = new SrsHlsMuxer(h); 834 + muxer = new SrsHlsMuxer();
826 hls_cache = new SrsHlsCache(); 835 hls_cache = new SrsHlsCache();
827 836
828 pprint = SrsPithyPrint::create_hls(); 837 pprint = SrsPithyPrint::create_hls();
@@ -841,6 +850,20 @@ SrsHls::~SrsHls() @@ -841,6 +850,20 @@ SrsHls::~SrsHls()
841 srs_freep(pprint); 850 srs_freep(pprint);
842 } 851 }
843 852
  853 +int SrsHls::initialize(SrsSource* s, ISrsHlsHandler* h)
  854 +{
  855 + int ret = ERROR_SUCCESS;
  856 +
  857 + source = s;
  858 + handler = h;
  859 +
  860 + if ((ret = muxer->initialize(h)) != ERROR_SUCCESS) {
  861 + return ret;
  862 + }
  863 +
  864 + return ret;
  865 +}
  866 +
844 int SrsHls::on_publish(SrsRequest* req) 867 int SrsHls::on_publish(SrsRequest* req)
845 { 868 {
846 int ret = ERROR_SUCCESS; 869 int ret = ERROR_SUCCESS;
@@ -195,12 +195,16 @@ private: @@ -195,12 +195,16 @@ private:
195 */ 195 */
196 SrsCodecAudio acodec; 196 SrsCodecAudio acodec;
197 public: 197 public:
198 - SrsHlsMuxer(ISrsHlsHandler* h); 198 + SrsHlsMuxer();
199 virtual ~SrsHlsMuxer(); 199 virtual ~SrsHlsMuxer();
200 public: 200 public:
201 virtual int sequence_no(); 201 virtual int sequence_no();
202 public: 202 public:
203 /** 203 /**
  204 + * initialize the hls muxer.
  205 + */
  206 + virtual int initialize(ISrsHlsHandler* h);
  207 + /**
204 * when publish, update the config for muxer. 208 * when publish, update the config for muxer.
205 */ 209 */
206 virtual int update_config(SrsRequest* r, std::string path, int fragment, int window); 210 virtual int update_config(SrsRequest* r, std::string path, int fragment, int window);
@@ -325,10 +329,14 @@ private: @@ -325,10 +329,14 @@ private:
325 */ 329 */
326 int64_t stream_dts; 330 int64_t stream_dts;
327 public: 331 public:
328 - SrsHls(SrsSource* s, ISrsHlsHandler* h); 332 + SrsHls();
329 virtual ~SrsHls(); 333 virtual ~SrsHls();
330 public: 334 public:
331 /** 335 /**
  336 + * initialize the hls by handler and source.
  337 + */
  338 + virtual int initialize(SrsSource* s, ISrsHlsHandler* h);
  339 + /**
332 * publish stream event, continue to write the m3u8, 340 * publish stream event, continue to write the m3u8,
333 * for the muxer object not destroyed. 341 * for the muxer object not destroyed.
334 */ 342 */
@@ -392,9 +392,11 @@ int SrsRtmpConn::stream_service_cycle() @@ -392,9 +392,11 @@ int SrsRtmpConn::stream_service_cycle()
392 bool vhost_is_edge = _srs_config->get_vhost_is_edge(req->vhost); 392 bool vhost_is_edge = _srs_config->get_vhost_is_edge(req->vhost);
393 393
394 // find a source to serve. 394 // find a source to serve.
395 - SrsSource* source = NULL;  
396 - if ((ret = SrsSource::find(req, server, server, &source)) != ERROR_SUCCESS) {  
397 - return ret; 395 + SrsSource* source = SrsSource::fetch(req);
  396 + if (!source) {
  397 + if ((ret = SrsSource::create(req, server, server, &source)) != ERROR_SUCCESS) {
  398 + return ret;
  399 + }
398 } 400 }
399 srs_assert(source != NULL); 401 srs_assert(source != NULL);
400 402
@@ -713,35 +713,47 @@ ISrsSourceHandler::~ISrsSourceHandler() @@ -713,35 +713,47 @@ ISrsSourceHandler::~ISrsSourceHandler()
713 713
714 std::map<std::string, SrsSource*> SrsSource::pool; 714 std::map<std::string, SrsSource*> SrsSource::pool;
715 715
716 -int SrsSource::find(SrsRequest* r, ISrsSourceHandler* h, ISrsHlsHandler* hh, SrsSource** pps) 716 +int SrsSource::create(SrsRequest* r, ISrsSourceHandler* h, ISrsHlsHandler* hh, SrsSource** pps)
717 { 717 {
718 int ret = ERROR_SUCCESS; 718 int ret = ERROR_SUCCESS;
719 719
720 string stream_url = r->get_stream_url(); 720 string stream_url = r->get_stream_url();
721 string vhost = r->vhost; 721 string vhost = r->vhost;
722 722
723 - if (pool.find(stream_url) == pool.end()) {  
724 - SrsSource* source = new SrsSource(hh);  
725 - if ((ret = source->initialize(r, h)) != ERROR_SUCCESS) {  
726 - srs_freep(source);  
727 - return ret;  
728 - }  
729 -  
730 - pool[stream_url] = source;  
731 - srs_info("create new source for url=%s, vhost=%s",  
732 - stream_url.c_str(), vhost.c_str()); 723 + // should always not exists for create a source.
  724 + srs_assert (pool.find(stream_url) == pool.end());
  725 +
  726 + SrsSource* source = new SrsSource();
  727 + if ((ret = source->initialize(r, h, hh)) != ERROR_SUCCESS) {
  728 + srs_freep(source);
  729 + return ret;
733 } 730 }
  731 +
  732 + pool[stream_url] = source;
  733 + srs_info("create new source for url=%s, vhost=%s", stream_url.c_str(), vhost.c_str());
734 734
  735 + *pps = source;
  736 +
  737 + return ret;
  738 +}
  739 +
  740 +SrsSource* SrsSource::fetch(SrsRequest* r)
  741 +{
  742 + SrsSource* source = NULL;
  743 +
  744 + string stream_url = r->get_stream_url();
  745 + if (pool.find(stream_url) == pool.end()) {
  746 + return NULL;
  747 + }
  748 +
  749 + source = pool[stream_url];
  750 +
735 // we always update the request of resource, 751 // we always update the request of resource,
736 // for origin auth is on, the token in request maybe invalid, 752 // for origin auth is on, the token in request maybe invalid,
737 // and we only need to update the token of request, it's simple. 753 // and we only need to update the token of request, it's simple.
738 - if (true) {  
739 - SrsSource* source = pool[stream_url];  
740 - source->_req->update_auth(r);  
741 - *pps = source;  
742 - }  
743 -  
744 - return ret; 754 + source->_req->update_auth(r);
  755 +
  756 + return source;
745 } 757 }
746 758
747 void SrsSource::destroy() 759 void SrsSource::destroy()
@@ -754,17 +766,16 @@ void SrsSource::destroy() @@ -754,17 +766,16 @@ void SrsSource::destroy()
754 pool.clear(); 766 pool.clear();
755 } 767 }
756 768
757 -SrsSource::SrsSource(ISrsHlsHandler* hh) 769 +SrsSource::SrsSource()
758 { 770 {
759 _req = NULL; 771 _req = NULL;
760 jitter_algorithm = SrsRtmpJitterAlgorithmOFF; 772 jitter_algorithm = SrsRtmpJitterAlgorithmOFF;
761 773
762 #ifdef SRS_AUTO_HLS 774 #ifdef SRS_AUTO_HLS
763 - // TODO: FIXME: refine code, use subscriber pattern.  
764 - hls = new SrsHls(this, hh); 775 + hls = new SrsHls();
765 #endif 776 #endif
766 #ifdef SRS_AUTO_DVR 777 #ifdef SRS_AUTO_DVR
767 - dvr = new SrsDvr(this); 778 + dvr = new SrsDvr();
768 #endif 779 #endif
769 #ifdef SRS_AUTO_TRANSCODE 780 #ifdef SRS_AUTO_TRANSCODE
770 encoder = new SrsEncoder(); 781 encoder = new SrsEncoder();
@@ -824,16 +835,26 @@ SrsSource::~SrsSource() @@ -824,16 +835,26 @@ SrsSource::~SrsSource()
824 srs_freep(_req); 835 srs_freep(_req);
825 } 836 }
826 837
827 -int SrsSource::initialize(SrsRequest* r, ISrsSourceHandler* h) 838 +int SrsSource::initialize(SrsRequest* r, ISrsSourceHandler* h, ISrsHlsHandler* hh)
828 { 839 {
829 int ret = ERROR_SUCCESS; 840 int ret = ERROR_SUCCESS;
830 841
  842 + srs_assert(h);
  843 + srs_assert(hh);
  844 + srs_assert(!_req);
  845 +
831 handler = h; 846 handler = h;
832 _req = r->copy(); 847 _req = r->copy();
833 atc = _srs_config->get_atc(_req->vhost); 848 atc = _srs_config->get_atc(_req->vhost);
  849 +
  850 +#ifdef SRS_AUTO_HLS
  851 + if ((ret = hls->initialize(this, hh)) != ERROR_SUCCESS) {
  852 + return ret;
  853 + }
  854 +#endif
834 855
835 #ifdef SRS_AUTO_DVR 856 #ifdef SRS_AUTO_DVR
836 - if ((ret = dvr->initialize(_req)) != ERROR_SUCCESS) { 857 + if ((ret = dvr->initialize(this, _req)) != ERROR_SUCCESS) {
837 return ret; 858 return ret;
838 } 859 }
839 #endif 860 #endif
@@ -997,7 +1018,7 @@ int SrsSource::on_reload_vhost_dvr(string vhost) @@ -997,7 +1018,7 @@ int SrsSource::on_reload_vhost_dvr(string vhost)
997 dvr->on_unpublish(); 1018 dvr->on_unpublish();
998 1019
999 // reinitialize the dvr, update plan. 1020 // reinitialize the dvr, update plan.
1000 - if ((ret = dvr->initialize(_req)) != ERROR_SUCCESS) { 1021 + if ((ret = dvr->initialize(this, _req)) != ERROR_SUCCESS) {
1001 return ret; 1022 return ret;
1002 } 1023 }
1003 1024
@@ -380,7 +380,12 @@ public: @@ -380,7 +380,12 @@ public:
380 * @param hh the event handler for hls. 380 * @param hh the event handler for hls.
381 * @param pps the matched source, if success never be NULL. 381 * @param pps the matched source, if success never be NULL.
382 */ 382 */
383 - static int find(SrsRequest* r, ISrsSourceHandler* h, ISrsHlsHandler* hh, SrsSource** pps); 383 + static int create(SrsRequest* r, ISrsSourceHandler* h, ISrsHlsHandler* hh, SrsSource** pps);
  384 + /**
  385 + * get the exists source, NULL when not exists.
  386 + * update the request and return the exists source.
  387 + */
  388 + static SrsSource* fetch(SrsRequest* r);
384 /** 389 /**
385 * when system exit, destroy the sources, 390 * when system exit, destroy the sources,
386 * for gmc to analysis mem leaks. 391 * for gmc to analysis mem leaks.
@@ -449,15 +454,14 @@ private: @@ -449,15 +454,14 @@ private:
449 // the cached audio sequence header. 454 // the cached audio sequence header.
450 SrsSharedPtrMessage* cache_sh_audio; 455 SrsSharedPtrMessage* cache_sh_audio;
451 public: 456 public:
452 - /**  
453 - * @param _req the client request object,  
454 - * this object will deep copy it for reload.  
455 - */  
456 - SrsSource(ISrsHlsHandler* hh); 457 + SrsSource();
457 virtual ~SrsSource(); 458 virtual ~SrsSource();
458 // initialize, get and setter. 459 // initialize, get and setter.
459 public: 460 public:
460 - virtual int initialize(SrsRequest* r, ISrsSourceHandler* h); 461 + /**
  462 + * initialize the hls with handlers.
  463 + */
  464 + virtual int initialize(SrsRequest* r, ISrsSourceHandler* h, ISrsHlsHandler* hh);
461 // interface ISrsReloadHandler 465 // interface ISrsReloadHandler
462 public: 466 public:
463 virtual int on_reload_vhost_atc(std::string vhost); 467 virtual int on_reload_vhost_atc(std::string vhost);
@@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31 // current release version 31 // current release version
32 #define VERSION_MAJOR 2 32 #define VERSION_MAJOR 2
33 #define VERSION_MINOR 0 33 #define VERSION_MINOR 0
34 -#define VERSION_REVISION 125 34 +#define VERSION_REVISION 126
35 35
36 // server info. 36 // server info.
37 #define RTMP_SIG_SRS_KEY "SRS" 37 #define RTMP_SIG_SRS_KEY "SRS"