From 362fb6800244f25c12e977cfa77811658964f8d0 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Sat, 31 Jan 2015 17:35:35 +0100 Subject: [PATCH] mpegts parsers: cleanup the error forwarding --- src/dvr/dvr_rec.c | 2 +- src/parsers/parsers.c | 74 +++++++++++++++++++++++++++++++------------ src/subscriptions.c | 6 ++-- src/tvheadend.h | 6 ++-- 4 files changed, 60 insertions(+), 28 deletions(-) diff --git a/src/dvr/dvr_rec.c b/src/dvr/dvr_rec.c index bd1ac542..92e120da 100644 --- a/src/dvr/dvr_rec.c +++ b/src/dvr/dvr_rec.c @@ -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); } } diff --git a/src/parsers/parsers.c b/src/parsers/parsers.c index 6c75f35e..4ef46dd1 100644 --- a/src/parsers/parsers.c +++ b/src/parsers/parsers.c @@ -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; +} diff --git a/src/subscriptions.c b/src/subscriptions.c index 9748628b..5f668225 100644 --- a/src/subscriptions.c +++ b/src/subscriptions.c @@ -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; } diff --git a/src/tvheadend.h b/src/tvheadend.h index 1528625f..5c77108f 100644 --- a/src/tvheadend.h +++ b/src/tvheadend.h @@ -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);