]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
The sbuf allocation cleanups 343/head
authorJaroslav Kysela <perex@perex.cz>
Wed, 12 Mar 2014 16:05:59 +0000 (17:05 +0100)
committerJaroslav Kysela <perex@perex.cz>
Fri, 14 Mar 2014 20:10:51 +0000 (21:10 +0100)
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.

src/input/mpegts/mpegts_service.c
src/input/mpegts/tsdemux.c
src/parsers/parsers.c
src/tvheadend.h
src/utils.c

index efab84190811b6495f9086c8a68f9a9916ff6bf3..763913388c88976b810238299a8c0013606d09b1 100644 (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);
 }
 
 /*
index 7cb078d18294c660d7220fcf46ddd9ad2591627c..d9b7ee4dbe926e050d5c803c3df4f8d05880f248 100644 (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);
 }
 
 /*
index c3f21803778b4cc4b84c4ce6ced1ff3ca9121de8..8ff6e4e18774823ddd98567d5152f67449fe25eb 100644 (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)
index 34b5cf130216e658057a7c174a9edec6b4ebde28..ace8a63ecaf84f79d5528f0b289661d30f621187 100644 (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_reset_and_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_err(sbuf_t *sb);
+void sbuf_alloc_(sbuf_t *sb, int len);
 
-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);
 
index 57bcbe2b36912ebeca74c7627347b3c440e3f756..69f51c28424c44faf77ba2a33b330f2d7367863f 100644 (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;
 }