]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
Refactor parsing buffer handling + better constification
authorAndreas Öman <andreas@lonelycoder.com>
Sat, 3 Jul 2010 16:18:50 +0000 (16:18 +0000)
committerAndreas Öman <andreas@lonelycoder.com>
Sat, 3 Jul 2010 16:18:50 +0000 (16:18 +0000)
12 files changed:
src/bitstream.c
src/bitstream.h
src/dvr/mkmux.c
src/parser_h264.c
src/parser_h264.h
src/parser_latm.c
src/parser_latm.h
src/parsers.c
src/transports.c
src/tvhead.h
src/utils.c
src/v4l.c

index be5ce9292c94d2478c8b7820299980f2cfa85dda..b88081990ce3af9f03e92dd0e0339dda009ac6e5 100644 (file)
 
 
 void
-init_bits(bitstream_t *bs, uint8_t *data, int bits)
+init_rbits(bitstream_t *bs, const uint8_t *data, int bits)
 {
-  bs->data = data;
+  bs->wdata = NULL;
+  bs->rdata = data;
+  bs->offset = 0;
+  bs->len = bits;
+}
+
+
+void
+init_wbits(bitstream_t *bs, uint8_t *data, int bits)
+{
+  bs->wdata = data;
+  bs->rdata = NULL;
   bs->offset = 0;
   bs->len = bits;
 }
@@ -46,7 +57,7 @@ read_bits(bitstream_t *bs, int num)
 
     num--;
 
-    if(bs->data[bs->offset / 8] & (1 << (7 - (bs->offset & 7))))
+    if(bs->rdata[bs->offset / 8] & (1 << (7 - (bs->offset & 7))))
       r |= 1 << num;
 
     bs->offset++;
@@ -103,9 +114,9 @@ put_bits(bitstream_t *bs, int val, int num)
     num--;
 
     if(val & (1 << num))
-      bs->data[bs->offset / 8] |= 1 << (7 - (bs->offset & 7));
+      bs->wdata[bs->offset / 8] |= 1 << (7 - (bs->offset & 7));
     else
-      bs->data[bs->offset / 8] &= ~(1 << (7 - (bs->offset & 7)));
+      bs->wdata[bs->offset / 8] &= ~(1 << (7 - (bs->offset & 7)));
 
     bs->offset++;
   }
index 40dd420d900418db90e61ae315608d36a558b0ae..5aa468bf882c58bca9650b023b30e93811a64658 100644 (file)
 #define BITSTREAM_H_
 
 typedef struct bitstream {
-  uint8_t *data;
+  const uint8_t *rdata;
+  uint8_t *wdata;
   int offset;
   int len;
 } bitstream_t;
 
 void skip_bits(bitstream_t *bs, int num);
 
-void init_bits(bitstream_t *bs, uint8_t *data, int bits);
+void init_rbits(bitstream_t *bs, const uint8_t *data, int bits);
+
+void init_wbits(bitstream_t *bs, uint8_t *data, int bits);
 
 unsigned int read_bits(bitstream_t *gb, int num);
 
index 53c3e5f8b2e75c45a8513f34411c34f642c80e39..3fa77df9be29b7c0c48d040ce974709587a0e5c7 100644 (file)
@@ -145,6 +145,7 @@ mk_build_segment_info(mk_mux_t *mkm)
   ebml_append_string(q, 0x4d80, "HTS Tvheadend Matroska muxer");
   ebml_append_string(q, 0x5741, app);
   ebml_append_uint(q, 0x2ad7b1, MATROSKA_TIMESCALE);
+  printf("Writing total duration %f\n", (float)mkm->totduration);
   if(mkm->totduration)
     ebml_append_float(q, 0x4489, (float)mkm->totduration);
   else
index d986b51267caebb183dd67ae21966c9e92c3f988..55c926c4da389f2a66e24dd5116d97a3057c8c8a 100644 (file)
 /**
  * H.264 parser, nal escaper
  */
-int
-h264_nal_deescape(bitstream_t *bs, uint8_t *data, int size)
+void *
+h264_nal_deescape(bitstream_t *bs, const uint8_t *data, int size)
 {
   int rbsp_size, i;
-  
-  bs->data = malloc(size);
+  uint8_t *d = malloc(size);
+  bs->rdata = d;
 
   /* Escape 0x000003 into 0x0000 */
 
   rbsp_size = 0;
   for(i = 1; i < size; i++) {
     if(i + 2 < size && data[i] == 0 && data[i + 1] == 0 && data[i + 2] == 3) {
-      bs->data[rbsp_size++] = 0;
-      bs->data[rbsp_size++] = 0;
+      d[rbsp_size++] = 0;
+      d[rbsp_size++] = 0;
       i += 2;
     } else {
-      bs->data[rbsp_size++] = data[i];
+      d[rbsp_size++] = data[i];
     }
   }
 
   bs->offset = 0;
   bs->len = rbsp_size * 8;
-  return 0;
+  return d;
 }
 
 
@@ -353,7 +353,7 @@ h264_decode_slice_header(th_stream_t *st, bitstream_t *bs, int *pkttype,
 
   st->st_vbv_delay = -1;
 
-  if(p->sps[sps_id].width && p->sps[sps_id].height && !st->st_buffer_errors)
+  if(p->sps[sps_id].width && p->sps[sps_id].height && !st->st_buf.sb_err)
     parser_set_stream_vsize(st, p->sps[sps_id].width, p->sps[sps_id].height);
   return 0;
 }
index cdbfa35fe3f74f9adde574662c3efc1722a09f46..ac63fbdb36f0476a2de4d28a3a420457a80a2f25 100644 (file)
@@ -21,7 +21,7 @@
 
 #include "bitstream.h"
 
-int h264_nal_deescape(bitstream_t *bs, uint8_t *data, int size);
+void *h264_nal_deescape(bitstream_t *bs, const uint8_t *data, int size);
 
 int h264_decode_seq_parameter_set(th_stream_t *st, bitstream_t *bs);
 
index d04cb68292f3f7e497f217a04ecb0273e13b2a0d..08656a649987f3f3e1a8f4c77a93ff976bd77e07 100644 (file)
@@ -159,15 +159,15 @@ read_stream_mux_config(th_stream_t *st, latm_private_t *latm, bitstream_t *bs)
  * Parse AAC LATM
  */
 th_pkt_t *
-parse_latm_audio_mux_element(th_transport_t *t, th_stream_t *st, uint8_t *data,
-                            int len)
+parse_latm_audio_mux_element(th_transport_t *t, th_stream_t *st, 
+                            const uint8_t *data, int len)
 {
   latm_private_t *latm;
   bitstream_t bs, out;
   int slot_len, tmp, i;
   uint8_t *buf;
 
-  init_bits(&bs, data, len * 8);
+  init_rbits(&bs, data, len * 8);
 
   if((latm = st->st_priv) == NULL)
     latm = st->st_priv = calloc(1, sizeof(latm_private_t));
@@ -202,7 +202,7 @@ parse_latm_audio_mux_element(th_transport_t *t, th_stream_t *st, uint8_t *data,
   pkt->pkt_channels = latm->channel_config;
 
   /* 7 bytes of ADTS header */
-  init_bits(&out, pktbuf_ptr(pkt->pkt_payload), 56);
+  init_wbits(&out, pktbuf_ptr(pkt->pkt_payload), 56);
 
   put_bits(&out, 0xfff, 12); // Sync marker
   put_bits(&out, 0, 1);      // ID 0 = MPEG 4
index 04dec3bab8e67d2eed52fce9f5e0fc5e89ef6403..948168695b605d7fa995c9b6a83a60e3f5870e5a 100644 (file)
@@ -20,6 +20,6 @@
 #define PARSER_LATM_H_
 
 th_pkt_t *parse_latm_audio_mux_element(th_transport_t *t, th_stream_t *st,
-                                      uint8_t *data, int len);
+                                      const uint8_t *data, int len);
 
 #endif /* PARSER_LATM_H_ */
index 31fc12327c60bbfa840513d5051ce4eddc01dca0..6ebf9f91e30579b68d57ef901821937acbb84951 100644 (file)
@@ -120,11 +120,9 @@ void
 parse_mpeg_ts(th_transport_t *t, th_stream_t *st, const uint8_t *data, 
              int len, int start, int err)
 {
-  if(start)
-    st->st_buffer_errors = 0;
-
+  
   if(err)
-    st->st_buffer_errors++;
+    sbuf_err(&st->st_buf);
 
   switch(st->st_type) {
   case SCT_MPEG2VIDEO:
@@ -194,7 +192,7 @@ parse_mpeg_ps(th_transport_t *t, th_stream_t *st, uint8_t *data, int len)
   }
 }
 
-
+#if 0
 /**
  *
  */
@@ -266,7 +264,7 @@ buffer3_cut(th_stream_t *st, int p)
   memmove(st->st_buffer3, st->st_buffer3 + p, st->st_buffer3_ptr);
 }
 
-
+#endif
 
 /**
  * Parse AAC LATM
@@ -281,34 +279,24 @@ parse_aac(th_transport_t *t, th_stream_t *st, const uint8_t *data,
   if(start) {
     /* Payload unit start */
     st->st_parser_state = 1;
-    st->st_buffer_ptr = 0;
     st->st_parser_ptr = 0;
+    sbuf_reset(&st->st_buf);
   }
 
   if(st->st_parser_state == 0)
     return;
 
-  if(st->st_buffer == NULL) {
-    st->st_buffer_size = 4000;
-    st->st_buffer = malloc(st->st_buffer_size);
-  }
-
-  if(st->st_buffer_ptr + len >= st->st_buffer_size) {
-    st->st_buffer_size += len * 4;
-    st->st_buffer = realloc(st->st_buffer, st->st_buffer_size);
-  }
-  
-  memcpy(st->st_buffer + st->st_buffer_ptr, data, len);
-  st->st_buffer_ptr += len;
+  sbuf_append(&st->st_buf, data, len);
 
 
   if(st->st_parser_ptr == 0) {
     int hlen;
 
-    if(st->st_buffer_ptr < 9)
+    if(st->st_buf.sb_ptr < 9)
       return;
 
-    hlen = parse_pes_header(t, st, st->st_buffer + 6, st->st_buffer_ptr - 6);
+    hlen = parse_pes_header(t, st, 
+                           st->st_buf.sb_data + 6, st->st_buf.sb_ptr - 6);
     if(hlen < 0)
       return;
     st->st_parser_ptr += 6 + hlen;
@@ -317,15 +305,15 @@ parse_aac(th_transport_t *t, th_stream_t *st, const uint8_t *data,
 
   p = st->st_parser_ptr;
 
-  while((l = st->st_buffer_ptr - p) > 3) {
-    if(st->st_buffer[p] == 0x56 && (st->st_buffer[p + 1] & 0xe0) == 0xe0) {
-      muxlen = (st->st_buffer[p + 1] & 0x1f) << 8 |
-       st->st_buffer[p + 2];
+  while((l = st->st_buf.sb_ptr - p) > 3) {
+    const uint8_t *d = st->st_buf.sb_data + p;
+    if(d[0] == 0x56 && (d[1] & 0xe0) == 0xe0) {
+      muxlen = (d[1] & 0x1f) << 8 | d[2];
 
       if(l < muxlen + 3)
        break;
 
-      pkt = parse_latm_audio_mux_element(t, st, st->st_buffer + p + 3, muxlen);
+      pkt = parse_latm_audio_mux_element(t, st, d + 3, muxlen);
 
       if(pkt != NULL)
        parser_deliver(t, st, pkt);
@@ -354,8 +342,7 @@ parse_sc(th_transport_t *t, th_stream_t *st, const uint8_t *data, int len,
 {
   uint32_t sc = st->st_startcond;
   int i, r;
-
-  buffer_alloc(st, len);
+  sbuf_alloc(&st->st_buf, len);
 
   for(i = 0; i < len; i++) {
 
@@ -378,20 +365,20 @@ parse_sc(th_transport_t *t, th_stream_t *st, const uint8_t *data, int len,
       continue;
     }
 
-    st->st_buffer[st->st_buffer_ptr++] = data[i];
+    st->st_buf.sb_data[st->st_buf.sb_ptr++] = data[i];
     sc = sc << 8 | data[i];
 
     if((sc & 0xffffff00) != 0x00000100)
       continue;
 
-    r = st->st_buffer_ptr - st->st_startcode_offset - 4;
+    r = st->st_buf.sb_ptr - st->st_startcode_offset - 4;
 
     if(r > 0 && st->st_startcode != 0) {
       r = vp(t, st, r, sc, st->st_startcode_offset);
       if(r == 3)
        continue;
       if(r == 4) {
-       st->st_buffer_ptr -= 4;
+       st->st_buf.sb_ptr -= 4;
        st->st_ssc_intercept = 1;
        st->st_ssc_ptr = 0;
        sc = -1;
@@ -403,27 +390,26 @@ parse_sc(th_transport_t *t, th_stream_t *st, const uint8_t *data, int len,
 
     if(r == 2) {
       // Drop packet
-      st->st_buffer_ptr = st->st_startcode_offset;
+      st->st_buf.sb_ptr = st->st_startcode_offset;
 
-      st->st_buffer[st->st_buffer_ptr++] = sc >> 24;
-      st->st_buffer[st->st_buffer_ptr++] = sc >> 16;
-      st->st_buffer[st->st_buffer_ptr++] = sc >> 8;
-      st->st_buffer[st->st_buffer_ptr++] = sc;
+      st->st_buf.sb_data[st->st_buf.sb_ptr++] = sc >> 24;
+      st->st_buf.sb_data[st->st_buf.sb_ptr++] = sc >> 16;
+      st->st_buf.sb_data[st->st_buf.sb_ptr++] = sc >> 8;
+      st->st_buf.sb_data[st->st_buf.sb_ptr++] = sc;
       st->st_startcode = sc;
 
     } else {
       if(r == 1) {
        /* Reset packet parser upon length error or if parser
           tells us so */
-       st->st_buffer_ptr = 0;
-       st->st_buffer_errors = 0;
-       st->st_buffer[st->st_buffer_ptr++] = sc >> 24;
-       st->st_buffer[st->st_buffer_ptr++] = sc >> 16;
-       st->st_buffer[st->st_buffer_ptr++] = sc >> 8;
-       st->st_buffer[st->st_buffer_ptr++] = sc;
+       sbuf_reset(&st->st_buf);
+       st->st_buf.sb_data[st->st_buf.sb_ptr++] = sc >> 24;
+       st->st_buf.sb_data[st->st_buf.sb_ptr++] = sc >> 16;
+       st->st_buf.sb_data[st->st_buf.sb_ptr++] = sc >> 8;
+       st->st_buf.sb_data[st->st_buf.sb_ptr++] = sc;
       }
       st->st_startcode = sc;
-      st->st_startcode_offset = st->st_buffer_ptr - 4;
+      st->st_startcode_offset = st->st_buf.sb_ptr - 4;
     }
   }
   st->st_startcond = sc;  
@@ -437,7 +423,7 @@ static int
 depacketize(th_transport_t *t, th_stream_t *st, size_t len, 
            uint32_t next_startcode, int sc_offset)
 {
-  const uint8_t *buf = st->st_buffer + sc_offset;
+  const uint8_t *buf = st->st_buf.sb_data + sc_offset;
   uint32_t sc = st->st_startcode;
   int hlen, plen;
 
@@ -463,7 +449,7 @@ depacketize(th_transport_t *t, th_stream_t *st, size_t len,
   buf += hlen;
   len -= hlen;
 
-  buffer3_append(st, buf, len);
+  sbuf_append(&st->st_buf_a, buf, len);
   return 0;
 }
 
@@ -521,8 +507,8 @@ parse_mpa(th_transport_t *t, th_stream_t *st, size_t ilen,
     return i;
 
  again:
-  buf = st->st_buffer3;
-  len = st->st_buffer3_ptr;
+  buf = st->st_buf_a.sb_data;
+  len = st->st_buf_a.sb_ptr;
 
   for(i = 0; i < len - 4; i++) {
     if(mpa_valid_frame(buf + i)) {
@@ -544,7 +530,7 @@ parse_mpa(th_transport_t *t, th_stream_t *st, size_t ilen,
          
          makeapkt(t, st, buf + i, fsize, dts, duration,
                   channels, mpa_sri[(buf[i+2] >> 2) & 3]);
-         buffer3_cut(st, i + fsize);
+         sbuf_cut(&st->st_buf_a, i + fsize);
          goto again;
        }
       }
@@ -634,8 +620,8 @@ parse_ac3(th_transport_t *t, th_stream_t *st, size_t ilen,
     return i;
 
  again:
-  buf = st->st_buffer3;
-  len = st->st_buffer3_ptr;
+  buf = st->st_buf_a.sb_data;
+  len = st->st_buf_a.sb_ptr;
 
   for(i = 0; i < len - 6; i++) {
     const uint8_t *p = buf + i;
@@ -677,7 +663,7 @@ parse_ac3(th_transport_t *t, th_stream_t *st, size_t ilen,
           ac3_valid_frame(p + fsize)) {
 
          bitstream_t bs;
-         init_bits(&bs, (uint8_t *)p + 5, (fsize - 5) * 8);
+         init_rbits(&bs, p + 5, (fsize - 5) * 8);
          
          read_bits(&bs, 5); // bsid
          read_bits(&bs, 3); // bsmod
@@ -694,7 +680,7 @@ parse_ac3(th_transport_t *t, th_stream_t *st, size_t ilen,
          int channels = acmodtab[acmod] + lfeon;
 
          makeapkt(t, st, p, fsize, dts, duration, channels, sri);
-         buffer3_cut(st, i + fsize);
+         sbuf_cut(&st->st_buf_a, i + fsize);
          goto again;
        }
       }
@@ -744,7 +730,7 @@ parse_pes_header(th_transport_t *t, th_stream_t *st,
   } else
     return hlen + 3;
 
-  if(st->st_buffer_errors) {
+  if(st->st_buf.sb_err) {
     st->st_curdts = PTS_UNSET;
     st->st_curpts = PTS_UNSET;
   } else {
@@ -889,7 +875,7 @@ parser_global_data_move(th_stream_t *st, const uint8_t *data, size_t len)
   memcpy(st->st_global_data + st->st_global_data_len, data, len2);
   st->st_global_data_len += len2;
 
-  st->st_buffer_ptr -= len;
+  st->st_buf.sb_ptr -= len;
 }
 
 
@@ -907,14 +893,14 @@ static int
 parse_mpeg2video(th_transport_t *t, th_stream_t *st, size_t len, 
                 uint32_t next_startcode, int sc_offset)
 {
-  uint8_t *buf = st->st_buffer + sc_offset;
+  const uint8_t *buf = st->st_buf.sb_data + sc_offset;
   bitstream_t bs;
   int frametype;
 
   if(next_startcode == 0x1e0)
     return 4;
 
-  init_bits(&bs, buf + 4, (len - 4) * 8);
+  init_rbits(&bs, buf + 4, (len - 4) * 8);
 
   switch(st->st_startcode) {
   case 0x000001e0 ... 0x000001ef:
@@ -944,7 +930,7 @@ parse_mpeg2video(th_transport_t *t, th_stream_t *st, size_t len,
 
   case 0x000001b3:
     /* Sequence start code */
-    if(!st->st_buffer_errors) {
+    if(!st->st_buf.sb_err) {
       if(parse_mpeg2video_seq_start(t, st, &bs))
        return 1;
       parser_global_data_move(st, buf, len);
@@ -957,12 +943,12 @@ parse_mpeg2video(th_transport_t *t, th_stream_t *st, size_t len,
     switch(buf[4] >> 4) {
     case 0x1:
       // Sequence Extension
-      if(!st->st_buffer_errors)
+      if(!st->st_buf.sb_err)
        parser_global_data_move(st, buf, len);
       return 2;
     case 0x2:
       // Sequence Display Extension
-      if(!st->st_buffer_errors)
+      if(!st->st_buf.sb_err)
        parser_global_data_move(st, buf, len);
       return 2;
     }
@@ -986,13 +972,14 @@ parse_mpeg2video(th_transport_t *t, th_stream_t *st, size_t len,
        st->st_global_data_len = 0;
       }
 
-      pkt->pkt_payload = pktbuf_make(st->st_buffer, st->st_buffer_ptr - 4);
+      pkt->pkt_payload = pktbuf_make(st->st_buf.sb_data,
+                                    st->st_buf.sb_ptr - 4);
       pkt->pkt_duration = st->st_frame_duration;
 
       parser_deliver(t, st, pkt);
       st->st_curpkt = NULL;
 
-      st->st_buffer = malloc(st->st_buffer_size);
+      st->st_buf.sb_data = malloc(st->st_buf.sb_size);
       
       /* If we know the frame duration, increase DTS accordingly */
       if(st->st_curdts != PTS_UNSET)
@@ -1006,7 +993,7 @@ parse_mpeg2video(th_transport_t *t, th_stream_t *st, size_t len,
 
   case 0x000001b8:
     // GOP header
-    if(!st->st_buffer_errors)
+    if(!st->st_buf.sb_err)
       parser_global_data_move(st, buf, len);
     return 2;
 
@@ -1029,7 +1016,7 @@ static int
 parse_h264(th_transport_t *t, th_stream_t *st, size_t len, 
           uint32_t next_startcode, int sc_offset)
 {
-  uint8_t *buf = st->st_buffer + sc_offset;
+  const uint8_t *buf = st->st_buf.sb_data + sc_offset;
   uint32_t sc = st->st_startcode;
   int64_t d;
   int l2, pkttype, duration, isfield;
@@ -1051,12 +1038,10 @@ parse_h264(th_transport_t *t, th_stream_t *st, size_t len,
     return 1;
   }
   
-  bs.data = NULL;
-
   if(sc == 0x10c) {
     // Padding
 
-    st->st_buffer_ptr -= len;
+    st->st_buf.sb_ptr -= len;
     ret = 2;
 
   } else {
@@ -1064,18 +1049,20 @@ parse_h264(th_transport_t *t, th_stream_t *st, size_t len,
     switch(sc & 0x1f) {
 
     case 7:
-      if(!st->st_buffer_errors) {
-       h264_nal_deescape(&bs, buf + 3, len - 3);
+      if(!st->st_buf.sb_err) {
+       void *f = h264_nal_deescape(&bs, buf + 3, len - 3);
        h264_decode_seq_parameter_set(st, &bs);
+       free(f);
        parser_global_data_move(st, buf, len);
       }
       ret = 2;
       break;
 
     case 8:
-      if(!st->st_buffer_errors) {
-       h264_nal_deescape(&bs, buf + 3, len - 3);
+      if(!st->st_buf.sb_err) {
+       void *f = h264_nal_deescape(&bs, buf + 3, len - 3);
        h264_decode_pic_parameter_set(st, &bs);
+       free(f);
        parser_global_data_move(st, buf, len);
       }
       ret = 2;
@@ -1087,12 +1074,14 @@ parse_h264(th_transport_t *t, th_stream_t *st, size_t len,
        break;
 
       l2 = len - 3 > 64 ? 64 : len - 3;
-      h264_nal_deescape(&bs, buf + 3, l2); /* we just want the first stuff */
+      void *f = h264_nal_deescape(&bs, buf + 3, l2);
+      /* we just want the first stuff */
 
       if(h264_decode_slice_header(st, &bs, &pkttype, &duration, &isfield)) {
-       free(bs.data);
+       free(f);
        return 1;
       }
+      free(f);
 
       st->st_curpkt = pkt_alloc(NULL, 0, st->st_curpts, st->st_curdts);
       st->st_curpkt->pkt_frametype = pkttype;
@@ -1105,7 +1094,6 @@ parse_h264(th_transport_t *t, th_stream_t *st, size_t len,
       break;
     }
   }
-  free(bs.data);
 
   if(next_startcode >= 0x000001e0 && next_startcode <= 0x000001ef) {
     /* Complete frame */
@@ -1121,11 +1109,12 @@ parse_h264(th_transport_t *t, th_stream_t *st, size_t len,
        st->st_global_data_len = 0;
       }
     
-      pkt->pkt_payload = pktbuf_make(st->st_buffer, st->st_buffer_ptr - 4);
+      pkt->pkt_payload = pktbuf_make(st->st_buf.sb_data,
+                                    st->st_buf.sb_ptr - 4);
       parser_deliver(t, st, pkt);
       
       st->st_curpkt = NULL;
-      st->st_buffer = malloc(st->st_buffer_size);
+      st->st_buf.sb_data = malloc(st->st_buf.sb_size);
 
       st->st_curdts = PTS_UNSET;
       st->st_curpts = PTS_UNSET;
@@ -1145,46 +1134,42 @@ parse_subtitles(th_transport_t *t, th_stream_t *st, const uint8_t *data,
 {
   th_pkt_t *pkt;
   int psize, hlen;
-  uint8_t *buf;
-
+  const uint8_t *buf;
+  const uint8_t *d;
   if(start) {
     /* Payload unit start */
     st->st_parser_state = 1;
-    st->st_buffer_errors = 0;
+    st->st_buf.sb_err = 0;
   }
 
   if(st->st_parser_state == 0)
     return;
 
-  buffer_append(st, data, len);
+  sbuf_append(&st->st_buf, data, len);
 
-  if(st->st_buffer_ptr < 6)
+  if(st->st_buf.sb_ptr < 6)
     return;
-
-  uint32_t startcode =
-    (st->st_buffer[0] << 24) |
-    (st->st_buffer[1] << 16) |
-    (st->st_buffer[2] << 8) |
-    (st->st_buffer[3]);
+  d = st->st_buf.sb_data;
+  uint32_t startcode = (d[0] << 24) | (d[1] << 16) | (d[2] << 8) | d[3];
 
   if(startcode == 0x1be) {
     st->st_parser_state = 0;
     return;
   }
 
-  psize = st->st_buffer[4] << 8 | st->st_buffer[5];
+  psize = d[4] << 8 | d[5];
 
-  if(st->st_buffer_ptr != psize + 6)
+  if(st->st_buf.sb_ptr != psize + 6)
     return;
 
   st->st_parser_state = 0;
 
-  hlen = parse_pes_header(t, st, st->st_buffer + 6, st->st_buffer_ptr - 6);
+  hlen = parse_pes_header(t, st, d + 6, st->st_buf.sb_ptr - 6);
   if(hlen < 0)
     return;
 
   psize -= hlen;
-  buf = st->st_buffer + 6 + hlen;
+  buf = d + 6 + hlen;
   
   if(psize < 2 || buf[0] != 0x20 || buf[1] != 0x00)
     return;
index b4a90e7852910aba1a5e5d0382b8cc376bf57c2f..44fc0f87970931f529518227f67b93f6809aec65 100644 (file)
@@ -92,22 +92,10 @@ stream_clean(th_stream_t *st)
   /* Clear reassembly buffers */
 
   st->st_startcode = 0;
-    
-  free(st->st_buffer);
-  st->st_buffer = NULL;
-  st->st_buffer_size = 0;
-  st->st_buffer_ptr = 0;
-
-  free(st->st_buffer2);
-  st->st_buffer2 = NULL;
-  st->st_buffer2_size = 0;
-  st->st_buffer2_ptr = 0;
-
-  free(st->st_buffer3);
-  st->st_buffer3 = NULL;
-  st->st_buffer3_size = 0;
-  st->st_buffer3_ptr = 0;
-
+  
+  sbuf_free(&st->st_buf);
+  sbuf_free(&st->st_buf_ps);
+  sbuf_free(&st->st_buf_a);
 
   if(st->st_curpkt != NULL) {
     pkt_ref_dec(st->st_curpkt);
index 812b4ff6b5cb0cf0eee60e7df0d81747da51a26b..d01e36bd95bd535b21c2874a41f7489788a3bffb 100644 (file)
@@ -313,6 +313,17 @@ typedef struct streaming_queue {
 } streaming_queue_t;
 
 
+/**
+ * Simple dynamically growing buffer
+ */
+typedef struct sbuf {
+  uint8_t *sb_data;
+  int sb_ptr;
+  int sb_size;
+  int sb_err;
+} sbuf_t;
+
+
 
 /**
  * Descrambler superclass
@@ -401,10 +412,7 @@ typedef struct th_stream {
 
   /* For transport stream packet reassembly */
 
-  uint8_t *st_buffer;
-  int st_buffer_ptr;
-  int st_buffer_size;
-  int st_buffer_errors;   /* Errors accumulated for this packet */
+  sbuf_t st_buf;
 
   uint32_t st_startcond;
   uint32_t st_startcode;
@@ -413,13 +421,8 @@ typedef struct th_stream {
   int st_parser_ptr;
   void *st_priv;          /* Parser private data */
 
-  uint8_t *st_buffer2;
-  int st_buffer2_ptr;
-  int st_buffer2_size;
-
-  uint8_t *st_buffer3;
-  int st_buffer3_ptr;
-  int st_buffer3_size;
+  sbuf_t st_buf_ps;       // program stream reassembly (analogue adapters)
+  sbuf_t st_buf_a;        // Audio packet reassembly
 
   uint8_t *st_global_data;
   int st_global_data_len;
@@ -853,4 +856,16 @@ static inline int64_t ts_rescale(int64_t ts, int tb)
   return (ts * tb ) / 90000LL;
 }
 
+void sbuf_free(sbuf_t *sb);
+
+void sbuf_reset(sbuf_t *sb);
+
+void sbuf_err(sbuf_t *sb);
+
+void sbuf_alloc(sbuf_t *sb, int len);
+
+void sbuf_append(sbuf_t *sb, const uint8_t *data, int len);
+
+void sbuf_cut(sbuf_t *sb, int off);
+
 #endif /* TV_HEAD_H */
index e3975f129b4adb1fd4223eebbafb914f395c2b54..8619554a4f96a1d8e02e7b7bc21cfb25fa123914 100644 (file)
@@ -18,6 +18,7 @@
  */
 
 #include <limits.h>
+#include <string.h>
 #include <assert.h>
 #include "tvhead.h"
 
@@ -224,3 +225,55 @@ put_utf8(char *out, int c)
   *out++ = 0x80 | (0x3f &  c);
   return 6;
 }
+
+
+
+void
+sbuf_free(sbuf_t *sb)
+{
+  free(sb->sb_data);
+  sb->sb_size = sb->sb_ptr = sb->sb_err = 0;
+}
+
+void
+sbuf_reset(sbuf_t *sb)
+{
+  sb->sb_ptr = 0;
+  sb->sb_err = 0;
+}
+
+void
+sbuf_err(sbuf_t *sb)
+{
+  sb->sb_err = 1;
+}
+
+void
+sbuf_alloc(sbuf_t *sb, int len)
+{
+  if(sb->sb_data == NULL) {
+    sb->sb_size = 4000;
+    sb->sb_data = malloc(sb->sb_size);
+  }
+
+  if(sb->sb_ptr + len >= sb->sb_size) {
+    sb->sb_size += len * 4;
+    sb->sb_data = realloc(sb->sb_data, sb->sb_size);
+  }
+}
+
+void
+sbuf_append(sbuf_t *sb, const uint8_t *data, int len)
+{
+  sbuf_alloc(sb, len);
+  memcpy(sb->sb_data + sb->sb_ptr, data, len);
+  sb->sb_ptr += len;
+}
+
+void 
+sbuf_cut(sbuf_t *sb, int off)
+{
+  assert(off <= sb->sb_ptr);
+  sb->sb_ptr = sb->sb_ptr - off;
+  memmove(sb->sb_data, sb->sb_data + off, sb->sb_ptr);
+}
index 0754079e38a7be39345b173710aa919e3d12e1ef..01921f59966de1fd412a9d90f448aef25bf3ad53 100644 (file)
--- a/src/v4l.c
+++ b/src/v4l.c
@@ -87,36 +87,36 @@ v4l_input(v4l_adapter_t *va)
     }
 
     if(va->va_lenlock == 2) {
-      l = st->st_buffer2_size;
-      st->st_buffer2 = pkt = realloc(st->st_buffer2, l);
+      l = st->st_buf_ps.sb_size;
+      st->st_buf_ps.sb_data = pkt = realloc(st->st_buf_ps.sb_data, l);
       
-      r = l - st->st_buffer2_ptr;
+      r = l - st->st_buf_ps.sb_ptr;
       if(r > len)
        r = len;
-      memcpy(pkt + st->st_buffer2_ptr, ptr, r);
+      memcpy(pkt + st->st_buf_ps.sb_ptr, ptr, r);
       
       ptr += r;
       len -= r;
 
-      st->st_buffer2_ptr += r;
-      if(st->st_buffer2_ptr == l) {
+      st->st_buf_ps.sb_ptr += r;
+      if(st->st_buf_ps.sb_ptr == l) {
 
        transport_set_streaming_status_flags(t, TSS_MUX_PACKETS);
 
        parse_mpeg_ps(t, st, pkt + 6, l - 6);
 
-       st->st_buffer2_size = 0;
+       st->st_buf_ps.sb_size = 0;
        va->va_startcode = 0;
       } else {
-       assert(st->st_buffer2_ptr < l);
+       assert(st->st_buf_ps.sb_ptr < l);
       }
       
     } else {
-      st->st_buffer2_size = st->st_buffer2_size << 8 | *ptr;
+      st->st_buf_ps.sb_size = st->st_buf_ps.sb_size << 8 | *ptr;
       va->va_lenlock++;
       if(va->va_lenlock == 2) {
-       st->st_buffer2_size += 6;
-       st->st_buffer2_ptr = 6;
+       st->st_buf_ps.sb_size += 6;
+       st->st_buf_ps.sb_ptr = 6;
       }
       ptr++; len--;
     }