static int parse_descriptor(struct exss_asset *asset) { struct exss_parser *exss = asset->parser; int i, j, ret, descr_pos = exss->bits.index; // Size of audio asset descriptor in bytes int descr_size = bits_get(&exss->bits, 9) + 1; // Audio asset identifier asset->asset_index = bits_get(&exss->bits, 3); // // Per stream static metadata // if (exss->static_fields_present) { // Asset type descriptor presence if (bits_get1(&exss->bits)) // Asset type descriptor bits_skip(&exss->bits, 4); // Language descriptor presence if (bits_get1(&exss->bits)) // Language descriptor bits_skip(&exss->bits, 24); // Additional textual information presence if (bits_get1(&exss->bits)) { // Byte size of additional text info int text_size = bits_get(&exss->bits, 10) + 1; // Additional textual information string bits_skip(&exss->bits, text_size * 8); } // PCM bit resolution asset->pcm_bit_res = bits_get(&exss->bits, 5) + 1; // Maximum sample rate asset->max_sample_rate = exss_sample_rates[bits_get(&exss->bits, 4)]; // Total number of channels asset->nchannels_total = bits_get(&exss->bits, 8) + 1; // One to one map channel to speakers asset->one_to_one_map_ch_to_spkr = bits_get1(&exss->bits); if (asset->one_to_one_map_ch_to_spkr) { // Embedded stereo flag if (asset->nchannels_total > 2) asset->embedded_stereo = bits_get1(&exss->bits); // Embedded 6 channels flag if (asset->nchannels_total > 6) asset->embedded_6ch = bits_get1(&exss->bits); // Speaker mask enabled flag asset->spkr_mask_enabled = bits_get1(&exss->bits); int spkr_mask_nbits = 0; if (asset->spkr_mask_enabled) { // Number of bits for speaker activity mask spkr_mask_nbits = (bits_get(&exss->bits, 2) + 1) << 2; // Loudspeaker activity mask asset->spkr_mask = bits_get(&exss->bits, spkr_mask_nbits); } // Number of speaker remapping sets int spkr_remap_nsets = bits_get(&exss->bits, 3); if (spkr_remap_nsets && !spkr_mask_nbits) { exss_err("Speaker mask disabled yet there are remapping sets"); return -DCADEC_EBADDATA; } // Standard loudspeaker layout mask int nspeakers[8]; for (i = 0; i < spkr_remap_nsets; i++) nspeakers[i] = count_chs_for_mask(bits_get(&exss->bits, spkr_mask_nbits)); for (i = 0; i < spkr_remap_nsets; i++) { // Number of channels to be decoded for speaker remapping int nch_for_remaps = bits_get(&exss->bits, 5) + 1; for (j = 0; j < nspeakers[i]; j++) { // Decoded channels to output speaker mapping mask int remap_ch_mask = bits_get(&exss->bits, nch_for_remaps); // Loudspeaker remapping codes int ncodes = dca_popcount(remap_ch_mask); bits_skip(&exss->bits, ncodes * 5); } } } else { asset->embedded_stereo = false; asset->embedded_6ch = false; asset->spkr_mask_enabled = false; asset->spkr_mask = 0; // Representation type asset->representation_type = bits_get(&exss->bits, 3); } } // // DRC, DNC and mixing metadata // // Dynamic range coefficient presence flag bool drc_present = bits_get1(&exss->bits); // Code for dynamic range coefficient if (drc_present) bits_skip(&exss->bits, 8); // Dialog normalization presence flag if (bits_get1(&exss->bits)) // Dialog normalization code bits_skip(&exss->bits, 5); // DRC for stereo downmix if (drc_present && asset->embedded_stereo) bits_skip(&exss->bits, 8); // Mixing metadata presence flag if (exss->mix_metadata_enabled && bits_get1(&exss->bits)) { // External mixing flag bits_skip1(&exss->bits); // Post mixing / replacement gain adjustment bits_skip(&exss->bits, 6); // DRC prior to mixing if (bits_get(&exss->bits, 2) == 3) // Custom code for mixing DRC bits_skip(&exss->bits, 8); else // Limit for mixing DRC bits_skip(&exss->bits, 3); // Scaling type for channels of main audio // Scaling parameters of main audio if (bits_get1(&exss->bits)) for (i = 0; i < exss->nmixoutconfigs; i++) bits_skip(&exss->bits, 6 * exss->nmixoutchs[i]); else bits_skip(&exss->bits, 6 * exss->nmixoutconfigs); int nchannels_dmix = asset->nchannels_total; if (asset->embedded_6ch) nchannels_dmix += 6; if (asset->embedded_stereo) nchannels_dmix += 2; for (i = 0; i < exss->nmixoutconfigs; i++) { for (j = 0; j < nchannels_dmix; j++) { if (!exss->nmixoutchs[i]) { exss_err("Invalid speaker layout mask for mixing configuration"); return -DCADEC_EBADDATA; } // Mix output mask int mix_map_mask = bits_get(&exss->bits, exss->nmixoutchs[i]); // Mixing coefficients int nmixcoefs = dca_popcount(mix_map_mask); bits_skip(&exss->bits, 6 * nmixcoefs); } } } // // Decoder navigation data // // Coding mode for the asset asset->coding_mode = bits_get(&exss->bits, 2); // Coding components used in asset switch (asset->coding_mode) { case 0: // Coding mode that may contain multiple coding components asset->extension_mask = bits_get(&exss->bits, 12); if (asset->extension_mask & EXSS_CORE) { // Size of core component in extension substream asset->core_size = bits_get(&exss->bits, 14) + 1; // Core sync word present flag if (bits_get1(&exss->bits)) // Core sync distance bits_skip(&exss->bits, 2); } if (asset->extension_mask & EXSS_XBR) // Size of XBR extension in extension substream asset->xbr_size = bits_get(&exss->bits, 14) + 1; if (asset->extension_mask & EXSS_XXCH) // Size of XXCH extension in extension substream asset->xxch_size = bits_get(&exss->bits, 14) + 1; if (asset->extension_mask & EXSS_X96) // Size of X96 extension in extension substream asset->x96_size = bits_get(&exss->bits, 12) + 1; if (asset->extension_mask & EXSS_LBR) parse_lbr_parameters(asset); if (asset->extension_mask & EXSS_XLL) parse_xll_parameters(asset); if (asset->extension_mask & EXSS_RSV1) bits_skip(&exss->bits, 16); if (asset->extension_mask & EXSS_RSV2) bits_skip(&exss->bits, 16); break; case 1: // Loss-less coding mode without CBR component asset->extension_mask = EXSS_XLL; parse_xll_parameters(asset); break; case 2: // Low bit rate mode asset->extension_mask = EXSS_LBR; parse_lbr_parameters(asset); break; case 3: // Auxiliary coding mode asset->extension_mask = 0; // Size of auxiliary coded data bits_skip(&exss->bits, 14); // Auxiliary codec identification bits_skip(&exss->bits, 8); // Aux sync word present flag if (bits_get1(&exss->bits)) // Aux sync distance bits_skip(&exss->bits, 3); break; } if (asset->extension_mask & EXSS_XLL) // DTS-HD stream ID asset->hd_stream_id = bits_get(&exss->bits, 3); // One to one mixing flag // Per channel main audio scaling flag // Main audio scaling codes // Decode asset in secondary decoder flag // Revision 2 DRC metadata // Reserved // Zero pad if ((ret = bits_seek(&exss->bits, descr_pos + descr_size * 8)) < 0) exss_err("Read past end of asset descriptor"); return ret; }
static int parse_descriptor(DCAExssParser *s, DCAExssAsset *asset) { int i, j, drc_present, descr_size, descr_pos = get_bits_count(&s->gb); // Size of audio asset descriptor in bytes descr_size = get_bits(&s->gb, 9) + 1; // Audio asset identifier asset->asset_index = get_bits(&s->gb, 3); // // Per stream static metadata // if (s->static_fields_present) { // Asset type descriptor presence if (get_bits1(&s->gb)) // Asset type descriptor skip_bits(&s->gb, 4); // Language descriptor presence if (get_bits1(&s->gb)) // Language descriptor skip_bits(&s->gb, 24); // Additional textual information presence if (get_bits1(&s->gb)) { // Byte size of additional text info int text_size = get_bits(&s->gb, 10) + 1; // Sanity check available size if (get_bits_left(&s->gb) < text_size * 8) return AVERROR_INVALIDDATA; // Additional textual information string skip_bits_long(&s->gb, text_size * 8); } // PCM bit resolution asset->pcm_bit_res = get_bits(&s->gb, 5) + 1; // Maximum sample rate asset->max_sample_rate = ff_dca_sampling_freqs[get_bits(&s->gb, 4)]; // Total number of channels asset->nchannels_total = get_bits(&s->gb, 8) + 1; // One to one map channel to speakers if (asset->one_to_one_map_ch_to_spkr = get_bits1(&s->gb)) { int spkr_mask_nbits = 0; int spkr_remap_nsets; int nspeakers[8]; // Embedded stereo flag asset->embedded_stereo = asset->nchannels_total > 2 && get_bits1(&s->gb); // Embedded 6 channels flag asset->embedded_6ch = asset->nchannels_total > 6 && get_bits1(&s->gb); // Speaker mask enabled flag if (asset->spkr_mask_enabled = get_bits1(&s->gb)) { // Number of bits for speaker activity mask spkr_mask_nbits = (get_bits(&s->gb, 2) + 1) << 2; // Loudspeaker activity mask asset->spkr_mask = get_bits(&s->gb, spkr_mask_nbits); } // Number of speaker remapping sets if ((spkr_remap_nsets = get_bits(&s->gb, 3)) && !spkr_mask_nbits) { av_log(s->avctx, AV_LOG_ERROR, "Speaker mask disabled yet there are remapping sets\n"); return AVERROR_INVALIDDATA; } // Standard loudspeaker layout mask for (i = 0; i < spkr_remap_nsets; i++) nspeakers[i] = ff_dca_count_chs_for_mask(get_bits(&s->gb, spkr_mask_nbits)); for (i = 0; i < spkr_remap_nsets; i++) { // Number of channels to be decoded for speaker remapping int nch_for_remaps = get_bits(&s->gb, 5) + 1; for (j = 0; j < nspeakers[i]; j++) { // Decoded channels to output speaker mapping mask int remap_ch_mask = get_bits_long(&s->gb, nch_for_remaps); // Loudspeaker remapping codes skip_bits_long(&s->gb, av_popcount(remap_ch_mask) * 5); } } } else { asset->embedded_stereo = 0; asset->embedded_6ch = 0; asset->spkr_mask_enabled = 0; asset->spkr_mask = 0; // Representation type asset->representation_type = get_bits(&s->gb, 3); } } // // DRC, DNC and mixing metadata // // Dynamic range coefficient presence flag drc_present = get_bits1(&s->gb); // Code for dynamic range coefficient if (drc_present) skip_bits(&s->gb, 8); // Dialog normalization presence flag if (get_bits1(&s->gb)) // Dialog normalization code skip_bits(&s->gb, 5); // DRC for stereo downmix if (drc_present && asset->embedded_stereo) skip_bits(&s->gb, 8); // Mixing metadata presence flag if (s->mix_metadata_enabled && get_bits1(&s->gb)) { int nchannels_dmix; // External mixing flag skip_bits1(&s->gb); // Post mixing / replacement gain adjustment skip_bits(&s->gb, 6); // DRC prior to mixing if (get_bits(&s->gb, 2) == 3) // Custom code for mixing DRC skip_bits(&s->gb, 8); else // Limit for mixing DRC skip_bits(&s->gb, 3); // Scaling type for channels of main audio // Scaling parameters of main audio if (get_bits1(&s->gb)) for (i = 0; i < s->nmixoutconfigs; i++) skip_bits_long(&s->gb, 6 * s->nmixoutchs[i]); else skip_bits_long(&s->gb, 6 * s->nmixoutconfigs); nchannels_dmix = asset->nchannels_total; if (asset->embedded_6ch) nchannels_dmix += 6; if (asset->embedded_stereo) nchannels_dmix += 2; for (i = 0; i < s->nmixoutconfigs; i++) { if (!s->nmixoutchs[i]) { av_log(s->avctx, AV_LOG_ERROR, "Invalid speaker layout mask for mixing configuration\n"); return AVERROR_INVALIDDATA; } for (j = 0; j < nchannels_dmix; j++) { // Mix output mask int mix_map_mask = get_bits(&s->gb, s->nmixoutchs[i]); // Mixing coefficients skip_bits_long(&s->gb, av_popcount(mix_map_mask) * 6); } } } // // Decoder navigation data // // Coding mode for the asset asset->coding_mode = get_bits(&s->gb, 2); // Coding components used in asset switch (asset->coding_mode) { case 0: // Coding mode that may contain multiple coding components asset->extension_mask = get_bits(&s->gb, 12); if (asset->extension_mask & DCA_EXSS_CORE) { // Size of core component in extension substream asset->core_size = get_bits(&s->gb, 14) + 1; // Core sync word present flag if (get_bits1(&s->gb)) // Core sync distance skip_bits(&s->gb, 2); } if (asset->extension_mask & DCA_EXSS_XBR) // Size of XBR extension in extension substream asset->xbr_size = get_bits(&s->gb, 14) + 1; if (asset->extension_mask & DCA_EXSS_XXCH) // Size of XXCH extension in extension substream asset->xxch_size = get_bits(&s->gb, 14) + 1; if (asset->extension_mask & DCA_EXSS_X96) // Size of X96 extension in extension substream asset->x96_size = get_bits(&s->gb, 12) + 1; if (asset->extension_mask & DCA_EXSS_LBR) parse_lbr_parameters(s, asset); if (asset->extension_mask & DCA_EXSS_XLL) parse_xll_parameters(s, asset); if (asset->extension_mask & DCA_EXSS_RSV1) skip_bits(&s->gb, 16); if (asset->extension_mask & DCA_EXSS_RSV2) skip_bits(&s->gb, 16); break; case 1: // Loss-less coding mode without CBR component asset->extension_mask = DCA_EXSS_XLL; parse_xll_parameters(s, asset); break; case 2: // Low bit rate mode asset->extension_mask = DCA_EXSS_LBR; parse_lbr_parameters(s, asset); break; case 3: // Auxiliary coding mode asset->extension_mask = 0; // Size of auxiliary coded data skip_bits(&s->gb, 14); // Auxiliary codec identification skip_bits(&s->gb, 8); // Aux sync word present flag if (get_bits1(&s->gb)) // Aux sync distance skip_bits(&s->gb, 3); break; } if (asset->extension_mask & DCA_EXSS_XLL) // DTS-HD stream ID asset->hd_stream_id = get_bits(&s->gb, 3); // One to one mixing flag // Per channel main audio scaling flag // Main audio scaling codes // Decode asset in secondary decoder flag // Revision 2 DRC metadata // Reserved // Zero pad if (ff_dca_seek_bits(&s->gb, descr_pos + descr_size * 8)) { av_log(s->avctx, AV_LOG_ERROR, "Read past end of EXSS asset descriptor\n"); return AVERROR_INVALIDDATA; } return 0; }