1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * Copyright (C) 2016 foo86 3cabdff1aSopenharmony_ci * 4cabdff1aSopenharmony_ci * This file is part of FFmpeg. 5cabdff1aSopenharmony_ci * 6cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 7cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 8cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 9cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 10cabdff1aSopenharmony_ci * 11cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 12cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 13cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14cabdff1aSopenharmony_ci * Lesser General Public License for more details. 15cabdff1aSopenharmony_ci * 16cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 17cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 18cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19cabdff1aSopenharmony_ci */ 20cabdff1aSopenharmony_ci 21cabdff1aSopenharmony_ci#include "dcadec.h" 22cabdff1aSopenharmony_ci 23cabdff1aSopenharmony_cistatic void parse_xll_parameters(DCAExssParser *s, DCAExssAsset *asset) 24cabdff1aSopenharmony_ci{ 25cabdff1aSopenharmony_ci // Size of XLL data in extension substream 26cabdff1aSopenharmony_ci asset->xll_size = get_bits(&s->gb, s->exss_size_nbits) + 1; 27cabdff1aSopenharmony_ci 28cabdff1aSopenharmony_ci // XLL sync word present flag 29cabdff1aSopenharmony_ci if (asset->xll_sync_present = get_bits1(&s->gb)) { 30cabdff1aSopenharmony_ci int xll_delay_nbits; 31cabdff1aSopenharmony_ci 32cabdff1aSopenharmony_ci // Peak bit rate smoothing buffer size 33cabdff1aSopenharmony_ci skip_bits(&s->gb, 4); 34cabdff1aSopenharmony_ci 35cabdff1aSopenharmony_ci // Number of bits for XLL decoding delay 36cabdff1aSopenharmony_ci xll_delay_nbits = get_bits(&s->gb, 5) + 1; 37cabdff1aSopenharmony_ci 38cabdff1aSopenharmony_ci // Initial XLL decoding delay in frames 39cabdff1aSopenharmony_ci asset->xll_delay_nframes = get_bits_long(&s->gb, xll_delay_nbits); 40cabdff1aSopenharmony_ci 41cabdff1aSopenharmony_ci // Number of bytes offset to XLL sync 42cabdff1aSopenharmony_ci asset->xll_sync_offset = get_bits(&s->gb, s->exss_size_nbits); 43cabdff1aSopenharmony_ci } else { 44cabdff1aSopenharmony_ci asset->xll_delay_nframes = 0; 45cabdff1aSopenharmony_ci asset->xll_sync_offset = 0; 46cabdff1aSopenharmony_ci } 47cabdff1aSopenharmony_ci} 48cabdff1aSopenharmony_ci 49cabdff1aSopenharmony_cistatic void parse_lbr_parameters(DCAExssParser *s, DCAExssAsset *asset) 50cabdff1aSopenharmony_ci{ 51cabdff1aSopenharmony_ci // Size of LBR component in extension substream 52cabdff1aSopenharmony_ci asset->lbr_size = get_bits(&s->gb, 14) + 1; 53cabdff1aSopenharmony_ci 54cabdff1aSopenharmony_ci // LBR sync word present flag 55cabdff1aSopenharmony_ci if (get_bits1(&s->gb)) 56cabdff1aSopenharmony_ci // LBR sync distance 57cabdff1aSopenharmony_ci skip_bits(&s->gb, 2); 58cabdff1aSopenharmony_ci} 59cabdff1aSopenharmony_ci 60cabdff1aSopenharmony_cistatic int parse_descriptor(DCAExssParser *s, DCAExssAsset *asset) 61cabdff1aSopenharmony_ci{ 62cabdff1aSopenharmony_ci int i, j, drc_present, descr_size, descr_pos = get_bits_count(&s->gb); 63cabdff1aSopenharmony_ci 64cabdff1aSopenharmony_ci // Size of audio asset descriptor in bytes 65cabdff1aSopenharmony_ci descr_size = get_bits(&s->gb, 9) + 1; 66cabdff1aSopenharmony_ci 67cabdff1aSopenharmony_ci // Audio asset identifier 68cabdff1aSopenharmony_ci asset->asset_index = get_bits(&s->gb, 3); 69cabdff1aSopenharmony_ci 70cabdff1aSopenharmony_ci // 71cabdff1aSopenharmony_ci // Per stream static metadata 72cabdff1aSopenharmony_ci // 73cabdff1aSopenharmony_ci 74cabdff1aSopenharmony_ci if (s->static_fields_present) { 75cabdff1aSopenharmony_ci // Asset type descriptor presence 76cabdff1aSopenharmony_ci if (get_bits1(&s->gb)) 77cabdff1aSopenharmony_ci // Asset type descriptor 78cabdff1aSopenharmony_ci skip_bits(&s->gb, 4); 79cabdff1aSopenharmony_ci 80cabdff1aSopenharmony_ci // Language descriptor presence 81cabdff1aSopenharmony_ci if (get_bits1(&s->gb)) 82cabdff1aSopenharmony_ci // Language descriptor 83cabdff1aSopenharmony_ci skip_bits(&s->gb, 24); 84cabdff1aSopenharmony_ci 85cabdff1aSopenharmony_ci // Additional textual information presence 86cabdff1aSopenharmony_ci if (get_bits1(&s->gb)) { 87cabdff1aSopenharmony_ci // Byte size of additional text info 88cabdff1aSopenharmony_ci int text_size = get_bits(&s->gb, 10) + 1; 89cabdff1aSopenharmony_ci 90cabdff1aSopenharmony_ci // Sanity check available size 91cabdff1aSopenharmony_ci if (get_bits_left(&s->gb) < text_size * 8) 92cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 93cabdff1aSopenharmony_ci 94cabdff1aSopenharmony_ci // Additional textual information string 95cabdff1aSopenharmony_ci skip_bits_long(&s->gb, text_size * 8); 96cabdff1aSopenharmony_ci } 97cabdff1aSopenharmony_ci 98cabdff1aSopenharmony_ci // PCM bit resolution 99cabdff1aSopenharmony_ci asset->pcm_bit_res = get_bits(&s->gb, 5) + 1; 100cabdff1aSopenharmony_ci 101cabdff1aSopenharmony_ci // Maximum sample rate 102cabdff1aSopenharmony_ci asset->max_sample_rate = ff_dca_sampling_freqs[get_bits(&s->gb, 4)]; 103cabdff1aSopenharmony_ci 104cabdff1aSopenharmony_ci // Total number of channels 105cabdff1aSopenharmony_ci asset->nchannels_total = get_bits(&s->gb, 8) + 1; 106cabdff1aSopenharmony_ci 107cabdff1aSopenharmony_ci // One to one map channel to speakers 108cabdff1aSopenharmony_ci if (asset->one_to_one_map_ch_to_spkr = get_bits1(&s->gb)) { 109cabdff1aSopenharmony_ci int spkr_mask_nbits = 0; 110cabdff1aSopenharmony_ci int spkr_remap_nsets; 111cabdff1aSopenharmony_ci int nspeakers[8]; 112cabdff1aSopenharmony_ci 113cabdff1aSopenharmony_ci // Embedded stereo flag 114cabdff1aSopenharmony_ci asset->embedded_stereo = asset->nchannels_total > 2 && get_bits1(&s->gb); 115cabdff1aSopenharmony_ci 116cabdff1aSopenharmony_ci // Embedded 6 channels flag 117cabdff1aSopenharmony_ci asset->embedded_6ch = asset->nchannels_total > 6 && get_bits1(&s->gb); 118cabdff1aSopenharmony_ci 119cabdff1aSopenharmony_ci // Speaker mask enabled flag 120cabdff1aSopenharmony_ci if (asset->spkr_mask_enabled = get_bits1(&s->gb)) { 121cabdff1aSopenharmony_ci // Number of bits for speaker activity mask 122cabdff1aSopenharmony_ci spkr_mask_nbits = (get_bits(&s->gb, 2) + 1) << 2; 123cabdff1aSopenharmony_ci 124cabdff1aSopenharmony_ci // Loudspeaker activity mask 125cabdff1aSopenharmony_ci asset->spkr_mask = get_bits(&s->gb, spkr_mask_nbits); 126cabdff1aSopenharmony_ci } 127cabdff1aSopenharmony_ci 128cabdff1aSopenharmony_ci // Number of speaker remapping sets 129cabdff1aSopenharmony_ci if ((spkr_remap_nsets = get_bits(&s->gb, 3)) && !spkr_mask_nbits) { 130cabdff1aSopenharmony_ci if (s->avctx) 131cabdff1aSopenharmony_ci av_log(s->avctx, AV_LOG_ERROR, "Speaker mask disabled yet there are remapping sets\n"); 132cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 133cabdff1aSopenharmony_ci } 134cabdff1aSopenharmony_ci 135cabdff1aSopenharmony_ci // Standard loudspeaker layout mask 136cabdff1aSopenharmony_ci for (i = 0; i < spkr_remap_nsets; i++) 137cabdff1aSopenharmony_ci nspeakers[i] = ff_dca_count_chs_for_mask(get_bits(&s->gb, spkr_mask_nbits)); 138cabdff1aSopenharmony_ci 139cabdff1aSopenharmony_ci for (i = 0; i < spkr_remap_nsets; i++) { 140cabdff1aSopenharmony_ci // Number of channels to be decoded for speaker remapping 141cabdff1aSopenharmony_ci int nch_for_remaps = get_bits(&s->gb, 5) + 1; 142cabdff1aSopenharmony_ci 143cabdff1aSopenharmony_ci for (j = 0; j < nspeakers[i]; j++) { 144cabdff1aSopenharmony_ci // Decoded channels to output speaker mapping mask 145cabdff1aSopenharmony_ci int remap_ch_mask = get_bits_long(&s->gb, nch_for_remaps); 146cabdff1aSopenharmony_ci 147cabdff1aSopenharmony_ci // Loudspeaker remapping codes 148cabdff1aSopenharmony_ci skip_bits_long(&s->gb, av_popcount(remap_ch_mask) * 5); 149cabdff1aSopenharmony_ci } 150cabdff1aSopenharmony_ci } 151cabdff1aSopenharmony_ci } else { 152cabdff1aSopenharmony_ci asset->embedded_stereo = 0; 153cabdff1aSopenharmony_ci asset->embedded_6ch = 0; 154cabdff1aSopenharmony_ci asset->spkr_mask_enabled = 0; 155cabdff1aSopenharmony_ci asset->spkr_mask = 0; 156cabdff1aSopenharmony_ci 157cabdff1aSopenharmony_ci // Representation type 158cabdff1aSopenharmony_ci asset->representation_type = get_bits(&s->gb, 3); 159cabdff1aSopenharmony_ci } 160cabdff1aSopenharmony_ci } 161cabdff1aSopenharmony_ci 162cabdff1aSopenharmony_ci // 163cabdff1aSopenharmony_ci // DRC, DNC and mixing metadata 164cabdff1aSopenharmony_ci // 165cabdff1aSopenharmony_ci 166cabdff1aSopenharmony_ci // Dynamic range coefficient presence flag 167cabdff1aSopenharmony_ci drc_present = get_bits1(&s->gb); 168cabdff1aSopenharmony_ci 169cabdff1aSopenharmony_ci // Code for dynamic range coefficient 170cabdff1aSopenharmony_ci if (drc_present) 171cabdff1aSopenharmony_ci skip_bits(&s->gb, 8); 172cabdff1aSopenharmony_ci 173cabdff1aSopenharmony_ci // Dialog normalization presence flag 174cabdff1aSopenharmony_ci if (get_bits1(&s->gb)) 175cabdff1aSopenharmony_ci // Dialog normalization code 176cabdff1aSopenharmony_ci skip_bits(&s->gb, 5); 177cabdff1aSopenharmony_ci 178cabdff1aSopenharmony_ci // DRC for stereo downmix 179cabdff1aSopenharmony_ci if (drc_present && asset->embedded_stereo) 180cabdff1aSopenharmony_ci skip_bits(&s->gb, 8); 181cabdff1aSopenharmony_ci 182cabdff1aSopenharmony_ci // Mixing metadata presence flag 183cabdff1aSopenharmony_ci if (s->mix_metadata_enabled && get_bits1(&s->gb)) { 184cabdff1aSopenharmony_ci int nchannels_dmix; 185cabdff1aSopenharmony_ci 186cabdff1aSopenharmony_ci // External mixing flag 187cabdff1aSopenharmony_ci skip_bits1(&s->gb); 188cabdff1aSopenharmony_ci 189cabdff1aSopenharmony_ci // Post mixing / replacement gain adjustment 190cabdff1aSopenharmony_ci skip_bits(&s->gb, 6); 191cabdff1aSopenharmony_ci 192cabdff1aSopenharmony_ci // DRC prior to mixing 193cabdff1aSopenharmony_ci if (get_bits(&s->gb, 2) == 3) 194cabdff1aSopenharmony_ci // Custom code for mixing DRC 195cabdff1aSopenharmony_ci skip_bits(&s->gb, 8); 196cabdff1aSopenharmony_ci else 197cabdff1aSopenharmony_ci // Limit for mixing DRC 198cabdff1aSopenharmony_ci skip_bits(&s->gb, 3); 199cabdff1aSopenharmony_ci 200cabdff1aSopenharmony_ci // Scaling type for channels of main audio 201cabdff1aSopenharmony_ci // Scaling parameters of main audio 202cabdff1aSopenharmony_ci if (get_bits1(&s->gb)) 203cabdff1aSopenharmony_ci for (i = 0; i < s->nmixoutconfigs; i++) 204cabdff1aSopenharmony_ci skip_bits_long(&s->gb, 6 * s->nmixoutchs[i]); 205cabdff1aSopenharmony_ci else 206cabdff1aSopenharmony_ci skip_bits_long(&s->gb, 6 * s->nmixoutconfigs); 207cabdff1aSopenharmony_ci 208cabdff1aSopenharmony_ci nchannels_dmix = asset->nchannels_total; 209cabdff1aSopenharmony_ci if (asset->embedded_6ch) 210cabdff1aSopenharmony_ci nchannels_dmix += 6; 211cabdff1aSopenharmony_ci if (asset->embedded_stereo) 212cabdff1aSopenharmony_ci nchannels_dmix += 2; 213cabdff1aSopenharmony_ci 214cabdff1aSopenharmony_ci for (i = 0; i < s->nmixoutconfigs; i++) { 215cabdff1aSopenharmony_ci if (!s->nmixoutchs[i]) { 216cabdff1aSopenharmony_ci if (s->avctx) 217cabdff1aSopenharmony_ci av_log(s->avctx, AV_LOG_ERROR, "Invalid speaker layout mask for mixing configuration\n"); 218cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 219cabdff1aSopenharmony_ci } 220cabdff1aSopenharmony_ci for (j = 0; j < nchannels_dmix; j++) { 221cabdff1aSopenharmony_ci // Mix output mask 222cabdff1aSopenharmony_ci int mix_map_mask = get_bits(&s->gb, s->nmixoutchs[i]); 223cabdff1aSopenharmony_ci 224cabdff1aSopenharmony_ci // Mixing coefficients 225cabdff1aSopenharmony_ci skip_bits_long(&s->gb, av_popcount(mix_map_mask) * 6); 226cabdff1aSopenharmony_ci } 227cabdff1aSopenharmony_ci } 228cabdff1aSopenharmony_ci } 229cabdff1aSopenharmony_ci 230cabdff1aSopenharmony_ci // 231cabdff1aSopenharmony_ci // Decoder navigation data 232cabdff1aSopenharmony_ci // 233cabdff1aSopenharmony_ci 234cabdff1aSopenharmony_ci // Coding mode for the asset 235cabdff1aSopenharmony_ci asset->coding_mode = get_bits(&s->gb, 2); 236cabdff1aSopenharmony_ci 237cabdff1aSopenharmony_ci // Coding components used in asset 238cabdff1aSopenharmony_ci switch (asset->coding_mode) { 239cabdff1aSopenharmony_ci case 0: // Coding mode that may contain multiple coding components 240cabdff1aSopenharmony_ci asset->extension_mask = get_bits(&s->gb, 12); 241cabdff1aSopenharmony_ci 242cabdff1aSopenharmony_ci if (asset->extension_mask & DCA_EXSS_CORE) { 243cabdff1aSopenharmony_ci // Size of core component in extension substream 244cabdff1aSopenharmony_ci asset->core_size = get_bits(&s->gb, 14) + 1; 245cabdff1aSopenharmony_ci // Core sync word present flag 246cabdff1aSopenharmony_ci if (get_bits1(&s->gb)) 247cabdff1aSopenharmony_ci // Core sync distance 248cabdff1aSopenharmony_ci skip_bits(&s->gb, 2); 249cabdff1aSopenharmony_ci } 250cabdff1aSopenharmony_ci 251cabdff1aSopenharmony_ci if (asset->extension_mask & DCA_EXSS_XBR) 252cabdff1aSopenharmony_ci // Size of XBR extension in extension substream 253cabdff1aSopenharmony_ci asset->xbr_size = get_bits(&s->gb, 14) + 1; 254cabdff1aSopenharmony_ci 255cabdff1aSopenharmony_ci if (asset->extension_mask & DCA_EXSS_XXCH) 256cabdff1aSopenharmony_ci // Size of XXCH extension in extension substream 257cabdff1aSopenharmony_ci asset->xxch_size = get_bits(&s->gb, 14) + 1; 258cabdff1aSopenharmony_ci 259cabdff1aSopenharmony_ci if (asset->extension_mask & DCA_EXSS_X96) 260cabdff1aSopenharmony_ci // Size of X96 extension in extension substream 261cabdff1aSopenharmony_ci asset->x96_size = get_bits(&s->gb, 12) + 1; 262cabdff1aSopenharmony_ci 263cabdff1aSopenharmony_ci if (asset->extension_mask & DCA_EXSS_LBR) 264cabdff1aSopenharmony_ci parse_lbr_parameters(s, asset); 265cabdff1aSopenharmony_ci 266cabdff1aSopenharmony_ci if (asset->extension_mask & DCA_EXSS_XLL) 267cabdff1aSopenharmony_ci parse_xll_parameters(s, asset); 268cabdff1aSopenharmony_ci 269cabdff1aSopenharmony_ci if (asset->extension_mask & DCA_EXSS_RSV1) 270cabdff1aSopenharmony_ci skip_bits(&s->gb, 16); 271cabdff1aSopenharmony_ci 272cabdff1aSopenharmony_ci if (asset->extension_mask & DCA_EXSS_RSV2) 273cabdff1aSopenharmony_ci skip_bits(&s->gb, 16); 274cabdff1aSopenharmony_ci break; 275cabdff1aSopenharmony_ci 276cabdff1aSopenharmony_ci case 1: // Loss-less coding mode without CBR component 277cabdff1aSopenharmony_ci asset->extension_mask = DCA_EXSS_XLL; 278cabdff1aSopenharmony_ci parse_xll_parameters(s, asset); 279cabdff1aSopenharmony_ci break; 280cabdff1aSopenharmony_ci 281cabdff1aSopenharmony_ci case 2: // Low bit rate mode 282cabdff1aSopenharmony_ci asset->extension_mask = DCA_EXSS_LBR; 283cabdff1aSopenharmony_ci parse_lbr_parameters(s, asset); 284cabdff1aSopenharmony_ci break; 285cabdff1aSopenharmony_ci 286cabdff1aSopenharmony_ci case 3: // Auxiliary coding mode 287cabdff1aSopenharmony_ci asset->extension_mask = 0; 288cabdff1aSopenharmony_ci 289cabdff1aSopenharmony_ci // Size of auxiliary coded data 290cabdff1aSopenharmony_ci skip_bits(&s->gb, 14); 291cabdff1aSopenharmony_ci 292cabdff1aSopenharmony_ci // Auxiliary codec identification 293cabdff1aSopenharmony_ci skip_bits(&s->gb, 8); 294cabdff1aSopenharmony_ci 295cabdff1aSopenharmony_ci // Aux sync word present flag 296cabdff1aSopenharmony_ci if (get_bits1(&s->gb)) 297cabdff1aSopenharmony_ci // Aux sync distance 298cabdff1aSopenharmony_ci skip_bits(&s->gb, 3); 299cabdff1aSopenharmony_ci break; 300cabdff1aSopenharmony_ci } 301cabdff1aSopenharmony_ci 302cabdff1aSopenharmony_ci if (asset->extension_mask & DCA_EXSS_XLL) 303cabdff1aSopenharmony_ci // DTS-HD stream ID 304cabdff1aSopenharmony_ci asset->hd_stream_id = get_bits(&s->gb, 3); 305cabdff1aSopenharmony_ci 306cabdff1aSopenharmony_ci // One to one mixing flag 307cabdff1aSopenharmony_ci // Per channel main audio scaling flag 308cabdff1aSopenharmony_ci // Main audio scaling codes 309cabdff1aSopenharmony_ci // Decode asset in secondary decoder flag 310cabdff1aSopenharmony_ci // Revision 2 DRC metadata 311cabdff1aSopenharmony_ci // Reserved 312cabdff1aSopenharmony_ci // Zero pad 313cabdff1aSopenharmony_ci if (ff_dca_seek_bits(&s->gb, descr_pos + descr_size * 8)) { 314cabdff1aSopenharmony_ci if (s->avctx) 315cabdff1aSopenharmony_ci av_log(s->avctx, AV_LOG_ERROR, "Read past end of EXSS asset descriptor\n"); 316cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 317cabdff1aSopenharmony_ci } 318cabdff1aSopenharmony_ci 319cabdff1aSopenharmony_ci return 0; 320cabdff1aSopenharmony_ci} 321cabdff1aSopenharmony_ci 322cabdff1aSopenharmony_cistatic int set_exss_offsets(DCAExssAsset *asset) 323cabdff1aSopenharmony_ci{ 324cabdff1aSopenharmony_ci int offs = asset->asset_offset; 325cabdff1aSopenharmony_ci int size = asset->asset_size; 326cabdff1aSopenharmony_ci 327cabdff1aSopenharmony_ci if (asset->extension_mask & DCA_EXSS_CORE) { 328cabdff1aSopenharmony_ci asset->core_offset = offs; 329cabdff1aSopenharmony_ci if (asset->core_size > size) 330cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 331cabdff1aSopenharmony_ci offs += asset->core_size; 332cabdff1aSopenharmony_ci size -= asset->core_size; 333cabdff1aSopenharmony_ci } 334cabdff1aSopenharmony_ci 335cabdff1aSopenharmony_ci if (asset->extension_mask & DCA_EXSS_XBR) { 336cabdff1aSopenharmony_ci asset->xbr_offset = offs; 337cabdff1aSopenharmony_ci if (asset->xbr_size > size) 338cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 339cabdff1aSopenharmony_ci offs += asset->xbr_size; 340cabdff1aSopenharmony_ci size -= asset->xbr_size; 341cabdff1aSopenharmony_ci } 342cabdff1aSopenharmony_ci 343cabdff1aSopenharmony_ci if (asset->extension_mask & DCA_EXSS_XXCH) { 344cabdff1aSopenharmony_ci asset->xxch_offset = offs; 345cabdff1aSopenharmony_ci if (asset->xxch_size > size) 346cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 347cabdff1aSopenharmony_ci offs += asset->xxch_size; 348cabdff1aSopenharmony_ci size -= asset->xxch_size; 349cabdff1aSopenharmony_ci } 350cabdff1aSopenharmony_ci 351cabdff1aSopenharmony_ci if (asset->extension_mask & DCA_EXSS_X96) { 352cabdff1aSopenharmony_ci asset->x96_offset = offs; 353cabdff1aSopenharmony_ci if (asset->x96_size > size) 354cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 355cabdff1aSopenharmony_ci offs += asset->x96_size; 356cabdff1aSopenharmony_ci size -= asset->x96_size; 357cabdff1aSopenharmony_ci } 358cabdff1aSopenharmony_ci 359cabdff1aSopenharmony_ci if (asset->extension_mask & DCA_EXSS_LBR) { 360cabdff1aSopenharmony_ci asset->lbr_offset = offs; 361cabdff1aSopenharmony_ci if (asset->lbr_size > size) 362cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 363cabdff1aSopenharmony_ci offs += asset->lbr_size; 364cabdff1aSopenharmony_ci size -= asset->lbr_size; 365cabdff1aSopenharmony_ci } 366cabdff1aSopenharmony_ci 367cabdff1aSopenharmony_ci if (asset->extension_mask & DCA_EXSS_XLL) { 368cabdff1aSopenharmony_ci asset->xll_offset = offs; 369cabdff1aSopenharmony_ci if (asset->xll_size > size) 370cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 371cabdff1aSopenharmony_ci offs += asset->xll_size; 372cabdff1aSopenharmony_ci size -= asset->xll_size; 373cabdff1aSopenharmony_ci } 374cabdff1aSopenharmony_ci 375cabdff1aSopenharmony_ci return 0; 376cabdff1aSopenharmony_ci} 377cabdff1aSopenharmony_ci 378cabdff1aSopenharmony_ciint ff_dca_exss_parse(DCAExssParser *s, const uint8_t *data, int size) 379cabdff1aSopenharmony_ci{ 380cabdff1aSopenharmony_ci int i, ret, offset, wide_hdr, header_size; 381cabdff1aSopenharmony_ci 382cabdff1aSopenharmony_ci if ((ret = init_get_bits8(&s->gb, data, size)) < 0) 383cabdff1aSopenharmony_ci return ret; 384cabdff1aSopenharmony_ci 385cabdff1aSopenharmony_ci // Extension substream sync word 386cabdff1aSopenharmony_ci skip_bits_long(&s->gb, 32); 387cabdff1aSopenharmony_ci 388cabdff1aSopenharmony_ci // User defined bits 389cabdff1aSopenharmony_ci skip_bits(&s->gb, 8); 390cabdff1aSopenharmony_ci 391cabdff1aSopenharmony_ci // Extension substream index 392cabdff1aSopenharmony_ci s->exss_index = get_bits(&s->gb, 2); 393cabdff1aSopenharmony_ci 394cabdff1aSopenharmony_ci // Flag indicating short or long header size 395cabdff1aSopenharmony_ci wide_hdr = get_bits1(&s->gb); 396cabdff1aSopenharmony_ci 397cabdff1aSopenharmony_ci // Extension substream header length 398cabdff1aSopenharmony_ci header_size = get_bits(&s->gb, 8 + 4 * wide_hdr) + 1; 399cabdff1aSopenharmony_ci 400cabdff1aSopenharmony_ci // Check CRC 401cabdff1aSopenharmony_ci if (s->avctx && ff_dca_check_crc(s->avctx, &s->gb, 32 + 8, header_size * 8)) { 402cabdff1aSopenharmony_ci av_log(s->avctx, AV_LOG_ERROR, "Invalid EXSS header checksum\n"); 403cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 404cabdff1aSopenharmony_ci } 405cabdff1aSopenharmony_ci 406cabdff1aSopenharmony_ci s->exss_size_nbits = 16 + 4 * wide_hdr; 407cabdff1aSopenharmony_ci 408cabdff1aSopenharmony_ci // Number of bytes of extension substream 409cabdff1aSopenharmony_ci s->exss_size = get_bits(&s->gb, s->exss_size_nbits) + 1; 410cabdff1aSopenharmony_ci if (s->exss_size > size) { 411cabdff1aSopenharmony_ci if (s->avctx) 412cabdff1aSopenharmony_ci av_log(s->avctx, AV_LOG_ERROR, "Packet too short for EXSS frame\n"); 413cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 414cabdff1aSopenharmony_ci } 415cabdff1aSopenharmony_ci 416cabdff1aSopenharmony_ci // Per stream static fields presence flag 417cabdff1aSopenharmony_ci if (s->static_fields_present = get_bits1(&s->gb)) { 418cabdff1aSopenharmony_ci int active_exss_mask[8]; 419cabdff1aSopenharmony_ci 420cabdff1aSopenharmony_ci // Reference clock code 421cabdff1aSopenharmony_ci skip_bits(&s->gb, 2); 422cabdff1aSopenharmony_ci 423cabdff1aSopenharmony_ci // Extension substream frame duration 424cabdff1aSopenharmony_ci skip_bits(&s->gb, 3); 425cabdff1aSopenharmony_ci 426cabdff1aSopenharmony_ci // Timecode presence flag 427cabdff1aSopenharmony_ci if (get_bits1(&s->gb)) 428cabdff1aSopenharmony_ci // Timecode data 429cabdff1aSopenharmony_ci skip_bits_long(&s->gb, 36); 430cabdff1aSopenharmony_ci 431cabdff1aSopenharmony_ci // Number of defined audio presentations 432cabdff1aSopenharmony_ci s->npresents = get_bits(&s->gb, 3) + 1; 433cabdff1aSopenharmony_ci if (s->npresents > 1) { 434cabdff1aSopenharmony_ci if (s->avctx) 435cabdff1aSopenharmony_ci avpriv_request_sample(s->avctx, "%d audio presentations", s->npresents); 436cabdff1aSopenharmony_ci return AVERROR_PATCHWELCOME; 437cabdff1aSopenharmony_ci } 438cabdff1aSopenharmony_ci 439cabdff1aSopenharmony_ci // Number of audio assets in extension substream 440cabdff1aSopenharmony_ci s->nassets = get_bits(&s->gb, 3) + 1; 441cabdff1aSopenharmony_ci if (s->nassets > 1) { 442cabdff1aSopenharmony_ci if (s->avctx) 443cabdff1aSopenharmony_ci avpriv_request_sample(s->avctx, "%d audio assets", s->nassets); 444cabdff1aSopenharmony_ci return AVERROR_PATCHWELCOME; 445cabdff1aSopenharmony_ci } 446cabdff1aSopenharmony_ci 447cabdff1aSopenharmony_ci // Active extension substream mask for audio presentation 448cabdff1aSopenharmony_ci for (i = 0; i < s->npresents; i++) 449cabdff1aSopenharmony_ci active_exss_mask[i] = get_bits(&s->gb, s->exss_index + 1); 450cabdff1aSopenharmony_ci 451cabdff1aSopenharmony_ci // Active audio asset mask 452cabdff1aSopenharmony_ci for (i = 0; i < s->npresents; i++) 453cabdff1aSopenharmony_ci skip_bits_long(&s->gb, av_popcount(active_exss_mask[i]) * 8); 454cabdff1aSopenharmony_ci 455cabdff1aSopenharmony_ci // Mixing metadata enable flag 456cabdff1aSopenharmony_ci if (s->mix_metadata_enabled = get_bits1(&s->gb)) { 457cabdff1aSopenharmony_ci int spkr_mask_nbits; 458cabdff1aSopenharmony_ci 459cabdff1aSopenharmony_ci // Mixing metadata adjustment level 460cabdff1aSopenharmony_ci skip_bits(&s->gb, 2); 461cabdff1aSopenharmony_ci 462cabdff1aSopenharmony_ci // Number of bits for mixer output speaker activity mask 463cabdff1aSopenharmony_ci spkr_mask_nbits = (get_bits(&s->gb, 2) + 1) << 2; 464cabdff1aSopenharmony_ci 465cabdff1aSopenharmony_ci // Number of mixing configurations 466cabdff1aSopenharmony_ci s->nmixoutconfigs = get_bits(&s->gb, 2) + 1; 467cabdff1aSopenharmony_ci 468cabdff1aSopenharmony_ci // Speaker layout mask for mixer output channels 469cabdff1aSopenharmony_ci for (i = 0; i < s->nmixoutconfigs; i++) 470cabdff1aSopenharmony_ci s->nmixoutchs[i] = ff_dca_count_chs_for_mask(get_bits(&s->gb, spkr_mask_nbits)); 471cabdff1aSopenharmony_ci } 472cabdff1aSopenharmony_ci } else { 473cabdff1aSopenharmony_ci s->npresents = 1; 474cabdff1aSopenharmony_ci s->nassets = 1; 475cabdff1aSopenharmony_ci } 476cabdff1aSopenharmony_ci 477cabdff1aSopenharmony_ci // Size of encoded asset data in bytes 478cabdff1aSopenharmony_ci offset = header_size; 479cabdff1aSopenharmony_ci for (i = 0; i < s->nassets; i++) { 480cabdff1aSopenharmony_ci s->assets[i].asset_offset = offset; 481cabdff1aSopenharmony_ci s->assets[i].asset_size = get_bits(&s->gb, s->exss_size_nbits) + 1; 482cabdff1aSopenharmony_ci offset += s->assets[i].asset_size; 483cabdff1aSopenharmony_ci if (offset > s->exss_size) { 484cabdff1aSopenharmony_ci if (s->avctx) 485cabdff1aSopenharmony_ci av_log(s->avctx, AV_LOG_ERROR, "EXSS asset out of bounds\n"); 486cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 487cabdff1aSopenharmony_ci } 488cabdff1aSopenharmony_ci } 489cabdff1aSopenharmony_ci 490cabdff1aSopenharmony_ci // Audio asset descriptor 491cabdff1aSopenharmony_ci for (i = 0; i < s->nassets; i++) { 492cabdff1aSopenharmony_ci if ((ret = parse_descriptor(s, &s->assets[i])) < 0) 493cabdff1aSopenharmony_ci return ret; 494cabdff1aSopenharmony_ci if ((ret = set_exss_offsets(&s->assets[i])) < 0) { 495cabdff1aSopenharmony_ci if (s->avctx) 496cabdff1aSopenharmony_ci av_log(s->avctx, AV_LOG_ERROR, "Invalid extension size in EXSS asset descriptor\n"); 497cabdff1aSopenharmony_ci return ret; 498cabdff1aSopenharmony_ci } 499cabdff1aSopenharmony_ci } 500cabdff1aSopenharmony_ci 501cabdff1aSopenharmony_ci // Backward compatible core present 502cabdff1aSopenharmony_ci // Backward compatible core substream index 503cabdff1aSopenharmony_ci // Backward compatible core asset index 504cabdff1aSopenharmony_ci // Reserved 505cabdff1aSopenharmony_ci // Byte align 506cabdff1aSopenharmony_ci // CRC16 of extension substream header 507cabdff1aSopenharmony_ci if (ff_dca_seek_bits(&s->gb, header_size * 8)) { 508cabdff1aSopenharmony_ci if (s->avctx) 509cabdff1aSopenharmony_ci av_log(s->avctx, AV_LOG_ERROR, "Read past end of EXSS header\n"); 510cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 511cabdff1aSopenharmony_ci } 512cabdff1aSopenharmony_ci 513cabdff1aSopenharmony_ci return 0; 514cabdff1aSopenharmony_ci} 515