FFmpeg
vorbis_parser.c
Go to the documentation of this file.
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 "libavutil/log.h"
29 
30 #include "get_bits.h"
31 #include "parser.h"
32 #include "xiph.h"
33 #include "vorbis_parser_internal.h"
34 
35 static const AVClass vorbis_parser_class = {
36  .class_name = "Vorbis parser",
37  .item_name = av_default_item_name,
38  .version = LIBAVUTIL_VERSION_INT,
39 };
40 
42  const uint8_t *buf, int buf_size)
43 {
44  /* Id header should be 30 bytes */
45  if (buf_size < 30) {
46  av_log(s, AV_LOG_ERROR, "Id header is too short\n");
47  return AVERROR_INVALIDDATA;
48  }
49 
50  /* make sure this is the Id header */
51  if (buf[0] != 1) {
52  av_log(s, AV_LOG_ERROR, "Wrong packet type in Id header\n");
53  return AVERROR_INVALIDDATA;
54  }
55 
56  /* check for header signature */
57  if (memcmp(&buf[1], "vorbis", 6)) {
58  av_log(s, AV_LOG_ERROR, "Invalid packet signature in Id header\n");
59  return AVERROR_INVALIDDATA;
60  }
61 
62  if (!(buf[29] & 0x1)) {
63  av_log(s, AV_LOG_ERROR, "Invalid framing bit in Id header\n");
64  return AVERROR_INVALIDDATA;
65  }
66 
67  s->blocksize[0] = 1 << (buf[28] & 0xF);
68  s->blocksize[1] = 1 << (buf[28] >> 4);
69 
70  return 0;
71 }
72 
74  const uint8_t *buf, int buf_size)
75 {
76  GetBitContext gb, gb0;
77  uint8_t *rev_buf;
78  int i, ret = 0;
79  int got_framing_bit, mode_count, got_mode_header, last_mode_count = 0;
80 
81  /* avoid overread */
82  if (buf_size < 7) {
83  av_log(s, AV_LOG_ERROR, "Setup header is too short\n");
84  return AVERROR_INVALIDDATA;
85  }
86 
87  /* make sure this is the Setup header */
88  if (buf[0] != 5) {
89  av_log(s, AV_LOG_ERROR, "Wrong packet type in Setup header\n");
90  return AVERROR_INVALIDDATA;
91  }
92 
93  /* check for header signature */
94  if (memcmp(&buf[1], "vorbis", 6)) {
95  av_log(s, AV_LOG_ERROR, "Invalid packet signature in Setup header\n");
96  return AVERROR_INVALIDDATA;
97  }
98 
99  /* reverse bytes so we can easily read backwards with get_bits() */
100  if (!(rev_buf = av_malloc(buf_size))) {
101  av_log(s, AV_LOG_ERROR, "Out of memory\n");
102  return AVERROR(ENOMEM);
103  }
104  for (i = 0; i < buf_size; i++)
105  rev_buf[i] = buf[buf_size - 1 - i];
106  init_get_bits(&gb, rev_buf, buf_size * 8);
107 
108  got_framing_bit = 0;
109  while (get_bits_left(&gb) > 97) {
110  if (get_bits1(&gb)) {
111  got_framing_bit = get_bits_count(&gb);
112  break;
113  }
114  }
115  if (!got_framing_bit) {
116  av_log(s, AV_LOG_ERROR, "Invalid Setup header\n");
117  ret = AVERROR_INVALIDDATA;
118  goto bad_header;
119  }
120 
121  /* Now we search backwards to find possible valid mode counts. This is not
122  * fool-proof because we could have false positive matches and read too
123  * far, but there isn't really any way to be sure without parsing through
124  * all the many variable-sized fields before the modes. This approach seems
125  * to work well in testing, and it is similar to how it is handled in
126  * liboggz. */
127  mode_count = 0;
128  got_mode_header = 0;
129  while (get_bits_left(&gb) >= 97) {
130  if (get_bits(&gb, 8) > 63 || get_bits(&gb, 16) || get_bits(&gb, 16))
131  break;
132  skip_bits(&gb, 1);
133  mode_count++;
134  if (mode_count > 64)
135  break;
136  gb0 = gb;
137  if (get_bits(&gb0, 6) + 1 == mode_count) {
138  got_mode_header = 1;
139  last_mode_count = mode_count;
140  }
141  }
142  if (!got_mode_header) {
143  av_log(s, AV_LOG_ERROR, "Invalid Setup header\n");
144  ret = AVERROR_INVALIDDATA;
145  goto bad_header;
146  }
147  /* All samples I've seen use <= 2 modes, so ask for a sample if we find
148  * more than that, as it is most likely a false positive. If we get any
149  * we may need to approach this the long way and parse the whole Setup
150  * header, but I hope very much that it never comes to that. */
151  if (last_mode_count > 2) {
153  "%d modes (either a false positive or a "
154  "sample from an unknown encoder)",
155  last_mode_count);
156  }
157  /* We're limiting the mode count to 63 so that we know that the previous
158  * block flag will be in the first packet byte. */
159  if (last_mode_count > 63) {
160  av_log(s, AV_LOG_ERROR, "Unsupported mode count: %d\n",
161  last_mode_count);
162  ret = AVERROR_INVALIDDATA;
163  goto bad_header;
164  }
165  s->mode_count = mode_count = last_mode_count;
166  /* Determine the number of bits required to code the mode and turn that
167  * into a bitmask to directly access the mode from the first frame byte. */
168  s->mode_mask = ((1 << (av_log2(mode_count - 1) + 1)) - 1) << 1;
169  /* The previous window flag is the next bit after the mode */
170  s->prev_mask = (s->mode_mask | 0x1) + 1;
171 
172  init_get_bits(&gb, rev_buf, buf_size * 8);
173  skip_bits_long(&gb, got_framing_bit);
174  for (i = mode_count - 1; i >= 0; i--) {
175  skip_bits_long(&gb, 40);
176  s->mode_blocksize[i] = get_bits1(&gb);
177  }
178 
179 bad_header:
180  av_free(rev_buf);
181  return ret;
182 }
183 
185  const uint8_t *extradata, int extradata_size)
186 {
187  const uint8_t *header_start[3];
188  int header_len[3];
189  int ret;
190 
192  s->extradata_parsed = 1;
193 
194  if ((ret = avpriv_split_xiph_headers(extradata,
195  extradata_size, 30,
196  header_start, header_len)) < 0) {
197  av_log(s, AV_LOG_ERROR, "Extradata corrupt.\n");
198  return ret;
199  }
200 
201  if ((ret = parse_id_header(s, header_start[0], header_len[0])) < 0)
202  return ret;
203 
204  if ((ret = parse_setup_header(s, header_start[2], header_len[2])) < 0)
205  return ret;
206 
207  s->valid_extradata = 1;
209 
210  return 0;
211 }
212 
214  int buf_size, int *flags)
215 {
216  int duration = 0;
217 
218  if (s->valid_extradata && buf_size > 0) {
219  int mode, current_blocksize;
220  int previous_blocksize = s->previous_blocksize;
221 
222  if (buf[0] & 1) {
223  /* If the user doesn't care about special packets, it's a bad one. */
224  if (!flags)
225  goto bad_packet;
226 
227  /* Set the flag for which kind of special packet it is. */
228  if (buf[0] == 1)
229  *flags |= VORBIS_FLAG_HEADER;
230  else if (buf[0] == 3)
231  *flags |= VORBIS_FLAG_COMMENT;
232  else if (buf[0] == 5)
233  *flags |= VORBIS_FLAG_SETUP;
234  else
235  goto bad_packet;
236 
237  /* Special packets have no duration. */
238  return 0;
239 
240 bad_packet:
241  av_log(s, AV_LOG_ERROR, "Invalid packet\n");
242  return AVERROR_INVALIDDATA;
243  }
244  if (s->mode_count == 1)
245  mode = 0;
246  else
247  mode = (buf[0] & s->mode_mask) >> 1;
248  if (mode >= s->mode_count) {
249  av_log(s, AV_LOG_ERROR, "Invalid mode in packet\n");
250  return AVERROR_INVALIDDATA;
251  }
252  if(s->mode_blocksize[mode]){
253  int flag = !!(buf[0] & s->prev_mask);
254  previous_blocksize = s->blocksize[flag];
255  }
256  current_blocksize = s->blocksize[s->mode_blocksize[mode]];
257  duration = (previous_blocksize + current_blocksize) >> 2;
258  s->previous_blocksize = current_blocksize;
259  }
260 
261  return duration;
262 }
263 
265  int buf_size)
266 {
267  return av_vorbis_parse_frame_flags(s, buf, buf_size, NULL);
268 }
269 
271 {
272  if (s->valid_extradata)
273  s->previous_blocksize = s->blocksize[0];
274 }
275 
277 {
278  av_freep(s);
279 }
280 
282  int extradata_size)
283 {
284  AVVorbisParseContext *s = av_mallocz(sizeof(*s));
285  int ret;
286 
287  if (!s)
288  return NULL;
289 
290  ret = vorbis_parse_init(s, extradata, extradata_size);
291  if (ret < 0) {
293  return NULL;
294  }
295 
296  return s;
297 }
298 
299 #if CONFIG_VORBIS_PARSER
300 
301 typedef struct VorbisParseContext {
303 } VorbisParseContext;
304 
305 static int vorbis_parse(AVCodecParserContext *s1, AVCodecContext *avctx,
306  const uint8_t **poutbuf, int *poutbuf_size,
307  const uint8_t *buf, int buf_size)
308 {
309  VorbisParseContext *s = s1->priv_data;
310  int duration;
311 
312  if (!s->vp && avctx->extradata && avctx->extradata_size) {
313  s->vp = av_vorbis_parse_init(avctx->extradata, avctx->extradata_size);
314  }
315  if (!s->vp)
316  goto end;
317 
318  if ((duration = av_vorbis_parse_frame(s->vp, buf, buf_size)) >= 0)
319  s1->duration = duration;
320 
321 end:
322  /* always return the full packet. this parser isn't doing any splitting or
323  combining, only packet analysis */
324  *poutbuf = buf;
325  *poutbuf_size = buf_size;
326  return buf_size;
327 }
328 
329 static void vorbis_parser_close(AVCodecParserContext *ctx)
330 {
331  VorbisParseContext *s = ctx->priv_data;
332  av_vorbis_parse_free(&s->vp);
333 }
334 
337  .priv_data_size = sizeof(VorbisParseContext),
338  .parser_parse = vorbis_parse,
339  .parser_close = vorbis_parser_close,
340 };
341 #endif /* CONFIG_VORBIS_PARSER */
#define NULL
Definition: coverity.c:32
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
int extradata_parsed
we have attempted to parse extradata
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:379
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
static void skip_bits_long(GetBitContext *s, int n)
Skips the specified number of bits.
Definition: get_bits.h:291
#define avpriv_request_sample(...)
int mode_count
number of modes
AVVorbisParseContext * av_vorbis_parse_init(const uint8_t *extradata, int extradata_size)
Allocate and initialize the Vorbis parser using headers in the extradata.
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:191
int codec_ids[5]
Definition: avcodec.h:5272
int av_log2(unsigned v)
Definition: intmath.c:26
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:236
int duration
Duration of the current frame.
Definition: avcodec.h:5226
int prev_mask
bitmask used to get the previous mode flag in each packet
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:72
uint8_t
#define av_malloc(s)
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:90
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:1666
int64_t duration
Definition: movenc.c:63
static int get_bits_count(const GetBitContext *s)
Definition: get_bits.h:219
bitstream reader API header.
#define av_log(a,...)
static int get_bits_left(GetBitContext *gb)
Definition: get_bits.h:849
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:260
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
void av_vorbis_parse_free(AVVorbisParseContext **s)
Free the parser and everything associated with it.
int valid_extradata
extradata is valid, so we can calculate duration
static int vorbis_parse_init(AVVorbisParseContext *s, const uint8_t *extradata, int extradata_size)
AVCodecParser ff_vorbis_parser
AVFormatContext * ctx
Definition: movenc.c:48
#define s(width, name)
Definition: cbs_vp9.c:257
#define VORBIS_FLAG_SETUP
Definition: vorbis_parser.h:46
int avpriv_split_xiph_headers(const uint8_t *extradata, int extradata_size, int first_header_size, const 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
int previous_blocksize
previous window size
#define VORBIS_FLAG_COMMENT
Definition: vorbis_parser.h:45
int mode_mask
bitmask used to get the mode in each packet
#define VORBIS_FLAG_HEADER
Definition: vorbis_parser.h:44
main external API structure.
Definition: avcodec.h:1565
void * buf
Definition: avisynth_c.h:766
int extradata_size
Definition: avcodec.h:1667
static unsigned int get_bits1(GetBitContext *s)
Definition: get_bits.h:498
Describe the class of an AVClass context structure.
Definition: log.h:67
static void skip_bits(GetBitContext *s, int n)
Definition: get_bits.h:467
static const AVClass vorbis_parser_class
Definition: vorbis_parser.c:35
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
Definition: get_bits.h:659
#define s1
Definition: regdef.h:38
int av_vorbis_parse_frame_flags(AVVorbisParseContext *s, const uint8_t *buf, int buf_size, int *flags)
Get the duration for a Vorbis packet.
#define flags(name, subs,...)
Definition: cbs_av1.c:561
int blocksize[2]
short and long window sizes
static int parse_id_header(AVVorbisParseContext *s, const uint8_t *buf, int buf_size)
Definition: vorbis_parser.c:41
Vorbis audio parser.
int av_vorbis_parse_frame(AVVorbisParseContext *s, const uint8_t *buf, int buf_size)
Get the duration for a Vorbis packet.
#define flag(name)
Definition: cbs_av1.c:553
static int parse_setup_header(AVVorbisParseContext *s, const uint8_t *buf, int buf_size)
Definition: vorbis_parser.c:73
#define av_free(p)
int mode_blocksize[64]
window size mapping for each mode
#define av_freep(p)
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame 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.Frame references ownership and permissions
mode
Use these values in ebur128_init (or&#39;ed).
Definition: ebur128.h:83
void av_vorbis_parse_reset(AVVorbisParseContext *s)