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:
Jaroslav Kysela 2014-03-12 17:05:59 +01:00
parent a678110453
commit dee579ea2a
5 changed files with 84 additions and 43 deletions

View file

@ -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);
}
/*

View file

@ -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);
}
/*

View file

@ -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)

View file

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

View file

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