diff --git a/README.md b/README.md index bb575a3bc..bf63b7511 100755 --- a/README.md +++ b/README.md @@ -208,6 +208,7 @@ Supported operating systems and hardware: * 2013-10-17, Created.
## History +* v1.0, 2014-09-25, fix [#177](https://github.com/winlinvip/simple-rtmp-server/issues/177), dvr segment add config dvr_wait_keyframe. 0.9.213. * v1.0, 2014-08-28, fix [#167](https://github.com/winlinvip/simple-rtmp-server/issues/167), add openssl includes to utest. 0.9.209. * v1.0, 2014-08-27, max connections is 32756, for st use mmap default. 0.9.209 * v1.0, 2014-08-24, fix [#150](https://github.com/winlinvip/simple-rtmp-server/issues/150), forward should forward the sequence header when retry. 0.9.208. diff --git a/trunk/conf/dvr.segment.conf b/trunk/conf/dvr.segment.conf index 3232d154c..d42029a43 100644 --- a/trunk/conf/dvr.segment.conf +++ b/trunk/conf/dvr.segment.conf @@ -10,5 +10,6 @@ vhost __defaultVhost__ { dvr_path ./objs/nginx/html; dvr_plan segment; dvr_duration 30; + dvr_wait_keyframe on; } } diff --git a/trunk/conf/full.conf b/trunk/conf/full.conf index 75787de60..09d046395 100644 --- a/trunk/conf/full.conf +++ b/trunk/conf/full.conf @@ -192,6 +192,12 @@ vhost dvr.srs.com { # the param for plan(segment), in seconds. # default: 30 dvr_duration 30; + # the param for plan(segment), + # whether wait keyframe to reap segment, + # if off, reap segment when duration exceed the dvr_duration, + # if on, reap segment when duration exceed and got keyframe. + # default: on + dvr_wait_keyframe on; # about the stream monotonically increasing: # 1. video timestamp is monotonically increasing, # 2. audio timestamp is monotonically increasing, diff --git a/trunk/src/app/srs_app_config.cpp b/trunk/src/app/srs_app_config.cpp index 1a99984ba..39cfd7a2d 100644 --- a/trunk/src/app/srs_app_config.cpp +++ b/trunk/src/app/srs_app_config.cpp @@ -1301,7 +1301,7 @@ int SrsConfig::check_config() for (int j = 0; j < (int)conf->directives.size(); j++) { string m = conf->at(j)->name.c_str(); if (m != "enabled" && m != "dvr_path" && m != "dvr_plan" - && m != "dvr_duration" && m != "time_jitter" + && m != "dvr_duration" && m != "dvr_wait_keyframe" && m != "time_jitter" ) { ret = ERROR_SYSTEM_CONFIG_INVALID; srs_error("unsupported vhost dvr directive %s, ret=%d", m.c_str(), ret); @@ -2968,6 +2968,23 @@ int SrsConfig::get_dvr_duration(string vhost) return ::atoi(conf->arg0().c_str()); } +bool SrsConfig::get_dvr_wait_keyframe(string vhost) +{ + SrsConfDirective* dvr = get_dvr(vhost); + + if (!dvr) { + return true; + } + + SrsConfDirective* conf = dvr->get("dvr_wait_keyframe"); + + if (!conf || conf->arg0() != "off") { + return true; + } + + return false; +} + int SrsConfig::get_dvr_time_jitter(string vhost) { SrsConfDirective* dvr = get_dvr(vhost); diff --git a/trunk/src/app/srs_app_config.hpp b/trunk/src/app/srs_app_config.hpp index 0b1bb2dc7..ef308e9a9 100644 --- a/trunk/src/app/srs_app_config.hpp +++ b/trunk/src/app/srs_app_config.hpp @@ -850,6 +850,10 @@ public: */ virtual int get_dvr_duration(std::string vhost); /** + * whether wait keyframe to reap segment, for segment plan. + */ + virtual bool get_dvr_wait_keyframe(std::string vhost); + /** * get the time_jitter algorithm for dvr. */ virtual int get_dvr_time_jitter(std::string vhost); diff --git a/trunk/src/app/srs_app_dvr.cpp b/trunk/src/app/srs_app_dvr.cpp index 75dba5eee..ed39eb8bd 100644 --- a/trunk/src/app/srs_app_dvr.cpp +++ b/trunk/src/app/srs_app_dvr.cpp @@ -256,12 +256,14 @@ int SrsDvrPlan::on_video(SrsSharedPtrMessage* video) return ret; } - int32_t timestamp = filter_timestamp(video->header.timestamp); - if ((ret = enc->write_video(timestamp, payload, size)) != ERROR_SUCCESS) { + // update segment duration, session plan just update the duration, + // the segment plan will reap segment if exceed, this video will write to next segment. + if ((ret = update_duration(video)) != ERROR_SUCCESS) { return ret; } - if ((ret = update_duration(video)) != ERROR_SUCCESS) { + int32_t timestamp = filter_timestamp(video->header.timestamp); + if ((ret = enc->write_video(timestamp, payload, size)) != ERROR_SUCCESS) { return ret; } @@ -478,28 +480,48 @@ int SrsDvrSegmentPlan::update_duration(SrsSharedPtrMessage* msg) srs_assert(segment); - // reap if exceed duration. - if (segment_duration > 0 && segment->duration > segment_duration) { - if ((ret = flv_close()) != ERROR_SUCCESS) { - segment->reset(); - return ret; - } - on_unpublish(); - - // open new flv file - if ((ret = open_new_segment()) != ERROR_SUCCESS) { + // ignore if duration ok. + if (segment_duration <= 0 || segment->duration < segment_duration) { + return ret; + } + + // when wait keyframe, ignore if no frame arrived. + // @see https://github.com/winlinvip/simple-rtmp-server/issues/177 + if (_srs_config->get_dvr_wait_keyframe(_req->vhost)) { + if (!msg->header.is_video()) { return ret; } - // update sequence header - if (sh_video && (ret = SrsDvrPlan::on_video(sh_video)) != ERROR_SUCCESS) { - return ret; - } - if (sh_audio && (ret = SrsDvrPlan::on_audio(sh_audio)) != ERROR_SUCCESS) { + char* payload = (char*)msg->payload; + int size = (int)msg->size; + bool is_key_frame = SrsFlvCodec::video_is_h264(payload, size) + && SrsFlvCodec::video_is_keyframe(payload, size) + && !SrsFlvCodec::video_is_sequence_header(payload, size); + if (!is_key_frame) { return ret; } } + // reap segment + if ((ret = flv_close()) != ERROR_SUCCESS) { + segment->reset(); + return ret; + } + on_unpublish(); + + // open new flv file + if ((ret = open_new_segment()) != ERROR_SUCCESS) { + return ret; + } + + // update sequence header + if (sh_video && (ret = SrsDvrPlan::on_video(sh_video)) != ERROR_SUCCESS) { + return ret; + } + if (sh_audio && (ret = SrsDvrPlan::on_audio(sh_audio)) != ERROR_SUCCESS) { + return ret; + } + return ret; } diff --git a/trunk/src/core/srs_core.hpp b/trunk/src/core/srs_core.hpp index a5729475b..5817d57af 100644 --- a/trunk/src/core/srs_core.hpp +++ b/trunk/src/core/srs_core.hpp @@ -31,7 +31,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // current release version #define VERSION_MAJOR "0" #define VERSION_MINOR "9" -#define VERSION_REVISION "212" +#define VERSION_REVISION "213" #define RTMP_SIG_SRS_VERSION VERSION_MAJOR"."VERSION_MINOR"."VERSION_REVISION // server info. #define RTMP_SIG_SRS_KEY "SRS" diff --git a/trunk/src/utest/srs_utest_config.cpp b/trunk/src/utest/srs_utest_config.cpp index b92cee3b8..fcdd3d7ab 100644 --- a/trunk/src/utest/srs_utest_config.cpp +++ b/trunk/src/utest/srs_utest_config.cpp @@ -271,6 +271,7 @@ std::string __full_conf = "" " # the param for plan(segment), in seconds. \n" " # default: 30 \n" " dvr_duration 30; \n" + " dvr_wait_keyframe on; \n" " # about the stream monotonically increasing: \n" " # 1. video timestamp is monotonically increasing, \n" " # 2. audio timestamp is monotonically increasing, \n" @@ -1937,6 +1938,7 @@ VOID TEST(ConfigMainTest, ParseFullConf) EXPECT_STREQ("./objs/nginx/html", conf.get_dvr_path(vhost).c_str()); EXPECT_STREQ("session", conf.get_dvr_plan(vhost).c_str()); EXPECT_EQ(30, conf.get_dvr_duration(vhost)); + EXPECT_TRUE(conf.get_dvr_wait_keyframe(vhost)); EXPECT_TRUE(SrsRtmpJitterAlgorithmFULL == conf.get_dvr_time_jitter(vhost)); EXPECT_FALSE(conf.get_vhost_http_enabled(vhost)); EXPECT_STREQ("/", conf.get_vhost_http_mount(vhost).c_str()); @@ -2022,6 +2024,7 @@ VOID TEST(ConfigMainTest, ParseFullConf_same_edge) EXPECT_STREQ("./objs/nginx/html", conf.get_dvr_path(vhost).c_str()); EXPECT_STREQ("session", conf.get_dvr_plan(vhost).c_str()); EXPECT_EQ(30, conf.get_dvr_duration(vhost)); + EXPECT_TRUE(conf.get_dvr_wait_keyframe(vhost)); EXPECT_TRUE(SrsRtmpJitterAlgorithmFULL == conf.get_dvr_time_jitter(vhost)); } @@ -2097,6 +2100,7 @@ VOID TEST(ConfigMainTest, ParseFullConf_change_edge) EXPECT_STREQ("./objs/nginx/html", conf.get_dvr_path(vhost).c_str()); EXPECT_STREQ("session", conf.get_dvr_plan(vhost).c_str()); EXPECT_EQ(30, conf.get_dvr_duration(vhost)); + EXPECT_TRUE(conf.get_dvr_wait_keyframe(vhost)); EXPECT_TRUE(SrsRtmpJitterAlgorithmFULL == conf.get_dvr_time_jitter(vhost));*/ } @@ -2171,6 +2175,7 @@ VOID TEST(ConfigMainTest, ParseFullConf_dvr) EXPECT_STREQ("./objs/nginx/html", conf.get_dvr_path(vhost).c_str()); EXPECT_STREQ("session", conf.get_dvr_plan(vhost).c_str()); EXPECT_EQ(30, conf.get_dvr_duration(vhost)); + EXPECT_TRUE(conf.get_dvr_wait_keyframe(vhost)); EXPECT_TRUE(SrsRtmpJitterAlgorithmFULL == conf.get_dvr_time_jitter(vhost)); } @@ -2266,6 +2271,7 @@ VOID TEST(ConfigMainTest, ParseFullConf_ingest) EXPECT_STREQ("./objs/nginx/html", conf.get_dvr_path(vhost).c_str()); EXPECT_STREQ("session", conf.get_dvr_plan(vhost).c_str()); EXPECT_EQ(30, conf.get_dvr_duration(vhost)); + EXPECT_TRUE(conf.get_dvr_wait_keyframe(vhost)); EXPECT_TRUE(SrsRtmpJitterAlgorithmFULL == conf.get_dvr_time_jitter(vhost)); } @@ -2340,6 +2346,7 @@ VOID TEST(ConfigMainTest, ParseFullConf_http) EXPECT_STREQ("./objs/nginx/html", conf.get_dvr_path(vhost).c_str()); EXPECT_STREQ("session", conf.get_dvr_plan(vhost).c_str()); EXPECT_EQ(30, conf.get_dvr_duration(vhost)); + EXPECT_TRUE(conf.get_dvr_wait_keyframe(vhost)); EXPECT_TRUE(SrsRtmpJitterAlgorithmFULL == conf.get_dvr_time_jitter(vhost)); EXPECT_TRUE(conf.get_vhost_http_enabled(vhost)); EXPECT_STREQ("/hls", conf.get_vhost_http_mount(vhost).c_str()); @@ -2417,6 +2424,7 @@ VOID TEST(ConfigMainTest, ParseFullConf_hls_enabled) EXPECT_STREQ("./objs/nginx/html", conf.get_dvr_path(vhost).c_str()); EXPECT_STREQ("session", conf.get_dvr_plan(vhost).c_str()); EXPECT_EQ(30, conf.get_dvr_duration(vhost)); + EXPECT_TRUE(conf.get_dvr_wait_keyframe(vhost)); EXPECT_TRUE(SrsRtmpJitterAlgorithmFULL == conf.get_dvr_time_jitter(vhost)); EXPECT_FALSE(conf.get_vhost_http_enabled(vhost)); EXPECT_STREQ("/", conf.get_vhost_http_mount(vhost).c_str()); @@ -2494,6 +2502,7 @@ VOID TEST(ConfigMainTest, ParseFullConf_hls_disabled) EXPECT_STREQ("./objs/nginx/html", conf.get_dvr_path(vhost).c_str()); EXPECT_STREQ("session", conf.get_dvr_plan(vhost).c_str()); EXPECT_EQ(30, conf.get_dvr_duration(vhost)); + EXPECT_TRUE(conf.get_dvr_wait_keyframe(vhost)); EXPECT_TRUE(SrsRtmpJitterAlgorithmFULL == conf.get_dvr_time_jitter(vhost)); EXPECT_FALSE(conf.get_vhost_http_enabled(vhost)); EXPECT_STREQ("/", conf.get_vhost_http_mount(vhost).c_str()); @@ -2602,6 +2611,7 @@ VOID TEST(ConfigMainTest, ParseFullConf_http_hooks) EXPECT_STREQ("./objs/nginx/html", conf.get_dvr_path(vhost).c_str()); EXPECT_STREQ("session", conf.get_dvr_plan(vhost).c_str()); EXPECT_EQ(30, conf.get_dvr_duration(vhost)); + EXPECT_TRUE(conf.get_dvr_wait_keyframe(vhost)); EXPECT_TRUE(SrsRtmpJitterAlgorithmFULL == conf.get_dvr_time_jitter(vhost)); EXPECT_FALSE(conf.get_vhost_http_enabled(vhost)); EXPECT_STREQ("/", conf.get_vhost_http_mount(vhost).c_str()); @@ -2680,6 +2690,7 @@ VOID TEST(ConfigMainTest, ParseFullConf_min_delay) EXPECT_STREQ("./objs/nginx/html", conf.get_dvr_path(vhost).c_str()); EXPECT_STREQ("session", conf.get_dvr_plan(vhost).c_str()); EXPECT_EQ(30, conf.get_dvr_duration(vhost)); + EXPECT_TRUE(conf.get_dvr_wait_keyframe(vhost)); EXPECT_TRUE(SrsRtmpJitterAlgorithmFULL == conf.get_dvr_time_jitter(vhost)); EXPECT_FALSE(conf.get_vhost_http_enabled(vhost)); EXPECT_STREQ("/", conf.get_vhost_http_mount(vhost).c_str()); @@ -2773,6 +2784,7 @@ VOID TEST(ConfigMainTest, ParseFullConf_refer_anti_suck) EXPECT_STREQ("./objs/nginx/html", conf.get_dvr_path(vhost).c_str()); EXPECT_STREQ("session", conf.get_dvr_plan(vhost).c_str()); EXPECT_EQ(30, conf.get_dvr_duration(vhost)); + EXPECT_TRUE(conf.get_dvr_wait_keyframe(vhost)); EXPECT_TRUE(SrsRtmpJitterAlgorithmFULL == conf.get_dvr_time_jitter(vhost)); EXPECT_FALSE(conf.get_vhost_http_enabled(vhost)); EXPECT_STREQ("/", conf.get_vhost_http_mount(vhost).c_str()); @@ -2856,6 +2868,7 @@ VOID TEST(ConfigMainTest, ParseFullConf_forward_same_vhost) EXPECT_STREQ("./objs/nginx/html", conf.get_dvr_path(vhost).c_str()); EXPECT_STREQ("session", conf.get_dvr_plan(vhost).c_str()); EXPECT_EQ(30, conf.get_dvr_duration(vhost)); + EXPECT_TRUE(conf.get_dvr_wait_keyframe(vhost)); EXPECT_TRUE(SrsRtmpJitterAlgorithmFULL == conf.get_dvr_time_jitter(vhost)); EXPECT_FALSE(conf.get_vhost_http_enabled(vhost)); EXPECT_STREQ("/", conf.get_vhost_http_mount(vhost).c_str()); @@ -2935,6 +2948,7 @@ VOID TEST(ConfigMainTest, ParseFullConf_forward_change_vhost) EXPECT_STREQ("./objs/nginx/html", conf.get_dvr_path(vhost).c_str()); EXPECT_STREQ("session", conf.get_dvr_plan(vhost).c_str()); EXPECT_EQ(30, conf.get_dvr_duration(vhost)); + EXPECT_TRUE(conf.get_dvr_wait_keyframe(vhost)); EXPECT_TRUE(SrsRtmpJitterAlgorithmFULL == conf.get_dvr_time_jitter(vhost)); EXPECT_FALSE(conf.get_vhost_http_enabled(vhost)); EXPECT_STREQ("/", conf.get_vhost_http_mount(vhost).c_str()); @@ -3024,6 +3038,7 @@ VOID TEST(ConfigMainTest, ParseFullConf_transcode_mirror) EXPECT_STREQ("./objs/nginx/html", conf.get_dvr_path(vhost).c_str()); EXPECT_STREQ("session", conf.get_dvr_plan(vhost).c_str()); EXPECT_EQ(30, conf.get_dvr_duration(vhost)); + EXPECT_TRUE(conf.get_dvr_wait_keyframe(vhost)); EXPECT_TRUE(SrsRtmpJitterAlgorithmFULL == conf.get_dvr_time_jitter(vhost)); EXPECT_FALSE(conf.get_vhost_http_enabled(vhost)); EXPECT_STREQ("/", conf.get_vhost_http_mount(vhost).c_str()); @@ -3113,6 +3128,7 @@ VOID TEST(ConfigMainTest, ParseFullConf_transcode_crop) EXPECT_STREQ("./objs/nginx/html", conf.get_dvr_path(vhost).c_str()); EXPECT_STREQ("session", conf.get_dvr_plan(vhost).c_str()); EXPECT_EQ(30, conf.get_dvr_duration(vhost)); + EXPECT_TRUE(conf.get_dvr_wait_keyframe(vhost)); EXPECT_TRUE(SrsRtmpJitterAlgorithmFULL == conf.get_dvr_time_jitter(vhost)); EXPECT_FALSE(conf.get_vhost_http_enabled(vhost)); EXPECT_STREQ("/", conf.get_vhost_http_mount(vhost).c_str()); @@ -3202,6 +3218,7 @@ VOID TEST(ConfigMainTest, ParseFullConf_transcode_logo) EXPECT_STREQ("./objs/nginx/html", conf.get_dvr_path(vhost).c_str()); EXPECT_STREQ("session", conf.get_dvr_plan(vhost).c_str()); EXPECT_EQ(30, conf.get_dvr_duration(vhost)); + EXPECT_TRUE(conf.get_dvr_wait_keyframe(vhost)); EXPECT_TRUE(SrsRtmpJitterAlgorithmFULL == conf.get_dvr_time_jitter(vhost)); EXPECT_FALSE(conf.get_vhost_http_enabled(vhost)); EXPECT_STREQ("/", conf.get_vhost_http_mount(vhost).c_str()); @@ -3285,6 +3302,7 @@ VOID TEST(ConfigMainTest, ParseFullConf_transcode_audio) EXPECT_STREQ("./objs/nginx/html", conf.get_dvr_path(vhost).c_str()); EXPECT_STREQ("session", conf.get_dvr_plan(vhost).c_str()); EXPECT_EQ(30, conf.get_dvr_duration(vhost)); + EXPECT_TRUE(conf.get_dvr_wait_keyframe(vhost)); EXPECT_TRUE(SrsRtmpJitterAlgorithmFULL == conf.get_dvr_time_jitter(vhost)); EXPECT_FALSE(conf.get_vhost_http_enabled(vhost)); EXPECT_STREQ("/", conf.get_vhost_http_mount(vhost).c_str()); @@ -3368,6 +3386,7 @@ VOID TEST(ConfigMainTest, ParseFullConf_transcode_vn) EXPECT_STREQ("./objs/nginx/html", conf.get_dvr_path(vhost).c_str()); EXPECT_STREQ("session", conf.get_dvr_plan(vhost).c_str()); EXPECT_EQ(30, conf.get_dvr_duration(vhost)); + EXPECT_TRUE(conf.get_dvr_wait_keyframe(vhost)); EXPECT_TRUE(SrsRtmpJitterAlgorithmFULL == conf.get_dvr_time_jitter(vhost)); EXPECT_FALSE(conf.get_vhost_http_enabled(vhost)); EXPECT_STREQ("/", conf.get_vhost_http_mount(vhost).c_str()); @@ -3447,6 +3466,7 @@ VOID TEST(ConfigMainTest, ParseFullConf_transcode_copy) EXPECT_STREQ("./objs/nginx/html", conf.get_dvr_path(vhost).c_str()); EXPECT_STREQ("session", conf.get_dvr_plan(vhost).c_str()); EXPECT_EQ(30, conf.get_dvr_duration(vhost)); + EXPECT_TRUE(conf.get_dvr_wait_keyframe(vhost)); EXPECT_TRUE(SrsRtmpJitterAlgorithmFULL == conf.get_dvr_time_jitter(vhost)); EXPECT_FALSE(conf.get_vhost_http_enabled(vhost)); EXPECT_STREQ("/", conf.get_vhost_http_mount(vhost).c_str()); @@ -3664,6 +3684,7 @@ VOID TEST(ConfigMainTest, ParseFullConf_transcode_all) EXPECT_STREQ("./objs/nginx/html", conf.get_dvr_path(vhost).c_str()); EXPECT_STREQ("session", conf.get_dvr_plan(vhost).c_str()); EXPECT_EQ(30, conf.get_dvr_duration(vhost)); + EXPECT_TRUE(conf.get_dvr_wait_keyframe(vhost)); EXPECT_TRUE(SrsRtmpJitterAlgorithmFULL == conf.get_dvr_time_jitter(vhost)); EXPECT_FALSE(conf.get_vhost_http_enabled(vhost)); EXPECT_STREQ("/", conf.get_vhost_http_mount(vhost).c_str()); @@ -3753,6 +3774,7 @@ VOID TEST(ConfigMainTest, ParseFullConf_transcode_ffempty) EXPECT_STREQ("./objs/nginx/html", conf.get_dvr_path(vhost).c_str()); EXPECT_STREQ("session", conf.get_dvr_plan(vhost).c_str()); EXPECT_EQ(30, conf.get_dvr_duration(vhost)); + EXPECT_TRUE(conf.get_dvr_wait_keyframe(vhost)); EXPECT_TRUE(SrsRtmpJitterAlgorithmFULL == conf.get_dvr_time_jitter(vhost)); EXPECT_FALSE(conf.get_vhost_http_enabled(vhost)); EXPECT_STREQ("/", conf.get_vhost_http_mount(vhost).c_str()); @@ -3842,6 +3864,7 @@ VOID TEST(ConfigMainTest, ParseFullConf_transcode_app) EXPECT_STREQ("./objs/nginx/html", conf.get_dvr_path(vhost).c_str()); EXPECT_STREQ("session", conf.get_dvr_plan(vhost).c_str()); EXPECT_EQ(30, conf.get_dvr_duration(vhost)); + EXPECT_TRUE(conf.get_dvr_wait_keyframe(vhost)); EXPECT_TRUE(SrsRtmpJitterAlgorithmFULL == conf.get_dvr_time_jitter(vhost)); EXPECT_FALSE(conf.get_vhost_http_enabled(vhost)); EXPECT_STREQ("/", conf.get_vhost_http_mount(vhost).c_str()); @@ -3931,6 +3954,7 @@ VOID TEST(ConfigMainTest, ParseFullConf_transcode_stream) EXPECT_STREQ("./objs/nginx/html", conf.get_dvr_path(vhost).c_str()); EXPECT_STREQ("session", conf.get_dvr_plan(vhost).c_str()); EXPECT_EQ(30, conf.get_dvr_duration(vhost)); + EXPECT_TRUE(conf.get_dvr_wait_keyframe(vhost)); EXPECT_TRUE(SrsRtmpJitterAlgorithmFULL == conf.get_dvr_time_jitter(vhost)); EXPECT_FALSE(conf.get_vhost_http_enabled(vhost)); EXPECT_STREQ("/", conf.get_vhost_http_mount(vhost).c_str()); @@ -4009,6 +4033,7 @@ VOID TEST(ConfigMainTest, ParseFullConf_bandcheck) EXPECT_STREQ("./objs/nginx/html", conf.get_dvr_path(vhost).c_str()); EXPECT_STREQ("session", conf.get_dvr_plan(vhost).c_str()); EXPECT_EQ(30, conf.get_dvr_duration(vhost)); + EXPECT_TRUE(conf.get_dvr_wait_keyframe(vhost)); EXPECT_TRUE(SrsRtmpJitterAlgorithmFULL == conf.get_dvr_time_jitter(vhost)); EXPECT_FALSE(conf.get_vhost_http_enabled(vhost)); EXPECT_STREQ("/", conf.get_vhost_http_mount(vhost).c_str()); @@ -4087,6 +4112,7 @@ VOID TEST(ConfigMainTest, ParseFullConf_chunksize) EXPECT_STREQ("./objs/nginx/html", conf.get_dvr_path(vhost).c_str()); EXPECT_STREQ("session", conf.get_dvr_plan(vhost).c_str()); EXPECT_EQ(30, conf.get_dvr_duration(vhost)); + EXPECT_TRUE(conf.get_dvr_wait_keyframe(vhost)); EXPECT_TRUE(SrsRtmpJitterAlgorithmFULL == conf.get_dvr_time_jitter(vhost)); EXPECT_FALSE(conf.get_vhost_http_enabled(vhost)); EXPECT_STREQ("/", conf.get_vhost_http_mount(vhost).c_str()); @@ -4165,6 +4191,7 @@ VOID TEST(ConfigMainTest, ParseFullConf_jitter) EXPECT_STREQ("./objs/nginx/html", conf.get_dvr_path(vhost).c_str()); EXPECT_STREQ("session", conf.get_dvr_plan(vhost).c_str()); EXPECT_EQ(30, conf.get_dvr_duration(vhost)); + EXPECT_TRUE(conf.get_dvr_wait_keyframe(vhost)); EXPECT_TRUE(SrsRtmpJitterAlgorithmFULL == conf.get_dvr_time_jitter(vhost)); EXPECT_FALSE(conf.get_vhost_http_enabled(vhost)); EXPECT_STREQ("/", conf.get_vhost_http_mount(vhost).c_str()); @@ -4243,6 +4270,7 @@ VOID TEST(ConfigMainTest, ParseFullConf_atc) EXPECT_STREQ("./objs/nginx/html", conf.get_dvr_path(vhost).c_str()); EXPECT_STREQ("session", conf.get_dvr_plan(vhost).c_str()); EXPECT_EQ(30, conf.get_dvr_duration(vhost)); + EXPECT_TRUE(conf.get_dvr_wait_keyframe(vhost)); EXPECT_TRUE(SrsRtmpJitterAlgorithmFULL == conf.get_dvr_time_jitter(vhost)); EXPECT_FALSE(conf.get_vhost_http_enabled(vhost)); EXPECT_STREQ("/", conf.get_vhost_http_mount(vhost).c_str()); @@ -4321,6 +4349,7 @@ VOID TEST(ConfigMainTest, ParseFullConf_removed) EXPECT_STREQ("./objs/nginx/html", conf.get_dvr_path(vhost).c_str()); EXPECT_STREQ("session", conf.get_dvr_plan(vhost).c_str()); EXPECT_EQ(30, conf.get_dvr_duration(vhost)); + EXPECT_TRUE(conf.get_dvr_wait_keyframe(vhost)); EXPECT_TRUE(SrsRtmpJitterAlgorithmFULL == conf.get_dvr_time_jitter(vhost)); EXPECT_FALSE(conf.get_vhost_http_enabled(vhost)); EXPECT_STREQ("/", conf.get_vhost_http_mount(vhost).c_str()); @@ -4746,6 +4775,16 @@ VOID TEST(ConfigMainTest, CheckConf_vhost_dvr) EXPECT_TRUE(ERROR_SUCCESS != conf.parse(_MIN_OK_CONF"vhost v{dvr{dvr_durations 30;}}")); } + if (true) { + MockSrsConfig conf; + EXPECT_TRUE(ERROR_SUCCESS == conf.parse(_MIN_OK_CONF"vhost v{dvr{dvr_wait_keyframe on;}}")); + } + + if (true) { + MockSrsConfig conf; + EXPECT_TRUE(ERROR_SUCCESS != conf.parse(_MIN_OK_CONF"vhost v{dvr{dvr_wait_keyframes on;}}")); + } + if (true) { MockSrsConfig conf; EXPECT_TRUE(ERROR_SUCCESS == conf.parse(_MIN_OK_CONF"vhost v{dvr{time_jitter full;}}"));