for #179, refine dvr, support POST create dvr when publish not start. 2.0.126
正在显示
11 个修改的文件
包含
265 行增加
和
174 行删除
| @@ -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" |
-
请 注册 或 登录 后发表评论