mirror of
https://github.com/zotanmew/nginx-rtmp-module.git
synced 2024-06-28 16:09:00 +02:00
Merge branch 'master' into control-redirect
This commit is contained in:
commit
13854403e2
|
@ -1348,22 +1348,24 @@ ngx_rtmp_hls_update_fragment(ngx_rtmp_session_t *s, uint64_t ts,
|
||||||
ngx_msec_t ts_frag_len;
|
ngx_msec_t ts_frag_len;
|
||||||
ngx_int_t same_frag;
|
ngx_int_t same_frag;
|
||||||
ngx_buf_t *b;
|
ngx_buf_t *b;
|
||||||
|
int64_t d;
|
||||||
|
|
||||||
hacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_hls_module);
|
hacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_hls_module);
|
||||||
|
|
||||||
ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_hls_module);
|
ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_hls_module);
|
||||||
|
|
||||||
f = NULL;
|
f = NULL;
|
||||||
|
|
||||||
if (ctx->opened) {
|
if (ctx->opened) {
|
||||||
|
|
||||||
f = ngx_rtmp_hls_get_frag(s, ctx->nfrags);
|
f = ngx_rtmp_hls_get_frag(s, ctx->nfrags);
|
||||||
f->duration = (ts - ctx->frag_ts) / 90000.;
|
d = (int64_t) (ts - ctx->frag_ts);
|
||||||
|
|
||||||
if (f->duration * 1000 > hacf->max_fraglen) {
|
if (d > (int64_t) hacf->max_fraglen * 90 || d < -90000) {
|
||||||
ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
|
ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
|
||||||
"hls: max fragment length reached");
|
"hls: max fragment length reached: %.3f sec, ",
|
||||||
|
f->duration);
|
||||||
boundary = 1;
|
boundary = 1;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
f->duration = (ts - ctx->frag_ts) / 90000.;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,9 @@ static ngx_int_t ngx_rtmp_mp4_send(ngx_rtmp_session_t *s, ngx_file_t *f,
|
||||||
static ngx_int_t ngx_rtmp_mp4_reset(ngx_rtmp_session_t *s);
|
static ngx_int_t ngx_rtmp_mp4_reset(ngx_rtmp_session_t *s);
|
||||||
|
|
||||||
|
|
||||||
|
#define NGX_RTMP_MP4_MAX_FRAMES 8
|
||||||
|
|
||||||
|
|
||||||
#pragma pack(push,4)
|
#pragma pack(push,4)
|
||||||
|
|
||||||
|
|
||||||
|
@ -2092,15 +2095,16 @@ ngx_rtmp_mp4_send(ngx_rtmp_session_t *s, ngx_file_t *f, ngx_uint_t *ts)
|
||||||
ngx_rtmp_header_t h, lh;
|
ngx_rtmp_header_t h, lh;
|
||||||
ngx_rtmp_core_srv_conf_t *cscf;
|
ngx_rtmp_core_srv_conf_t *cscf;
|
||||||
ngx_chain_t *out, in;
|
ngx_chain_t *out, in;
|
||||||
ngx_rtmp_mp4_track_t *t;
|
ngx_rtmp_mp4_track_t *t, *cur_t;
|
||||||
ngx_rtmp_mp4_cursor_t *cr;
|
ngx_rtmp_mp4_cursor_t *cr, *cur_cr;
|
||||||
uint32_t buflen, end_timestamp, sched,
|
uint32_t buflen, end_timestamp,
|
||||||
timestamp, last_timestamp, rdelay;
|
timestamp, last_timestamp, rdelay,
|
||||||
|
cur_timestamp;
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
u_char fhdr[5];
|
u_char fhdr[5];
|
||||||
size_t fhdr_size;
|
size_t fhdr_size;
|
||||||
ngx_int_t rc;
|
ngx_int_t rc;
|
||||||
ngx_uint_t n, active;
|
ngx_uint_t n, counter;
|
||||||
|
|
||||||
cscf = ngx_rtmp_get_module_srv_conf(s, ngx_rtmp_core_module);
|
cscf = ngx_rtmp_get_module_srv_conf(s, ngx_rtmp_core_module);
|
||||||
|
|
||||||
|
@ -2123,31 +2127,57 @@ ngx_rtmp_mp4_send(ngx_rtmp_session_t *s, ngx_file_t *f, ngx_uint_t *ts)
|
||||||
buflen = (s->buflen ? s->buflen + NGX_RTMP_MP4_BUFLEN_ADDON:
|
buflen = (s->buflen ? s->buflen + NGX_RTMP_MP4_BUFLEN_ADDON:
|
||||||
NGX_RTMP_MP4_DEFAULT_BUFLEN);
|
NGX_RTMP_MP4_DEFAULT_BUFLEN);
|
||||||
|
|
||||||
t = ctx->tracks;
|
counter = 0;
|
||||||
|
|
||||||
sched = 0;
|
|
||||||
active = 0;
|
|
||||||
last_timestamp = 0;
|
last_timestamp = 0;
|
||||||
|
|
||||||
end_timestamp = ctx->start_timestamp +
|
end_timestamp = ctx->start_timestamp +
|
||||||
(ngx_current_msec - ctx->epoch) + buflen;
|
(ngx_current_msec - ctx->epoch) + buflen;
|
||||||
|
|
||||||
for (n = 0; n < ctx->ntracks; ++n, ++t) {
|
for ( ;; ) {
|
||||||
cr = &t->cursor;
|
counter++;
|
||||||
|
if (counter > NGX_RTMP_MP4_MAX_FRAMES) {
|
||||||
if (!cr->valid) {
|
return NGX_OK;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
timestamp = ngx_rtmp_mp4_to_rtmp_timestamp(t, cr->timestamp);
|
timestamp = 0;
|
||||||
|
t = NULL;
|
||||||
|
|
||||||
|
for (n = 0; n < ctx->ntracks; n++) {
|
||||||
|
cur_t = &ctx->tracks[n];
|
||||||
|
cur_cr = &cur_t->cursor;
|
||||||
|
|
||||||
|
if (!cur_cr->valid) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
cur_timestamp = ngx_rtmp_mp4_to_rtmp_timestamp(cur_t,
|
||||||
|
cur_cr->timestamp);
|
||||||
|
|
||||||
|
if (t == NULL || cur_timestamp < timestamp) {
|
||||||
|
timestamp = cur_timestamp;
|
||||||
|
t = cur_t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (t == NULL) {
|
||||||
|
ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
|
||||||
|
"mp4: no track");
|
||||||
|
return NGX_DONE;
|
||||||
|
}
|
||||||
|
|
||||||
if (timestamp > end_timestamp) {
|
if (timestamp > end_timestamp) {
|
||||||
ngx_log_debug3(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
ngx_log_debug3(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
||||||
"mp4: track#%ui ahead %uD > %uD",
|
"mp4: track#%ui ahead %uD > %uD",
|
||||||
t->id, timestamp, end_timestamp);
|
t->id, timestamp, end_timestamp);
|
||||||
goto next;
|
|
||||||
|
if (ts) {
|
||||||
|
*ts = last_timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (uint32_t) (timestamp - end_timestamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cr = &t->cursor;
|
||||||
|
|
||||||
last_timestamp = ngx_rtmp_mp4_to_rtmp_timestamp(t, cr->last_timestamp);
|
last_timestamp = ngx_rtmp_mp4_to_rtmp_timestamp(t, cr->last_timestamp);
|
||||||
|
|
||||||
ngx_memzero(&h, sizeof(h));
|
ngx_memzero(&h, sizeof(h));
|
||||||
|
@ -2245,7 +2275,7 @@ ngx_rtmp_mp4_send(ngx_rtmp_session_t *s, ngx_file_t *f, ngx_uint_t *ts)
|
||||||
ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
|
ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
|
||||||
"mp4: track#%ui too big frame: %D>%uz",
|
"mp4: track#%ui too big frame: %D>%uz",
|
||||||
t->id, cr->size, sizeof(ngx_rtmp_mp4_buffer));
|
t->id, cr->size, sizeof(ngx_rtmp_mp4_buffer));
|
||||||
continue;
|
goto next;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = ngx_read_file(f, ngx_rtmp_mp4_buffer + fhdr_size,
|
ret = ngx_read_file(f, ngx_rtmp_mp4_buffer + fhdr_size,
|
||||||
|
@ -2254,7 +2284,7 @@ ngx_rtmp_mp4_send(ngx_rtmp_session_t *s, ngx_file_t *f, ngx_uint_t *ts)
|
||||||
if (ret != (ssize_t) cr->size) {
|
if (ret != (ssize_t) cr->size) {
|
||||||
ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
|
ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
|
||||||
"mp4: track#%ui could not read frame", t->id);
|
"mp4: track#%ui could not read frame", t->id);
|
||||||
continue;
|
goto next;
|
||||||
}
|
}
|
||||||
|
|
||||||
in.buf = &in_buf;
|
in.buf = &in_buf;
|
||||||
|
@ -2273,35 +2303,11 @@ ngx_rtmp_mp4_send(ngx_rtmp_session_t *s, ngx_file_t *f, ngx_uint_t *ts)
|
||||||
|
|
||||||
s->current_time = timestamp;
|
s->current_time = timestamp;
|
||||||
|
|
||||||
if (ngx_rtmp_mp4_next(s, t) != NGX_OK) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
next:
|
next:
|
||||||
active = 1;
|
if (ngx_rtmp_mp4_next(s, t) != NGX_OK) {
|
||||||
|
return NGX_DONE;
|
||||||
if (timestamp > end_timestamp &&
|
|
||||||
(sched == 0 || timestamp < end_timestamp + sched))
|
|
||||||
{
|
|
||||||
sched = (uint32_t) (timestamp - end_timestamp);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sched) {
|
|
||||||
return sched;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (active) {
|
|
||||||
return NGX_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ts) {
|
|
||||||
*ts = last_timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*ngx_rtmp_mp4_reset(s);*/
|
|
||||||
|
|
||||||
return NGX_DONE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue