/** * Continue processing of transport stream packets */ static void ts_recv_packet0 (mpegts_service_t *t, elementary_stream_t *st, const uint8_t *tsb) { int off, pusi, cc, error; service_set_streaming_status_flags((service_t*)t, TSS_MUX_PACKETS); if(streaming_pad_probe_type(&t->s_streaming_pad, SMT_MPEGTS)) ts_remux(t, tsb); if (!st) return; error = !!(tsb[1] & 0x80); pusi = !!(tsb[1] & 0x40); /* Check CC */ if(tsb[3] & 0x10) { cc = tsb[3] & 0xf; if(st->es_cc != -1 && cc != st->es_cc) { /* Let the hardware to stabilize and don't flood the log */ if (t->s_start_time + 1 < dispatch_clock && tvhlog_limit(&st->es_cc_log, 10)) tvhwarn("TS", "%s Continuity counter error (total %zi)", service_component_nicename(st), st->es_cc_log.count); avgstat_add(&t->s_cc_errors, 1, dispatch_clock); avgstat_add(&st->es_cc_errors, 1, dispatch_clock); // Mark as error if this is not the first packet of a payload if(!pusi) error |= 0x2; } st->es_cc = (cc + 1) & 0xf; } off = tsb[3] & 0x20 ? tsb[4] + 5 : 4; switch(st->es_type) { case SCT_CA: break; default: if(!streaming_pad_probe_type(&t->s_streaming_pad, SMT_PACKET)) break; if(st->es_type == SCT_TELETEXT) teletext_input(t, st, tsb); if(off > 188) break; if(t->s_status == SERVICE_RUNNING) parse_mpeg_ts((service_t*)t, st, tsb + off, 188 - off, pusi, error); break; } }
static void tvhcsa_csa_cbc_descramble ( 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_fill_size); #if ENABLE_DVBCSA uint8_t *pkt; int_fast8_t ev_od; int_fast16_t len; int_fast16_t offset; 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 if((pkt[3] & 0x80) == 0) // clear or reserved (0x40) break; ev_od = pkt[3] & 0x40; pkt[3] &= 0x3f; // consider it decrypted now if(pkt[3] & 0x20) { // incomplete packet if(!(pkt[3] & 0x10)) // no payload - but why scrambled??? break; offset = 4 + pkt[4] + 1; if (offset >= 188){ // invalid offset (residue handling?) if (tvhlog_limit(&csa->tvhcsa_loglimit, 30)) tvhtrace(LS_CSA, "invalid payload offset in packet for service \"%s\" (offset=%d pkt[3]=0x%02x pkt[4]=0x%02x)", ((mpegts_service_t *)s)->s_dvb_svcname, (int)offset, pkt[3], pkt[4]); break; // no more processing } len = 188 - offset; } else { len = 184; offset = 4; } 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++; if(csa->csa_fill_even == csa->csa_cluster_size) tvhcsa_csa_cbc_flush(csa, s); } 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++; if(csa->csa_fill_odd == csa->csa_cluster_size) tvhcsa_csa_cbc_flush(csa, s); } } while(0); if(csa->csa_fill == csa->csa_fill_size ) tvhcsa_csa_cbc_flush(csa, s); } #else #error "Unknown CSA descrambler" #endif }