Merge branch 'master' into control-redirect

This commit is contained in:
Roman Arutyunyan 2014-01-03 16:14:03 +04:00
commit 13854403e2
2 changed files with 61 additions and 53 deletions

View file

@ -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.;
} }
} }

View file

@ -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;
} }