Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
mpegts: optimize the data patch (join MPEG-TS packets for processing)
  • Loading branch information
perexg committed Mar 17, 2015
1 parent c4adde6 commit a698e08
Show file tree
Hide file tree
Showing 11 changed files with 318 additions and 232 deletions.
2 changes: 1 addition & 1 deletion src/descrambler.h
Expand Up @@ -167,7 +167,7 @@ void descrambler_keys ( th_descrambler_t *t, int type,
const uint8_t *even, const uint8_t *odd );
int descrambler_descramble ( struct service *t,
struct elementary_stream *st,
const uint8_t *tsb );
const uint8_t *tsb, int len );
int descrambler_open_pid ( struct mpegts_mux *mux, void *opaque, int pid,
descrambler_section_callback_t callback,
struct service *service );
Expand Down
28 changes: 15 additions & 13 deletions src/descrambler/descrambler.c
Expand Up @@ -367,26 +367,28 @@ ecm_reset( service_t *t, th_descrambler_runtime_t *dr )
int
descrambler_descramble ( service_t *t,
elementary_stream_t *st,
const uint8_t *tsb )
const uint8_t *tsb,
int len )
{
th_descrambler_t *td;
th_descrambler_runtime_t *dr = t->s_descramble;
int count, failed, resolved, off, size, flush_data = 0;
uint8_t *tsb2, ki;
int count, failed, resolved, off, len2, len3, flush_data = 0;
const uint8_t *tsb2;
uint8_t ki;

lock_assert(&t->s_stream_mutex);

if (dr == NULL) {
if ((tsb[3] & 0x80) == 0) {
ts_recv_packet2((mpegts_service_t *)t, tsb);
ts_recv_packet2((mpegts_service_t *)t, tsb, len);
return 1;
}
return -1;
}

if (dr->dr_csa.csa_type == DESCRAMBLER_NONE && dr->dr_buf.sb_ptr == 0)
if ((tsb[3] & 0x80) == 0) {
ts_recv_packet2((mpegts_service_t *)t, tsb);
ts_recv_packet2((mpegts_service_t *)t, tsb, len);
return 1;
}

Expand Down Expand Up @@ -414,12 +416,11 @@ descrambler_descramble ( service_t *t,

/* process the queued TS packets */
if (dr->dr_buf.sb_ptr > 0) {
for (off = 0, size = dr->dr_buf.sb_ptr; off < size; off += 188) {
tsb2 = dr->dr_buf.sb_data + off;
for (tsb2 = tsb, len2 = dr->dr_buf.sb_ptr; len2 > 0; tsb2 += len3, len2 -= len3) {
ki = tsb2[3];
if ((ki & 0x80) != 0x00) {
if (key_valid(dr, ki) == 0) {
sbuf_cut(&dr->dr_buf, off);
sbuf_cut(&dr->dr_buf, tsb2 - tsb);
flush_data = 1;
goto next;
}
Expand All @@ -429,18 +430,19 @@ descrambler_descramble ( service_t *t,
(ki & 0x40) ? "odd" : "even",
((mpegts_service_t *)t)->s_dvb_svcname);
if (key_late(dr, ki)) {
sbuf_cut(&dr->dr_buf, off);
if (ecm_reset(t, dr)) {
sbuf_cut(&dr->dr_buf, tsb2 - tsb);
flush_data = 1;
goto next;
}
}
key_update(dr, ki);
}
}
dr->dr_csa.csa_descramble(&dr->dr_csa, (mpegts_service_t *)t, tsb2);
len3 = mpegts_word_count(tsb2, len2, 0xFF0000C0);
dr->dr_csa.csa_descramble(&dr->dr_csa, (mpegts_service_t *)t, tsb2, len3);
}
if (off > 0)
if (len2 == 0)
service_reset_streaming_status_flags(t, TSS_NO_ACCESS);
sbuf_free(&dr->dr_buf);
}
Expand Down Expand Up @@ -473,7 +475,7 @@ descrambler_descramble ( service_t *t,
key_update(dr, ki);
}
}
dr->dr_csa.csa_descramble(&dr->dr_csa, (mpegts_service_t *)t, tsb);
dr->dr_csa.csa_descramble(&dr->dr_csa, (mpegts_service_t *)t, tsb, len);
service_reset_streaming_status_flags(t, TSS_NO_ACCESS);
return 1;
}
Expand Down Expand Up @@ -520,7 +522,7 @@ descrambler_descramble ( service_t *t,
((mpegts_service_t *)t)->s_dvb_svcname);
}
}
sbuf_append(&dr->dr_buf, tsb, 188);
sbuf_append(&dr->dr_buf, tsb, len);
service_set_streaming_status_flags(t, TSS_NO_ACCESS);
}
} else {
Expand Down
164 changes: 78 additions & 86 deletions src/descrambler/tvhcsa.c
Expand Up @@ -33,10 +33,13 @@ tvhcsa_aes_flush

static void
tvhcsa_aes_descramble
( tvhcsa_t *csa, struct mpegts_service *s, const uint8_t *tsb )
( tvhcsa_t *csa, struct mpegts_service *s, const uint8_t *tsb, int len )
{
aes_decrypt_packet(csa->csa_aes_keys, (unsigned char *)tsb);
ts_recv_packet2(s, tsb);
const uint8_t *tsb2, *end2;

for (tsb2 = tsb, end2 = tsb + len; tsb2 < end2; tsb2 += 188)
aes_decrypt_packet(csa->csa_aes_keys, (unsigned char *)tsb2);
ts_recv_packet2(s, tsb, len);
}

static void
Expand All @@ -45,9 +48,6 @@ tvhcsa_des_flush
{
#if ENABLE_DVBCSA

int i;
const uint8_t *t0;

if(csa->csa_fill_even) {
csa->csa_tsbbatch_even[csa->csa_fill_even].data = NULL;
dvbcsa_bs_decrypt(csa->csa_key_even, csa->csa_tsbbatch_even, 184);
Expand All @@ -59,54 +59,42 @@ tvhcsa_des_flush
csa->csa_fill_odd = 0;
}

t0 = csa->csa_tsbcluster;
ts_recv_packet2(s, csa->csa_tsbcluster, csa->csa_fill * 188);

for(i = 0; i < csa->csa_fill; i++) {
ts_recv_packet2(s, t0);
t0 += 188;
}
csa->csa_fill = 0;

#else

int r;
int r, l;
unsigned char *vec[3];

while(1) {
vec[0] = csa->csa_tsbcluster;
vec[1] = csa->csa_tsbcluster + csa->csa_fill * 188;
vec[2] = NULL;

vec[0] = csa->csa_tsbcluster;
vec[1] = csa->csa_tsbcluster + csa->csa_fill * 188;
vec[2] = NULL;
r = decrypt_packets(csa->csa_keys, vec);
if(r > 0) {
ts_recv_packet2(s, csa->csa_tsbcluster, r * 188);

r = decrypt_packets(csa->csa_keys, vec);
if(r > 0) {
int i;
const uint8_t *t0 = csa->csa_tsbcluster;
l = csa->csa_fill - r;
assert(l >= 0);

for(i = 0; i < r; i++) {
ts_recv_packet2(s, t0);
t0 += 188;
}

r = csa->csa_fill - r;
assert(r >= 0);

if(r > 0)
memmove(csa->csa_tsbcluster, t0, r * 188);
csa->csa_fill = r;
} else {
csa->csa_fill = 0;
}
break;
if(l > 0)
memmove(csa->csa_tsbcluster, csa->csa_tsbcluster + r * 188, l * 188);
csa->csa_fill = l;
} else {
csa->csa_fill = 0;
}

#endif
}

static void
tvhcsa_des_descramble
( tvhcsa_t *csa, struct mpegts_service *s, const uint8_t *tsb )
( tvhcsa_t *csa, struct mpegts_service *s, const uint8_t *tsb, int tsb_len )
{
const uint8_t *tsb_end = tsb + tsb_len;

assert(csa->csa_fill >= 0 && csa->csa_fill < csa->csa_cluster_size);

#if ENABLE_DVBCSA
Expand All @@ -117,61 +105,65 @@ tvhcsa_des_descramble
int offset;
int n;

pkt = csa->csa_tsbcluster + csa->csa_fill * 188;
memcpy(pkt, tsb, 188);
csa->csa_fill++;

do { // handle this packet
xc0 = pkt[3] & 0xc0;
if(xc0 == 0x00) { // clear
break;
}
if(xc0 == 0x40) { // reserved
break;
}
if(xc0 == 0x80 || xc0 == 0xc0) { // encrypted
ev_od = (xc0 & 0x40) >> 6; // 0 even, 1 odd
pkt[3] &= 0x3f; // consider it decrypted now
if(pkt[3] & 0x20) { // incomplete packet
offset = 4 + pkt[4] + 1;
len = 188 - offset;
n = len >> 3;
// FIXME: //residue = len - (n << 3);
if(n == 0) { // decrypted==encrypted!
break; // this doesn't need more processing
}
} else {
len = 184;
offset = 4;
// FIXME: //n = 23;
// FIXME: //residue = 0;
}
if(ev_od == 0) {
csa->csa_tsbbatch_even[csa->csa_fill_even].data = pkt + offset;
csa->csa_tsbbatch_even[csa->csa_fill_even].len = len;
csa->csa_fill_even++;
} else {
csa->csa_tsbbatch_odd[csa->csa_fill_odd].data = pkt + offset;
csa->csa_tsbbatch_odd[csa->csa_fill_odd].len = len;
csa->csa_fill_odd++;
}
}
} while(0);

if(csa->csa_fill != csa->csa_cluster_size)
return;

tvhcsa_des_flush(csa, s);
for ( ; tsb < tsb_end; tsb += 188) {

pkt = csa->csa_tsbcluster + csa->csa_fill * 188;
memcpy(pkt, tsb, 188);
csa->csa_fill++;

do { // handle this packet
xc0 = pkt[3] & 0xc0;
if(xc0 == 0x00) { // clear
break;
}
if(xc0 == 0x40) { // reserved
break;
}
if(xc0 == 0x80 || xc0 == 0xc0) { // encrypted
ev_od = (xc0 & 0x40) >> 6; // 0 even, 1 odd
pkt[3] &= 0x3f; // consider it decrypted now
if(pkt[3] & 0x20) { // incomplete packet
offset = 4 + pkt[4] + 1;
len = 188 - offset;
n = len >> 3;
// FIXME: //residue = len - (n << 3);
if(n == 0) { // decrypted==encrypted!
break; // this doesn't need more processing
}
} else {
len = 184;
offset = 4;
// FIXME: //n = 23;
// FIXME: //residue = 0;
}
if(ev_od == 0) {
csa->csa_tsbbatch_even[csa->csa_fill_even].data = pkt + offset;
csa->csa_tsbbatch_even[csa->csa_fill_even].len = len;
csa->csa_fill_even++;
} else {
csa->csa_tsbbatch_odd[csa->csa_fill_odd].data = pkt + offset;
csa->csa_tsbbatch_odd[csa->csa_fill_odd].len = len;
csa->csa_fill_odd++;
}
}
} while(0);

if(csa->csa_fill == csa->csa_cluster_size)
tvhcsa_des_flush(csa, s);

}

#else

memcpy(csa->csa_tsbcluster + csa->csa_fill * 188, tsb, 188);
csa->csa_fill++;
for ( ; tsb < tsb_end; tsb += 188 ) {

if(csa->csa_fill != csa->csa_cluster_size)
return;
memcpy(csa->csa_tsbcluster + csa->csa_fill * 188, tsb, 188);
csa->csa_fill++;

tvhcsa_des_flush(csa, s);
if(csa->csa_fill == csa->csa_cluster_size)
tvhcsa_des_flush(csa, s);

}

#endif
}
Expand Down
3 changes: 2 additions & 1 deletion src/descrambler/tvhcsa.h
Expand Up @@ -41,7 +41,8 @@ typedef struct tvhcsa
int csa_type; /*< see DESCRAMBLER_* defines */
int csa_keylen;
void (*csa_descramble)
( struct tvhcsa *csa, struct mpegts_service *s, const uint8_t *tsb );
( struct tvhcsa *csa, struct mpegts_service *s,
const uint8_t *tsb, int len );
void (*csa_flush)
( struct tvhcsa *csa, struct mpegts_service *s );

Expand Down
3 changes: 2 additions & 1 deletion src/input/mpegts.h
Expand Up @@ -262,8 +262,9 @@ struct mpegts_table

struct mpegts_table_feed {
TAILQ_ENTRY(mpegts_table_feed) mtf_link;
uint8_t mtf_tsb[188];
int mtf_len;
mpegts_mux_t *mtf_mux;
uint8_t mtf_tsb[0];
};

/*
Expand Down

0 comments on commit a698e08

Please sign in to comment.