mirror of
https://github.com/zotanmew/nginx-rtmp-module.git
synced 2024-05-20 09:51:08 +02:00
implemented shared output chains
This commit is contained in:
parent
201d1b28ae
commit
40684b12b4
19
ngx_rtmp.h
19
ngx_rtmp.h
|
@ -216,8 +216,11 @@ typedef struct {
|
||||||
ngx_pool_t *in_old_pool;
|
ngx_pool_t *in_old_pool;
|
||||||
ngx_int_t in_chunk_size_changing;
|
ngx_int_t in_chunk_size_changing;
|
||||||
|
|
||||||
ngx_chain_t *out;
|
/* circular buffer of RTMP message pointers */
|
||||||
ngx_chain_t *out_free_chains;
|
ngx_chain_t **out_start, **out_end;
|
||||||
|
ngx_chain_t **out_pos, **out_last;
|
||||||
|
ngx_chain_t *out_chain;
|
||||||
|
u_char *out_bpos;
|
||||||
} ngx_rtmp_session_t;
|
} ngx_rtmp_session_t;
|
||||||
|
|
||||||
|
|
||||||
|
@ -260,8 +263,7 @@ typedef struct ngx_rtmp_core_srv_conf_s {
|
||||||
ngx_int_t chunk_size;
|
ngx_int_t chunk_size;
|
||||||
ngx_pool_t *pool;
|
ngx_pool_t *pool;
|
||||||
ngx_chain_t *free;
|
ngx_chain_t *free;
|
||||||
ngx_chain_t *free_chains;
|
size_t max_queue;
|
||||||
size_t max_buf;
|
|
||||||
size_t max_message;
|
size_t max_message;
|
||||||
ngx_flag_t play_time_fix;
|
ngx_flag_t play_time_fix;
|
||||||
ngx_flag_t publish_time_fix;
|
ngx_flag_t publish_time_fix;
|
||||||
|
@ -361,11 +363,9 @@ ngx_int_t ngx_rtmp_amf_shared_object_handler(ngx_rtmp_session_t *s,
|
||||||
|
|
||||||
/* Shared output buffers */
|
/* Shared output buffers */
|
||||||
ngx_chain_t * ngx_rtmp_alloc_shared_buf(ngx_rtmp_core_srv_conf_t *cscf);
|
ngx_chain_t * ngx_rtmp_alloc_shared_buf(ngx_rtmp_core_srv_conf_t *cscf);
|
||||||
void ngx_rtmp_free_shared_bufs(ngx_rtmp_core_srv_conf_t *cscf,
|
void ngx_rtmp_acquire_shared_chain(ngx_chain_t *in);
|
||||||
ngx_chain_t *out);
|
void ngx_rtmp_free_shared_chain(ngx_rtmp_core_srv_conf_t *cscf,
|
||||||
void ngx_rtmp_free_shared_buf(ngx_rtmp_core_srv_conf_t *cscf,
|
ngx_chain_t *in);
|
||||||
ngx_buf_t *b);
|
|
||||||
void ngx_rtmp_acquire_shared_buf(ngx_buf_t *b);
|
|
||||||
ngx_chain_t * ngx_rtmp_append_shared_bufs(ngx_rtmp_core_srv_conf_t *cscf,
|
ngx_chain_t * ngx_rtmp_append_shared_bufs(ngx_rtmp_core_srv_conf_t *cscf,
|
||||||
ngx_chain_t *head, ngx_chain_t *in);
|
ngx_chain_t *head, ngx_chain_t *in);
|
||||||
|
|
||||||
|
@ -380,6 +380,7 @@ ngx_int_t ngx_rtmp_send_message(ngx_rtmp_session_t *s, ngx_chain_t *out,
|
||||||
* the bigger value the lower the priority.
|
* the bigger value the lower the priority.
|
||||||
* priority=0 is the highest */
|
* priority=0 is the highest */
|
||||||
|
|
||||||
|
|
||||||
#define NGX_RTMP_LIMIT_SOFT 0
|
#define NGX_RTMP_LIMIT_SOFT 0
|
||||||
#define NGX_RTMP_LIMIT_HARD 1
|
#define NGX_RTMP_LIMIT_HARD 1
|
||||||
#define NGX_RTMP_LIMIT_DYNAMIC 2
|
#define NGX_RTMP_LIMIT_DYNAMIC 2
|
||||||
|
|
|
@ -89,11 +89,11 @@ static ngx_command_t ngx_rtmp_core_commands[] = {
|
||||||
offsetof(ngx_rtmp_core_srv_conf_t, chunk_size),
|
offsetof(ngx_rtmp_core_srv_conf_t, chunk_size),
|
||||||
NULL },
|
NULL },
|
||||||
|
|
||||||
{ ngx_string("max_buf"),
|
{ ngx_string("max_queue"),
|
||||||
NGX_RTMP_MAIN_CONF|NGX_RTMP_SRV_CONF|NGX_CONF_TAKE1,
|
NGX_RTMP_MAIN_CONF|NGX_RTMP_SRV_CONF|NGX_CONF_TAKE1,
|
||||||
ngx_conf_set_size_slot,
|
ngx_conf_set_size_slot,
|
||||||
NGX_RTMP_SRV_CONF_OFFSET,
|
NGX_RTMP_SRV_CONF_OFFSET,
|
||||||
offsetof(ngx_rtmp_core_srv_conf_t, max_buf),
|
offsetof(ngx_rtmp_core_srv_conf_t, max_queue),
|
||||||
NULL },
|
NULL },
|
||||||
|
|
||||||
{ ngx_string("max_message"),
|
{ ngx_string("max_message"),
|
||||||
|
@ -199,7 +199,7 @@ ngx_rtmp_core_create_srv_conf(ngx_conf_t *cf)
|
||||||
conf->max_streams = NGX_CONF_UNSET;
|
conf->max_streams = NGX_CONF_UNSET;
|
||||||
conf->chunk_size = NGX_CONF_UNSET;
|
conf->chunk_size = NGX_CONF_UNSET;
|
||||||
conf->ack_window = NGX_CONF_UNSET;
|
conf->ack_window = NGX_CONF_UNSET;
|
||||||
conf->max_buf = NGX_CONF_UNSET;
|
conf->max_queue = NGX_CONF_UNSET;
|
||||||
conf->max_message = NGX_CONF_UNSET;
|
conf->max_message = NGX_CONF_UNSET;
|
||||||
conf->play_time_fix = NGX_CONF_UNSET;
|
conf->play_time_fix = NGX_CONF_UNSET;
|
||||||
conf->publish_time_fix = NGX_CONF_UNSET;
|
conf->publish_time_fix = NGX_CONF_UNSET;
|
||||||
|
@ -217,11 +217,11 @@ ngx_rtmp_core_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child)
|
||||||
ngx_conf_merge_msec_value(conf->timeout, prev->timeout, 60000);
|
ngx_conf_merge_msec_value(conf->timeout, prev->timeout, 60000);
|
||||||
|
|
||||||
ngx_conf_merge_value(conf->so_keepalive, prev->so_keepalive, 0);
|
ngx_conf_merge_value(conf->so_keepalive, prev->so_keepalive, 0);
|
||||||
ngx_conf_merge_value(conf->max_streams, prev->max_streams, 64);
|
ngx_conf_merge_value(conf->max_streams, prev->max_streams, 16);
|
||||||
ngx_conf_merge_value(conf->chunk_size, prev->chunk_size, 4096);
|
ngx_conf_merge_value(conf->chunk_size, prev->chunk_size, 4096);
|
||||||
ngx_conf_merge_uint_value(conf->ack_window, prev->ack_window, 5000000);
|
ngx_conf_merge_uint_value(conf->ack_window, prev->ack_window, 5000000);
|
||||||
ngx_conf_merge_size_value(conf->max_buf, prev->max_buf, 128 * 1024);
|
ngx_conf_merge_size_value(conf->max_queue, prev->max_queue, 256);
|
||||||
ngx_conf_merge_size_value(conf->max_message, prev->max_message, 4 * 1024 * 1024);
|
ngx_conf_merge_size_value(conf->max_message, prev->max_message, 1 * 1024 * 1024);
|
||||||
ngx_conf_merge_value(conf->play_time_fix, prev->play_time_fix, 1);
|
ngx_conf_merge_value(conf->play_time_fix, prev->play_time_fix, 1);
|
||||||
ngx_conf_merge_value(conf->publish_time_fix, prev->publish_time_fix, 1);
|
ngx_conf_merge_value(conf->publish_time_fix, prev->publish_time_fix, 1);
|
||||||
|
|
||||||
|
|
|
@ -48,9 +48,9 @@ ngx_rtmp_message_type(uint8_t type) {
|
||||||
"amf3_meta",
|
"amf3_meta",
|
||||||
"amf3_shared",
|
"amf3_shared",
|
||||||
"amd3_cmd",
|
"amd3_cmd",
|
||||||
"amf0_meta",
|
"amf_meta",
|
||||||
"amf0_shared",
|
"amf_shared",
|
||||||
"amf0_cmd",
|
"amf_cmd",
|
||||||
"?",
|
"?",
|
||||||
"aggregate"
|
"aggregate"
|
||||||
};
|
};
|
||||||
|
@ -233,6 +233,7 @@ ngx_rtmp_init_session(ngx_connection_t *c)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
s->in_streams = ngx_pcalloc(c->pool, sizeof(ngx_rtmp_stream_t)
|
s->in_streams = ngx_pcalloc(c->pool, sizeof(ngx_rtmp_stream_t)
|
||||||
* cscf->max_streams);
|
* cscf->max_streams);
|
||||||
if (s->in_streams == NULL) {
|
if (s->in_streams == NULL) {
|
||||||
|
@ -241,8 +242,19 @@ ngx_rtmp_init_session(ngx_connection_t *c)
|
||||||
}
|
}
|
||||||
size = NGX_RTMP_HANDSHAKE_SIZE + 1;
|
size = NGX_RTMP_HANDSHAKE_SIZE + 1;
|
||||||
|
|
||||||
|
|
||||||
|
s->out_start = ngx_palloc(c->pool, sizeof(ngx_chain_t *) * cscf->max_queue);
|
||||||
|
if (s->out_start == NULL) {
|
||||||
|
ngx_rtmp_close_connection(c);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
s->out_pos = s->out_last = s->out_start;
|
||||||
|
s->out_end = s->out_start + cscf->max_queue;
|
||||||
|
|
||||||
|
|
||||||
ngx_rtmp_set_chunk_size(s, NGX_RTMP_DEFAULT_CHUNK_SIZE);
|
ngx_rtmp_set_chunk_size(s, NGX_RTMP_DEFAULT_CHUNK_SIZE);
|
||||||
|
|
||||||
|
|
||||||
/* start handshake */
|
/* start handshake */
|
||||||
b = &s->hs_in_buf;
|
b = &s->hs_in_buf;
|
||||||
b->start = b->pos = b->last = ngx_pcalloc(s->in_pool, size);
|
b->start = b->pos = b->last = ngx_pcalloc(s->in_pool, size);
|
||||||
|
@ -790,10 +802,7 @@ ngx_rtmp_send(ngx_event_t *wev)
|
||||||
ngx_connection_t *c;
|
ngx_connection_t *c;
|
||||||
ngx_rtmp_session_t *s;
|
ngx_rtmp_session_t *s;
|
||||||
ngx_rtmp_core_srv_conf_t *cscf;
|
ngx_rtmp_core_srv_conf_t *cscf;
|
||||||
ngx_chain_t *out, *l, *cl;
|
ngx_int_t n;
|
||||||
u_char *p;
|
|
||||||
off_t limit;
|
|
||||||
size_t n;
|
|
||||||
|
|
||||||
c = wev->data;
|
c = wev->data;
|
||||||
s = c->data;
|
s = c->data;
|
||||||
|
@ -815,78 +824,43 @@ ngx_rtmp_send(ngx_event_t *wev)
|
||||||
ngx_del_timer(wev);
|
ngx_del_timer(wev);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (s->out) {
|
while (s->out_chain) {
|
||||||
p = s->out->buf->pos;
|
n = c->send(c, s->out_bpos, s->out_chain->buf->last - s->out_bpos);
|
||||||
|
|
||||||
/* send_chain calls writev for output.
|
if (n == NGX_ERROR) {
|
||||||
* It uses mixed allocation model for
|
|
||||||
* for iovecs passed to writev. Only 64
|
|
||||||
* structs fit into stack. When writing more
|
|
||||||
* memory is allocated from c->pool and
|
|
||||||
* **NEVER EVER** returned back.
|
|
||||||
* IOV_MAX=1024 on Linux.
|
|
||||||
*
|
|
||||||
* The only way to escape allocation is
|
|
||||||
* limiting the number of output data blocks
|
|
||||||
* being written at once with NGX_HEADERS
|
|
||||||
* (64 by default).
|
|
||||||
*
|
|
||||||
* FIXME: NGINX
|
|
||||||
* Unfortunately NGINX API does not allow
|
|
||||||
* us to specify max number of such blocks
|
|
||||||
* but only size limit. We're left with
|
|
||||||
* limiting by size which leads to extra
|
|
||||||
* loop here to find size of first 64
|
|
||||||
* blocks in output.
|
|
||||||
* */
|
|
||||||
|
|
||||||
limit = 0;
|
|
||||||
n = 0;
|
|
||||||
cl = s->out;
|
|
||||||
while (cl && n < 64) {
|
|
||||||
++n;
|
|
||||||
limit += cl->buf->last - cl->buf->pos;
|
|
||||||
cl = cl->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
out = c->send_chain(c, s->out, limit);
|
|
||||||
|
|
||||||
if (out == NGX_CHAIN_ERROR) {
|
|
||||||
ngx_rtmp_finalize_session(s);
|
ngx_rtmp_finalize_session(s);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (out == s->out && out->buf->pos == p) {
|
if (n == NGX_AGAIN || n == 0) {
|
||||||
cscf = ngx_rtmp_get_module_srv_conf(s, ngx_rtmp_core_module);
|
|
||||||
ngx_add_timer(c->write, cscf->timeout);
|
ngx_add_timer(c->write, cscf->timeout);
|
||||||
if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
|
if (ngx_handle_write_event(c->write, 0) != NGX_OK) {
|
||||||
ngx_rtmp_finalize_session(s);
|
ngx_rtmp_finalize_session(s);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (s->out) {
|
s->out_bpos += n;
|
||||||
l = s->out;
|
if (s->out_bpos == s->out_chain->buf->last) {
|
||||||
|
s->out_chain = s->out_chain->next;
|
||||||
if (l->buf->pos < l->buf->last) {
|
if (s->out_chain == NULL) {
|
||||||
break;
|
ngx_rtmp_free_shared_chain(cscf, *s->out_pos);
|
||||||
}
|
++s->out_pos;
|
||||||
|
if (s->out_pos == s->out_end) {
|
||||||
s->out = s->out->next;
|
s->out_pos = s->out_start;
|
||||||
l->next = NULL;
|
}
|
||||||
|
if (s->out_pos == s->out_last) {
|
||||||
l->next = s->out_free_chains;
|
break;
|
||||||
s->out_free_chains = l;
|
}
|
||||||
|
s->out_chain = *s->out_pos;
|
||||||
ngx_rtmp_free_shared_buf(cscf, l->buf);
|
|
||||||
|
|
||||||
if (s->out == out) {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
s->out_bpos = s->out_chain->buf->pos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ngx_del_event(wev, NGX_WRITE_EVENT, 0);
|
if (wev->active) {
|
||||||
|
ngx_del_event(wev, NGX_WRITE_EVENT, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1038,68 +1012,42 @@ ngx_int_t
|
||||||
ngx_rtmp_send_message(ngx_rtmp_session_t *s, ngx_chain_t *out,
|
ngx_rtmp_send_message(ngx_rtmp_session_t *s, ngx_chain_t *out,
|
||||||
ngx_uint_t priority)
|
ngx_uint_t priority)
|
||||||
{
|
{
|
||||||
ngx_chain_t *l, **ll;
|
|
||||||
ngx_connection_t *c;
|
ngx_connection_t *c;
|
||||||
ngx_buf_t *b;
|
|
||||||
ngx_rtmp_core_srv_conf_t *cscf;
|
ngx_rtmp_core_srv_conf_t *cscf;
|
||||||
size_t nbytes, nbufs, qbytes, qbufs;
|
size_t nmsg;
|
||||||
|
|
||||||
c = s->connection;
|
c = s->connection;
|
||||||
cscf = ngx_rtmp_get_module_srv_conf(s, ngx_rtmp_core_module);
|
cscf = ngx_rtmp_get_module_srv_conf(s, ngx_rtmp_core_module);
|
||||||
qbytes = 0;
|
|
||||||
qbufs = 0;
|
|
||||||
nbytes = 0;
|
|
||||||
nbufs = 0;
|
|
||||||
|
|
||||||
for(ll = &s->out; *ll; ll = &(*ll)->next) {
|
nmsg = (s->out_pos <= s->out_last)
|
||||||
qbytes += (*ll)->buf->last - (*ll)->buf->pos;
|
? s->out_last - s->out_pos
|
||||||
++qbufs;
|
: (s->out_end - s->out_pos) + (s->out_last - s->out_start);
|
||||||
}
|
++nmsg;
|
||||||
|
|
||||||
/* drop packet? */
|
/* drop packet?
|
||||||
if (qbytes > cscf->max_buf / (priority + 1)) {
|
* Note we always leave 1 slot free */
|
||||||
ngx_log_debug3(NGX_LOG_DEBUG_RTMP, c->log, 0,
|
if (nmsg >= (s->out_end - s->out_start) / (priority + 1)) {
|
||||||
"drop message bytes=%uz, bufs=%uz priority=%ui",
|
ngx_log_debug2(NGX_LOG_DEBUG_RTMP, c->log, 0,
|
||||||
qbytes, qbufs, priority);
|
"RTMP drop message bufs=%ui, priority=%ui",
|
||||||
|
nmsg, priority);
|
||||||
return NGX_AGAIN;
|
return NGX_AGAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* append locally-linked chain of shared buffers */
|
ngx_rtmp_acquire_shared_chain(out);
|
||||||
for(l = out; l; l = l->next) {
|
|
||||||
|
|
||||||
if (s->out_free_chains) {
|
*s->out_last++ = out;
|
||||||
*ll = s->out_free_chains;
|
if (s->out_last >= s->out_end) {
|
||||||
s->out_free_chains = (*ll)->next;
|
s->out_last = s->out_start;
|
||||||
|
|
||||||
} else {
|
|
||||||
*ll = ngx_alloc_chain_link(c->pool);
|
|
||||||
if (*ll == NULL) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
(*ll)->buf = ngx_calloc_buf(c->pool);
|
|
||||||
if ((*ll)->buf == NULL) {
|
|
||||||
ngx_free_chain(c->pool, (*ll));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
b = (*ll)->buf;
|
|
||||||
*b = *l->buf;
|
|
||||||
|
|
||||||
ngx_rtmp_acquire_shared_buf(b);
|
|
||||||
|
|
||||||
ll = &(*ll)->next;
|
|
||||||
|
|
||||||
nbytes += (b->last - b->pos);
|
|
||||||
++nbufs;
|
|
||||||
}
|
}
|
||||||
*ll = NULL;
|
|
||||||
|
|
||||||
ngx_log_debug7(NGX_LOG_DEBUG_RTMP, c->log, 0,
|
if (s->out_chain == NULL) {
|
||||||
"RTMP send bytes=%uz+%uz, bufs=%uz+%uz, priority=%ui, "
|
s->out_chain = out;
|
||||||
"ready=%d, active=%d",
|
s->out_bpos = out->buf->pos;
|
||||||
qbytes, nbytes, qbufs, nbufs, priority,
|
}
|
||||||
c->write->ready, c->write->active);
|
|
||||||
|
ngx_log_debug4(NGX_LOG_DEBUG_RTMP, c->log, 0,
|
||||||
|
"RTMP send nmsg=%ui, priority=%ui, ready=%d, active=%d",
|
||||||
|
nmsg, priority, c->write->ready, c->write->active);
|
||||||
|
|
||||||
if (!c->write->active) {
|
if (!c->write->active) {
|
||||||
ngx_rtmp_send(c->write);
|
ngx_rtmp_send(c->write);
|
||||||
|
@ -1306,10 +1254,12 @@ ngx_rtmp_close_session_handler(ngx_event_t *e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* release only buffers, links are local
|
while (s->out_pos != s->out_last) {
|
||||||
* and will be released as part of pool */
|
ngx_rtmp_free_shared_chain(cscf, *s->out_pos);
|
||||||
for (; s->out; s->out = s->out->next) {
|
++s->out_pos;
|
||||||
ngx_rtmp_free_shared_buf(cscf, s->out->buf);
|
if (s->out_pos == s->out_end) {
|
||||||
|
s->out_pos = s->out_start;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ngx_rtmp_close_connection(c);
|
ngx_rtmp_close_connection(c);
|
||||||
|
|
|
@ -281,7 +281,7 @@ ngx_rtmp_live_send_abs_message(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
||||||
|
|
||||||
rc = ngx_rtmp_send_message(s, out, 0);
|
rc = ngx_rtmp_send_message(s, out, 0);
|
||||||
|
|
||||||
ngx_rtmp_free_shared_bufs(cscf, out);
|
ngx_rtmp_free_shared_chain(cscf, out);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@ -430,7 +430,7 @@ ngx_rtmp_live_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ngx_rtmp_free_shared_bufs(cscf, out);
|
ngx_rtmp_free_shared_chain(cscf, out);
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
#define NGX_RTMP_USER_END(s) \
|
#define NGX_RTMP_USER_END(s) \
|
||||||
ngx_rtmp_prepare_message(s, &__h, NULL, __l); \
|
ngx_rtmp_prepare_message(s, &__h, NULL, __l); \
|
||||||
rc = ngx_rtmp_send_message(s, __l, 0); \
|
rc = ngx_rtmp_send_message(s, __l, 0); \
|
||||||
ngx_rtmp_free_shared_bufs(__cscf, __l); \
|
ngx_rtmp_free_shared_chain(__cscf, __l); \
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
|
|
||||||
|
@ -269,7 +269,7 @@ ngx_int_t ngx_rtmp_send_amf(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
||||||
rc = ngx_rtmp_send_message(s, first, 0);
|
rc = ngx_rtmp_send_message(s, first, 0);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
ngx_rtmp_free_shared_bufs(cscf, first);
|
ngx_rtmp_free_shared_chain(cscf, first);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,21 +37,14 @@ ngx_rtmp_alloc_shared_buf(ngx_rtmp_core_srv_conf_t *cscf)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (cscf->free_chains) {
|
out = ngx_alloc_chain_link(cscf->pool);
|
||||||
out = cscf->free_chains;
|
if (out == NULL) {
|
||||||
cscf->free_chains = out->next;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
out->buf = ngx_calloc_buf(cscf->pool);
|
||||||
out = ngx_alloc_chain_link(cscf->pool);
|
if (out->buf == NULL) {
|
||||||
if (out == NULL) {
|
return NULL;
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
out->buf = ngx_calloc_buf(cscf->pool);
|
|
||||||
if (out->buf == NULL) {
|
|
||||||
ngx_free_chain(cscf->pool, out);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size = cscf->chunk_size + NGX_RTMP_MAX_CHUNK_HEADER
|
size = cscf->chunk_size + NGX_RTMP_MAX_CHUNK_HEADER
|
||||||
|
@ -60,8 +53,6 @@ ngx_rtmp_alloc_shared_buf(ngx_rtmp_core_srv_conf_t *cscf)
|
||||||
b = out->buf;
|
b = out->buf;
|
||||||
b->start = ngx_palloc(cscf->pool, size);
|
b->start = ngx_palloc(cscf->pool, size);
|
||||||
if (b->start == NULL) {
|
if (b->start == NULL) {
|
||||||
out->next = cscf->free_chains;
|
|
||||||
cscf->free_chains = out;
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,68 +73,28 @@ ngx_rtmp_alloc_shared_buf(ngx_rtmp_core_srv_conf_t *cscf)
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ngx_rtmp_free_shared_bufs(ngx_rtmp_core_srv_conf_t *cscf, ngx_chain_t *out)
|
ngx_rtmp_acquire_shared_chain(ngx_chain_t *in)
|
||||||
{
|
{
|
||||||
ngx_chain_t *cl;
|
ngx_rtmp_ref_get(in->buf->start);
|
||||||
|
|
||||||
while (out) {
|
|
||||||
cl = out;
|
|
||||||
out = out->next;
|
|
||||||
|
|
||||||
if (ngx_rtmp_ref_put(cl->buf->start) == 0) {
|
|
||||||
/* both chain & buf are free;
|
|
||||||
* put the whole chain in free list */
|
|
||||||
cl->next = cscf->free;
|
|
||||||
cscf->free = cl;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* only chain is free;
|
|
||||||
* buf is still used by somebody & will
|
|
||||||
* be freed in ngx_rtmp_free_shared_buf */
|
|
||||||
cl->next = cscf->free_chains;
|
|
||||||
cscf->free_chains = cl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ngx_rtmp_acquire_shared_buf(ngx_buf_t *b)
|
ngx_rtmp_free_shared_chain(ngx_rtmp_core_srv_conf_t *cscf, ngx_chain_t *in)
|
||||||
{
|
{
|
||||||
ngx_rtmp_ref_get(b->start);
|
ngx_chain_t *cl;
|
||||||
}
|
|
||||||
|
|
||||||
|
if (ngx_rtmp_ref_put(in->buf->start)) {
|
||||||
void
|
|
||||||
ngx_rtmp_free_shared_buf(ngx_rtmp_core_srv_conf_t *cscf, ngx_buf_t *b)
|
|
||||||
{
|
|
||||||
ngx_chain_t *cl;
|
|
||||||
|
|
||||||
if (ngx_rtmp_ref_put(b->start)) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cscf->free_chains) {
|
for (cl = in; ; cl = cl->next) {
|
||||||
cl = cscf->free_chains;
|
if (cl->next == NULL) {
|
||||||
cscf->free_chains = cl->next;
|
cl->next = cscf->free;
|
||||||
|
cscf->free = in;
|
||||||
} else {
|
|
||||||
cl = ngx_alloc_chain_link(cscf->pool);
|
|
||||||
if (cl == NULL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
cl->buf = ngx_calloc_buf(cscf->pool);
|
|
||||||
if (cl->buf == NULL) {
|
|
||||||
ngx_free_chain(cscf->pool, cl);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cl->buf->start = b->start;
|
|
||||||
cl->buf->end = b->end;
|
|
||||||
cl->next = cscf->free;
|
|
||||||
cscf->free = cl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -22,7 +22,7 @@ rtmp {
|
||||||
|
|
||||||
chunk_size 128;
|
chunk_size 128;
|
||||||
|
|
||||||
max_buf 1000000;
|
max_queue 256;
|
||||||
|
|
||||||
publish_time_fix off;
|
publish_time_fix off;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue