FFmpeg
Loading...
Searching...
No Matches
vorbis.c
Go to the documentation of this file.
1/*
2 * Copyright (C) 2005 Michael Ahlberg, Måns Rullgård
3 *
4 * Permission is hereby granted, free of charge, to any person
5 * obtaining a copy of this software and associated documentation
6 * files (the "Software"), to deal in the Software without
7 * restriction, including without limitation the rights to use, copy,
8 * modify, merge, publish, distribute, sublicense, and/or sell copies
9 * of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25#include <stdlib.h>
26
27#include "libavutil/dict.h"
28#include "libavutil/mem.h"
29
32
34#include "libavformat/demux.h"
39
40/*
41 * Parse the vorbis header
42 *
43 * Vorbis Identification header from Vorbis_I_spec.html#vorbis-spec-codec
44 * [vorbis_version] = read 32 bits as unsigned integer | Not used
45 * [audio_channels] = read 8 bit integer as unsigned | Used
46 * [audio_sample_rate] = read 32 bits as unsigned integer | Used
47 * [bitrate_maximum] = read 32 bits as signed integer | Not used yet
48 * [bitrate_nominal] = read 32 bits as signed integer | Not used yet
49 * [bitrate_minimum] = read 32 bits as signed integer | Used as bitrate
50 * [blocksize_0] = read 4 bits as unsigned integer | Not Used
51 * [blocksize_1] = read 4 bits as unsigned integer | Not Used
52 * [framing_flag] = read one bit | Not Used
53 */
54
62
64 unsigned int len[3];
65 unsigned char *packet[3];
66 enum VorbisPacketType last_packet; ///< type of the last packet seen by vorbis_packet()
72};
73
75 struct oggvorbis_private *priv,
76 uint8_t **buf)
77{
78 int i, offset, len, err;
79 int buf_len;
80 unsigned char *ptr;
81 uint64_t total_len;
82
83 total_len = (uint64_t)priv->len[0] + priv->len[1] + priv->len[2];
84 if (total_len + total_len / 255 + 64 > INT_MAX)
86
87 len = total_len;
88 buf_len = len + len / 255 + 64;
89
90 if (*buf)
92
93 ptr = *buf = av_realloc(NULL, buf_len);
94 if (!ptr)
95 return AVERROR(ENOMEM);
96 memset(*buf, '\0', buf_len);
97
98 ptr[0] = 2;
99 offset = 1;
100 offset += av_xiphlacing(&ptr[offset], priv->len[0]);
101 offset += av_xiphlacing(&ptr[offset], priv->len[1]);
102 for (i = 0; i < 3; i++) {
103 memcpy(&ptr[offset], priv->packet[i], priv->len[i]);
104 offset += priv->len[i];
105 av_freep(&priv->packet[i]);
106 }
107 if ((err = av_reallocp(buf, offset + AV_INPUT_BUFFER_PADDING_SIZE)) < 0)
108 return err;
109 return offset;
110}
111
112static void vorbis_cleanup(AVFormatContext *s, int idx)
113{
114 struct ogg *ogg = s->priv_data;
115 struct ogg_stream *os = ogg->streams + idx;
116 struct oggvorbis_private *priv = os->private;
117 int i;
118 if (os->private) {
119 av_vorbis_parse_free(&priv->vp);
120 for (i = 0; i < 3; i++)
121 av_freep(&priv->packet[i]);
122 }
123}
124
126 const uint8_t *buf, int size)
127{
128 struct ogg *ogg = s->priv_data;
129 struct ogg_stream *os = ogg->streams + st->index;
130 int ret;
131
132 /* New metadata packet; release old data. */
135 if (ret < 0)
136 return ret;
137
138 /* Update the metadata if possible. */
140 if (st->metadata) {
142 /* Send an empty dictionary to indicate that metadata has been cleared. */
143 } else {
144 os->new_metadata = av_mallocz(1);
145 os->new_metadata_size = 0;
146 }
147
148 return ret;
149}
150
152 const uint8_t *p, unsigned int psize)
153{
154 unsigned blocksize, bs0, bs1;
155 int srate;
156 int channels;
157
158 if (psize != 30)
159 return AVERROR_INVALIDDATA;
160
161 p += 7; /* skip "\001vorbis" tag */
162
163 if (bytestream_get_le32(&p) != 0) /* vorbis_version */
164 return AVERROR_INVALIDDATA;
165
166 channels = bytestream_get_byte(&p);
167 if (st->codecpar->ch_layout.nb_channels &&
169 av_log(s, AV_LOG_ERROR, "Channel change is not supported\n");
171 }
173 srate = bytestream_get_le32(&p);
174 p += 4; // skip maximum bitrate
175 st->codecpar->bit_rate = bytestream_get_le32(&p); // nominal bitrate
176 p += 4; // skip minimum bitrate
177
178 blocksize = bytestream_get_byte(&p);
179 bs0 = blocksize & 15;
180 bs1 = blocksize >> 4;
181
182 if (bs0 > bs1)
183 return AVERROR_INVALIDDATA;
184 if (bs0 < 6 || bs1 > 13)
185 return AVERROR_INVALIDDATA;
186
187 if (bytestream_get_byte(&p) != 1) /* framing_flag */
188 return AVERROR_INVALIDDATA;
189
192
193 if (srate > 0) {
194 if (st->codecpar->sample_rate &&
195 srate != st->codecpar->sample_rate) {
196 av_log(s, AV_LOG_ERROR, "Sample rate change is not supported\n");
198 }
199
200 st->codecpar->sample_rate = srate;
201 avpriv_set_pts_info(st, 64, 1, srate);
202 }
203
204 return 1;
205}
206
208{
209 struct ogg *ogg = s->priv_data;
210 struct ogg_stream *os = ogg->streams + idx;
211 AVStream *st = s->streams[idx];
212
213 if (os->psize <= 8)
214 return 0;
215
216 return ff_vorbis_update_metadata(s, st, os->buf + os->pstart + 7,
217 os->psize - 8);
218}
219
220static int vorbis_header(AVFormatContext *s, int idx)
221{
222 struct ogg *ogg = s->priv_data;
223 AVStream *st = s->streams[idx];
224 struct ogg_stream *os = ogg->streams + idx;
225 struct oggvorbis_private *priv;
226 int pkt_type = os->buf[os->pstart];
227
228 if (!os->private)
229 os->private = av_mallocz(sizeof(struct oggvorbis_private));
230
231 if (!os->private)
232 return AVERROR(ENOMEM);
233
234 priv = os->private;
235 priv->bos_page_pos = -1;
236
237 if (!(pkt_type & 1))
238 return priv->vp ? 0 : AVERROR_INVALIDDATA;
239
240 if (pkt_type > 5) {
241 av_log(s, AV_LOG_VERBOSE, "Ignoring packet with unknown type %d\n", pkt_type);
242 return 1;
243 }
244
245 if (os->psize < 1)
246 return AVERROR_INVALIDDATA;
247
248 if (priv->packet[pkt_type >> 1])
249 return AVERROR_INVALIDDATA;
250 if (pkt_type > 1 && !priv->packet[0] || pkt_type > 3 && !priv->packet[1])
251 return priv->vp ? 0 : AVERROR_INVALIDDATA;
252
253 priv->len[pkt_type >> 1] = os->psize;
254 priv->packet[pkt_type >> 1] = av_memdup(os->buf + os->pstart, os->psize);
255 if (!priv->packet[pkt_type >> 1])
256 return AVERROR(ENOMEM);
257 if (pkt_type == 1)
258 return vorbis_parse_header(s, st, os->buf + os->pstart, os->psize);
259
260 if (pkt_type == 3) {
261 if (vorbis_update_metadata(s, idx) >= 0 && priv->len[1] > 10) {
262 unsigned new_len;
263
264 int ret = ff_replaygain_export(st, st->metadata);
265 if (ret < 0)
266 return ret;
267
268 // drop all metadata we parsed and which is not required by libvorbis
269 new_len = 7 + 4 + AV_RL32(priv->packet[1] + 7) + 4 + 1;
270 if (new_len >= 16 && new_len < os->psize) {
271 AV_WL32(priv->packet[1] + new_len - 5, 0);
272 priv->packet[1][new_len - 1] = 1;
273 priv->len[1] = new_len;
274 }
275 }
276 } else {
277 int ret;
278
279 if (priv->vp)
280 return AVERROR_INVALIDDATA;
281
283 if (ret < 0) {
284 st->codecpar->extradata_size = 0;
285 return ret;
286 }
288
290 if (!priv->vp) {
292 st->codecpar->extradata_size = 0;
293 return AVERROR_UNKNOWN;
294 }
295 }
296
297 return 1;
298}
299
300/**
301 * Check that a packet follows the identification, comment, setup order of a
302 * chained stream's headers, and record it as the last packet.
303 *
304 * An identification header starts a new set. A misplaced packet discards the
305 * buffered headers, so an incomplete or misordered set is never packed.
306 * Reserved packet types are ignored, per Vorbis I §1.3.2.
307 *
308 * @return 0 if the packet is in order, AVERROR_INVALIDDATA otherwise
309 */
311 struct oggvorbis_private *priv,
313{
314 enum VorbisPacketType last = priv->last_packet;
315 const char *error = NULL;
316
317 switch (type) {
319 return 0;
321 if (last == VORBIS_PACKET_ID || last == VORBIS_PACKET_COMMENT)
322 error = "data packet before the setup header";
323 break;
324 case VORBIS_PACKET_ID:
325 if (last == VORBIS_PACKET_ID || last == VORBIS_PACKET_COMMENT)
326 error = "identification header before the setup header";
327 break;
329 if (last != VORBIS_PACKET_ID)
330 error = "comment header without identification header";
331 break;
333 if (last != VORBIS_PACKET_COMMENT)
334 error = "setup header without comment header";
335 break;
336 }
337
338 if (error)
340 "Invalid chained stream headers: %s, discarding them\n", error);
341
342 if (error || type == VORBIS_PACKET_ID)
343 for (int i = 0; i < 3; i++)
344 av_freep(&priv->packet[i]);
345
347 return error ? AVERROR_INVALIDDATA : 0;
348}
349
350static int vorbis_packet(AVFormatContext *s, int idx)
351{
352 struct ogg *ogg = s->priv_data;
353 struct ogg_stream *os = ogg->streams + idx;
354 struct oggvorbis_private *priv = os->private;
355 int duration, flags = 0;
356 int bos, skip_packet = 0;
357 int ret;
358
359 if (os->psize == 0)
360 return AVERROR_INVALIDDATA;
361
362 if (!priv->vp)
363 return AVERROR_INVALIDDATA;
364
365 /* Track the page holding the first data packet by its file position,
366 * which stays stable when probing rescans the start of the stream. */
367 if (priv->bos_page_pos < 0)
368 priv->bos_page_pos = os->page_pos;
369
370 bos = os->page_start && os->page_pos == priv->bos_page_pos;
371
372 if (bos || (os->page_start && os->lastpts == AV_NOPTS_VALUE))
374 if (bos)
375 priv->last_page_granule = 0;
376
377 duration = av_vorbis_parse_frame_flags(priv->vp, os->buf + os->pstart, 1, &flags);
378 if (duration < 0) {
380 return 0;
381 }
382 os->pduration = duration;
383
384 /* Save ts_offset from the very first chained stream to account for the
385 * first priming packet. This only shifts timestamps; the Vorbis decoder
386 * discards the leading priming samples itself, so we do not set
387 * codecpar->initial_padding. */
388 if (!priv->ts_offset)
389 priv->ts_offset = os->pduration;
390
391 /* Initial position shift to account for encoder delay, or page scan
392 * to recover the page start timestamp after a seek. */
393 if (bos) {
394 if (os->lastpts != AV_NOPTS_VALUE) {
395 if (s->streams[idx]->start_time == AV_NOPTS_VALUE) {
396 s->streams[idx]->start_time = os->lastpts;
397 if (s->streams[idx]->duration != AV_NOPTS_VALUE)
398 s->streams[idx]->duration -= s->streams[idx]->start_time;
399 }
400 os->lastpts -= priv->ts_offset;
401 }
402 if (os->lastdts != AV_NOPTS_VALUE)
403 os->lastdts -= priv->ts_offset;
404 } else if (os->page_start && os->lastpts == AV_NOPTS_VALUE &&
405 !(os->flags & OGG_FLAG_EOS) && (int64_t)os->granule >= 0) {
406 int seg, page_duration = os->pduration;
407 uint8_t *last_pkt = os->buf + os->pstart + os->psize;
408 uint8_t *next_pkt = last_pkt;
409
410 for (seg = os->segp; seg < os->nsegs; seg++) {
411 next_pkt += os->segments[seg];
412 if (os->segments[seg] < 255 && next_pkt != last_pkt) {
413 int pkt_flags = 0;
414 int d = av_vorbis_parse_frame_flags(priv->vp, last_pkt, 1, &pkt_flags);
415 if (d < 0) {
416 page_duration = os->granule;
417 break;
418 }
419 page_duration += d;
420 last_pkt = next_pkt;
421 }
422 }
423 av_vorbis_parse_frame_flags(priv->vp, os->buf + os->pstart, 1, &flags);
424 os->lastpts =
425 os->lastdts = os->granule - page_duration;
426 }
427
428 /* Broken files may have granule=0 on pages that contain audio data.
429 * In that case timestamps are unreliable, so discard them.
430 * See https://trac.ffmpeg.org/ticket/3710 */
431 if (!os->granule && os->pduration)
432 os->lastpts = os->lastdts = AV_NOPTS_VALUE;
433
434 if (os->flags & OGG_FLAG_EOS) {
435 /* Reset at the start of the EOS page to avoid carrying over stale
436 * duration from a previously processed EOS page, as can happen on
437 * short or chained ogg streams and when probing rescans the page.
438 * os->segp has already been advanced past the current packet by
439 * ogg_packet(), so rely on os->page_start to detect the page start. */
440 if (os->page_start)
441 priv->eos_page_duration = 0;
442
443 if (os->segp != os->nsegs) {
444 priv->eos_page_duration += os->pduration;
445 } else {
447 (os->granule - priv->last_page_granule);
448 if (skip > 0)
449 os->end_trimming = skip;
450 }
451 } else
452 priv->last_page_granule = os->granule;
453
454 /* Handle in-stream header packets from chained streams. The packet is
455 * skipped; the headers are buffered and attached as extradata to the
456 * first data packet that follows. */
459
460 ret = vorbis_parse_header(s, s->streams[idx], os->buf + os->pstart, os->psize);
461 if (ret < 0)
462 return ret;
463
464 ret = av_reallocp(&priv->packet[0], os->psize);
465 if (ret < 0)
466 return ret;
467
468 memcpy(priv->packet[0], os->buf + os->pstart, os->psize);
469 priv->len[0] = os->psize;
470
471 skip_packet = 1;
472 }
473
476 return 1;
477
479 if (ret < 0)
480 return ret;
481
482 ret = av_reallocp(&priv->packet[1], os->psize);
483 if (ret < 0)
484 return ret;
485
486 memcpy(priv->packet[1], os->buf + os->pstart, os->psize);
487 priv->len[1] = os->psize;
488
489 flags = 0;
490 skip_packet = 1;
491 }
492
493 if (flags & VORBIS_FLAG_SETUP) {
495 return 1;
496
497 ret = av_reallocp(&priv->packet[2], os->psize);
498 if (ret < 0)
499 return ret;
500
501 memcpy(priv->packet[2], os->buf + os->pstart, os->psize);
502 priv->len[2] = os->psize;
503
504 skip_packet = 1;
505 }
506
507 if (!skip_packet)
508 vorbis_check_packet_order(s, priv, os->buf[os->pstart] & 1 ?
510
511 /* All three headers for the new chained stream have been collected;
512 * pack them into new extradata to be attached to the next data packet. */
513 if (priv->packet[0] && priv->packet[1] && priv->packet[2]) {
516 if (ret < 0) {
517 os->new_extradata_size = 0;
518 return ret;
519 }
521
522 av_vorbis_parse_free(&priv->vp);
524 if (!priv->vp) {
525 av_log(s, AV_LOG_ERROR, "Failed to re-initialize Vorbis parser\n");
526 return AVERROR_INVALIDDATA;
527 }
528
529 /* Reset bos_page_pos so the next packet will initialize it for the
530 * new chained stream. */
531 priv->bos_page_pos = -1;
532 }
533
534 return skip_packet;
535}
536
538 .magic = "\001vorbis",
539 .magicsize = 7,
540 .header = vorbis_header,
541 .packet = vorbis_packet,
542 .cleanup = vorbis_cleanup,
543 .nb_header = 3,
544};
channels
Definition aptx.h:31
void avpriv_set_pts_info(AVStream *st, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition avformat.c:865
Main libavformat public API header.
static void BS_FUNC skip(BSCTX *bc, unsigned int n)
Skip n bits in the buffer.
#define flags(name, subs,...)
Definition cbs_h264.c:74
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define s(width, name)
Definition cbs_vp9.c:198
int ff_vorbis_comment_read_stream(AVFormatContext *as, AVStream *st, const uint8_t *buf, int size)
Parse Vorbis comments and add metadata to an AVStream.
Definition reader.c:73
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
unsigned int av_xiphlacing(unsigned char *s, unsigned int v)
Encode extradata length to a buffer.
Definition utils.c:847
Public dictionary API.
static int64_t duration
Definition ffplay.c:359
int ret
Definition ffplay.c:391
@ AV_CODEC_ID_VORBIS
Definition codec_id.h:464
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding.
Definition defs.h:40
#define AV_PKT_FLAG_CORRUPT
The packet content is corrupted.
Definition packet.h:658
uint8_t * av_packet_pack_dictionary(const AVDictionary *dict, size_t *size)
Pack a dictionary for use in side_data.
Definition packet.c:320
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
Definition dict.c:236
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
Definition error.h:73
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition error.h:64
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR(e)
Definition error.h:45
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition log.h:216
#define AV_LOG_VERBOSE
Detailed information.
Definition log.h:226
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
int av_reallocp(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory through a pointer to a pointer.
Definition mem.c:289
void * av_memdup(const void *p, size_t size)
Duplicate a buffer with av_malloc().
Definition mem.c:408
@ AVMEDIA_TYPE_AUDIO
Definition avutil.h:201
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition avutil.h:247
#define AV_WL32(p, v)
#define AV_RL32(p)
enum MPFType type
Definition jpegmpfenc.c:55
unsigned offset
Definition libaomenc.c:763
int ff_vorbis_update_metadata(AVFormatContext *s, AVStream *st, const uint8_t *buf, int size)
Parse Vorbis comments, add metadata to an AVStream.
Definition vorbis.c:125
static int vorbis_parse_header(AVFormatContext *s, AVStream *st, const uint8_t *p, unsigned int psize)
Definition vorbis.c:151
static int vorbis_check_packet_order(AVFormatContext *s, struct oggvorbis_private *priv, enum VorbisPacketType type)
Check that a packet follows the identification, comment, setup order of a chained stream's headers,...
Definition vorbis.c:310
static int fixup_vorbis_headers(AVFormatContext *as, struct oggvorbis_private *priv, uint8_t **buf)
Definition vorbis.c:74
static void vorbis_cleanup(AVFormatContext *s, int idx)
Definition vorbis.c:112
VorbisPacketType
Definition vorbis.c:55
@ VORBIS_PACKET_ID
Definition vorbis.c:57
@ VORBIS_PACKET_DATA
Definition vorbis.c:56
@ VORBIS_PACKET_COMMENT
Definition vorbis.c:58
@ VORBIS_PACKET_RESERVED
Definition vorbis.c:60
@ VORBIS_PACKET_SETUP
Definition vorbis.c:59
static int vorbis_update_metadata(AVFormatContext *s, int idx)
Definition vorbis.c:207
static int vorbis_packet(AVFormatContext *s, int idx)
Definition vorbis.c:350
static int vorbis_header(AVFormatContext *s, int idx)
Definition vorbis.c:220
const struct ogg_codec ff_vorbis_codec
Definition vorbis.c:537
#define OGG_FLAG_EOS
Definition mapping.h:123
Memory handling functions.
#define av_realloc(p, s)
Definition ops_static.c:54
int ff_replaygain_export(AVStream *st, AVDictionary *metadata)
Parse replaygain tags and export them as per-stream side data.
Definition replaygain.c:94
int nb_channels
Number of channels in this layout.
int extradata_size
Size of the extradata content in bytes.
Definition codec_par.h:75
AVChannelLayout ch_layout
The channel layout and number of channels.
Definition codec_par.h:207
int64_t bit_rate
The average bitrate of the encoded data (in bits per second).
Definition codec_par.h:99
enum AVMediaType codec_type
General type of the encoded data.
Definition codec_par.h:53
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition codec_par.h:71
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition codec_par.h:57
int sample_rate
The number of audio samples per second.
Definition codec_par.h:213
Format I/O context.
Definition avformat.h:1401
Stream structure.
Definition avformat.h:768
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition avformat.h:791
AVDictionary * metadata
Definition avformat.h:848
int index
stream index in AVFormatContext
Definition avformat.h:774
Copyright (C) 2005 Michael Ahlberg, Måns Rullgård.
Definition mapping.h:30
unsigned int pduration
Definition mapping.h:74
uint8_t * new_extradata
Definition mapping.h:99
size_t new_metadata_size
Definition mapping.h:98
size_t new_extradata_size
Definition mapping.h:100
int end_trimming
set the number of packets to drop from the end
Definition mapping.h:95
unsigned int pflags
Definition mapping.h:73
uint8_t * new_metadata
Definition mapping.h:97
int nsegs
Definition mapping.h:85
uint8_t segments[255]
Definition mapping.h:86
int page_start
current packet is the first one starting in the page
Definition mapping.h:88
uint64_t granule
Definition mapping.h:76
int64_t lastdts
Definition mapping.h:79
unsigned int pstart
Definition mapping.h:71
unsigned int psize
Definition mapping.h:72
void * private
Definition mapping.h:101
uint8_t * buf
Definition mapping.h:68
int64_t page_pos
file offset of the current page
Definition mapping.h:81
int64_t lastpts
Definition mapping.h:78
int segp
Definition mapping.h:85
int flags
Definition mapping.h:82
Definition mapping.h:112
struct ogg_stream * streams
Definition mapping.h:113
int64_t bos_page_pos
Definition vorbis.c:68
int eos_page_duration
Definition vorbis.c:71
unsigned char * packet[3]
Definition vorbis.c:65
unsigned int len[3]
Definition vorbis.c:64
AVVorbisParseContext * vp
Definition vorbis.c:67
enum VorbisPacketType last_packet
type of the last packet seen by vorbis_packet()
Definition vorbis.c:66
int64_t last_page_granule
Definition vorbis.c:70
#define av_mallocz(s)
#define av_freep(p)
#define av_log(a,...)
static void error(const char *err)
int size
int len
void av_vorbis_parse_free(AVVorbisParseContext **s)
Free the parser and everything associated with it.
int av_vorbis_parse_frame_flags(AVVorbisParseContext *s, const uint8_t *buf, int buf_size, int *flags)
Get the duration for a Vorbis packet.
AVVorbisParseContext * av_vorbis_parse_init(const uint8_t *extradata, int extradata_size)
Allocate and initialize the Vorbis parser using headers in the extradata.
void av_vorbis_parse_reset(AVVorbisParseContext *s)
A public API for Vorbis parsing.
#define VORBIS_FLAG_SETUP
#define VORBIS_FLAG_COMMENT
#define VORBIS_FLAG_HEADER