dca_parser.c 11.3 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
/*
 * DCA parser
 * Copyright (C) 2004 Gildas Bazin
 * Copyright (C) 2004 Benjamin Zores
 * Copyright (C) 2006 Benjamin Larsson
 * Copyright (C) 2007 Konstantin Shishkov
 *
 * 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 "dca.h"
26
#include "dca_core.h"
27
#include "dca_exss.h"
28
#include "dca_lbr.h"
29
#include "dca_syncwords.h"
30
#include "get_bits.h"
31
#include "parser.h"
32 33 34 35

typedef struct DCAParseContext {
    ParseContext pc;
    uint32_t lastmarker;
36 37
    int size;
    int framesize;
38
    unsigned int startpos;
39 40
    DCAExssParser exss;
    unsigned int sr_code;
41 42
} DCAParseContext;

43 44 45 46 47 48 49 50
#define IS_CORE_MARKER(state) \
    (((state & 0xFFFFFFFFF0FF) == (((uint64_t)DCA_SYNCWORD_CORE_14B_LE << 16) | 0xF007)) || \
     ((state & 0xFFFFFFFFFFF0) == (((uint64_t)DCA_SYNCWORD_CORE_14B_BE << 16) | 0x07F0)) || \
     ((state & 0xFFFFFFFF00FC) == (((uint64_t)DCA_SYNCWORD_CORE_LE     << 16) | 0x00FC)) || \
     ((state & 0xFFFFFFFFFC00) == (((uint64_t)DCA_SYNCWORD_CORE_BE     << 16) | 0xFC00)))

#define IS_EXSS_MARKER(state)   ((state & 0xFFFFFFFF) == DCA_SYNCWORD_SUBSTREAM)

51
#define IS_MARKER(state)        (IS_CORE_MARKER(state) || IS_EXSS_MARKER(state))
52

53 54
#define CORE_MARKER(state)      ((state >> 16) & 0xFFFFFFFF)
#define EXSS_MARKER(state)      (state & 0xFFFFFFFF)
55

56 57 58 59 60 61 62 63
#define STATE_LE(state)     (((state & 0xFF00FF00) >> 8) | ((state & 0x00FF00FF) << 8))
#define STATE_14(state)     (((state & 0x3FFF0000) >> 8) | ((state & 0x00003FFF) >> 6))

#define CORE_FRAMESIZE(state)   (((state >> 4) & 0x3FFF) + 1)
#define EXSS_FRAMESIZE(state)   ((state & 0x2000000000) ? \
                                 ((state >>  5) & 0xFFFFF) + 1 : \
                                 ((state >> 13) & 0x0FFFF) + 1)

64
/**
65
 * Find the end of the current frame in the bitstream.
66 67
 * @return the position of the first byte of the next frame, or -1
 */
68
static int dca_find_frame_end(DCAParseContext *pc1, const uint8_t *buf,
69 70
                              int buf_size)
{
71
    int start_found, size, i;
72
    uint64_t state;
73 74 75
    ParseContext *pc = &pc1->pc;

    start_found = pc->frame_start_found;
76
    state       = pc->state64;
77
    size        = pc1->size;
78 79 80

    i = 0;
    if (!start_found) {
81 82
        for (; i < buf_size; i++) {
            size++;
83
            state = (state << 8) | buf[i];
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101

            if (IS_MARKER(state) &&
                (!pc1->lastmarker ||
                  pc1->lastmarker == CORE_MARKER(state) ||
                  pc1->lastmarker == DCA_SYNCWORD_SUBSTREAM)) {
                if (!pc1->lastmarker)
                    pc1->startpos = IS_EXSS_MARKER(state) ? size - 4 : size - 6;

                if (IS_EXSS_MARKER(state))
                    pc1->lastmarker = EXSS_MARKER(state);
                else
                    pc1->lastmarker = CORE_MARKER(state);

                start_found = 1;
                size        = 0;

                i++;
                break;
102 103 104
            }
        }
    }
105

106 107
    if (start_found) {
        for (; i < buf_size; i++) {
108
            size++;
109
            state = (state << 8) | buf[i];
110 111 112 113 114 115 116 117 118 119 120 121

            if (start_found == 1) {
                switch (pc1->lastmarker) {
                case DCA_SYNCWORD_CORE_BE:
                    if (size == 2) {
                        pc1->framesize = CORE_FRAMESIZE(state);
                        start_found    = 2;
                    }
                    break;
                case DCA_SYNCWORD_CORE_LE:
                    if (size == 2) {
                        pc1->framesize = CORE_FRAMESIZE(STATE_LE(state));
122
                        start_found    = 4;
123 124 125 126
                    }
                    break;
                case DCA_SYNCWORD_CORE_14B_BE:
                    if (size == 4) {
127
                        pc1->framesize = CORE_FRAMESIZE(STATE_14(state));
128
                        start_found    = 4;
129 130 131 132
                    }
                    break;
                case DCA_SYNCWORD_CORE_14B_LE:
                    if (size == 4) {
133
                        pc1->framesize = CORE_FRAMESIZE(STATE_14(STATE_LE(state)));
134
                        start_found    = 4;
135 136 137 138 139
                    }
                    break;
                case DCA_SYNCWORD_SUBSTREAM:
                    if (size == 6) {
                        pc1->framesize = EXSS_FRAMESIZE(state);
140
                        start_found    = 4;
141 142 143 144 145 146 147 148
                    }
                    break;
                default:
                    av_assert0(0);
                }
                continue;
            }

149 150 151 152 153 154
            if (start_found == 2 && IS_EXSS_MARKER(state) &&
                pc1->framesize <= size + 2) {
                pc1->framesize  = size + 2;
                start_found     = 3;
                continue;
            }
155

156 157 158 159
            if (start_found == 3) {
                if (size == pc1->framesize + 4) {
                    pc1->framesize += EXSS_FRAMESIZE(state);
                    start_found     = 4;
160
                }
161
                continue;
162 163 164 165 166
            }

            if (pc1->framesize > size)
                continue;

167 168 169
            if (IS_MARKER(state) &&
                (pc1->lastmarker == CORE_MARKER(state) ||
                 pc1->lastmarker == DCA_SYNCWORD_SUBSTREAM)) {
170
                pc->frame_start_found = 0;
171
                pc->state64           = -1;
172
                pc1->size             = 0;
173
                return IS_EXSS_MARKER(state) ? i - 3 : i - 5;
174 175 176
            }
        }
    }
177

178
    pc->frame_start_found = start_found;
179
    pc->state64           = state;
180
    pc1->size             = size;
181 182 183
    return END_NOT_FOUND;
}

184
static av_cold int dca_parse_init(AVCodecParserContext *s)
185 186 187 188
{
    DCAParseContext *pc1 = s->priv_data;

    pc1->lastmarker = 0;
189
    pc1->sr_code = -1;
190 191 192
    return 0;
}

193
static int dca_parse_params(DCAParseContext *pc1, const uint8_t *buf,
194 195
                            int buf_size, int *duration, int *sample_rate,
                            int *profile)
196
{
197
    DCAExssAsset *asset = &pc1->exss.assets[0];
198
    GetBitContext gb;
199 200
    DCACoreFrameHeader h;
    uint8_t hdr[DCA_CORE_FRAME_HEADER_SIZE + AV_INPUT_BUFFER_PADDING_SIZE] = { 0 };
201
    int ret, frame_size;
202

203
    if (buf_size < DCA_CORE_FRAME_HEADER_SIZE)
204 205
        return AVERROR_INVALIDDATA;

206 207 208 209 210 211 212 213 214 215 216 217
    if (AV_RB32(buf) == DCA_SYNCWORD_SUBSTREAM) {
        if ((ret = ff_dca_exss_parse(&pc1->exss, buf, buf_size)) < 0)
            return ret;

        if (asset->extension_mask & DCA_EXSS_LBR) {
            if ((ret = init_get_bits8(&gb, buf + asset->lbr_offset, asset->lbr_size)) < 0)
                return ret;

            if (get_bits_long(&gb, 32) != DCA_SYNCWORD_LBR)
                return AVERROR_INVALIDDATA;

            switch (get_bits(&gb, 8)) {
218
            case DCA_LBR_HEADER_DECODER_INIT:
219
                pc1->sr_code = get_bits(&gb, 8);
220
            case DCA_LBR_HEADER_SYNC_ONLY:
221 222 223 224 225 226 227 228 229 230
                break;
            default:
                return AVERROR_INVALIDDATA;
            }

            if (pc1->sr_code >= FF_ARRAY_ELEMS(ff_dca_sampling_freqs))
                return AVERROR_INVALIDDATA;

            *sample_rate = ff_dca_sampling_freqs[pc1->sr_code];
            *duration = 1024 << ff_dca_freq_ranges[pc1->sr_code];
231
            *profile = FF_PROFILE_DTS_EXPRESS;
232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
            return 0;
        }

        if (asset->extension_mask & DCA_EXSS_XLL) {
            int nsamples_log2;

            if ((ret = init_get_bits8(&gb, buf + asset->xll_offset, asset->xll_size)) < 0)
                return ret;

            if (get_bits_long(&gb, 32) != DCA_SYNCWORD_XLL)
                return AVERROR_INVALIDDATA;

            if (get_bits(&gb, 4))
                return AVERROR_INVALIDDATA;

            skip_bits(&gb, 8);
            skip_bits_long(&gb, get_bits(&gb, 5) + 1);
            skip_bits(&gb, 4);
            nsamples_log2 = get_bits(&gb, 4) + get_bits(&gb, 4);
            if (nsamples_log2 > 24)
                return AVERROR_INVALIDDATA;

            *sample_rate = asset->max_sample_rate;
            *duration = (1 + (*sample_rate > 96000)) << nsamples_log2;
256
            *profile = FF_PROFILE_DTS_HD_MA;
257 258 259 260 261 262
            return 0;
        }

        return AVERROR_INVALIDDATA;
    }

263 264
    if ((ret = avpriv_dca_convert_bitstream(buf, DCA_CORE_FRAME_HEADER_SIZE,
                                            hdr, DCA_CORE_FRAME_HEADER_SIZE)) < 0)
265
        return ret;
266
    if (avpriv_dca_parse_core_frame_header(&h, hdr, ret) < 0)
267 268
        return AVERROR_INVALIDDATA;

269
    *duration = h.npcmblocks * DCA_PCMBLOCK_SAMPLES;
270
    *sample_rate = avpriv_dca_sample_rates[h.sr_code];
271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301
    if (*profile != FF_PROFILE_UNKNOWN)
        return 0;

    *profile = FF_PROFILE_DTS;
    if (h.ext_audio_present) {
        switch (h.ext_audio_type) {
        case DCA_EXT_AUDIO_XCH:
        case DCA_EXT_AUDIO_XXCH:
            *profile = FF_PROFILE_DTS_ES;
            break;
        case DCA_EXT_AUDIO_X96:
            *profile = FF_PROFILE_DTS_96_24;
            break;
        }
    }

    frame_size = FFALIGN(h.frame_size, 4);
    if (buf_size - 4 < frame_size)
        return 0;

    buf      += frame_size;
    buf_size -= frame_size;
    if (AV_RB32(buf) != DCA_SYNCWORD_SUBSTREAM)
        return 0;
    if (ff_dca_exss_parse(&pc1->exss, buf, buf_size) < 0)
        return 0;

    if (asset->extension_mask & DCA_EXSS_XLL)
        *profile = FF_PROFILE_DTS_HD_MA;
    else if (asset->extension_mask & (DCA_EXSS_XBR | DCA_EXSS_XXCH | DCA_EXSS_X96))
        *profile = FF_PROFILE_DTS_HD_HRA;
302 303 304 305

    return 0;
}

306 307 308
static int dca_parse(AVCodecParserContext *s, AVCodecContext *avctx,
                     const uint8_t **poutbuf, int *poutbuf_size,
                     const uint8_t *buf, int buf_size)
309 310 311
{
    DCAParseContext *pc1 = s->priv_data;
    ParseContext *pc = &pc1->pc;
312
    int next, duration, sample_rate;
313 314 315 316 317 318

    if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) {
        next = buf_size;
    } else {
        next = dca_find_frame_end(pc1, buf, buf_size);

319
        if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
320
            *poutbuf      = NULL;
321 322 323
            *poutbuf_size = 0;
            return buf_size;
        }
324 325 326 327 328 329 330

        /* skip initial padding */
        if (buf_size  > pc1->startpos) {
            buf      += pc1->startpos;
            buf_size -= pc1->startpos;
        }
        pc1->startpos = 0;
331
    }
332 333

    /* read the duration and sample rate from the frame header */
334
    if (!dca_parse_params(pc1, buf, buf_size, &duration, &sample_rate, &avctx->profile)) {
335 336 337
        if (!avctx->sample_rate)
            avctx->sample_rate = sample_rate;
        s->duration = av_rescale(duration, avctx->sample_rate, sample_rate);
338 339 340
    } else
        s->duration = 0;

341
    *poutbuf      = buf;
342 343 344 345
    *poutbuf_size = buf_size;
    return next;
}

346
AVCodecParser ff_dca_parser = {
347
    .codec_ids      = { AV_CODEC_ID_DTS },
348 349 350 351
    .priv_data_size = sizeof(DCAParseContext),
    .parser_init    = dca_parse_init,
    .parser_parse   = dca_parse,
    .parser_close   = ff_parse_close,
352
};