From 77bd08ab88bf90c1ca7e5f25482707f8ec824d59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20=C3=96man?= Date: Thu, 1 Jul 2010 08:26:34 +0000 Subject: [PATCH] Extract # of channels and samplerate for AC3 and MPA --- src/parsers.c | 40 ++++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/src/parsers.c b/src/parsers.c index 25432578..31fc1232 100644 --- a/src/parsers.c +++ b/src/parsers.c @@ -475,14 +475,16 @@ depacketize(th_transport_t *t, th_stream_t *st, size_t len, */ static void makeapkt(th_transport_t *t, th_stream_t *st, const void *buf, - int len, int64_t dts, int duration) + int len, int64_t dts, int duration, int channels, int sri) { th_pkt_t *pkt = pkt_alloc(buf, len, dts, dts); pkt->pkt_commercial = t->tht_tt_commercial_advice; pkt->pkt_duration = duration; - + pkt->pkt_channels = channels; + pkt->pkt_sri = sri; + parser_deliver(t, st, pkt); st->st_curdts = PTS_UNSET; @@ -498,8 +500,8 @@ const static int mpa_br[16] = { 256, 320, 384, 0 }; -const static int mpa_sr[4] = {44100, 48000, 32000, 0}; - +const static int mpa_sr[4] = {44100, 48000, 32000, 0}; +const static int mpa_sri[4] = {4, 3, 5, 0}; static int mpa_valid_frame(const uint8_t *buf) @@ -527,12 +529,12 @@ parse_mpa(th_transport_t *t, th_stream_t *st, size_t ilen, int br = mpa_br[ buf[i+2] >> 4 ]; int sr = mpa_sr[(buf[i+2] >> 2) & 3]; int pad = (buf[i+2] >> 1) & 1; - + if(br && sr) { int fsize = 144000 * br / sr + pad; int duration = 90000 * 1152 / sr; int64_t dts = st->st_curdts; - + int channels = (buf[i + 3] & 0xc0) == 0xc0 ? 1 : 2; if(dts == PTS_UNSET) dts = st->st_nextdts; @@ -540,7 +542,8 @@ parse_mpa(th_transport_t *t, th_stream_t *st, size_t ilen, len >= i + fsize + 4 && mpa_valid_frame(buf + i + fsize)) { - makeapkt(t, st, buf + i, fsize, dts, duration); + makeapkt(t, st, buf + i, fsize, dts, duration, + channels, mpa_sri[(buf[i+2] >> 2) & 3]); buffer3_cut(st, i + fsize); goto again; } @@ -617,6 +620,8 @@ ac3_valid_frame(const uint8_t *buf) } } +static const char acmodtab[8] = {2,1,2,3,3,4,4,5}; + static int parse_ac3(th_transport_t *t, th_stream_t *st, size_t ilen, @@ -663,13 +668,32 @@ parse_ac3(th_transport_t *t, th_stream_t *st, size_t ilen, if(sr) { int duration = 90000 * 1536 / sr; int64_t dts = st->st_curdts; + int sri = rate_to_sri(sr); if(dts == PTS_UNSET) dts = st->st_nextdts; if(dts != PTS_UNSET && len >= i + fsize + 6 && ac3_valid_frame(p + fsize)) { - makeapkt(t, st, p, fsize, dts, duration); + + bitstream_t bs; + init_bits(&bs, (uint8_t *)p + 5, (fsize - 5) * 8); + + read_bits(&bs, 5); // bsid + read_bits(&bs, 3); // bsmod + int acmod = read_bits(&bs, 3); + + if((acmod & 0x1) && (acmod != 0x1)) + read_bits(&bs, 2); // cmixlen + if(acmod & 0x4) + read_bits(&bs, 2); // surmixlev + if(acmod == 0x2) + read_bits(&bs, 2); // dsurmod + + int lfeon = read_bits(&bs, 1); + int channels = acmodtab[acmod] + lfeon; + + makeapkt(t, st, p, fsize, dts, duration, channels, sri); buffer3_cut(st, i + fsize); goto again; }