xref: /third_party/ffmpeg/libavcodec/dca_exss.c (revision cabdff1a)
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