From a1785d95c28c81c5443695100b6016bf68da3025 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=96man?= Date: Mon, 28 Jan 2008 21:53:49 +0000 Subject: [PATCH] Implement the TS packet demuxer as a startcode parser instead of relying on the payload-unit-start-indicator bit. This delivers packets faster thru the system for sources that only sets the payload-unit-start-indicator bits on I-frames --- pes.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ pes.h | 3 +++ tsdemux.c | 57 +--------------------------------------------------- 3 files changed, 64 insertions(+), 56 deletions(-) diff --git a/pes.c b/pes.c index dace71ce..4a487655 100644 --- a/pes.c +++ b/pes.c @@ -62,6 +62,66 @@ static void pes_compute_pts(th_transport_t *t, th_stream_t *st, th_pkt_t *pkt); _pts; \ }) +/** + * pes_reassembly() + * + * + */ + +void +pes_reassembly(th_transport_t *t, th_stream_t *st, uint8_t *data, + int len, int start, int err) +{ + uint32_t sc; + int i; + + if(LIST_FIRST(&t->tht_muxers) == NULL) + return; /* No muxers will take packet, so drop here */ + + sc = st->st_startcond; + + 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); + } + + for(i = 0; i < len; i++) { + st->st_buffer[st->st_buffer_ptr++] = data[i]; + sc = sc << 8 | data[i]; + + if((sc & 0xffffff00) == 0x00000100) { + /* Startcode condition */ + switch(sc) { + case 0x000001e0 ... 0x000001ef: + case 0x000001c0 ... 0x000001cf: + case 0x000001bd: + st->st_buffer_ptr -= 4; + if(st->st_buffer_ptr < 0) { + /* Fake startcode, can be seen during stream start */ + st->st_buffer_ptr = 0; + break; + } + + if(st->st_startcode != 0) { + /* It would be nice to embed much of what's done in + * pes_packet_input() here to avoid a bunch of memcpy()s + */ + pes_packet_input(t, st, st->st_buffer + 2, st->st_buffer_ptr - 2); + st->st_buffer_ptr = 0; + } + st->st_startcode = sc; + break; + } + } + } + st->st_startcond = sc; +} + diff --git a/pes.h b/pes.h index ff95cf0f..8a9cbce5 100644 --- a/pes.h +++ b/pes.h @@ -24,4 +24,7 @@ int pes_packet_input(th_transport_t *th, th_stream_t *st, uint8_t *data, void pes_compute_duration(th_transport_t *t, th_stream_t *st, th_pkt_t *pkt); +void pes_reassembly(th_transport_t *t, th_stream_t *st, uint8_t *data, + int len, int start, int err); + #endif /* PES_H */ diff --git a/tsdemux.c b/tsdemux.c index 2f20c519..672f50e8 100644 --- a/tsdemux.c +++ b/tsdemux.c @@ -49,61 +49,6 @@ #include "buffer.h" #include "tsdemux.h" -static int -ts_reassembly_pes(th_transport_t *t, th_stream_t *st, uint8_t *data, int len) -{ - int l2; - - if(len < 9) - return -1; - - if(data[0] != 0 || data[1] != 0 || data[2] != 1) - return -1; - - l2 = (data[4] << 8) | data[5]; - - len -= 6; - data += 6; - - return pes_packet_input(t, st, data, len); -} - -/* - * TS packet reassembly - */ -static void -ts_reassembly(th_transport_t *t, th_stream_t *st, uint8_t *data, int len, - int pusi, int err) -{ - if(pusi) { - if(ts_reassembly_pes(t, st, st->st_buffer, st->st_buffer_ptr) == 0) - st->st_buffer = NULL; /* Memory was consumed by pes_packet_input() */ - - st->st_buffer_ptr = 0; - st->st_buffer_errors = 0; - - if(st->st_buffer == NULL) { - - if(st->st_buffer_size < 1000) - st->st_buffer_size = 4000; - - st->st_buffer = malloc(st->st_buffer_size); - } - } - - if(st->st_buffer == NULL) - return; - - st->st_buffer_errors += err; - - 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; -} /** * Code for dealing with a complete section @@ -216,7 +161,7 @@ ts_recv_packet(th_transport_t *t, int pid, uint8_t *tsb, int dodescramble) if(afl > 188) break; - ts_reassembly(t, st, tsb + afl, 188 - afl, pusi, err); + pes_reassembly(t, st, tsb + afl, 188 - afl, pusi, err); break; } }