]> git.ipfire.org Git - thirdparty/tvheadend.git/commitdiff
Add EAC3 support.
authorAndreas Öman <andreas@lonelycoder.com>
Sun, 31 Oct 2010 11:48:25 +0000 (11:48 +0000)
committerAndreas Öman <andreas@lonelycoder.com>
Sun, 31 Oct 2010 11:48:25 +0000 (11:48 +0000)
Ticket #219

src/dvb/dvb_support.h
src/dvr/mkmux.c
src/parsers.c
src/psi.c
src/tvhead.h

index 055cfdd0b056ca096c3b94b334213368ed98461e..2cdf474b3230633a8d98c6c3cf3d32d495753ff9 100644 (file)
@@ -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
 
index 35829b26a0c0b63c8b9723f35228a4a28afaee76..c8ad8751f3e64d5f6a37c89c870fa46e491bea8f 100644 (file)
@@ -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";
index 8205247275b7760939d6d7f2348cba2f2fff1981..e7a0442d41334baa9090d99c7ae9c29b74690b42 100644 (file)
@@ -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
index 1dbe9f8e652aebd460e19bbc357e5e06554417bd..ba30d89e552f89e99d638fc78a7def0ae5eedf68 100644 (file)
--- 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 },
 };
 
 
index a125e622725038ac652a5f7be779f809d5dd6ffc..e3f26838da3e9c6ad81a466304c7671c7fc60475 100644 (file)
@@ -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)