yading@10: /* yading@10: * Copyright (c) 2012 Justin Ruggles yading@10: * yading@10: * This file is part of Libav. yading@10: * yading@10: * Libav is free software; you can redistribute it and/or yading@10: * modify it under the terms of the GNU Lesser General Public yading@10: * License as published by the Free Software Foundation; either yading@10: * version 2.1 of the License, or (at your option) any later version. yading@10: * yading@10: * Libav is distributed in the hope that it will be useful, yading@10: * but WITHOUT ANY WARRANTY; without even the implied warranty of yading@10: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU yading@10: * Lesser General Public License for more details. yading@10: * yading@10: * You should have received a copy of the GNU Lesser General Public yading@10: * License along with Libav; if not, write to the Free Software yading@10: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA yading@10: */ yading@10: yading@10: /** yading@10: * @file yading@10: * Vorbis audio parser yading@10: * yading@10: * Determines the duration for each packet. yading@10: */ yading@10: yading@10: #include "get_bits.h" yading@10: #include "parser.h" yading@10: #include "xiph.h" yading@10: #include "vorbis_parser.h" yading@10: yading@10: static int parse_id_header(AVCodecContext *avctx, VorbisParseContext *s, yading@10: const uint8_t *buf, int buf_size) yading@10: { yading@10: /* Id header should be 30 bytes */ yading@10: if (buf_size < 30) { yading@10: av_log(avctx, AV_LOG_ERROR, "Id header is too short\n"); yading@10: return AVERROR_INVALIDDATA; yading@10: } yading@10: yading@10: /* make sure this is the Id header */ yading@10: if (buf[0] != 1) { yading@10: av_log(avctx, AV_LOG_ERROR, "Wrong packet type in Id header\n"); yading@10: return AVERROR_INVALIDDATA; yading@10: } yading@10: yading@10: /* check for header signature */ yading@10: if (memcmp(&buf[1], "vorbis", 6)) { yading@10: av_log(avctx, AV_LOG_ERROR, "Invalid packet signature in Id header\n"); yading@10: return AVERROR_INVALIDDATA; yading@10: } yading@10: yading@10: if (!(buf[29] & 0x1)) { yading@10: av_log(avctx, AV_LOG_ERROR, "Invalid framing bit in Id header\n"); yading@10: return AVERROR_INVALIDDATA; yading@10: } yading@10: yading@10: s->blocksize[0] = 1 << (buf[28] & 0xF); yading@10: s->blocksize[1] = 1 << (buf[28] >> 4); yading@10: yading@10: return 0; yading@10: } yading@10: yading@10: static int parse_setup_header(AVCodecContext *avctx, VorbisParseContext *s, yading@10: const uint8_t *buf, int buf_size) yading@10: { yading@10: GetBitContext gb, gb0; yading@10: uint8_t *rev_buf; yading@10: int i, ret = 0; yading@10: int got_framing_bit, mode_count, got_mode_header, last_mode_count = 0; yading@10: yading@10: /* avoid overread */ yading@10: if (buf_size < 7) { yading@10: av_log(avctx, AV_LOG_ERROR, "Setup header is too short\n"); yading@10: return AVERROR_INVALIDDATA; yading@10: } yading@10: yading@10: /* make sure this is the Setup header */ yading@10: if (buf[0] != 5) { yading@10: av_log(avctx, AV_LOG_ERROR, "Wrong packet type in Setup header\n"); yading@10: return AVERROR_INVALIDDATA; yading@10: } yading@10: yading@10: /* check for header signature */ yading@10: if (memcmp(&buf[1], "vorbis", 6)) { yading@10: av_log(avctx, AV_LOG_ERROR, "Invalid packet signature in Setup header\n"); yading@10: return AVERROR_INVALIDDATA; yading@10: } yading@10: yading@10: /* reverse bytes so we can easily read backwards with get_bits() */ yading@10: if (!(rev_buf = av_malloc(buf_size))) { yading@10: av_log(avctx, AV_LOG_ERROR, "Out of memory\n"); yading@10: return AVERROR(ENOMEM); yading@10: } yading@10: for (i = 0; i < buf_size; i++) yading@10: rev_buf[i] = buf[buf_size - 1 - i]; yading@10: init_get_bits(&gb, rev_buf, buf_size * 8); yading@10: yading@10: got_framing_bit = 0; yading@10: while (get_bits_left(&gb) > 97) { yading@10: if (get_bits1(&gb)) { yading@10: got_framing_bit = get_bits_count(&gb); yading@10: break; yading@10: } yading@10: } yading@10: if (!got_framing_bit) { yading@10: av_log(avctx, AV_LOG_ERROR, "Invalid Setup header\n"); yading@10: ret = AVERROR_INVALIDDATA; yading@10: goto bad_header; yading@10: } yading@10: yading@10: /* Now we search backwards to find possible valid mode counts. This is not yading@10: * fool-proof because we could have false positive matches and read too yading@10: * far, but there isn't really any way to be sure without parsing through yading@10: * all the many variable-sized fields before the modes. This approach seems yading@10: * to work well in testing, and it is similar to how it is handled in yading@10: * liboggz. */ yading@10: mode_count = 0; yading@10: got_mode_header = 0; yading@10: while (get_bits_left(&gb) >= 97) { yading@10: if (get_bits(&gb, 8) > 63 || get_bits(&gb, 16) || get_bits(&gb, 16)) yading@10: break; yading@10: skip_bits(&gb, 1); yading@10: mode_count++; yading@10: if (mode_count > 64) yading@10: break; yading@10: gb0 = gb; yading@10: if (get_bits(&gb0, 6) + 1 == mode_count) { yading@10: got_mode_header = 1; yading@10: last_mode_count = mode_count; yading@10: } yading@10: } yading@10: if (!got_mode_header) { yading@10: av_log(avctx, AV_LOG_ERROR, "Invalid Setup header\n"); yading@10: ret = AVERROR_INVALIDDATA; yading@10: goto bad_header; yading@10: } yading@10: /* All samples I've seen use <= 2 modes, so ask for a sample if we find yading@10: * more than that, as it is most likely a false positive. If we get any yading@10: * we may need to approach this the long way and parse the whole Setup yading@10: * header, but I hope very much that it never comes to that. */ yading@10: if (last_mode_count > 2) { yading@10: avpriv_request_sample(avctx, yading@10: "%d modes (either a false positive or a " yading@10: "sample from an unknown encoder)", yading@10: last_mode_count); yading@10: } yading@10: /* We're limiting the mode count to 63 so that we know that the previous yading@10: * block flag will be in the first packet byte. */ yading@10: if (last_mode_count > 63) { yading@10: av_log(avctx, AV_LOG_ERROR, "Unsupported mode count: %d\n", yading@10: last_mode_count); yading@10: ret = AVERROR_INVALIDDATA; yading@10: goto bad_header; yading@10: } yading@10: s->mode_count = mode_count = last_mode_count; yading@10: /* Determine the number of bits required to code the mode and turn that yading@10: * into a bitmask to directly access the mode from the first frame byte. */ yading@10: s->mode_mask = ((1 << (av_log2(mode_count - 1) + 1)) - 1) << 1; yading@10: /* The previous window flag is the next bit after the mode */ yading@10: s->prev_mask = (s->mode_mask | 0x1) + 1; yading@10: yading@10: init_get_bits(&gb, rev_buf, buf_size * 8); yading@10: skip_bits_long(&gb, got_framing_bit); yading@10: for (i = mode_count - 1; i >= 0; i--) { yading@10: skip_bits_long(&gb, 40); yading@10: s->mode_blocksize[i] = get_bits1(&gb); yading@10: } yading@10: yading@10: bad_header: yading@10: av_free(rev_buf); yading@10: return ret; yading@10: } yading@10: yading@10: int avpriv_vorbis_parse_extradata(AVCodecContext *avctx, VorbisParseContext *s) yading@10: { yading@10: uint8_t *header_start[3]; yading@10: int header_len[3]; yading@10: int ret; yading@10: yading@10: s->avctx = avctx; yading@10: s->extradata_parsed = 1; yading@10: yading@10: if ((ret = avpriv_split_xiph_headers(avctx->extradata, yading@10: avctx->extradata_size, 30, yading@10: header_start, header_len)) < 0) { yading@10: av_log(avctx, AV_LOG_ERROR, "Extradata corrupt.\n"); yading@10: return ret; yading@10: } yading@10: yading@10: if ((ret = parse_id_header(avctx, s, header_start[0], header_len[0])) < 0) yading@10: return ret; yading@10: yading@10: if ((ret = parse_setup_header(avctx, s, header_start[2], header_len[2])) < 0) yading@10: return ret; yading@10: yading@10: s->valid_extradata = 1; yading@10: s->previous_blocksize = s->blocksize[s->mode_blocksize[0]]; yading@10: yading@10: return 0; yading@10: } yading@10: yading@10: int avpriv_vorbis_parse_frame(VorbisParseContext *s, const uint8_t *buf, yading@10: int buf_size) yading@10: { yading@10: int duration = 0; yading@10: yading@10: if (s->valid_extradata && buf_size > 0) { yading@10: int mode, current_blocksize; yading@10: int previous_blocksize = s->previous_blocksize; yading@10: yading@10: if (buf[0] & 1) { yading@10: av_log(s->avctx, AV_LOG_ERROR, "Invalid packet\n"); yading@10: return AVERROR_INVALIDDATA; yading@10: } yading@10: if (s->mode_count == 1) yading@10: mode = 0; yading@10: else yading@10: mode = (buf[0] & s->mode_mask) >> 1; yading@10: if (mode >= s->mode_count) { yading@10: av_log(s->avctx, AV_LOG_ERROR, "Invalid mode in packet\n"); yading@10: return AVERROR_INVALIDDATA; yading@10: } yading@10: if(s->mode_blocksize[mode]){ yading@10: int flag = !!(buf[0] & s->prev_mask); yading@10: previous_blocksize = s->blocksize[flag]; yading@10: } yading@10: current_blocksize = s->blocksize[s->mode_blocksize[mode]]; yading@10: duration = (previous_blocksize + current_blocksize) >> 2; yading@10: s->previous_blocksize = current_blocksize; yading@10: } yading@10: yading@10: return duration; yading@10: } yading@10: yading@10: void avpriv_vorbis_parse_reset(VorbisParseContext *s) yading@10: { yading@10: if (s->valid_extradata) yading@10: s->previous_blocksize = s->blocksize[0]; yading@10: } yading@10: yading@10: #if CONFIG_VORBIS_PARSER yading@10: static int vorbis_parse(AVCodecParserContext *s1, AVCodecContext *avctx, yading@10: const uint8_t **poutbuf, int *poutbuf_size, yading@10: const uint8_t *buf, int buf_size) yading@10: { yading@10: VorbisParseContext *s = s1->priv_data; yading@10: int duration; yading@10: yading@10: if (!s->extradata_parsed && avctx->extradata && avctx->extradata_size) yading@10: if (avpriv_vorbis_parse_extradata(avctx, s)) yading@10: goto end; yading@10: yading@10: if ((duration = avpriv_vorbis_parse_frame(s, buf, buf_size)) >= 0) yading@10: s1->duration = duration; yading@10: yading@10: end: yading@10: /* always return the full packet. this parser isn't doing any splitting or yading@10: combining, only packet analysis */ yading@10: *poutbuf = buf; yading@10: *poutbuf_size = buf_size; yading@10: return buf_size; yading@10: } yading@10: yading@10: AVCodecParser ff_vorbis_parser = { yading@10: .codec_ids = { AV_CODEC_ID_VORBIS }, yading@10: .priv_data_size = sizeof(VorbisParseContext), yading@10: .parser_parse = vorbis_parse, yading@10: }; yading@10: #endif /* CONFIG_VORBIS_PARSER */