/* * Copyright (C) 2016 foo86 * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "dcadec.h" static void parse_xll_parameters(DCAExssParser *s, DCAExssAsset *asset) { // Size of XLL data in extension substream asset->xll_size = get_bits(&s->gb, s->exss_size_nbits) + 1; // XLL sync word present flag if (asset->xll_sync_present = get_bits1(&s->gb)) { int xll_delay_nbits; // Peak bit rate smoothing buffer size skip_bits(&s->gb, 4); // Number of bits for XLL decoding delay xll_delay_nbits = get_bits(&s->gb, 5) + 1; // Initial XLL decoding delay in frames asset->xll_delay_nframes = get_bits_long(&s->gb, xll_delay_nbits); // Number of bytes offset to XLL sync asset->xll_sync_offset = get_bits(&s->gb, s->exss_size_nbits); } else { asset->xll_delay_nframes = 0; asset->xll_sync_offset = 0; } } static void parse_lbr_parameters(DCAExssParser *s, DCAExssAsset *asset) { // Size of LBR component in extension substream asset->lbr_size = get_bits(&s->gb, 14) + 1; // LBR sync word present flag if (get_bits1(&s->gb)) // LBR sync distance skip_bits(&s->gb, 2); } 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) { if (s->avctx) 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]) { if (s->avctx) 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)) { if (s->avctx) av_log(s->avctx, AV_LOG_ERROR, "Read past end of EXSS asset descriptor\n"); return AVERROR_INVALIDDATA; } return 0; } static int set_exss_offsets(DCAExssAsset *asset) { int offs = asset->asset_offset; int size = asset->asset_size; if (asset->extension_mask & DCA_EXSS_CORE) { asset->core_offset = offs; if (asset->core_size > size) return AVERROR_INVALIDDATA; offs += asset->core_size; size -= asset->core_size; } if (asset->extension_mask & DCA_EXSS_XBR) { asset->xbr_offset = offs; if (asset->xbr_size > size) return AVERROR_INVALIDDATA; offs += asset->xbr_size; size -= asset->xbr_size; } if (asset->extension_mask & DCA_EXSS_XXCH) { asset->xxch_offset = offs; if (asset->xxch_size > size) return AVERROR_INVALIDDATA; offs += asset->xxch_size; size -= asset->xxch_size; } if (asset->extension_mask & DCA_EXSS_X96) { asset->x96_offset = offs; if (asset->x96_size > size) return AVERROR_INVALIDDATA; offs += asset->x96_size; size -= asset->x96_size; } if (asset->extension_mask & DCA_EXSS_LBR) { asset->lbr_offset = offs; if (asset->lbr_size > size) return AVERROR_INVALIDDATA; offs += asset->lbr_size; size -= asset->lbr_size; } if (asset->extension_mask & DCA_EXSS_XLL) { asset->xll_offset = offs; if (asset->xll_size > size) return AVERROR_INVALIDDATA; offs += asset->xll_size; size -= asset->xll_size; } return 0; } int ff_dca_exss_parse(DCAExssParser *s, const uint8_t *data, int size) { int i, ret, offset, wide_hdr, header_size; if ((ret = init_get_bits8(&s->gb, data, size)) < 0) return ret; // Extension substream sync word skip_bits_long(&s->gb, 32); // User defined bits skip_bits(&s->gb, 8); // Extension substream index s->exss_index = get_bits(&s->gb, 2); // Flag indicating short or long header size wide_hdr = get_bits1(&s->gb); // Extension substream header length header_size = get_bits(&s->gb, 8 + 4 * wide_hdr) + 1; // Check CRC if (s->avctx && ff_dca_check_crc(s->avctx, &s->gb, 32 + 8, header_size * 8)) { av_log(s->avctx, AV_LOG_ERROR, "Invalid EXSS header checksum\n"); return AVERROR_INVALIDDATA; } s->exss_size_nbits = 16 + 4 * wide_hdr; // Number of bytes of extension substream s->exss_size = get_bits(&s->gb, s->exss_size_nbits) + 1; if (s->exss_size > size) { if (s->avctx) av_log(s->avctx, AV_LOG_ERROR, "Packet too short for EXSS frame\n"); return AVERROR_INVALIDDATA; } // Per stream static fields presence flag if (s->static_fields_present = get_bits1(&s->gb)) { int active_exss_mask[8]; // Reference clock code skip_bits(&s->gb, 2); // Extension substream frame duration skip_bits(&s->gb, 3); // Timecode presence flag if (get_bits1(&s->gb)) // Timecode data skip_bits_long(&s->gb, 36); // Number of defined audio presentations s->npresents = get_bits(&s->gb, 3) + 1; if (s->npresents > 1) { if (s->avctx) avpriv_request_sample(s->avctx, "%d audio presentations", s->npresents); return AVERROR_PATCHWELCOME; } // Number of audio assets in extension substream s->nassets = get_bits(&s->gb, 3) + 1; if (s->nassets > 1) { if (s->avctx) avpriv_request_sample(s->avctx, "%d audio assets", s->nassets); return AVERROR_PATCHWELCOME; } // Active extension substream mask for audio presentation for (i = 0; i < s->npresents; i++) active_exss_mask[i] = get_bits(&s->gb, s->exss_index + 1); // Active audio asset mask for (i = 0; i < s->npresents; i++) skip_bits_long(&s->gb, av_popcount(active_exss_mask[i]) * 8); // Mixing metadata enable flag if (s->mix_metadata_enabled = get_bits1(&s->gb)) { int spkr_mask_nbits; // Mixing metadata adjustment level skip_bits(&s->gb, 2); // Number of bits for mixer output speaker activity mask spkr_mask_nbits = (get_bits(&s->gb, 2) + 1) << 2; // Number of mixing configurations s->nmixoutconfigs = get_bits(&s->gb, 2) + 1; // Speaker layout mask for mixer output channels for (i = 0; i < s->nmixoutconfigs; i++) s->nmixoutchs[i] = ff_dca_count_chs_for_mask(get_bits(&s->gb, spkr_mask_nbits)); } } else { s->npresents = 1; s->nassets = 1; } // Size of encoded asset data in bytes offset = header_size; for (i = 0; i < s->nassets; i++) { s->assets[i].asset_offset = offset; s->assets[i].asset_size = get_bits(&s->gb, s->exss_size_nbits) + 1; offset += s->assets[i].asset_size; if (offset > s->exss_size) { if (s->avctx) av_log(s->avctx, AV_LOG_ERROR, "EXSS asset out of bounds\n"); return AVERROR_INVALIDDATA; } } // Audio asset descriptor for (i = 0; i < s->nassets; i++) { if ((ret = parse_descriptor(s, &s->assets[i])) < 0) return ret; if ((ret = set_exss_offsets(&s->assets[i])) < 0) { if (s->avctx) av_log(s->avctx, AV_LOG_ERROR, "Invalid extension size in EXSS asset descriptor\n"); return ret; } } // Backward compatible core present // Backward compatible core substream index // Backward compatible core asset index // Reserved // Byte align // CRC16 of extension substream header if (ff_dca_seek_bits(&s->gb, header_size * 8)) { if (s->avctx) av_log(s->avctx, AV_LOG_ERROR, "Read past end of EXSS header\n"); return AVERROR_INVALIDDATA; } return 0; }