The sbuf allocation cleanups
This is an attempt to fix the nonoptimal memory allocations. The old code tries to allocate new chunks based on maximum packet value, but the streams contain mostly short chunks. Also, in some cases, we know the fixed sbuf size, so use it.
This commit is contained in:
parent
a678110453
commit
dee579ea2a
5 changed files with 84 additions and 43 deletions
|
@ -241,6 +241,9 @@ mpegts_service_stop(service_t *t)
|
|||
/* Stop */
|
||||
if (i)
|
||||
i->mi_close_service(i, s);
|
||||
|
||||
/* Save some memory */
|
||||
sbuf_free(&s->s_tsbuf);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -297,6 +297,9 @@ ts_remux(mpegts_service_t *t, const uint8_t *src)
|
|||
pktbuf_t *pb;
|
||||
sbuf_t *sb = &t->s_tsbuf;
|
||||
|
||||
if (sb->sb_data == NULL)
|
||||
sbuf_init_fixed(sb, TS_REMUX_BUFSIZE);
|
||||
|
||||
sbuf_append(sb, src, 188);
|
||||
|
||||
if(sb->sb_ptr < TS_REMUX_BUFSIZE)
|
||||
|
@ -312,7 +315,7 @@ ts_remux(mpegts_service_t *t, const uint8_t *src)
|
|||
|
||||
service_set_streaming_status_flags((service_t*)t, TSS_PACKETS);
|
||||
|
||||
sbuf_reset(sb);
|
||||
sbuf_reset(sb, TS_REMUX_BUFSIZE);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -231,7 +231,7 @@ parse_aac(service_t *t, elementary_stream_t *st, const uint8_t *data,
|
|||
/* Payload unit start */
|
||||
st->es_parser_state = 1;
|
||||
st->es_parser_ptr = 0;
|
||||
sbuf_reset(&st->es_buf);
|
||||
sbuf_reset(&st->es_buf, 4000);
|
||||
}
|
||||
|
||||
if(st->es_parser_state == 0)
|
||||
|
@ -351,9 +351,9 @@ parse_sc(service_t *t, elementary_stream_t *st, const uint8_t *data, int len,
|
|||
r = 1;
|
||||
}
|
||||
|
||||
assert(st->es_buf.sb_data != NULL);
|
||||
|
||||
if(r == 2) {
|
||||
assert(st->es_buf.sb_data != NULL);
|
||||
|
||||
// Drop packet
|
||||
st->es_buf.sb_ptr = st->es_startcode_offset;
|
||||
|
||||
|
@ -367,12 +367,13 @@ parse_sc(service_t *t, elementary_stream_t *st, const uint8_t *data, int len,
|
|||
if(r == 1) {
|
||||
/* Reset packet parser upon length error or if parser
|
||||
tells us so */
|
||||
sbuf_reset(&st->es_buf);
|
||||
sbuf_reset_and_alloc(&st->es_buf, 256);
|
||||
st->es_buf.sb_data[st->es_buf.sb_ptr++] = sc >> 24;
|
||||
st->es_buf.sb_data[st->es_buf.sb_ptr++] = sc >> 16;
|
||||
st->es_buf.sb_data[st->es_buf.sb_ptr++] = sc >> 8;
|
||||
st->es_buf.sb_data[st->es_buf.sb_ptr++] = sc;
|
||||
}
|
||||
assert(st->es_buf.sb_data != NULL);
|
||||
st->es_startcode = sc;
|
||||
st->es_startcode_offset = st->es_buf.sb_ptr - 4;
|
||||
}
|
||||
|
@ -1118,17 +1119,11 @@ parse_mpeg2video(service_t *t, elementary_stream_t *st, size_t len,
|
|||
pkt->pkt_payload = pktbuf_make(st->es_buf.sb_data,
|
||||
st->es_buf.sb_ptr - 4);
|
||||
pkt->pkt_duration = st->es_frame_duration;
|
||||
sbuf_steal_data(&st->es_buf);
|
||||
|
||||
parser_deliver(t, st, pkt, st->es_buf.sb_err);
|
||||
st->es_curpkt = NULL;
|
||||
|
||||
st->es_buf.sb_data = malloc(st->es_buf.sb_size);
|
||||
if(st->es_buf.sb_data == NULL) {
|
||||
fprintf(stderr, "Unable to allocate %d bytes\n",
|
||||
st->es_buf.sb_size);
|
||||
abort();
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
@ -1248,10 +1243,10 @@ parse_h264(service_t *t, elementary_stream_t *st, size_t len,
|
|||
|
||||
pkt->pkt_payload = pktbuf_make(st->es_buf.sb_data,
|
||||
st->es_buf.sb_ptr - 4);
|
||||
sbuf_steal_data(&st->es_buf);
|
||||
parser_deliver(t, st, pkt, st->es_buf.sb_err);
|
||||
|
||||
st->es_curpkt = NULL;
|
||||
st->es_buf.sb_data = malloc(st->es_buf.sb_size);
|
||||
|
||||
st->es_curdts = PTS_UNSET;
|
||||
st->es_curpts = PTS_UNSET;
|
||||
|
@ -1276,7 +1271,7 @@ parse_subtitles(service_t *t, elementary_stream_t *st, const uint8_t *data,
|
|||
if(start) {
|
||||
/* Payload unit start */
|
||||
st->es_parser_state = 1;
|
||||
sbuf_reset(&st->es_buf);
|
||||
sbuf_reset(&st->es_buf, 4000);
|
||||
}
|
||||
|
||||
if(st->es_parser_state == 0)
|
||||
|
@ -1339,7 +1334,7 @@ parse_teletext(service_t *t, elementary_stream_t *st, const uint8_t *data,
|
|||
if(start) {
|
||||
st->es_parser_state = 1;
|
||||
st->es_parser_ptr = 0;
|
||||
sbuf_reset(&st->es_buf);
|
||||
sbuf_reset(&st->es_buf, 4000);
|
||||
}
|
||||
|
||||
if(st->es_parser_state == 0)
|
||||
|
|
|
@ -583,13 +583,32 @@ static inline int64_t ts_rescale_i(int64_t ts, int tb)
|
|||
|
||||
void sbuf_init(sbuf_t *sb);
|
||||
|
||||
void sbuf_init_fixed(sbuf_t *sb, int len);
|
||||
|
||||
void sbuf_free(sbuf_t *sb);
|
||||
|
||||
void sbuf_reset(sbuf_t *sb);
|
||||
void sbuf_reset(sbuf_t *sb, int max_len);
|
||||
|
||||
void sbuf_err(sbuf_t *sb);
|
||||
void sbuf_reset_and_alloc(sbuf_t *sb, int len);
|
||||
|
||||
void sbuf_alloc(sbuf_t *sb, int len);
|
||||
static inline void sbuf_steal_data(sbuf_t *sb)
|
||||
{
|
||||
sb->sb_data = NULL;
|
||||
sb->sb_ptr = sb->sb_size = 0;
|
||||
}
|
||||
|
||||
static inline void sbuf_err(sbuf_t *sb)
|
||||
{
|
||||
sb->sb_err = 1;
|
||||
}
|
||||
|
||||
void sbuf_alloc_(sbuf_t *sb, int len);
|
||||
|
||||
static inline void sbuf_alloc(sbuf_t *sb, int len)
|
||||
{
|
||||
if (sb->sb_ptr + len >= sb->sb_size)
|
||||
sbuf_alloc_(sb, len);
|
||||
}
|
||||
|
||||
void sbuf_append(sbuf_t *sb, const void *data, int len);
|
||||
|
||||
|
|
71
src/utils.c
71
src/utils.c
|
@ -247,6 +247,12 @@ put_utf8(char *out, int c)
|
|||
return 6;
|
||||
}
|
||||
|
||||
static void
|
||||
sbuf_alloc_fail(int len)
|
||||
{
|
||||
fprintf(stderr, "Unable to allocate %d bytes\n", len);
|
||||
abort();
|
||||
}
|
||||
|
||||
void
|
||||
sbuf_init(sbuf_t *sb)
|
||||
|
@ -254,62 +260,77 @@ sbuf_init(sbuf_t *sb)
|
|||
memset(sb, 0, sizeof(sbuf_t));
|
||||
}
|
||||
|
||||
void
|
||||
sbuf_init_fixed(sbuf_t *sb, int len)
|
||||
{
|
||||
memset(sb, 0, sizeof(sbuf_t));
|
||||
sb->sb_data = malloc(len);
|
||||
if (sb->sb_data == NULL)
|
||||
sbuf_alloc_fail(len);
|
||||
sb->sb_size = len;
|
||||
}
|
||||
|
||||
void
|
||||
sbuf_free(sbuf_t *sb)
|
||||
{
|
||||
if(sb->sb_data)
|
||||
free(sb->sb_data);
|
||||
free(sb->sb_data);
|
||||
sb->sb_size = sb->sb_ptr = sb->sb_err = 0;
|
||||
sb->sb_data = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
sbuf_reset(sbuf_t *sb)
|
||||
sbuf_reset(sbuf_t *sb, int max_len)
|
||||
{
|
||||
sb->sb_ptr = 0;
|
||||
sb->sb_err = 0;
|
||||
sb->sb_ptr = sb->sb_err = 0;
|
||||
if (sb->sb_size > max_len) {
|
||||
void *n = realloc(sb->sb_data, max_len);
|
||||
if (n) {
|
||||
sb->sb_data = n;
|
||||
sb->sb_size = max_len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sbuf_err(sbuf_t *sb)
|
||||
sbuf_reset_and_alloc(sbuf_t *sb, int len)
|
||||
{
|
||||
sb->sb_err = 1;
|
||||
if (sb->sb_data) {
|
||||
if (len != sb->sb_size) {
|
||||
void *n = realloc(sb->sb_data, len);
|
||||
if (n) {
|
||||
sb->sb_data = n;
|
||||
sb->sb_size = len;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
sb->sb_data = malloc(len);
|
||||
sb->sb_size = len;
|
||||
}
|
||||
if (sb->sb_data == NULL)
|
||||
sbuf_alloc_fail(len);
|
||||
sb->sb_ptr = sb->sb_err = 0;
|
||||
}
|
||||
|
||||
void
|
||||
sbuf_alloc(sbuf_t *sb, int len)
|
||||
sbuf_alloc_(sbuf_t *sb, int len)
|
||||
{
|
||||
if(sb->sb_data == NULL) {
|
||||
sb->sb_size = len * 4 > 4000 ? len * 4 : 4000;
|
||||
sb->sb_data = malloc(sb->sb_size);
|
||||
return;
|
||||
}
|
||||
|
||||
if(sb->sb_ptr + len >= sb->sb_size) {
|
||||
} else {
|
||||
sb->sb_size += len * 4;
|
||||
sb->sb_data = realloc(sb->sb_data, sb->sb_size);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sbuf_alloc1(sbuf_t *sb, int len)
|
||||
{
|
||||
if(sb->sb_data == NULL) {
|
||||
sb->sb_size = len * 4 > 4000 ? len * 4 : 4000;
|
||||
sb->sb_data = malloc(sb->sb_size);
|
||||
return;
|
||||
}
|
||||
|
||||
sb->sb_size += len * 4;
|
||||
sb->sb_data = realloc(sb->sb_data, sb->sb_size);
|
||||
if(sb->sb_data == NULL)
|
||||
sbuf_alloc_fail(sb->sb_size);
|
||||
}
|
||||
|
||||
void
|
||||
sbuf_append(sbuf_t *sb, const void *data, int len)
|
||||
{
|
||||
if(sb->sb_ptr + len >= sb->sb_size)
|
||||
sbuf_alloc1(sb, len);
|
||||
sbuf_alloc(sb, len);
|
||||
memcpy(sb->sb_data + sb->sb_ptr, data, len);
|
||||
sb->sb_ptr += len;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue