diff --git a/src/packet.h b/src/packet.h index 836c2d55..fedc1402 100644 --- a/src/packet.h +++ b/src/packet.h @@ -49,6 +49,7 @@ typedef struct th_pkt { uint8_t pkt_channels; uint8_t pkt_sri; + uint8_t pkt_err; uint16_t pkt_aspect_num; uint16_t pkt_aspect_den; diff --git a/src/parsers.c b/src/parsers.c index d72b0f0f..9b4768d9 100644 --- a/src/parsers.c +++ b/src/parsers.c @@ -119,7 +119,8 @@ 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); +static void parser_deliver(service_t *t, elementary_stream_t *st, th_pkt_t *pkt, + int errors); static int parse_pes_header(service_t *t, elementary_stream_t *st, const uint8_t *buf, size_t len); @@ -266,7 +267,7 @@ 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); + parser_deliver(t, st, pkt, st->es_buf.sb_err); p += muxlen + 3; } else { @@ -413,6 +414,8 @@ depacketize(service_t *t, elementary_stream_t *st, size_t len, buf += hlen; len -= hlen; + st->es_buf_a.sb_err = st->es_buf.sb_err; + sbuf_append(&st->es_buf_a, buf, len); return 0; } @@ -425,7 +428,8 @@ depacketize(service_t *t, elementary_stream_t *st, size_t len, */ static void makeapkt(service_t *t, elementary_stream_t *st, const void *buf, - int len, int64_t dts, int duration, int channels, int sri) + int len, int64_t dts, int duration, int channels, int sri, + int errors) { th_pkt_t *pkt = pkt_alloc(buf, len, dts, dts); @@ -435,7 +439,7 @@ makeapkt(service_t *t, elementary_stream_t *st, const void *buf, pkt->pkt_channels = channels; pkt->pkt_sri = sri; - parser_deliver(t, st, pkt); + parser_deliver(t, st, pkt, errors); st->es_curdts = PTS_UNSET; st->es_nextdts = dts + duration; @@ -471,7 +475,7 @@ mp4a_valid_frame(const uint8_t *buf) } static int parse_mp4a(service_t *t, elementary_stream_t *st, size_t ilen, - uint32_t next_startcode, int sc_offset) + uint32_t next_startcode, int sc_offset) { int i, len; const uint8_t *buf; @@ -505,7 +509,9 @@ static int parse_mp4a(service_t *t, elementary_stream_t *st, size_t ilen, int channels = ((p[2] & 0x01) << 2) | ((p[3] & 0xc0) >> 6); - makeapkt(t, st, p, fsize, dts, duration, channels, sri); + makeapkt(t, st, p, fsize, dts, duration, channels, sri, + st->es_buf_a.sb_err); + st->es_buf_a.sb_err = 0; sbuf_cut(&st->es_buf_a, i + fsize); goto again; } @@ -565,7 +571,9 @@ parse_mpa2(service_t *t, elementary_stream_t *st) mpa_valid_frame(buf + i + fsize)) { makeapkt(t, st, buf + i, fsize, dts, duration, - channels, mpa_sri[(buf[i+2] >> 2) & 3]); + channels, mpa_sri[(buf[i+2] >> 2) & 3], + st->es_buf_a.sb_err); + st->es_buf_a.sb_err = 0; sbuf_cut(&st->es_buf_a, i + fsize); goto again; } @@ -705,7 +713,9 @@ parse_ac3(service_t *t, elementary_stream_t *st, size_t ilen, int lfeon = read_bits(&bs, 1); int channels = acmodtab[acmod] + lfeon; - makeapkt(t, st, p, fsize, dts, duration, channels, sri); + makeapkt(t, st, p, fsize, dts, duration, channels, sri, + st->es_buf_a.sb_err); + st->es_buf_a.sb_err = 0; sbuf_cut(&st->es_buf_a, i + fsize); goto again; } @@ -775,7 +785,9 @@ parse_eac3(service_t *t, elementary_stream_t *st, size_t ilen, if(dts != PTS_UNSET && len >= i + fsize + 6 && eac3_valid_frame(p + fsize)) { - makeapkt(t, st, p, fsize, dts, duration, channels, sri); + makeapkt(t, st, p, fsize, dts, duration, channels, sri, + st->es_buf_a.sb_err); + st->es_buf_a.sb_err = 0; sbuf_cut(&st->es_buf_a, i + fsize); goto again; } @@ -1104,7 +1116,7 @@ parse_mpeg2video(service_t *t, elementary_stream_t *st, size_t len, st->es_buf.sb_ptr - 4); pkt->pkt_duration = st->es_frame_duration; - parser_deliver(t, st, pkt); + parser_deliver(t, st, pkt, st->es_buf.sb_err); st->es_curpkt = NULL; st->es_buf.sb_data = malloc(st->es_buf.sb_size); @@ -1240,7 +1252,7 @@ parse_h264(service_t *t, elementary_stream_t *st, size_t len, pkt->pkt_payload = pktbuf_make(st->es_buf.sb_data, st->es_buf.sb_ptr - 4); - parser_deliver(t, st, pkt); + parser_deliver(t, st, pkt, st->es_buf.sb_err); st->es_curpkt = NULL; st->es_buf.sb_data = malloc(st->es_buf.sb_size); @@ -1268,8 +1280,7 @@ parse_subtitles(service_t *t, elementary_stream_t *st, const uint8_t *data, if(start) { /* Payload unit start */ st->es_parser_state = 1; - st->es_buf.sb_err = 0; - st->es_buf.sb_ptr = 0; + sbuf_reset(&st->es_buf); } if(st->es_parser_state == 0) @@ -1313,7 +1324,7 @@ 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); + parser_deliver(t, st, pkt, st->es_buf.sb_err); } } } @@ -1331,7 +1342,6 @@ parse_teletext(service_t *t, elementary_stream_t *st, const uint8_t *data, const uint8_t *d; if(start) { st->es_parser_state = 1; - st->es_buf.sb_err = 0; st->es_parser_ptr = 0; sbuf_reset(&st->es_buf); } @@ -1363,7 +1373,7 @@ parse_teletext(service_t *t, elementary_stream_t *st, const uint8_t *data, pkt = pkt_alloc(buf, psize, st->es_curpts, st->es_curdts); pkt->pkt_commercial = t->s_tt_commercial_advice; - parser_deliver(t, st, pkt); + parser_deliver(t, st, pkt, st->es_buf.sb_err); } } @@ -1371,8 +1381,10 @@ 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) +parser_deliver(service_t *t, elementary_stream_t *st, th_pkt_t *pkt, int error) { + 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 ||