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);
{
if(err && (err != 2 || !start))
- sbuf_err(&st->es_buf);
+ sbuf_err(&st->es_buf, 1);
switch(st->es_type) {
case SCT_MPEG2VIDEO:
}
}
-
/**
* Parse program stream, as from V4L2, etc.
*
/* Payload unit start */
st->es_parser_state = 1;
st->es_parser_ptr = 0;
+ parser_deliver_error(t, st);
sbuf_reset(&st->es_buf, 4000);
}
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 */
p++;
}
}
+
st->es_parser_ptr = p;
}
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;
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;
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);
}
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;
/* 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)
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;
}
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);
if(start) {
/* Payload unit start */
st->es_parser_state = 1;
+ parser_deliver_error(t, st);
sbuf_reset(&st->es_buf, 4000);
}
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);
}
}
}
if(start) {
st->es_parser_state = 1;
st->es_parser_ptr = 0;
+ parser_deliver_error(t, st);
sbuf_reset(&st->es_buf, 4000);
}
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);
}
}
*
*/
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 ||
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),
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;
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;
+}