You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
127 lines
2.6 KiB
127 lines
2.6 KiB
5 years ago
|
|
||
|
/*
|
||
|
* Copyright (C) Roman Arutyunyan
|
||
|
*/
|
||
|
|
||
|
|
||
|
#include <ngx_config.h>
|
||
|
#include <ngx_core.h>
|
||
|
#include "ngx_rtmp.h"
|
||
|
|
||
|
|
||
|
ngx_chain_t *
|
||
|
ngx_rtmp_alloc_shared_buf(ngx_rtmp_core_srv_conf_t *cscf)
|
||
|
{
|
||
|
u_char *p;
|
||
|
ngx_chain_t *out;
|
||
|
ngx_buf_t *b;
|
||
|
size_t size;
|
||
|
|
||
|
if (cscf->free) {
|
||
|
out = cscf->free;
|
||
|
cscf->free = out->next;
|
||
|
|
||
|
} else {
|
||
|
|
||
|
size = cscf->chunk_size + NGX_RTMP_MAX_CHUNK_HEADER;
|
||
|
|
||
|
p = ngx_pcalloc(cscf->pool, NGX_RTMP_REFCOUNT_BYTES
|
||
|
+ sizeof(ngx_chain_t)
|
||
|
+ sizeof(ngx_buf_t)
|
||
|
+ size);
|
||
|
if (p == NULL) {
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
p += NGX_RTMP_REFCOUNT_BYTES;
|
||
|
out = (ngx_chain_t *)p;
|
||
|
|
||
|
p += sizeof(ngx_chain_t);
|
||
|
out->buf = (ngx_buf_t *)p;
|
||
|
|
||
|
p += sizeof(ngx_buf_t);
|
||
|
out->buf->start = p;
|
||
|
out->buf->end = p + size;
|
||
|
}
|
||
|
|
||
|
out->next = NULL;
|
||
|
b = out->buf;
|
||
|
b->pos = b->last = b->start + NGX_RTMP_MAX_CHUNK_HEADER;
|
||
|
b->memory = 1;
|
||
|
|
||
|
/* buffer has refcount =1 when created! */
|
||
|
ngx_rtmp_ref_set(out, 1);
|
||
|
|
||
|
return out;
|
||
|
}
|
||
|
|
||
|
|
||
|
void
|
||
|
ngx_rtmp_free_shared_chain(ngx_rtmp_core_srv_conf_t *cscf, ngx_chain_t *in)
|
||
|
{
|
||
|
ngx_chain_t *cl;
|
||
|
|
||
|
if (ngx_rtmp_ref_put(in)) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
for (cl = in; ; cl = cl->next) {
|
||
|
if (cl->next == NULL) {
|
||
|
cl->next = cscf->free;
|
||
|
cscf->free = in;
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
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 *l, **ll;
|
||
|
u_char *p;
|
||
|
size_t size;
|
||
|
|
||
|
ll = &head;
|
||
|
p = in->buf->pos;
|
||
|
l = head;
|
||
|
|
||
|
if (l) {
|
||
|
for(; l->next; l = l->next);
|
||
|
ll = &l->next;
|
||
|
}
|
||
|
|
||
|
for ( ;; ) {
|
||
|
|
||
|
if (l == NULL || l->buf->last == l->buf->end) {
|
||
|
l = ngx_rtmp_alloc_shared_buf(cscf);
|
||
|
if (l == NULL || l->buf == NULL) {
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
*ll = l;
|
||
|
ll = &l->next;
|
||
|
}
|
||
|
|
||
|
while (l->buf->end - l->buf->last >= in->buf->last - p) {
|
||
|
l->buf->last = ngx_cpymem(l->buf->last, p,
|
||
|
in->buf->last - p);
|
||
|
in = in->next;
|
||
|
if (in == NULL) {
|
||
|
goto done;
|
||
|
}
|
||
|
p = in->buf->pos;
|
||
|
}
|
||
|
|
||
|
size = l->buf->end - l->buf->last;
|
||
|
l->buf->last = ngx_cpymem(l->buf->last, p, size);
|
||
|
p += size;
|
||
|
}
|
||
|
|
||
|
done:
|
||
|
*ll = NULL;
|
||
|
|
||
|
return head;
|
||
|
}
|