static int parse_mpa(service_t *t, elementary_stream_t *st, size_t len,
uint32_t next_startcode, int sc_offset);
-static int parse_mpa2(service_t *t, elementary_stream_t *st);
+static int parse_mpa123(service_t *t, elementary_stream_t *st);
static int parse_ac3(service_t *t, elementary_stream_t *st, size_t len,
uint32_t next_startcode, int sc_offset);
st->es_buf_a.sb_err = st->es_buf.sb_err;
+ tvhtrace("parser", "depacketize add %zd", len);
+ tvhlog_hexdump("parser", buf, len);
sbuf_append(&st->es_buf_a, buf, len);
return PARSER_APPEND;
}
}
}
-const static int mpa_br[16] = {
- 0, 32, 48, 56,
- 64, 80, 96, 112,
- 128, 160, 192, 224,
- 256, 320, 384, 0
+const static int mpa_br[2][3][16] = {
+{
+ {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 0},
+ {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 0},
+ {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0},
+},
+{
+ {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 0},
+ {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0},
+ {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 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)
+static inline int
+mpa_valid_frame(uint32_t h)
{
- return buf[0] == 0xff && (buf[1] & 0xfe) == 0xfc;
+ if ((h & 0xffe00000) != 0xffe00000) return 0; /* start bits */
+ if ((h & (3<<17)) == 0) return 0; /* unknown MPEG audio layer */
+ if ((h & (15<<12)) == (15<<12)) return 0; /* invalid bitrate */
+ if ((h & (3<<10)) == (3<<10)) return 0; /* invalid frequency */
+ return 1;
}
-
/**
*
*/
static int
-parse_mpa2(service_t *t, elementary_stream_t *st)
+parse_mpa123(service_t *t, elementary_stream_t *st)
{
- int i, len;
+ int i, len, layer, lsf, mpeg25, br, sr, pad, fsize, channels, duration;
+ int64_t dts;
+ uint32_t h;
const uint8_t *buf;
again:
buf = st->es_buf_a.sb_data;
len = st->es_buf_a.sb_ptr;
- for(i = 0; i < len - 4; i++) {
- if(mpa_valid_frame(buf + i)) {
- int br = mpa_br[ buf[i+2] >> 4 ];
- int sr = mpa_sr[(buf[i+2] >> 2) & 3];
- int pad = (buf[i+2] >> 1) & 1;
+ for (i = 0; i < len - 4; i++) {
+ if (!mpa_valid_frame(h = RB32(buf + i))) continue;
- if(br && sr) {
- int fsize = 144000 * br / sr + pad;
- int duration = 90000 * 1152 / sr;
- int64_t dts = st->es_curdts;
- int channels = (buf[i + 3] & 0xc0) == 0xc0 ? 1 : 2;
- if(dts == PTS_UNSET)
- dts = st->es_nextdts;
+ layer = 4 - ((h >> 17) & 3);
+ lsf = mpeg25 = 1;
+ pad = (h >> 9) & 1;
+ if (h & (1<<20)) {
+ lsf = ((h >> 19) & 1) ^ 1;
+ mpeg25 = 0;
+ }
+ sr = mpa_sr[(h >> 10) & 3] >> (lsf + mpeg25);
+ br = (h >> 12) & 0xf;
- if(dts != PTS_UNSET &&
- len >= i + fsize + 4 &&
- mpa_valid_frame(buf + i + fsize)) {
+ if (br == 0 || sr == 0) continue;
- makeapkt(t, st, buf + i, fsize, dts, duration,
- 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;
- }
- }
+ br = mpa_br[lsf][layer - 1][br];
+ if (br == 0) continue;
+
+ switch (layer) {
+ case 1: fsize = (((br * 12000) / sr) + pad) * 4; break;
+ case 2: fsize = ((br * 144000) / sr) + pad; break;
+ case 3: fsize = ((br * 144000) / (sr << lsf)) + pad; break;
+ default: fsize = 0;
+ }
+
+ duration = 90000 * 1152 / sr;
+ channels = ((h >> 6) & 3) == 3 ? 1 : 2;
+ dts = st->es_curdts;
+ if (dts == PTS_UNSET) {
+ dts = st->es_nextdts;
+ if(dts == PTS_UNSET) continue;
+ }
+
+ if(len < i + fsize + 4) continue;
+
+ h = RB32(buf + i + fsize);
+ if(mpa_valid_frame(h)) {
+ makeapkt(t, st, buf + i, fsize, dts, duration,
+ 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;
}
}
+
return PARSER_RESET;
}
if((r = depacketize(t, st, ilen, next_startcode, sc_offset)) != PARSER_APPEND)
return r;
- return parse_mpa2(t, st);
+ return parse_mpa123(t, st);
}