vorbis_parser.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012 Justin Ruggles
3  *
4  * This file is part of Libav.
5  *
6  * Libav 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  * Libav 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 Libav; 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 "get_bits.h"
29 #include "parser.h"
30 #include "xiph.h"
31 #include "vorbis_parser.h"
32 
34  const uint8_t *buf, int buf_size)
35 {
36  /* Id header should be 30 bytes */
37  if (buf_size < 30) {
38  av_log(avctx, AV_LOG_ERROR, "Id header is too short\n");
39  return AVERROR_INVALIDDATA;
40  }
41 
42  /* make sure this is the Id header */
43  if (buf[0] != 1) {
44  av_log(avctx, AV_LOG_ERROR, "Wrong packet type in Id header\n");
45  return AVERROR_INVALIDDATA;
46  }
47 
48  /* check for header signature */
49  if (memcmp(&buf[1], "vorbis", 6)) {
50  av_log(avctx, AV_LOG_ERROR, "Invalid packet signature in Id header\n");
51  return AVERROR_INVALIDDATA;
52  }
53 
54  if (!(buf[29] & 0x1)) {
55  av_log(avctx, AV_LOG_ERROR, "Invalid framing bit in Id header\n");
56  return AVERROR_INVALIDDATA;
57  }
58 
59  s->blocksize[0] = 1 << (buf[28] & 0xF);
60  s->blocksize[1] = 1 << (buf[28] >> 4);
61 
62  return 0;
63 }
64 
66  const uint8_t *buf, int buf_size)
67 {
68  GetBitContext gb, gb0;
69  uint8_t *rev_buf;
70  int i, ret = 0;
71  int got_framing_bit, mode_count, got_mode_header, last_mode_count = 0;
72 
73  /* avoid overread */
74  if (buf_size < 7) {
75  av_log(avctx, AV_LOG_ERROR, "Setup header is too short\n");
76  return AVERROR_INVALIDDATA;
77  }
78 
79  /* make sure this is the Setup header */
80  if (buf[0] != 5) {
81  av_log(avctx, AV_LOG_ERROR, "Wrong packet type in Setup header\n");
82  return AVERROR_INVALIDDATA;
83  }
84 
85  /* check for header signature */
86  if (memcmp(&buf[1], "vorbis", 6)) {
87  av_log(avctx, AV_LOG_ERROR, "Invalid packet signature in Setup header\n");
88  return AVERROR_INVALIDDATA;
89  }
90 
91  /* reverse bytes so we can easily read backwards with get_bits() */
92  if (!(rev_buf = av_malloc(buf_size))) {
93  av_log(avctx, AV_LOG_ERROR, "Out of memory\n");
94  return AVERROR(ENOMEM);
95  }
96  for (i = 0; i < buf_size; i++)
97  rev_buf[i] = buf[buf_size - 1 - i];
98  init_get_bits(&gb, rev_buf, buf_size * 8);
99 
100  got_framing_bit = 0;
101  while (get_bits_left(&gb) > 97) {
102  if (get_bits1(&gb)) {
103  got_framing_bit = get_bits_count(&gb);
104  break;
105  }
106  }
107  if (!got_framing_bit) {
108  av_log(avctx, AV_LOG_ERROR, "Invalid Setup header\n");
109  ret = AVERROR_INVALIDDATA;
110  goto bad_header;
111  }
112 
113  /* Now we search backwards to find possible valid mode counts. This is not
114  * fool-proof because we could have false positive matches and read too
115  * far, but there isn't really any way to be sure without parsing through
116  * all the many variable-sized fields before the modes. This approach seems
117  * to work well in testing, and it is similar to how it is handled in
118  * liboggz. */
119  mode_count = 0;
120  got_mode_header = 0;
121  while (get_bits_left(&gb) >= 97) {
122  if (get_bits(&gb, 8) > 63 || get_bits(&gb, 16) || get_bits(&gb, 16))
123  break;
124  skip_bits(&gb, 1);
125  mode_count++;
126  if (mode_count > 64)
127  break;
128  gb0 = gb;
129  if (get_bits(&gb0, 6) + 1 == mode_count) {
130  got_mode_header = 1;
131  last_mode_count = mode_count;
132  }
133  }
134  if (!got_mode_header) {
135  av_log(avctx, AV_LOG_ERROR, "Invalid Setup header\n");
136  ret = AVERROR_INVALIDDATA;
137  goto bad_header;
138  }
139  /* All samples I've seen use <= 2 modes, so ask for a sample if we find
140  * more than that, as it is most likely a false positive. If we get any
141  * we may need to approach this the long way and parse the whole Setup
142  * header, but I hope very much that it never comes to that. */
143  if (last_mode_count > 2) {
144  avpriv_request_sample(avctx,
145  "%d modes (either a false positive or a "
146  "sample from an unknown encoder)",
147  last_mode_count);
148  }
149  /* We're limiting the mode count to 63 so that we know that the previous
150  * block flag will be in the first packet byte. */
151  if (last_mode_count > 63) {
152  av_log(avctx, AV_LOG_ERROR, "Unsupported mode count: %d\n",
153  last_mode_count);
154  ret = AVERROR_INVALIDDATA;
155  goto bad_header;
156  }
157  s->mode_count = mode_count = last_mode_count;
158  /* Determine the number of bits required to code the mode and turn that
159  * into a bitmask to directly access the mode from the first frame byte. */
160  s->mode_mask = ((1 << (av_log2(mode_count - 1) + 1)) - 1) << 1;
161  /* The previous window flag is the next bit after the mode */
162  s->prev_mask = (s->mode_mask | 0x1) + 1;
163 
164  init_get_bits(&gb, rev_buf, buf_size * 8);
165  skip_bits_long(&gb, got_framing_bit);
166  for (i = mode_count - 1; i >= 0; i--) {
167  skip_bits_long(&gb, 40);
168  s->mode_blocksize[i] = get_bits1(&gb);
169  }
170 
171 bad_header:
172  av_free(rev_buf);
173  return ret;
174 }
175 
177 {
178  uint8_t *header_start[3];
179  int header_len[3];
180  int ret;
181 
182  s->avctx = avctx;
183  s->extradata_parsed = 1;
184 
185  if ((ret = avpriv_split_xiph_headers(avctx->extradata,
186  avctx->extradata_size, 30,
187  header_start, header_len)) < 0) {
188  av_log(avctx, AV_LOG_ERROR, "Extradata corrupt.\n");
189  return ret;
190  }
191 
192  if ((ret = parse_id_header(avctx, s, header_start[0], header_len[0])) < 0)
193  return ret;
194 
195  if ((ret = parse_setup_header(avctx, s, header_start[2], header_len[2])) < 0)
196  return ret;
197 
198  s->valid_extradata = 1;
200 
201  return 0;
202 }
203 
205  int buf_size)
206 {
207  int duration = 0;
208 
209  if (s->valid_extradata && buf_size > 0) {
210  int mode, current_blocksize;
211  int previous_blocksize = s->previous_blocksize;
212 
213  if (buf[0] & 1) {
214  av_log(s->avctx, AV_LOG_ERROR, "Invalid packet\n");
215  return AVERROR_INVALIDDATA;
216  }
217  if (s->mode_count == 1)
218  mode = 0;
219  else
220  mode = (buf[0] & s->mode_mask) >> 1;
221  if (mode >= s->mode_count) {
222  av_log(s->avctx, AV_LOG_ERROR, "Invalid mode in packet\n");
223  return AVERROR_INVALIDDATA;
224  }
225  if(s->mode_blocksize[mode]){
226  int flag = !!(buf[0] & s->prev_mask);
227  previous_blocksize = s->blocksize[flag];
228  }
229  current_blocksize = s->blocksize[s->mode_blocksize[mode]];
230  duration = (previous_blocksize + current_blocksize) >> 2;
231  s->previous_blocksize = current_blocksize;
232  }
233 
234  return duration;
235 }
236 
238 {
239  if (s->valid_extradata)
240  s->previous_blocksize = s->blocksize[0];
241 }
242 
243 #if CONFIG_VORBIS_PARSER
244 static int vorbis_parse(AVCodecParserContext *s1, AVCodecContext *avctx,
245  const uint8_t **poutbuf, int *poutbuf_size,
246  const uint8_t *buf, int buf_size)
247 {
249  int duration;
250 
251  if (!s->extradata_parsed && avctx->extradata && avctx->extradata_size)
252  if (avpriv_vorbis_parse_extradata(avctx, s))
253  goto end;
254 
255  if ((duration = avpriv_vorbis_parse_frame(s, buf, buf_size)) >= 0)
256  s1->duration = duration;
257 
258 end:
259  /* always return the full packet. this parser isn't doing any splitting or
260  combining, only packet analysis */
261  *poutbuf = buf;
262  *poutbuf_size = buf_size;
263  return buf_size;
264 }
265 
266 AVCodecParser ff_vorbis_parser = {
268  .priv_data_size = sizeof(VorbisParseContext),
269  .parser_parse = vorbis_parse,
270 };
271 #endif /* CONFIG_VORBIS_PARSER */
const char * s
Definition: avisynth_c.h:668
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
int avpriv_vorbis_parse_frame(VorbisParseContext *s, const uint8_t *buf, int buf_size)
Get the duration for a Vorbis packet.
int mode_blocksize[64]
window size mapping for each mode
Definition: vorbis_parser.h:39
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:240
int blocksize[2]
short and long window sizes
Definition: vorbis_parser.h:37
static void skip_bits_long(GetBitContext *s, int n)
Definition: get_bits.h:198
void avpriv_vorbis_parse_reset(VorbisParseContext *s)
x1
Definition: genspecsines3.m:7
int duration
Duration of the current frame.
int prev_mask
bitmask used to get the previous mode flag in each packet
Definition: vorbis_parser.h:42
struct VorbisParseContext VorbisParseContext
void void avpriv_request_sample(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
uint8_t
mode
Definition: f_perms.c:27
int mode_count
number of modes
Definition: vorbis_parser.h:40
int valid_extradata
extradata is valid, so we can calculate duration
Definition: vorbis_parser.h:36
end end
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Vorbis audio parser.
static int get_bits_count(const GetBitContext *s)
Definition: get_bits.h:193
bitstream reader API header.
static int64_t duration
Definition: ffplay.c:294
static int get_bits_left(GetBitContext *gb)
Definition: get_bits.h:557
void av_free(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc(). ...
Definition: mem.c:183
static int parse_id_header(AVCodecContext *avctx, VorbisParseContext *s, const uint8_t *buf, int buf_size)
Definition: vorbis_parser.c:33
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
int mode_mask
bitmask used to get the mode in each packet
Definition: vorbis_parser.h:41
ret
Definition: avfilter.c:821
int extradata_parsed
we have attempted to parse extradata
Definition: vorbis_parser.h:35
main external API structure.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:148
void * buf
Definition: avisynth_c.h:594
static unsigned int get_bits1(GetBitContext *s)
Definition: get_bits.h:273
void * av_malloc(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:73
static void skip_bits(GetBitContext *s, int n)
Definition: get_bits.h:265
synthesis window for stochastic i
static int parse_setup_header(AVCodecContext *avctx, VorbisParseContext *s, const uint8_t *buf, int buf_size)
Definition: vorbis_parser.c:65
int previous_blocksize
previous window size
Definition: vorbis_parser.h:38
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition: get_bits.h:379
int avpriv_split_xiph_headers(uint8_t *extradata, int extradata_size, int first_header_size, uint8_t *header_start[3], int header_len[3])
Split a single extradata buffer into the three headers that most Xiph codecs use. ...
Definition: xiph.c:24
#define s1
Definition: regdef.h:38
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Buffer references ownership and permissions
#define av_log2
Definition: intmath.h:89
int avpriv_vorbis_parse_extradata(AVCodecContext *avctx, VorbisParseContext *s)
Initialize the Vorbis parser using headers in the extradata.
AVCodecContext * avctx
codec context
Definition: vorbis_parser.h:34