diff --git a/src/dvb/dvb_support.h b/src/dvb/dvb_support.h index 055cfdd0..2cdf474b 100644 --- a/src/dvb/dvb_support.h +++ b/src/dvb/dvb_support.h @@ -46,6 +46,7 @@ #define DVB_DESC_TELETEXT 0x56 #define DVB_DESC_SUBTITLE 0x59 #define DVB_DESC_AC3 0x6a +#define DVB_DESC_EAC3 0x7a #define DVB_DESC_AAC 0x7c #define DVB_DESC_LOCAL_CHAN 0x83 diff --git a/src/dvr/mkmux.c b/src/dvr/mkmux.c index 35829b26..c8ad8751 100644 --- a/src/dvr/mkmux.c +++ b/src/dvr/mkmux.c @@ -208,6 +208,11 @@ mk_build_tracks(mk_mux_t *mkm, const struct streaming_start *ss) codec_id = "A_AC3"; break; + case SCT_EAC3: + tracktype = 2; + codec_id = "A_EAC3"; + break; + case SCT_AAC: tracktype = 2; codec_id = "A_AAC"; diff --git a/src/parsers.c b/src/parsers.c index 82052472..e7a0442d 100644 --- a/src/parsers.c +++ b/src/parsers.c @@ -110,6 +110,9 @@ static int parse_mpa2(th_transport_t *t, th_stream_t *st); static int parse_ac3(th_transport_t *t, th_stream_t *st, size_t len, uint32_t next_startcode, int sc_offset); +static int parse_eac3(th_transport_t *t, th_stream_t *st, size_t len, + uint32_t next_startcode, int sc_offset); + static void parser_deliver(th_transport_t *t, th_stream_t *st, th_pkt_t *pkt); static int parse_pes_header(th_transport_t *t, th_stream_t *st, @@ -143,6 +146,10 @@ parse_mpeg_ts(th_transport_t *t, th_stream_t *st, const uint8_t *data, parse_sc(t, st, data, len, parse_ac3); break; + case SCT_EAC3: + parse_sc(t, st, data, len, parse_eac3); + break; + case SCT_DVBSUB: parse_subtitles(t, st, data, len, start); break; @@ -625,6 +632,76 @@ parse_ac3(th_transport_t *t, th_stream_t *st, size_t ilen, } +/** + * EAC3 audio parser + */ + + +static int +eac3_valid_frame(const uint8_t *buf) +{ + if(buf[0] != 0x0b || buf[1] != 0x77 || buf[5] >> 3 <= 10) + return 0; + return (buf[4] & 0xc0) != 0xc0; +} + +static int +parse_eac3(th_transport_t *t, th_stream_t *st, size_t ilen, + uint32_t next_startcode, int sc_offset) +{ + int i, len; + const uint8_t *buf; + + if((i = depacketize(t, st, ilen, next_startcode, sc_offset)) != 0) + return i; + + again: + buf = st->st_buf_a.sb_data; + len = st->st_buf_a.sb_ptr; + + for(i = 0; i < len - 6; i++) { + const uint8_t *p = buf + i; + if(eac3_valid_frame(p)) { + + int fsize = ((((p[2] & 0x7) << 8) + p[3]) + 1) * 2; + + int sr = p[4] >> 6; + int rate; + if(sr == 3) { + int sr2 = (p[4] >> 4) & 0x3; + if(sr2 == 3) + continue; + rate = ac3_freq_tab[sr2] / 2; + } else { + rate = ac3_freq_tab[sr]; + } + + + int64_t dts = st->st_curdts; + int sri = rate_to_sri(rate); + + int acmod = (p[4] >> 1) & 0x7; + int lfeon = p[4] & 1; + + int channels = acmodtab[acmod] + lfeon; + int duration = 90000 * 1536 / rate; + + if(dts == PTS_UNSET) + dts = st->st_nextdts; + + if(dts != PTS_UNSET && len >= i + fsize + 6 && + eac3_valid_frame(p + fsize)) { + makeapkt(t, st, p, fsize, dts, duration, channels, sri); + sbuf_cut(&st->st_buf_a, i + fsize); + goto again; + } + } + } + return 1; +} + + + /** * PES header parser diff --git a/src/psi.c b/src/psi.c index 1dbe9f8e..ba30d89e 100644 --- a/src/psi.c +++ b/src/psi.c @@ -580,6 +580,11 @@ psi_parse_pmt(th_transport_t *t, const uint8_t *ptr, int len, int chksvcid, hts_stream_type = SCT_DVBSUB; break; + case DVB_DESC_EAC3: + if(estype == 0x06 || estype == 0x81) + hts_stream_type = SCT_EAC3; + break; + default: break; } @@ -845,6 +850,7 @@ static struct strtab streamtypetab[] = { { "AAC", SCT_AAC }, { "MPEGTS", SCT_MPEGTS }, { "TEXTSUB", SCT_TEXTSUB }, + { "EAC3", SCT_EAC3 }, }; diff --git a/src/tvhead.h b/src/tvhead.h index a125e622..e3f26838 100644 --- a/src/tvhead.h +++ b/src/tvhead.h @@ -162,6 +162,7 @@ typedef enum { SCT_AAC, SCT_MPEGTS, SCT_TEXTSUB, + SCT_EAC3, } streaming_component_type_t; #define SCT_ISVIDEO(t) ((t) == SCT_MPEG2VIDEO || (t) == SCT_H264)