Beispiel #1
0
/**
 * 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;
  }
}
Beispiel #2
0
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
}