parsers: AAC - better handle SBR extension
This commit is contained in:
parent
f6537ab39f
commit
538e7acb56
6 changed files with 44 additions and 14 deletions
|
@ -57,6 +57,7 @@ typedef struct mk_track {
|
|||
|
||||
uint8_t channels;
|
||||
uint8_t sri;
|
||||
uint8_t ext_sri;
|
||||
|
||||
uint16_t aspect_num;
|
||||
uint16_t aspect_den;
|
||||
|
@ -432,6 +433,8 @@ mk_build_tracks(mk_mux_t *mkm, const streaming_start_t *ss)
|
|||
htsbuf_queue_t *au = htsbuf_queue_alloc(0);
|
||||
|
||||
ebml_append_float(au, 0xb5, sri_to_rate(ssc->ssc_sri));
|
||||
if (ssc->ssc_ext_sri)
|
||||
ebml_append_float(au, 0x78b5, sri_to_rate(ssc->ssc_ext_sri - 1));
|
||||
ebml_append_uint(au, 0x9f, ssc->ssc_channels);
|
||||
if (bit_depth)
|
||||
ebml_append_uint(au, 0x6264, bit_depth);
|
||||
|
@ -1215,6 +1218,7 @@ mk_mux_write_pkt(mk_mux_t *mkm, th_pkt_t *pkt)
|
|||
pkt->pkt_sri) {
|
||||
mark = 1;
|
||||
t->sri = pkt->pkt_sri;
|
||||
t->ext_sri = pkt->pkt_ext_sri;
|
||||
}
|
||||
if(pkt->pkt_commercial != t->commercial &&
|
||||
pkt->pkt_commercial != COMMERCIAL_UNKNOWN) {
|
||||
|
|
|
@ -59,6 +59,7 @@ typedef struct th_pkt {
|
|||
|
||||
uint8_t pkt_channels;
|
||||
uint8_t pkt_sri;
|
||||
uint8_t pkt_ext_sri;
|
||||
uint8_t pkt_err;
|
||||
|
||||
uint16_t pkt_aspect_num;
|
||||
|
|
|
@ -43,7 +43,8 @@ typedef struct latm_private {
|
|||
int aot;
|
||||
int frame_length_type;
|
||||
|
||||
int sample_rate_index;
|
||||
int sri;
|
||||
int ext_sri;
|
||||
int channel_config;
|
||||
|
||||
} latm_private_t;
|
||||
|
@ -95,25 +96,40 @@ static int
|
|||
read_audio_specific_config(elementary_stream_t *st, latm_private_t *latm,
|
||||
bitstream_t *bs)
|
||||
{
|
||||
int aot, sr;
|
||||
int aot, sr, sri;
|
||||
|
||||
if ((bs->offset % 8) != 0)
|
||||
return -1;
|
||||
|
||||
aot = read_aot(bs);
|
||||
sr = read_sr(bs, &latm->sample_rate_index);
|
||||
sr = read_sr(bs, &latm->sri);
|
||||
latm->channel_config = read_bits(bs, 4);
|
||||
|
||||
if (sr < 7350 || sr > 96000 ||
|
||||
latm->channel_config == 0 || latm->channel_config > 7)
|
||||
return -1;
|
||||
|
||||
st->es_frame_duration = 1024 * 90000 / sr;
|
||||
|
||||
latm->ext_sri = 0;
|
||||
if (aot == AOT_SBR ||
|
||||
(aot == AOT_PS && !(show_bits(bs, 3) & 3 && !(show_bits(bs, 9) & 0x3f)))) {
|
||||
sr = read_sr(bs, &latm->sample_rate_index);
|
||||
aot = read_aot(bs); // this is the main object type (i.e. non-extended)
|
||||
sr = read_sr(bs, &latm->ext_sri);
|
||||
if (sr < 7350 || sr > 96000)
|
||||
return -1;
|
||||
latm->ext_sri++; // zero means "not set"
|
||||
aot = read_aot(bs); // this is the main object type (i.e. non-extended)
|
||||
}
|
||||
|
||||
/* it's really unusual to use lower sample rates than 32000Hz */
|
||||
/* for the professional broadcasting, assume the SBR extension */
|
||||
if (aot == AOT_AAC_LC && latm->ext_sri == 0 && sr <= 24000) {
|
||||
sri = rate_to_sri(sr * 2);
|
||||
if (sri < 0)
|
||||
return -1;
|
||||
latm->ext_sri = sri + 1;
|
||||
}
|
||||
|
||||
if (sr == 0 || latm->channel_config == 0)
|
||||
return -1;
|
||||
if (aot != AOT_AAC_MAIN && aot != AOT_AAC_LC &&
|
||||
aot != AOT_AAC_SSR && aot != AOT_AAC_LTP)
|
||||
return -1;
|
||||
|
@ -121,10 +137,10 @@ read_audio_specific_config(elementary_stream_t *st, latm_private_t *latm,
|
|||
|
||||
if (read_bits1(bs)) // framelen_flag
|
||||
return -1;
|
||||
if (read_bits1(bs)) // depends_on_coder
|
||||
if (read_bits1(bs)) // depends_on_coder
|
||||
skip_bits(bs, 14);
|
||||
|
||||
if (read_bits1(bs)) // ext_flag
|
||||
if (read_bits1(bs)) // ext_flag
|
||||
skip_bits(bs, 1); // ext3_flag
|
||||
return 0;
|
||||
}
|
||||
|
@ -250,9 +266,10 @@ parse_latm_audio_mux_element(service_t *t, elementary_stream_t *st,
|
|||
th_pkt_t *pkt = pkt_alloc(NULL, slot_len + 7, st->es_curdts, st->es_curdts);
|
||||
|
||||
pkt->pkt_commercial = t->s_tt_commercial_advice;
|
||||
pkt->pkt_duration = st->es_frame_duration;
|
||||
pkt->pkt_sri = latm->sample_rate_index;
|
||||
pkt->pkt_channels = latm->channel_config == 7 ? 8 : latm->channel_config;
|
||||
pkt->pkt_duration = st->es_frame_duration;
|
||||
pkt->pkt_sri = latm->sri + 1;
|
||||
pkt->pkt_ext_sri = latm->ext_sri;
|
||||
pkt->pkt_channels = latm->channel_config == 7 ? 8 : latm->channel_config;
|
||||
|
||||
/* 7 bytes of ADTS header */
|
||||
init_wbits(&out, pktbuf_ptr(pkt->pkt_payload), 7 * 8);
|
||||
|
@ -262,7 +279,7 @@ parse_latm_audio_mux_element(service_t *t, elementary_stream_t *st,
|
|||
put_bits(&out, 0, 2); // Layer
|
||||
put_bits(&out, 1, 1); // Protection absent
|
||||
put_bits(&out, adts_aot(latm->aot), 2);
|
||||
put_bits(&out, latm->sample_rate_index, 4);
|
||||
put_bits(&out, latm->sri, 4);
|
||||
put_bits(&out, 1, 1); // Private bit
|
||||
put_bits(&out, latm->channel_config, 3);
|
||||
put_bits(&out, 1, 1); // Original
|
||||
|
|
|
@ -314,6 +314,7 @@ parse_aac(service_t *t, elementary_stream_t *st, const uint8_t *data,
|
|||
|
||||
/* Wrong bytestream */
|
||||
} else {
|
||||
tvhtrace("parser", "AAC skip byte %02x", d[0]);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -86,6 +86,7 @@ apply_header(streaming_start_component_t *ssc, th_pkt_t *pkt)
|
|||
if(SCT_ISAUDIO(ssc->ssc_type) && !ssc->ssc_channels && !ssc->ssc_sri) {
|
||||
ssc->ssc_channels = pkt->pkt_channels;
|
||||
ssc->ssc_sri = pkt->pkt_sri;
|
||||
ssc->ssc_ext_sri = pkt->pkt_ext_sri;
|
||||
}
|
||||
|
||||
if(SCT_ISVIDEO(ssc->ssc_type)) {
|
||||
|
@ -105,12 +106,17 @@ apply_header(streaming_start_component_t *ssc, th_pkt_t *pkt)
|
|||
}
|
||||
|
||||
if (ssc->ssc_type == SCT_MP4A || ssc->ssc_type == SCT_AAC) {
|
||||
ssc->ssc_gh = pktbuf_alloc(NULL, 2);
|
||||
ssc->ssc_gh = pktbuf_alloc(NULL, pkt->pkt_ext_sri ? 5 : 2);
|
||||
uint8_t *d = pktbuf_ptr(ssc->ssc_gh);
|
||||
|
||||
const int profile = 2; /* AAC LC */
|
||||
d[0] = (profile << 3) | ((pkt->pkt_sri & 0xe) >> 1);
|
||||
d[1] = ((pkt->pkt_sri & 0x1) << 7) | (pkt->pkt_channels << 3);
|
||||
if (pkt->pkt_ext_sri) { /* SBR extension */
|
||||
d[2] = 0x56;
|
||||
d[3] = 0xe5;
|
||||
d[4] = 0x80 | ((pkt->pkt_ext_sri - 1) << 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ typedef struct streaming_start_component {
|
|||
int16_t ssc_aspect_num;
|
||||
int16_t ssc_aspect_den;
|
||||
uint8_t ssc_sri;
|
||||
uint8_t ssc_ext_sri;
|
||||
uint8_t ssc_channels;
|
||||
uint8_t ssc_disabled;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue