514 lines · 16.0 KB · C
RawDownload
/* * 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;        }    } 

Lines 1–500 of 514.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t