tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

vorbis_parser.c (10766B)


      1 /*
      2 * Copyright (c) 2012 Justin Ruggles
      3 *
      4 * This file is part of FFmpeg.
      5 *
      6 * FFmpeg is free software; you can redistribute it and/or
      7 * modify it under the terms of the GNU Lesser General Public
      8 * License as published by the Free Software Foundation; either
      9 * version 2.1 of the License, or (at your option) any later version.
     10 *
     11 * FFmpeg is distributed in the hope that it will be useful,
     12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14 * Lesser General Public License for more details.
     15 *
     16 * You should have received a copy of the GNU Lesser General Public
     17 * License along with FFmpeg; if not, write to the Free Software
     18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
     19 */
     20 
     21 /**
     22 * @file
     23 * Vorbis audio parser
     24 *
     25 * Determines the duration for each packet.
     26 */
     27 
     28 #include "config_components.h"
     29 
     30 #include "libavutil/log.h"
     31 #include "libavutil/mem.h"
     32 
     33 #include "get_bits.h"
     34 #include "xiph.h"
     35 #include "vorbis_parser_internal.h"
     36 
     37 static const AVClass vorbis_parser_class = {
     38    .class_name = "Vorbis parser",
     39    .item_name  = av_default_item_name,
     40    .version    = LIBAVUTIL_VERSION_INT,
     41 };
     42 
     43 static int parse_id_header(AVVorbisParseContext *s,
     44                           const uint8_t *buf, int buf_size)
     45 {
     46    /* Id header should be 30 bytes */
     47    if (buf_size < 30) {
     48        av_log(s, AV_LOG_ERROR, "Id header is too short\n");
     49        return AVERROR_INVALIDDATA;
     50    }
     51 
     52    /* make sure this is the Id header */
     53    if (buf[0] != 1) {
     54        av_log(s, AV_LOG_ERROR, "Wrong packet type in Id header\n");
     55        return AVERROR_INVALIDDATA;
     56    }
     57 
     58    /* check for header signature */
     59    if (memcmp(&buf[1], "vorbis", 6)) {
     60        av_log(s, AV_LOG_ERROR, "Invalid packet signature in Id header\n");
     61        return AVERROR_INVALIDDATA;
     62    }
     63 
     64    if (!(buf[29] & 0x1)) {
     65        av_log(s, AV_LOG_ERROR, "Invalid framing bit in Id header\n");
     66        return AVERROR_INVALIDDATA;
     67    }
     68 
     69    s->blocksize[0] = 1 << (buf[28] & 0xF);
     70    s->blocksize[1] = 1 << (buf[28] >>  4);
     71 
     72    return 0;
     73 }
     74 
     75 static int parse_setup_header(AVVorbisParseContext *s,
     76                              const uint8_t *buf, int buf_size)
     77 {
     78    GetBitContext gb, gb0;
     79    uint8_t *rev_buf;
     80    int i, ret = 0;
     81    int got_framing_bit, mode_count, got_mode_header, last_mode_count = 0;
     82 
     83    /* avoid overread */
     84    if (buf_size < 7) {
     85        av_log(s, AV_LOG_ERROR, "Setup header is too short\n");
     86        return AVERROR_INVALIDDATA;
     87    }
     88 
     89    /* make sure this is the Setup header */
     90    if (buf[0] != 5) {
     91        av_log(s, AV_LOG_ERROR, "Wrong packet type in Setup header\n");
     92        return AVERROR_INVALIDDATA;
     93    }
     94 
     95    /* check for header signature */
     96    if (memcmp(&buf[1], "vorbis", 6)) {
     97        av_log(s, AV_LOG_ERROR, "Invalid packet signature in Setup header\n");
     98        return AVERROR_INVALIDDATA;
     99    }
    100 
    101    /* reverse bytes so we can easily read backwards with get_bits() */
    102    if (!(rev_buf = av_malloc(buf_size))) {
    103        av_log(s, AV_LOG_ERROR, "Out of memory\n");
    104        return AVERROR(ENOMEM);
    105    }
    106    for (i = 0; i < buf_size; i++)
    107        rev_buf[i] = buf[buf_size - 1 - i];
    108    init_get_bits(&gb, rev_buf, buf_size * 8);
    109 
    110    got_framing_bit = 0;
    111    while (get_bits_left(&gb) > 97) {
    112        if (get_bits1(&gb)) {
    113            got_framing_bit = get_bits_count(&gb);
    114            break;
    115        }
    116    }
    117    if (!got_framing_bit) {
    118        av_log(s, AV_LOG_ERROR, "Invalid Setup header\n");
    119        ret = AVERROR_INVALIDDATA;
    120        goto bad_header;
    121    }
    122 
    123    /* Now we search backwards to find possible valid mode counts. This is not
    124     * fool-proof because we could have false positive matches and read too
    125     * far, but there isn't really any way to be sure without parsing through
    126     * all the many variable-sized fields before the modes. This approach seems
    127     * to work well in testing, and it is similar to how it is handled in
    128     * liboggz. */
    129    mode_count = 0;
    130    got_mode_header = 0;
    131    while (get_bits_left(&gb) >= 97) {
    132        if (get_bits(&gb, 8) > 63 || get_bits(&gb, 16) || get_bits(&gb, 16))
    133            break;
    134        skip_bits(&gb, 1);
    135        mode_count++;
    136        if (mode_count > 64)
    137            break;
    138        gb0 = gb;
    139        if (get_bits(&gb0, 6) + 1 == mode_count) {
    140            got_mode_header = 1;
    141            last_mode_count = mode_count;
    142        }
    143    }
    144    if (!got_mode_header) {
    145        av_log(s, AV_LOG_ERROR, "Invalid Setup header\n");
    146        ret = AVERROR_INVALIDDATA;
    147        goto bad_header;
    148    }
    149    /* All samples I've seen use <= 2 modes, so ask for a sample if we find
    150     * more than that, as it is most likely a false positive. If we get any
    151     * we may need to approach this the long way and parse the whole Setup
    152     * header, but I hope very much that it never comes to that. */
    153    if (last_mode_count > 2) {
    154        avpriv_request_sample(s,
    155                              "%d modes (either a false positive or a "
    156                              "sample from an unknown encoder)",
    157                              last_mode_count);
    158    }
    159    /* We're limiting the mode count to 63 so that we know that the previous
    160     * block flag will be in the first packet byte. */
    161    if (last_mode_count > 63) {
    162        av_log(s, AV_LOG_ERROR, "Unsupported mode count: %d\n",
    163               last_mode_count);
    164        ret = AVERROR_INVALIDDATA;
    165        goto bad_header;
    166    }
    167    s->mode_count = mode_count = last_mode_count;
    168    /* Determine the number of bits required to code the mode and turn that
    169     * into a bitmask to directly access the mode from the first frame byte. */
    170    s->mode_mask = ((1 << (av_log2(mode_count - 1) + 1)) - 1) << 1;
    171    /* The previous window flag is the next bit after the mode */
    172    s->prev_mask = (s->mode_mask | 0x1) + 1;
    173 
    174    init_get_bits(&gb, rev_buf, buf_size * 8);
    175    skip_bits_long(&gb, got_framing_bit);
    176    for (i = mode_count - 1; i >= 0; i--) {
    177        skip_bits_long(&gb, 40);
    178        s->mode_blocksize[i] = get_bits1(&gb);
    179    }
    180 
    181 bad_header:
    182    av_free(rev_buf);
    183    return ret;
    184 }
    185 
    186 static int vorbis_parse_init(AVVorbisParseContext *s,
    187                             const uint8_t *extradata, int extradata_size)
    188 {
    189    const uint8_t *header_start[3];
    190    int header_len[3];
    191    int ret;
    192 
    193    s->class = &vorbis_parser_class;
    194    s->extradata_parsed = 1;
    195 
    196    if ((ret = avpriv_split_xiph_headers(extradata,
    197                                         extradata_size, 30,
    198                                         header_start, header_len)) < 0) {
    199        av_log(s, AV_LOG_ERROR, "Extradata corrupt.\n");
    200        return ret;
    201    }
    202 
    203    if ((ret = parse_id_header(s, header_start[0], header_len[0])) < 0)
    204        return ret;
    205 
    206    if ((ret = parse_setup_header(s, header_start[2], header_len[2])) < 0)
    207        return ret;
    208 
    209    s->valid_extradata = 1;
    210    s->previous_blocksize = s->blocksize[s->mode_blocksize[0]];
    211 
    212    return 0;
    213 }
    214 
    215 int av_vorbis_parse_frame_flags(AVVorbisParseContext *s, const uint8_t *buf,
    216                                int buf_size, int *flags)
    217 {
    218    int duration = 0;
    219 
    220    if (s->valid_extradata && buf_size > 0) {
    221        int mode, current_blocksize;
    222        int previous_blocksize = s->previous_blocksize;
    223 
    224        if (buf[0] & 1) {
    225            /* If the user doesn't care about special packets, it's a bad one. */
    226            if (!flags)
    227                goto bad_packet;
    228 
    229            /* Set the flag for which kind of special packet it is. */
    230            if (buf[0] == 1)
    231                *flags |= VORBIS_FLAG_HEADER;
    232            else if (buf[0] == 3)
    233                *flags |= VORBIS_FLAG_COMMENT;
    234            else if (buf[0] == 5)
    235                *flags |= VORBIS_FLAG_SETUP;
    236            else
    237                av_log(s, AV_LOG_VERBOSE, "Ignoring packet with unknown type %u\n",
    238                       buf[0]);
    239 
    240            /* Special packets have no duration. */
    241            return 0;
    242 
    243 bad_packet:
    244            av_log(s, AV_LOG_ERROR, "Invalid packet\n");
    245            return AVERROR_INVALIDDATA;
    246        }
    247        if (s->mode_count == 1)
    248            mode = 0;
    249        else
    250            mode = (buf[0] & s->mode_mask) >> 1;
    251        if (mode >= s->mode_count) {
    252            av_log(s, AV_LOG_ERROR, "Invalid mode in packet\n");
    253            return AVERROR_INVALIDDATA;
    254        }
    255        if(s->mode_blocksize[mode]){
    256            int flag = !!(buf[0] & s->prev_mask);
    257            previous_blocksize = s->blocksize[flag];
    258        }
    259        current_blocksize     = s->blocksize[s->mode_blocksize[mode]];
    260        duration              = (previous_blocksize + current_blocksize) >> 2;
    261        s->previous_blocksize = current_blocksize;
    262    }
    263 
    264    return duration;
    265 }
    266 
    267 int av_vorbis_parse_frame(AVVorbisParseContext *s, const uint8_t *buf,
    268                          int buf_size)
    269 {
    270    return av_vorbis_parse_frame_flags(s, buf, buf_size, NULL);
    271 }
    272 
    273 void av_vorbis_parse_reset(AVVorbisParseContext *s)
    274 {
    275    if (s->valid_extradata)
    276        s->previous_blocksize = s->blocksize[0];
    277 }
    278 
    279 void av_vorbis_parse_free(AVVorbisParseContext **s)
    280 {
    281    av_freep(s);
    282 }
    283 
    284 AVVorbisParseContext *av_vorbis_parse_init(const uint8_t *extradata,
    285                                           int extradata_size)
    286 {
    287    AVVorbisParseContext *s = av_mallocz(sizeof(*s));
    288    int ret;
    289 
    290    if (!s)
    291        return NULL;
    292 
    293    ret = vorbis_parse_init(s, extradata, extradata_size);
    294    if (ret < 0) {
    295        av_vorbis_parse_free(&s);
    296        return NULL;
    297    }
    298 
    299    return s;
    300 }
    301 
    302 #if CONFIG_VORBIS_PARSER
    303 
    304 typedef struct VorbisParseContext {
    305    AVVorbisParseContext *vp;
    306 } VorbisParseContext;
    307 
    308 static int vorbis_parse(AVCodecParserContext *s1, AVCodecContext *avctx,
    309                        const uint8_t **poutbuf, int *poutbuf_size,
    310                        const uint8_t *buf, int buf_size)
    311 {
    312    VorbisParseContext *s = s1->priv_data;
    313    int duration;
    314 
    315    if (!s->vp && avctx->extradata && avctx->extradata_size) {
    316        s->vp = av_vorbis_parse_init(avctx->extradata, avctx->extradata_size);
    317    }
    318    if (!s->vp)
    319        goto end;
    320 
    321    if ((duration = av_vorbis_parse_frame(s->vp, buf, buf_size)) >= 0)
    322        s1->duration = duration;
    323 
    324 end:
    325    /* always return the full packet. this parser isn't doing any splitting or
    326       combining, only packet analysis */
    327    *poutbuf      = buf;
    328    *poutbuf_size = buf_size;
    329    return buf_size;
    330 }
    331 
    332 static void vorbis_parser_close(AVCodecParserContext *ctx)
    333 {
    334    VorbisParseContext *s = ctx->priv_data;
    335    av_vorbis_parse_free(&s->vp);
    336 }
    337 
    338 const AVCodecParser ff_vorbis_parser = {
    339    .codec_ids      = { AV_CODEC_ID_VORBIS },
    340    .priv_data_size = sizeof(VorbisParseContext),
    341    .parser_parse   = vorbis_parse,
    342    .parser_close   = vorbis_parser_close,
    343 };
    344 #endif /* CONFIG_VORBIS_PARSER */