mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
Parse & decode DTS XXCH frames
Reviewed-by: Benjamin Larsson <benjamin@southpole.se> Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
parent
8d9fd58113
commit
16f6c16ac0
108
libavcodec/dca.c
108
libavcodec/dca.c
@ -376,6 +376,10 @@ typedef struct {
|
||||
int xch_present; ///< XCh extension present and valid
|
||||
int xch_base_channel; ///< index of first (only) channel containing XCH data
|
||||
|
||||
/* XXCH extension information */
|
||||
int xxch_spk_layout;
|
||||
int xxch_nbits_spk_mask;
|
||||
|
||||
/* ExSS header parser */
|
||||
int static_fields; ///< static fields present
|
||||
int mix_metadata; ///< mixing metadata present
|
||||
@ -462,16 +466,44 @@ static inline void get_array(GetBitContext *gb, int *dst, int len, int bits)
|
||||
*dst++ = get_bits(gb, bits);
|
||||
}
|
||||
|
||||
static int dca_parse_audio_coding_header(DCAContext *s, int base_channel)
|
||||
static int dca_parse_audio_coding_header(DCAContext *s, int base_channel,
|
||||
int xxch)
|
||||
{
|
||||
int i, j;
|
||||
static const float adj_table[4] = { 1.0, 1.1250, 1.2500, 1.4375 };
|
||||
static const int bitlen[11] = { 0, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3 };
|
||||
static const int thr[11] = { 0, 1, 3, 3, 3, 3, 7, 7, 7, 7, 7 };
|
||||
int hdr_pos = 0, hdr_size = 0;
|
||||
int mask[8];
|
||||
|
||||
/* xxch has arbitrary sized audio coding headers */
|
||||
if (xxch) {
|
||||
hdr_pos = get_bits_count(&s->gb);
|
||||
hdr_size = get_bits(&s->gb, 7) + 1;
|
||||
}
|
||||
|
||||
s->total_channels = get_bits(&s->gb, 3) + 1 + base_channel;
|
||||
s->prim_channels = s->total_channels;
|
||||
|
||||
/* obtain speaker layout mask & mixdown coefficients if applicable */
|
||||
if (xxch) {
|
||||
s->xxch_spk_layout |= get_bits(&s->gb, s->xxch_nbits_spk_mask - 6);
|
||||
if (get_bits1(&s->gb)) {
|
||||
get_bits1(&s->gb);
|
||||
skip_bits(&s->gb, 6);
|
||||
for (i = base_channel; i < s->prim_channels; i++) {
|
||||
mask[i] = get_bits(&s->gb, s->xxch_nbits_spk_mask);
|
||||
}
|
||||
for (j = base_channel; j < s->prim_channels; j++) {
|
||||
for (i = 0; i < s->xxch_nbits_spk_mask; i++) {
|
||||
if (mask[j] & (1 << i)) {
|
||||
int coeff = get_bits(&s->gb, 7);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (s->prim_channels > DCA_PRIM_CHANNELS_MAX)
|
||||
s->prim_channels = DCA_PRIM_CHANNELS_MAX;
|
||||
|
||||
@ -508,9 +540,16 @@ static int dca_parse_audio_coding_header(DCAContext *s, int base_channel)
|
||||
if (s->quant_index_huffman[i][j] < thr[j])
|
||||
s->scalefactor_adj[i][j] = adj_table[get_bits(&s->gb, 2)];
|
||||
|
||||
if (s->crc_present) {
|
||||
/* Audio header CRC check */
|
||||
get_bits(&s->gb, 16);
|
||||
if (!xxch) {
|
||||
if (s->crc_present) {
|
||||
/* Audio header CRC check */
|
||||
get_bits(&s->gb, 16);
|
||||
}
|
||||
} else {
|
||||
/* Skip to the end of the header, also ignore CRC if present */
|
||||
i = get_bits_count(&s->gb);
|
||||
if (hdr_pos + 8 * hdr_size > i)
|
||||
skip_bits_long(&s->gb, hdr_pos + 8 * hdr_size - i);
|
||||
}
|
||||
|
||||
s->current_subframe = 0;
|
||||
@ -639,7 +678,7 @@ static int dca_parse_frame_header(DCAContext *s)
|
||||
/* Primary audio coding header */
|
||||
s->subframes = get_bits(&s->gb, 4) + 1;
|
||||
|
||||
return dca_parse_audio_coding_header(s, 0);
|
||||
return dca_parse_audio_coding_header(s, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
@ -1727,6 +1766,58 @@ static int dca_xbr_parse_frame(DCAContext *s)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* parse initial header for XXCH and dump details */
|
||||
static int dca_xxch_decode_frame(DCAContext *s)
|
||||
{
|
||||
int hdr_size, chhdr_crc, spkmsk_bits, num_chsets, core_spk, hdr_pos;
|
||||
int i, chset, base_channel, chstart, fsize[8];
|
||||
|
||||
/* assume header word has already been parsed */
|
||||
hdr_pos = get_bits_count(&s->gb) - 32;
|
||||
hdr_size = get_bits(&s->gb, 6) + 1;
|
||||
chhdr_crc = get_bits1(&s->gb);
|
||||
spkmsk_bits = get_bits(&s->gb, 5) + 1;
|
||||
num_chsets = get_bits(&s->gb, 2) + 1;
|
||||
|
||||
for (i = 0; i < num_chsets; i++)
|
||||
fsize[i] = get_bits(&s->gb, 14) + 1;
|
||||
|
||||
core_spk = get_bits(&s->gb, spkmsk_bits);
|
||||
|
||||
s->xxch_spk_layout = core_spk;
|
||||
s->xxch_nbits_spk_mask = spkmsk_bits;
|
||||
|
||||
/* skip to the end of the header */
|
||||
i = get_bits_count(&s->gb);
|
||||
if (hdr_pos + hdr_size * 8 > i)
|
||||
skip_bits_long(&s->gb, hdr_pos + hdr_size * 8 - i);
|
||||
|
||||
for (chset = 0; chset < num_chsets; chset++) {
|
||||
chstart = get_bits_count(&s->gb);
|
||||
base_channel = s->prim_channels;
|
||||
|
||||
/* XXCH and Core headers differ, see 6.4.2 "XXCH Channel Set Header" vs.
|
||||
5.3.2 "Primary Audio Coding Header", DTS Spec 1.3.1 */
|
||||
dca_parse_audio_coding_header(s, base_channel, 1);
|
||||
|
||||
/* decode channel data */
|
||||
for (i = 0; i < (s->sample_blocks / 8); i++) {
|
||||
if (dca_decode_block(s, base_channel, i)) {
|
||||
av_log(s->avctx, AV_LOG_ERROR,
|
||||
"Error decoding DTS-XXCH extension\n");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* skip to end of this section */
|
||||
i = get_bits_count(&s->gb);
|
||||
if (chstart + fsize[chset] * 8 > i)
|
||||
skip_bits_long(&s->gb, chstart + fsize[chset] * 8 - i);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse extension substream header (HD)
|
||||
*/
|
||||
@ -1823,6 +1914,8 @@ static void dca_exss_parse_header(DCAContext *s)
|
||||
|
||||
if(mkr == 0x655e315e)
|
||||
dca_xbr_parse_frame(s);
|
||||
else
|
||||
av_log(s->avctx, AV_LOG_DEBUG, "DTS-MA: unknown marker = 0x%08x\n", mkr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1885,7 +1978,7 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data,
|
||||
|
||||
/* only scan for extensions if ext_descr was unknown or indicated a
|
||||
* supported XCh extension */
|
||||
if (s->core_ext_mask < 0 || s->core_ext_mask & DCA_EXT_XCH) {
|
||||
if (s->core_ext_mask < 0 || s->core_ext_mask & (DCA_EXT_XCH | DCA_EXT_XXCH)) {
|
||||
|
||||
/* if ext_descr was unknown, clear s->core_ext_mask so that the
|
||||
* extensions scan can fill it up */
|
||||
@ -1923,7 +2016,7 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data,
|
||||
}
|
||||
|
||||
/* much like core primary audio coding header */
|
||||
dca_parse_audio_coding_header(s, s->xch_base_channel);
|
||||
dca_parse_audio_coding_header(s, s->xch_base_channel, 0);
|
||||
|
||||
for (i = 0; i < (s->sample_blocks / 8); i++)
|
||||
if ((ret = dca_decode_block(s, s->xch_base_channel, i))) {
|
||||
@ -1939,6 +2032,7 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data,
|
||||
/* usually found either in core or HD part in DTS-HD HRA streams,
|
||||
* but not in DTS-ES which contains XCh extensions instead */
|
||||
s->core_ext_mask |= DCA_EXT_XXCH;
|
||||
dca_xxch_decode_frame(s);
|
||||
break;
|
||||
|
||||
case 0x1d95f262: {
|
||||
|
Loading…
Reference in New Issue
Block a user