正在显示
3 个修改的文件
包含
30 行增加
和
40 行删除
| @@ -562,6 +562,7 @@ Supported operating systems and hardware: | @@ -562,6 +562,7 @@ Supported operating systems and hardware: | ||
| 562 | 562 | ||
| 563 | ### SRS 2.0 history | 563 | ### SRS 2.0 history |
| 564 | 564 | ||
| 565 | +* v2.0, 2015-04-10, refine the hls deviation for floor algorithm. | ||
| 565 | * v2.0, 2015-04-08, for [#375](https://github.com/winlinvip/simple-rtmp-server/issues/375), fix hls bug, keep cc continous between ts files. 2.0.159. | 566 | * v2.0, 2015-04-08, for [#375](https://github.com/winlinvip/simple-rtmp-server/issues/375), fix hls bug, keep cc continous between ts files. 2.0.159. |
| 566 | * v2.0, 2015-04-04, for [#304](https://github.com/winlinvip/simple-rtmp-server/issues/304), rewrite annexb mux for ts, refer to apple sample. 2.0.157. | 567 | * v2.0, 2015-04-04, for [#304](https://github.com/winlinvip/simple-rtmp-server/issues/304), rewrite annexb mux for ts, refer to apple sample. 2.0.157. |
| 567 | * v2.0, 2015-04-03, enhanced avc decode, parse the sps get width+height. 2.0.156. | 568 | * v2.0, 2015-04-03, enhanced avc decode, parse the sps get width+height. 2.0.156. |
| @@ -59,10 +59,10 @@ using namespace std; | @@ -59,10 +59,10 @@ using namespace std; | ||
| 59 | // drop the segment when duration of ts too small. | 59 | // drop the segment when duration of ts too small. |
| 60 | #define SRS_AUTO_HLS_SEGMENT_MIN_DURATION_MS 100 | 60 | #define SRS_AUTO_HLS_SEGMENT_MIN_DURATION_MS 100 |
| 61 | 61 | ||
| 62 | -// startup piece, the first piece, fragment percent to reap. | ||
| 63 | -#define SRS_HLS_FLOOR_STARTUP_PERCENT 0.1 | ||
| 64 | // fragment plus the deviation percent. | 62 | // fragment plus the deviation percent. |
| 65 | #define SRS_HLS_FLOOR_REAP_PERCENT 0.2 | 63 | #define SRS_HLS_FLOOR_REAP_PERCENT 0.2 |
| 64 | +// reset the piece id when deviation overflow this. | ||
| 65 | +#define SRS_JUMP_WHEN_PIECE_DEVIATION 10 | ||
| 66 | 66 | ||
| 67 | ISrsHlsHandler::ISrsHlsHandler() | 67 | ISrsHlsHandler::ISrsHlsHandler() |
| 68 | { | 68 | { |
| @@ -224,7 +224,7 @@ SrsHlsMuxer::SrsHlsMuxer() | @@ -224,7 +224,7 @@ SrsHlsMuxer::SrsHlsMuxer() | ||
| 224 | handler = NULL; | 224 | handler = NULL; |
| 225 | hls_fragment = hls_window = 0; | 225 | hls_fragment = hls_window = 0; |
| 226 | hls_aof_ratio = 1.0; | 226 | hls_aof_ratio = 1.0; |
| 227 | - hls_fragment_deviation = 0; | 227 | + deviation_ts = 0; |
| 228 | hls_cleanup = true; | 228 | hls_cleanup = true; |
| 229 | previous_floor_ts = 0; | 229 | previous_floor_ts = 0; |
| 230 | accept_floor_ts = 0; | 230 | accept_floor_ts = 0; |
| @@ -269,26 +269,14 @@ double SrsHlsMuxer::duration() | @@ -269,26 +269,14 @@ double SrsHlsMuxer::duration() | ||
| 269 | return current? current->duration:0; | 269 | return current? current->duration:0; |
| 270 | } | 270 | } |
| 271 | 271 | ||
| 272 | -double SrsHlsMuxer::deviation() | 272 | +int SrsHlsMuxer::deviation() |
| 273 | { | 273 | { |
| 274 | // no floor, no deviation. | 274 | // no floor, no deviation. |
| 275 | if (!hls_ts_floor) { | 275 | if (!hls_ts_floor) { |
| 276 | return 0; | 276 | return 0; |
| 277 | } | 277 | } |
| 278 | 278 | ||
| 279 | - return hls_fragment_deviation; | ||
| 280 | -} | ||
| 281 | - | ||
| 282 | -int SrsHlsMuxer::absolute_deviation() | ||
| 283 | -{ | ||
| 284 | - // no floor, no deviation. | ||
| 285 | - if (!hls_ts_floor) { | ||
| 286 | - return 0; | ||
| 287 | - } | ||
| 288 | - | ||
| 289 | - // accept the floor ts for the first piece. | ||
| 290 | - int64_t floor_ts = (int64_t)(srs_get_system_time_ms() / (1000 * hls_fragment)); | ||
| 291 | - return (int)(accept_floor_ts - (floor_ts - 1)); | 279 | + return deviation_ts; |
| 292 | } | 280 | } |
| 293 | 281 | ||
| 294 | int SrsHlsMuxer::initialize(ISrsHlsHandler* h) | 282 | int SrsHlsMuxer::initialize(ISrsHlsHandler* h) |
| @@ -323,9 +311,7 @@ int SrsHlsMuxer::update_config(SrsRequest* r, string entry_prefix, | @@ -323,9 +311,7 @@ int SrsHlsMuxer::update_config(SrsRequest* r, string entry_prefix, | ||
| 323 | previous_floor_ts = 0; | 311 | previous_floor_ts = 0; |
| 324 | accept_floor_ts = 0; | 312 | accept_floor_ts = 0; |
| 325 | hls_window = window; | 313 | hls_window = window; |
| 326 | - // for the first time, we set to -N% of fragment, | ||
| 327 | - // that is, the first piece always smaller. | ||
| 328 | - hls_fragment_deviation = -1 * (fragment * SRS_HLS_FLOOR_STARTUP_PERCENT); | 314 | + deviation_ts = 0; |
| 329 | 315 | ||
| 330 | // generate the m3u8 dir and path. | 316 | // generate the m3u8 dir and path. |
| 331 | m3u8 = path + "/" + m3u8_file; | 317 | m3u8 = path + "/" + m3u8_file; |
| @@ -412,24 +398,33 @@ int SrsHlsMuxer::segment_open(int64_t segment_start_dts) | @@ -412,24 +398,33 @@ int SrsHlsMuxer::segment_open(int64_t segment_start_dts) | ||
| 412 | ts_file = srs_path_build_stream(ts_file, req->vhost, req->app, req->stream); | 398 | ts_file = srs_path_build_stream(ts_file, req->vhost, req->app, req->stream); |
| 413 | if (hls_ts_floor) { | 399 | if (hls_ts_floor) { |
| 414 | // accept the floor ts for the first piece. | 400 | // accept the floor ts for the first piece. |
| 415 | - int64_t floor_ts = (int64_t)(srs_get_system_time_ms() / (1000 * hls_fragment)); | 401 | + int64_t current_floor_ts = (int64_t)(srs_get_system_time_ms() / (1000 * hls_fragment)); |
| 416 | if (!accept_floor_ts) { | 402 | if (!accept_floor_ts) { |
| 417 | - accept_floor_ts = floor_ts - 1; | 403 | + accept_floor_ts = current_floor_ts - 1; |
| 418 | } else { | 404 | } else { |
| 419 | accept_floor_ts++; | 405 | accept_floor_ts++; |
| 420 | } | 406 | } |
| 421 | 407 | ||
| 408 | + // jump when deviation more than 10p | ||
| 409 | + if (accept_floor_ts - current_floor_ts > SRS_JUMP_WHEN_PIECE_DEVIATION) { | ||
| 410 | + srs_warn("hls: jmp for ts deviation, current=%"PRId64", accept=%"PRId64, current_floor_ts, accept_floor_ts); | ||
| 411 | + accept_floor_ts = current_floor_ts - 1; | ||
| 412 | + } | ||
| 413 | + | ||
| 414 | + // when reap ts, adjust the deviation. | ||
| 415 | + deviation_ts = (int)(accept_floor_ts - current_floor_ts); | ||
| 416 | + | ||
| 422 | // we always ensure the piece is increase one by one. | 417 | // we always ensure the piece is increase one by one. |
| 423 | std::stringstream ts_floor; | 418 | std::stringstream ts_floor; |
| 424 | ts_floor << accept_floor_ts; | 419 | ts_floor << accept_floor_ts; |
| 425 | ts_file = srs_string_replace(ts_file, "[timestamp]", ts_floor.str()); | 420 | ts_file = srs_string_replace(ts_file, "[timestamp]", ts_floor.str()); |
| 426 | 421 | ||
| 427 | // dup/jmp detect for ts in floor mode. | 422 | // dup/jmp detect for ts in floor mode. |
| 428 | - if (previous_floor_ts && previous_floor_ts != floor_ts - 1) { | ||
| 429 | - srs_warn("hls: dup or jmp for floor ts, previous=%"PRId64", current=%"PRId64", ts=%s, deviation=%.2f", | ||
| 430 | - previous_floor_ts, floor_ts, ts_file.c_str(), hls_fragment_deviation); | 423 | + if (previous_floor_ts && previous_floor_ts != current_floor_ts - 1) { |
| 424 | + srs_warn("hls: dup or jmp for floor ts, previous=%"PRId64", current=%"PRId64", accept=%"PRId64", deviation=%d", | ||
| 425 | + previous_floor_ts, current_floor_ts, accept_floor_ts, deviation_ts); | ||
| 431 | } | 426 | } |
| 432 | - previous_floor_ts = floor_ts; | 427 | + previous_floor_ts = current_floor_ts; |
| 433 | } | 428 | } |
| 434 | ts_file = srs_path_build_timestamp(ts_file); | 429 | ts_file = srs_path_build_timestamp(ts_file); |
| 435 | if (true) { | 430 | if (true) { |
| @@ -497,7 +492,7 @@ bool SrsHlsMuxer::is_segment_overflow() | @@ -497,7 +492,7 @@ bool SrsHlsMuxer::is_segment_overflow() | ||
| 497 | srs_assert(current); | 492 | srs_assert(current); |
| 498 | 493 | ||
| 499 | // use N% deviation, to smoother. | 494 | // use N% deviation, to smoother. |
| 500 | - double deviation = hls_ts_floor? SRS_HLS_FLOOR_REAP_PERCENT * hls_fragment_deviation : 0.0; | 495 | + double deviation = hls_ts_floor? SRS_HLS_FLOOR_REAP_PERCENT * deviation_ts * hls_fragment : 0.0; |
| 501 | 496 | ||
| 502 | return current->duration >= hls_fragment + deviation; | 497 | return current->duration >= hls_fragment + deviation; |
| 503 | } | 498 | } |
| @@ -594,19 +589,14 @@ int SrsHlsMuxer::segment_close(string log_desc) | @@ -594,19 +589,14 @@ int SrsHlsMuxer::segment_close(string log_desc) | ||
| 594 | if (current->duration * 1000 >= SRS_AUTO_HLS_SEGMENT_MIN_DURATION_MS) { | 589 | if (current->duration * 1000 >= SRS_AUTO_HLS_SEGMENT_MIN_DURATION_MS) { |
| 595 | segments.push_back(current); | 590 | segments.push_back(current); |
| 596 | 591 | ||
| 597 | - // when reap ts, adjust the deviation. | ||
| 598 | - if (hls_ts_floor) { | ||
| 599 | - hls_fragment_deviation += (double)(hls_fragment - current->duration); | ||
| 600 | - } | ||
| 601 | - | ||
| 602 | // use async to call the http hooks, for it will cause thread switch. | 592 | // use async to call the http hooks, for it will cause thread switch. |
| 603 | if ((ret = async->call(new SrsDvrAsyncCallOnHls(req, current->full_path, current->sequence_no, current->duration))) != ERROR_SUCCESS) { | 593 | if ((ret = async->call(new SrsDvrAsyncCallOnHls(req, current->full_path, current->sequence_no, current->duration))) != ERROR_SUCCESS) { |
| 604 | return ret; | 594 | return ret; |
| 605 | } | 595 | } |
| 606 | 596 | ||
| 607 | - srs_info("%s reap ts segment, sequence_no=%d, uri=%s, duration=%.2f, start=%"PRId64", deviation=%.2f", | 597 | + srs_info("%s reap ts segment, sequence_no=%d, uri=%s, duration=%.2f, start=%"PRId64, |
| 608 | log_desc.c_str(), current->sequence_no, current->uri.c_str(), current->duration, | 598 | log_desc.c_str(), current->sequence_no, current->uri.c_str(), current->duration, |
| 609 | - current->segment_start_dts, hls_fragment_deviation); | 599 | + current->segment_start_dts); |
| 610 | 600 | ||
| 611 | // notify handler for update ts. | 601 | // notify handler for update ts. |
| 612 | srs_assert(current->writer); | 602 | srs_assert(current->writer); |
| @@ -1222,9 +1212,9 @@ void SrsHls::hls_show_mux_log() | @@ -1222,9 +1212,9 @@ void SrsHls::hls_show_mux_log() | ||
| 1222 | // the run time is not equals to stream time, | 1212 | // the run time is not equals to stream time, |
| 1223 | // @see: https://github.com/winlinvip/simple-rtmp-server/issues/81#issuecomment-48100994 | 1213 | // @see: https://github.com/winlinvip/simple-rtmp-server/issues/81#issuecomment-48100994 |
| 1224 | // it's ok. | 1214 | // it's ok. |
| 1225 | - srs_trace("-> "SRS_CONSTS_LOG_HLS" time=%"PRId64", stream dts=%"PRId64"(%"PRId64"ms), sno=%d, ts=%s, dur=%.2f, dva=%.2fs/%dp", | 1215 | + srs_trace("-> "SRS_CONSTS_LOG_HLS" time=%"PRId64", stream dts=%"PRId64"(%"PRId64"ms), sno=%d, ts=%s, dur=%.2f, dva=%dp", |
| 1226 | pprint->age(), stream_dts, stream_dts / 90, muxer->sequence_no(), muxer->ts_url().c_str(), | 1216 | pprint->age(), stream_dts, stream_dts / 90, muxer->sequence_no(), muxer->ts_url().c_str(), |
| 1227 | - muxer->duration(), muxer->deviation(), muxer->absolute_deviation()); | 1217 | + muxer->duration(), muxer->deviation()); |
| 1228 | } | 1218 | } |
| 1229 | } | 1219 | } |
| 1230 | 1220 |
| @@ -199,9 +199,9 @@ private: | @@ -199,9 +199,9 @@ private: | ||
| 199 | private: | 199 | private: |
| 200 | // whether use floor algorithm for timestamp. | 200 | // whether use floor algorithm for timestamp. |
| 201 | bool hls_ts_floor; | 201 | bool hls_ts_floor; |
| 202 | - // the deviation in seconds to adjust the fragment to be more | 202 | + // the deviation in piece to adjust the fragment to be more |
| 203 | // bigger or smaller. | 203 | // bigger or smaller. |
| 204 | - double hls_fragment_deviation; | 204 | + int deviation_ts; |
| 205 | // the previous reap floor timestamp, | 205 | // the previous reap floor timestamp, |
| 206 | // used to detect the dup or jmp or ts. | 206 | // used to detect the dup or jmp or ts. |
| 207 | int64_t accept_floor_ts; | 207 | int64_t accept_floor_ts; |
| @@ -242,8 +242,7 @@ public: | @@ -242,8 +242,7 @@ public: | ||
| 242 | virtual int sequence_no(); | 242 | virtual int sequence_no(); |
| 243 | virtual std::string ts_url(); | 243 | virtual std::string ts_url(); |
| 244 | virtual double duration(); | 244 | virtual double duration(); |
| 245 | - virtual double deviation(); | ||
| 246 | - virtual int absolute_deviation(); | 245 | + virtual int deviation(); |
| 247 | public: | 246 | public: |
| 248 | /** | 247 | /** |
| 249 | * initialize the hls muxer. | 248 | * initialize the hls muxer. |
-
请 注册 或 登录 后发表评论