]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
mpegts parsers: cleanup the error forwarding
authorJaroslav Kysela <perex@perex.cz>
Sat, 31 Jan 2015 16:35:35 +0000 (17:35 +0100)
committerJaroslav Kysela <perex@perex.cz>
Sat, 31 Jan 2015 16:35:35 +0000 (17:35 +0100)
src/dvr/dvr_rec.c
src/parsers/parsers.c
src/subscriptions.c
src/tvheadend.h

index bd1ac54211743485b77104602c3bfb5a5f2a38c1..92e120da0d438d44b62380598ebc23961bfca778 100644 (file)
@@ -504,7 +504,7 @@ dvr_thread(void *aux)
       if (sm->sm_type == SMT_PACKET) {
         pb = ((th_pkt_t*)sm->sm_data)->pkt_payload;
         if (((th_pkt_t*)sm->sm_data)->pkt_err) {
-          de->de_data_errors++;
+          de->de_data_errors += ((th_pkt_t*)sm->sm_data)->pkt_err;
           idnode_notify_simple(&de->de_id);
         }
       }
index 6c75f35e45a61b3e21192c924122d97382699e0d..4ef46dd1aa133c589c7864ef7ef48d06c407bcb3 100644 (file)
@@ -120,8 +120,9 @@ static int parse_eac3(service_t *t, elementary_stream_t *st, size_t len,
 static int parse_mp4a(service_t *t, elementary_stream_t *st, size_t ilen,
                       uint32_t next_startcode, int sc_offset);
 
-static void parser_deliver(service_t *t, elementary_stream_t *st, th_pkt_t *pkt,
-                           int errors);
+static void parser_deliver(service_t *t, elementary_stream_t *st, th_pkt_t *pkt);
+
+static void parser_deliver_error(service_t *t, elementary_stream_t *st);
 
 static int parse_pes_header(service_t *t, elementary_stream_t *st,
                             const uint8_t *buf, size_t len);
@@ -135,7 +136,7 @@ parse_mpeg_ts(service_t *t, elementary_stream_t *st, const uint8_t *data,
 {
   
   if(err && (err != 2 || !start))
-    sbuf_err(&st->es_buf);
+    sbuf_err(&st->es_buf, 1);
 
   switch(st->es_type) {
   case SCT_MPEG2VIDEO:
@@ -179,7 +180,6 @@ parse_mpeg_ts(service_t *t, elementary_stream_t *st, const uint8_t *data,
   }
 }
 
-
 /**
  * Parse program stream, as from V4L2, etc.
  *
@@ -232,6 +232,7 @@ parse_aac(service_t *t, elementary_stream_t *st, const uint8_t *data,
     /* Payload unit start */
     st->es_parser_state = 1;
     st->es_parser_ptr = 0;
+    parser_deliver_error(t, st);
     sbuf_reset(&st->es_buf, 4000);
   }
 
@@ -266,8 +267,11 @@ parse_aac(service_t *t, elementary_stream_t *st, const uint8_t *data,
 
       pkt = parse_latm_audio_mux_element(t, st, d + 3, muxlen);
 
-      if(pkt != NULL)
-        parser_deliver(t, st, pkt, st->es_buf.sb_err);
+      if(pkt != NULL) {
+        pkt->pkt_err = st->es_buf.sb_err;
+        parser_deliver(t, st, pkt);
+        st->es_buf.sb_err = 0;
+      }
 
       p += muxlen + 3;
     /* ADTS */
@@ -290,6 +294,7 @@ parse_aac(service_t *t, elementary_stream_t *st, const uint8_t *data,
       p++;
     }
   }
+
   st->es_parser_ptr = p;
 }
 
@@ -381,6 +386,7 @@ parse_sc(service_t *t, elementary_stream_t *st, const uint8_t *data, int len,
       if(r == 1) {
         /* Reset packet parser upon length error or if parser
            tells us so */
+        parser_deliver_error(t, st);
         sbuf_reset_and_alloc(&st->es_buf, 256);
         st->es_buf.sb_data[st->es_buf.sb_ptr++] = sc >> 24;
         st->es_buf.sb_data[st->es_buf.sb_ptr++] = sc >> 16;
@@ -444,15 +450,15 @@ makeapkt(service_t *t, elementary_stream_t *st, const void *buf,
          int len, int64_t dts, int duration, int channels, int sri,
          int errors)
 {
-
   th_pkt_t *pkt = pkt_alloc(buf, len, dts, dts);
 
   pkt->pkt_commercial = t->s_tt_commercial_advice;
   pkt->pkt_duration = duration;
   pkt->pkt_channels = channels;
   pkt->pkt_sri = sri;
+  pkt->pkt_err = errors;
 
-  parser_deliver(t, st, pkt, errors);
+  parser_deliver(t, st, pkt);
 
   st->es_curdts = PTS_UNSET;
   st->es_nextdts = dts + duration;
@@ -1134,6 +1140,10 @@ parse_mpeg2video(service_t *t, elementary_stream_t *st, size_t len,
         st->es_global_data_len = 0;
       }
 
+      if (st->es_buf.sb_err) {
+        pkt->pkt_err = 1;
+        st->es_buf.sb_err = 0;
+      }
       if (metalen) {
         pkt->pkt_payload = pktbuf_alloc(NULL, metalen + st->es_buf.sb_ptr - 4);
         memcpy(pktbuf_ptr(pkt->pkt_payload), pktbuf_ptr(pkt->pkt_meta), metalen);
@@ -1146,7 +1156,7 @@ parse_mpeg2video(service_t *t, elementary_stream_t *st, size_t len,
       }
       pkt->pkt_duration = st->es_frame_duration;
 
-      parser_deliver(t, st, pkt, st->es_buf.sb_err);
+      parser_deliver(t, st, pkt);
       st->es_curpkt = NULL;
 
       return 1;
@@ -1187,8 +1197,8 @@ parse_h264(service_t *t, elementary_stream_t *st, size_t len,
   /* delimiter - finished frame */
   if ((sc & 0x1f) == 9 && st->es_curpkt && st->es_curpkt->pkt_payload) {
     if (st->es_curdts != PTS_UNSET && st->es_frame_duration) {
-       parser_deliver(t, st, st->es_curpkt, st->es_buf.sb_err);
-       st->es_curpkt = NULL;
+      parser_deliver(t, st, st->es_curpkt);
+      st->es_curpkt = NULL;
 
       st->es_curdts += st->es_frame_duration;
       if (st->es_curpts != PTS_UNSET)
@@ -1216,7 +1226,7 @@ parse_h264(service_t *t, elementary_stream_t *st, size_t len,
           pkt->pkt_payload = pktbuf_append(pkt->pkt_payload, buf + 6 + l2, len - 6 - l2 - 1);
         }
 
-        parser_deliver(t, st, pkt, st->es_buf.sb_err);
+        parser_deliver(t, st, pkt);
 
         st->es_curpkt = NULL;
       }
@@ -1298,6 +1308,10 @@ parse_h264(service_t *t, elementary_stream_t *st, size_t len,
         st->es_global_data_len = 0;
       }
 
+      if (st->es_buf.sb_err) {
+        pkt->pkt_err = st->es_buf.sb_err;
+        st->es_buf.sb_err = 0;
+      }
       if (metalen) {
         pkt->pkt_payload = pktbuf_alloc(NULL, metalen + st->es_buf.sb_ptr - 4);
         memcpy(pktbuf_ptr(pkt->pkt_payload), pktbuf_ptr(pkt->pkt_meta), metalen);
@@ -1329,6 +1343,7 @@ parse_subtitles(service_t *t, elementary_stream_t *st, const uint8_t *data,
   if(start) {
     /* Payload unit start */
     st->es_parser_state = 1;
+    parser_deliver_error(t, st);
     sbuf_reset(&st->es_buf, 4000);
   }
 
@@ -1373,7 +1388,9 @@ parse_subtitles(service_t *t, elementary_stream_t *st, const uint8_t *data,
     if(buf[psize - 1] == 0xff) {
       pkt = pkt_alloc(buf, psize - 1, st->es_curpts, st->es_curdts);
       pkt->pkt_commercial = t->s_tt_commercial_advice;
-      parser_deliver(t, st, pkt, st->es_buf.sb_err);
+      pkt->pkt_err = st->es_buf.sb_err;
+      parser_deliver(t, st, pkt);
+      sbuf_reset(&st->es_buf, 4000);
     }
   }
 }
@@ -1392,6 +1409,7 @@ parse_teletext(service_t *t, elementary_stream_t *st, const uint8_t *data,
   if(start) {
     st->es_parser_state = 1;
     st->es_parser_ptr = 0;
+    parser_deliver_error(t, st);
     sbuf_reset(&st->es_buf, 4000);
   }
 
@@ -1419,10 +1437,11 @@ parse_teletext(service_t *t, elementary_stream_t *st, const uint8_t *data,
   buf = d + 6 + hlen;
   
   if(psize >= 46) {
-
       pkt = pkt_alloc(buf, psize, st->es_curpts, st->es_curdts);
       pkt->pkt_commercial = t->s_tt_commercial_advice;
-      parser_deliver(t, st, pkt, st->es_buf.sb_err);
+      pkt->pkt_err = st->es_buf.sb_err;
+      parser_deliver(t, st, pkt);
+      sbuf_reset(&st->es_buf, 4000);
   }
 }
 
@@ -1430,10 +1449,8 @@ parse_teletext(service_t *t, elementary_stream_t *st, const uint8_t *data,
  *
  */
 static void
-parser_deliver(service_t *t, elementary_stream_t *st, th_pkt_t *pkt, int error)
+parser_deliver(service_t *t, elementary_stream_t *st, th_pkt_t *pkt)
 {
-  pkt->pkt_err = error;
-
   if(SCT_ISAUDIO(st->es_type) && pkt->pkt_pts != PTS_UNSET &&
      (t->s_current_pts == PTS_UNSET ||
       pkt->pkt_pts > t->s_current_pts ||
@@ -1443,7 +1460,7 @@ parser_deliver(service_t *t, elementary_stream_t *st, th_pkt_t *pkt, int error)
   tvhtrace("parser",
            "pkt stream %2d %-12s type %c"
            " dts %10"PRId64" (%10"PRId64") pts %10"PRId64" (%10"PRId64")"
-           " dur %10d len %10zu",
+           " dur %10d len %10zu err %i",
            st->es_index,
            streaming_component_type2txt(st->es_type),
            pkt_frametype_to_char(pkt->pkt_frametype),
@@ -1452,7 +1469,8 @@ parser_deliver(service_t *t, elementary_stream_t *st, th_pkt_t *pkt, int error)
            ts_rescale(pkt->pkt_dts, 1000000),
            pkt->pkt_pts,
            pkt->pkt_duration,
-           pktbuf_len(pkt->pkt_payload));
+           pktbuf_len(pkt->pkt_payload),
+           pkt->pkt_err);
 
   pkt->pkt_aspect_num = st->es_aspect_num;
   pkt->pkt_aspect_den = st->es_aspect_den;
@@ -1474,3 +1492,19 @@ parser_deliver(service_t *t, elementary_stream_t *st, th_pkt_t *pkt, int error)
   pkt_ref_dec(pkt);
 
 }
+
+/**
+ * Deliver errors
+ */
+static void
+parser_deliver_error(service_t *t, elementary_stream_t *st)
+{
+  th_pkt_t *pkt;
+
+  if (!st->es_buf.sb_err)
+    return;
+  pkt = pkt_alloc(NULL, 0, PTS_UNSET, PTS_UNSET);
+  pkt->pkt_err = st->es_buf.sb_err;
+  parser_deliver(t, st, pkt);
+  st->es_buf.sb_err = 0;
+}
index 9748628bb56755867d2bd7093a42ac1cc311f55c..5f6682257861366c9863e0d0b0ac27d20075a27f 100644 (file)
@@ -427,13 +427,11 @@ subscription_input_direct(void *opauqe, streaming_message_t *sm)
   /* Log data and errors */
   if(sm->sm_type == SMT_PACKET) {
     th_pkt_t *pkt = sm->sm_data;
-    if(pkt->pkt_err)
-      s->ths_total_err++;
+    s->ths_total_err += pkt->pkt_err;
     s->ths_bytes_in += pkt->pkt_payload->pb_size;
   } else if(sm->sm_type == SMT_MPEGTS) {
     pktbuf_t *pb = sm->sm_data;
-    if(pb->pb_err)
-      s->ths_total_err += pb->pb_err;
+    s->ths_total_err += pb->pb_err;
     s->ths_bytes_in += pb->pb_size;
   }
 
index 1528625f763e4c5e44b4f41fd67f0e02952f54f5..5c77108fd1accf3a140dfd4cd8cf25c5c525e5d9 100644 (file)
@@ -659,12 +659,12 @@ void sbuf_reset_and_alloc(sbuf_t *sb, int len);
 static inline void sbuf_steal_data(sbuf_t *sb)
 {
   sb->sb_data = NULL;
-  sb->sb_ptr = sb->sb_size = 0;
+  sb->sb_ptr = sb->sb_size = sb->sb_err = 0;
 }
 
-static inline void sbuf_err(sbuf_t *sb)
+static inline void sbuf_err(sbuf_t *sb, int errors)
 {
-  sb->sb_err = 1;
+  sb->sb_err += errors;
 }
 
 void sbuf_alloc_(sbuf_t *sb, int len);