]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
Add support for deliberate corruption of generated MPEG TS streams
authorAndreas Öman <andreas@lonelycoder.com>
Tue, 5 Feb 2008 11:27:57 +0000 (11:27 +0000)
committerAndreas Öman <andreas@lonelycoder.com>
Tue, 5 Feb 2008 11:27:57 +0000 (11:27 +0000)
htsclient.c
iptv_output.c
rtsp.c
tsmux.c
tsmux.h
tvhead.h

index 1f270037800de1149ccdde62185f273463335a71..f4985de06f31d33c8dff7904d9cb39b7e335ad92 100644 (file)
@@ -410,7 +410,7 @@ client_subscription_callback(struct th_subscription *s,
   case TRANSPORT_AVAILABLE:
     assert(c->c_muxer == NULL);
     c->c_muxer = ts_muxer_init(s, client_output_ts, c,
-                              TS_HTSCLIENT | TS_SEEK);
+                              TS_HTSCLIENT | TS_SEEK, 0);
     ts_muxer_play(c->c_muxer, 0);
     break;
 
index 0bcba4b51f61e02d41b4bbe4b0350ffcd193ee4e..4c1621ae7b54d17cbd6a95bf24996a188700f78b 100644 (file)
@@ -44,7 +44,7 @@ typedef struct output_multicast {
   int om_fd;
   struct sockaddr_in om_dst;
 
-  int om_intra_drop_rate;
+  int om_corruption;
 
   int om_inter_drop_rate;
   int om_inter_drop_cnt;
@@ -101,8 +101,8 @@ iptv_subscription_callback(struct th_subscription *s,
   switch(event) {
   case TRANSPORT_AVAILABLE:
     assert(om->om_muxer == NULL);
-    om->om_muxer = ts_muxer_init(s, iptv_output_ts, om, TS_SEEK);
-    //    om->om_muxer->tm_drop_rate = om->om_intra_drop_rate;
+    om->om_muxer = ts_muxer_init(s, iptv_output_ts, om, TS_SEEK
+                                om->om_corruption);
     ts_muxer_play(om->om_muxer, 0);
     break;
 
@@ -166,8 +166,8 @@ output_multicast_load(struct config_head *head)
     ttl = atoi(s);
 
 
-  if((s = config_get_str_sub(head, "intra-drop-rate", NULL)) != NULL)
-    om->om_intra_drop_rate = atoi(s);
+  if((s = config_get_str_sub(head, "corruption-interval", NULL)) != NULL)
+    om->om_corruption = atoi(s);
 
   if((s = config_get_str_sub(head, "inter-drop-rate", NULL)) != NULL)
     om->om_inter_drop_rate = atoi(s);
diff --git a/rtsp.c b/rtsp.c
index d08adc811d32b24474211066505a59e69e6e8df9..e8298521cead8d80655049956e663d765f7cc5a6 100644 (file)
--- a/rtsp.c
+++ b/rtsp.c
@@ -124,7 +124,7 @@ rtsp_subscription_callback(struct th_subscription *s,
   case TRANSPORT_AVAILABLE:
     assert(rs->rs_muxer == NULL);
     rs->rs_muxer = ts_muxer_init(s, rtp_output_ts, &rs->rs_rtp_streamer, 
-                                TS_SEEK);
+                                TS_SEEK, 0);
     break;
 
   case TRANSPORT_UNAVAILABLE:
diff --git a/tsmux.c b/tsmux.c
index 1780e957353571029bdf07798f5ff939e8b7ec00..d59ca83287503b4a9faef88f1226deb0ebb80f34 100644 (file)
--- a/tsmux.c
+++ b/tsmux.c
@@ -366,7 +366,7 @@ lookahead_dequeue(ts_muxer_t *ts, th_muxstream_t *tms)
   
   if(tms->tms_mux_offset == AV_NOPTS_VALUE) {
     if(tms->tms_stream->st_vbv_delay == -1)
-      tms->tms_mux_offset = tdur + pkt->pkt_duration;
+      tms->tms_mux_offset = tdur - pkt->pkt_duration;
     else
       tms->tms_mux_offset = tms->tms_stream->st_vbv_delay;
   }
@@ -532,15 +532,31 @@ lookahead_dequeue(ts_muxer_t *ts, th_muxstream_t *tms)
        *tsb++ = u16 >> 8;
        *tsb++ = u16;
       }
-    
+
       memcpy(tsb, pkt->pkt_payload + off, tsrem);
+
+      if(tms->tms_corruption_interval != 0) {
+       /* Only corruption payload, never the header */
+       if(tms->tms_corruption_last + tms->tms_corruption_interval < pcr &&
+          off != 0 && pkt->pkt_frametype == PKT_I_FRAME) {
+         tms->tms_corruption_counter = 50;
+         tms->tms_corruption_last = pcr;
+       }
+
+       if(tms->tms_corruption_counter) {
+         tms->tms_cc++;
+         tms->tms_corruption_counter--;
+       }
+      }
+    
       tm->tm_contentsize = tsrem;
       
       tmf_enq(&tms->tms_delivery_fifo, tm);
 
       toff += tsrem;
       off += tsrem;
-    }
+
+     }
 
     tms->tms_lookahead_depth -= pkt->pkt_payloadlen;
     tms->tms_lookahead_packets--;
@@ -587,7 +603,7 @@ ts_mux_packet_input(void *opaque, th_muxstream_t *tms, th_pkt_t *pkt)
  */
 ts_muxer_t *
 ts_muxer_init(th_subscription_t *s, ts_mux_output_t *output,
-             void *opaque, int flags)
+             void *opaque, int flags, int corruption)
 {
   ts_muxer_t *ts = calloc(1, sizeof(ts_muxer_t));
   int dopcr;
@@ -610,6 +626,7 @@ ts_muxer_init(th_subscription_t *s, ts_mux_output_t *output,
   ts->ts_pcr_start = AV_NOPTS_VALUE;
   ts->ts_pcr_ref   = AV_NOPTS_VALUE;
   ts->ts_pcr_last  = INT64_MIN;
+  
 
   /* Do TS MUX specific init per stream */
 
@@ -619,6 +636,7 @@ ts_muxer_init(th_subscription_t *s, ts_mux_output_t *output,
     dopcr = 0;
     switch(st->st_type) {
     case HTSTV_MPEG2VIDEO:
+      tms->tms_corruption_interval = (int64_t)corruption * 1000000LL;
       tms->tms_sc = 0x1e0;
       dopcr = 1;
       break;
diff --git a/tsmux.h b/tsmux.h
index 6d31f1b16a32e5b456af4568f71a48d731948f0f..0459d77d7032ec08c922d1e363edf513a7db4eda 100644 (file)
--- a/tsmux.h
+++ b/tsmux.h
@@ -45,14 +45,13 @@ typedef struct ts_muxer {
   int64_t ts_pcr_start;
   int64_t ts_pcr_ref;  /* System clock when PCR was/is/will be 0 */
   int64_t ts_pcr_last;
-
 } ts_muxer_t;
 
 
 
 
 ts_muxer_t *ts_muxer_init(th_subscription_t *s, ts_mux_output_t *output,
-                         void *opaque, int flags);
+                         void *opaque, int flags, int corruption);
 
 void ts_muxer_deinit(ts_muxer_t *ts, th_subscription_t *s);
 
index c388df0e20e5d13933bdb7a817a5fafb7bfbb306..3cfd0e994ab5e03f4fa82419f36e2c24995950cc 100644 (file)
--- a/tvhead.h
+++ b/tvhead.h
@@ -601,7 +601,11 @@ typedef struct th_muxstream {
 
   int tms_sc; /* start code */
   int tms_cc;
+
+  int64_t tms_corruption_interval;
+  int64_t tms_corruption_last;
+  int tms_corruption_counter;
+
   /* Memebers used when running with ffmpeg */
   
   struct AVStream *tms_avstream;