FFmpeg
Loading...
Searching...
No Matches
oggparsevorbis.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/avstring.h"
28#include "libavutil/base64.h"
29#include "libavutil/dict.h"
30#include "libavutil/mem.h"
31
34
35#include "avformat.h"
36#include "demux.h"
37#include "flac_picture.h"
38#include "internal.h"
39#include "oggdec.h"
40#include "vorbiscomment.h"
41#include "replaygain.h"
42
43static int ogm_chapter(AVFormatContext *as, const uint8_t *key, const uint8_t *val)
44{
45 int i, cnum, h, m, s, ms, keylen = strlen(key);
46 AVChapter *chapter = NULL;
47
48 if (keylen < 9 || av_strncasecmp(key, "CHAPTER", 7) || sscanf(key+7, "%03d", &cnum) != 1)
49 return 0;
50
51 if (keylen <= 10) {
52 if (sscanf(val, "%02d:%02d:%02d.%03d", &h, &m, &s, &ms) < 4)
53 return 0;
54
55 avpriv_new_chapter(as, cnum, (AVRational) { 1, 1000 },
56 ms + 1000 * (s + 60 * (m + 60 * h)),
58 } else if (!av_strcasecmp(key + keylen - 4, "NAME")) {
59 for (i = 0; i < as->nb_chapters; i++)
60 if (as->chapters[i]->id == cnum) {
61 chapter = as->chapters[i];
62 break;
63 }
64 if (!chapter)
65 return 0;
66
67 av_dict_set(&chapter->metadata, "title", val, 0);
68 } else
69 return 0;
70
71 return 1;
72}
73
75 const uint8_t *buf, int size)
76{
77 int updates = ff_vorbis_comment(as, &st->metadata, buf, size, 1);
78
79 if (updates > 0) {
81 }
82
83 return updates;
84}
85
86/**
87 * This function temporarily modifies the (const qualified) input buffer
88 * and reverts its changes before return. The input buffer needs to have
89 * at least one byte of padding.
90 */
92 const uint8_t *buf, uint32_t size,
93 int *updates, int parse_picture)
94{
95 char *t = (char*)buf, *v = memchr(t, '=', size);
96 int tl, vl;
97 char backup;
98
99 if (!v)
100 return 0;
101
102 tl = v - t;
103 vl = size - tl - 1;
104 v++;
105
106 if (!tl || !vl)
107 return 0;
108
109 t[tl] = 0;
110
111 backup = v[vl];
112 v[vl] = 0;
113
114 /* The format in which the pictures are stored is the FLAC format.
115 * Xiph says: "The binary FLAC picture structure is base64 encoded
116 * and placed within a VorbisComment with the tag name
117 * 'METADATA_BLOCK_PICTURE'. This is the preferred and
118 * recommended way of embedding cover art within VorbisComments."
119 */
120 if (!av_strcasecmp(t, "METADATA_BLOCK_PICTURE") && parse_picture) {
121 int ret, len = AV_BASE64_DECODE_SIZE(vl);
122 uint8_t *pict = av_malloc(len + AV_INPUT_BUFFER_PADDING_SIZE);
123
124 if (!pict) {
125 av_log(as, AV_LOG_WARNING, "out-of-memory error. Skipping cover art block.\n");
126 goto end;
127 }
128 ret = av_base64_decode(pict, v, len);
129 if (ret > 0)
130 ret = ff_flac_parse_picture(as, &pict, ret, 0);
131 av_freep(&pict);
132 if (ret < 0) {
133 av_log(as, AV_LOG_WARNING, "Failed to parse cover art block.\n");
134 goto end;
135 }
136 } else if (!ogm_chapter(as, t, v)) {
137 (*updates)++;
138 if (av_dict_get(*m, t, NULL, 0))
139 av_dict_set(m, t, ";", AV_DICT_APPEND);
140 av_dict_set(m, t, v, AV_DICT_APPEND);
141 }
142end:
143 t[tl] = '=';
144 v[vl] = backup;
145
146 return 0;
147}
148
150 const uint8_t *buf, int size,
151 int parse_picture)
152{
153 const uint8_t *p = buf;
154 const uint8_t *end = buf + size;
155 int updates = 0;
156 unsigned n;
157 int s, ret;
158
159 /* must have vendor_length and user_comment_list_length */
160 if (size < 8)
161 return AVERROR_INVALIDDATA;
162
163 s = bytestream_get_le32(&p);
164
165 if (end - p - 4 < s || s < 0)
166 return AVERROR_INVALIDDATA;
167
168 p += s;
169
170 n = bytestream_get_le32(&p);
171
172 while (end - p >= 4 && n > 0) {
173 s = bytestream_get_le32(&p);
174
175 if (end - p < s || s < 0)
176 break;
177
178 ret = vorbis_parse_single_comment(as, m, p, s, &updates, parse_picture);
179 if (ret < 0)
180 return ret;
181 p += s;
182 n--;
183 }
184
185 if (p != end)
187 "%td bytes of comment header remain\n", end - p);
188 if (n > 0)
190 "truncated comment header, %i comments not found\n", n);
191
193
194 return updates;
195}
196
197/*
198 * Parse the vorbis header
199 *
200 * Vorbis Identification header from Vorbis_I_spec.html#vorbis-spec-codec
201 * [vorbis_version] = read 32 bits as unsigned integer | Not used
202 * [audio_channels] = read 8 bit integer as unsigned | Used
203 * [audio_sample_rate] = read 32 bits as unsigned integer | Used
204 * [bitrate_maximum] = read 32 bits as signed integer | Not used yet
205 * [bitrate_nominal] = read 32 bits as signed integer | Not used yet
206 * [bitrate_minimum] = read 32 bits as signed integer | Used as bitrate
207 * [blocksize_0] = read 4 bits as unsigned integer | Not Used
208 * [blocksize_1] = read 4 bits as unsigned integer | Not Used
209 * [framing_flag] = read one bit | Not Used
210 */
211
227
229 struct oggvorbis_private *priv,
230 uint8_t **buf)
231{
232 int i, offset, len, err;
233 int buf_len;
234 unsigned char *ptr;
235 uint64_t total_len;
236
237 total_len = (uint64_t)priv->len[0] + priv->len[1] + priv->len[2];
238 if (total_len + total_len / 255 + 64 > INT_MAX)
239 return AVERROR_INVALIDDATA;
240
241 len = total_len;
242 buf_len = len + len / 255 + 64;
243
244 if (*buf)
245 return AVERROR_INVALIDDATA;
246
247 ptr = *buf = av_realloc(NULL, buf_len);
248 if (!ptr)
249 return AVERROR(ENOMEM);
250 memset(*buf, '\0', buf_len);
251
252 ptr[0] = 2;
253 offset = 1;
254 offset += av_xiphlacing(&ptr[offset], priv->len[0]);
255 offset += av_xiphlacing(&ptr[offset], priv->len[1]);
256 for (i = 0; i < 3; i++) {
257 memcpy(&ptr[offset], priv->packet[i], priv->len[i]);
258 offset += priv->len[i];
259 av_freep(&priv->packet[i]);
260 }
261 if ((err = av_reallocp(buf, offset + AV_INPUT_BUFFER_PADDING_SIZE)) < 0)
262 return err;
263 return offset;
264}
265
266static void vorbis_cleanup(AVFormatContext *s, int idx)
267{
268 struct ogg *ogg = s->priv_data;
269 struct ogg_stream *os = ogg->streams + idx;
270 struct oggvorbis_private *priv = os->private;
271 int i;
272 if (os->private) {
273 av_vorbis_parse_free(&priv->vp);
274 for (i = 0; i < 3; i++)
275 av_freep(&priv->packet[i]);
276
277 av_freep(&priv->header);
278 av_freep(&priv->comment);
279 av_freep(&priv->setup);
280 }
281}
282
284 const uint8_t *buf, int size)
285{
286 struct ogg *ogg = s->priv_data;
287 struct ogg_stream *os = ogg->streams + st->index;
288 int ret;
289
290 /* New metadata packet; release old data. */
292 ret = ff_vorbis_stream_comment(s, st, buf, size);
293 if (ret < 0)
294 return ret;
295
296 /* Update the metadata if possible. */
298 if (st->metadata) {
300 /* Send an empty dictionary to indicate that metadata has been cleared. */
301 } else {
302 os->new_metadata = av_mallocz(1);
303 os->new_metadata_size = 0;
304 }
305
306 return ret;
307}
308
310 const uint8_t *p, unsigned int psize)
311{
312 unsigned blocksize, bs0, bs1;
313 int srate;
314 int channels;
315
316 if (psize != 30)
317 return AVERROR_INVALIDDATA;
318
319 p += 7; /* skip "\001vorbis" tag */
320
321 if (bytestream_get_le32(&p) != 0) /* vorbis_version */
322 return AVERROR_INVALIDDATA;
323
324 channels = bytestream_get_byte(&p);
325 if (st->codecpar->ch_layout.nb_channels &&
327 av_log(s, AV_LOG_ERROR, "Channel change is not supported\n");
329 }
331 srate = bytestream_get_le32(&p);
332 p += 4; // skip maximum bitrate
333 st->codecpar->bit_rate = bytestream_get_le32(&p); // nominal bitrate
334 p += 4; // skip minimum bitrate
335
336 blocksize = bytestream_get_byte(&p);
337 bs0 = blocksize & 15;
338 bs1 = blocksize >> 4;
339
340 if (bs0 > bs1)
341 return AVERROR_INVALIDDATA;
342 if (bs0 < 6 || bs1 > 13)
343 return AVERROR_INVALIDDATA;
344
345 if (bytestream_get_byte(&p) != 1) /* framing_flag */
346 return AVERROR_INVALIDDATA;
347
350
351 if (srate > 0) {
352 if (st->codecpar->sample_rate &&
353 srate != st->codecpar->sample_rate) {
354 av_log(s, AV_LOG_ERROR, "Sample rate change is not supported\n");
356 }
357
358 st->codecpar->sample_rate = srate;
359 avpriv_set_pts_info(st, 64, 1, srate);
360 }
361
362 return 1;
363}
364
366{
367 struct ogg *ogg = s->priv_data;
368 struct ogg_stream *os = ogg->streams + idx;
369 AVStream *st = s->streams[idx];
370
371 if (os->psize <= 8)
372 return 0;
373
374 return ff_vorbis_update_metadata(s, st, os->buf + os->pstart + 7,
375 os->psize - 8);
376}
377
378static int vorbis_header(AVFormatContext *s, int idx)
379{
380 struct ogg *ogg = s->priv_data;
381 AVStream *st = s->streams[idx];
382 struct ogg_stream *os = ogg->streams + idx;
383 struct oggvorbis_private *priv;
384 int pkt_type = os->buf[os->pstart];
385
386 if (!os->private)
387 os->private = av_mallocz(sizeof(struct oggvorbis_private));
388
389 if (!os->private)
390 return AVERROR(ENOMEM);
391
392 priv = os->private;
393 priv->bos_page_pos = -1;
394
395 if (!(pkt_type & 1))
396 return priv->vp ? 0 : AVERROR_INVALIDDATA;
397
398 if (pkt_type > 5) {
399 av_log(s, AV_LOG_VERBOSE, "Ignoring packet with unknown type %d\n", pkt_type);
400 return 1;
401 }
402
403 if (os->psize < 1)
404 return AVERROR_INVALIDDATA;
405
406 if (priv->packet[pkt_type >> 1])
407 return AVERROR_INVALIDDATA;
408 if (pkt_type > 1 && !priv->packet[0] || pkt_type > 3 && !priv->packet[1])
409 return priv->vp ? 0 : AVERROR_INVALIDDATA;
410
411 priv->len[pkt_type >> 1] = os->psize;
412 priv->packet[pkt_type >> 1] = av_memdup(os->buf + os->pstart, os->psize);
413 if (!priv->packet[pkt_type >> 1])
414 return AVERROR(ENOMEM);
415 if (pkt_type == 1)
416 return vorbis_parse_header(s, st, os->buf + os->pstart, os->psize);
417
418 if (pkt_type == 3) {
419 if (vorbis_update_metadata(s, idx) >= 0 && priv->len[1] > 10) {
420 unsigned new_len;
421
422 int ret = ff_replaygain_export(st, st->metadata);
423 if (ret < 0)
424 return ret;
425
426 // drop all metadata we parsed and which is not required by libvorbis
427 new_len = 7 + 4 + AV_RL32(priv->packet[1] + 7) + 4 + 1;
428 if (new_len >= 16 && new_len < os->psize) {
429 AV_WL32(priv->packet[1] + new_len - 5, 0);
430 priv->packet[1][new_len - 1] = 1;
431 priv->len[1] = new_len;
432 }
433 }
434 } else {
435 int ret;
436
437 if (priv->vp)
438 return AVERROR_INVALIDDATA;
439
440 ret = fixup_vorbis_headers(s, priv, &st->codecpar->extradata);
441 if (ret < 0) {
442 st->codecpar->extradata_size = 0;
443 return ret;
444 }
445 st->codecpar->extradata_size = ret;
446
448 if (!priv->vp) {
450 st->codecpar->extradata_size = 0;
451 return AVERROR_UNKNOWN;
452 }
453 }
454
455 return 1;
456}
457
458static int vorbis_packet(AVFormatContext *s, int idx)
459{
460 struct ogg *ogg = s->priv_data;
461 struct ogg_stream *os = ogg->streams + idx;
462 struct oggvorbis_private *priv = os->private;
463 int duration, flags = 0;
464 int bos, skip_packet = 0;
465 int ret, new_extradata_size;
467
468 if (os->psize == 0)
469 return AVERROR_INVALIDDATA;
470
471 if (!priv->vp)
472 return AVERROR_INVALIDDATA;
473
474 /* Track the page holding the first data packet by its file position,
475 * which stays stable when probing rescans the start of the stream. */
476 if (priv->bos_page_pos < 0)
477 priv->bos_page_pos = os->page_pos;
478
479 bos = os->page_start && os->page_pos == priv->bos_page_pos;
480
481 if (bos) {
483 priv->last_page_granule = 0;
484 }
485
486 duration = av_vorbis_parse_frame_flags(priv->vp, os->buf + os->pstart, 1, &flags);
487 if (duration < 0) {
489 return 0;
490 }
491 os->pduration = duration;
492
493 /* Save ts_offset from the very first chained stream to account for the
494 * first priming packet. This only shifts timestamps; the Vorbis decoder
495 * discards the leading priming samples itself, so we do not set
496 * codecpar->initial_padding. */
497 if (!priv->ts_offset)
498 priv->ts_offset = os->pduration;
499
500 /* Initial position shift to account for encoder delay. */
501 if (bos) {
502 if (os->lastpts != AV_NOPTS_VALUE)
503 os->lastpts -= priv->ts_offset;
504 if (os->lastdts != AV_NOPTS_VALUE)
505 os->lastdts -= priv->ts_offset;
506 }
507
508 /* Broken files may have granule=0 on pages that contain audio data.
509 * In that case timestamps are unreliable, so discard them.
510 * See https://trac.ffmpeg.org/ticket/3710 */
511 if (!os->granule && os->pduration)
512 os->lastpts = os->lastdts = AV_NOPTS_VALUE;
513
514 if (os->flags & OGG_FLAG_EOS) {
515 /* Reset at the start of the EOS page to avoid carrying over stale
516 * duration from a previously processed EOS page, as can happen on
517 * short or chained ogg streams and when probing rescans the page.
518 * os->segp has already been advanced past the current packet by
519 * ogg_packet(), so rely on os->page_start to detect the page start. */
520 if (os->page_start)
521 priv->eos_page_duration = 0;
522
523 if (os->segp != os->nsegs) {
524 priv->eos_page_duration += os->pduration;
525 } else {
527 (os->granule - priv->last_page_granule);
528 if (skip > 0)
529 os->end_trimming = skip;
530 }
531 } else
532 priv->last_page_granule = os->granule;
533
534 /* Handle in-stream header packets from chained streams. The packet is
535 * skipped; the headers are buffered and attached as extradata to the
536 * first data packet that follows. */
538 ret = vorbis_parse_header(s, s->streams[idx], os->buf + os->pstart, os->psize);
539 if (ret < 0)
540 return ret;
541
542 ret = av_reallocp(&priv->header, os->psize);
543 if (ret < 0)
544 return ret;
545
546 memcpy(priv->header, os->buf + os->pstart, os->psize);
547 priv->header_size = os->psize;
548
549 skip_packet = 1;
550 }
551
553 ret = vorbis_update_metadata(s, idx);
554 if (ret < 0)
555 return ret;
556
557 ret = av_reallocp(&priv->comment, os->psize);
558 if (ret < 0)
559 return ret;
560
561 memcpy(priv->comment, os->buf + os->pstart, os->psize);
562 priv->comment_size = os->psize;
563
564 flags = 0;
565 skip_packet = 1;
566 }
567
568 if (flags & VORBIS_FLAG_SETUP) {
569 ret = av_reallocp(&priv->setup, os->psize);
570 if (ret < 0)
571 return ret;
572
573 memcpy(priv->setup, os->buf + os->pstart, os->psize);
574 priv->setup_size = os->psize;
575
576 skip_packet = 1;
577 }
578
579
580 /* All three headers for the new chained stream have been collected;
581 * pack them into new extradata to be attached to the next data packet. */
582 if (priv->header && priv->comment && priv->setup) {
583 new_extradata_size = priv->header_size + priv->comment_size + priv->setup_size + 6;
584
585 ret = av_reallocp(&os->new_extradata, new_extradata_size);
586 if (ret < 0)
587 return ret;
588
589 os->new_extradata_size = new_extradata_size;
590 bytestream2_init_writer(&pb, os->new_extradata, new_extradata_size);
591 bytestream2_put_be16(&pb, priv->header_size);
592 bytestream2_put_buffer(&pb, priv->header, priv->header_size);
593 bytestream2_put_be16(&pb, priv->comment_size);
595 bytestream2_put_be16(&pb, priv->setup_size);
596 bytestream2_put_buffer(&pb, priv->setup, priv->setup_size);
597
598 av_freep(&priv->header);
599 priv->header_size = 0;
600 av_freep(&priv->comment);
601 priv->comment_size = 0;
602 av_freep(&priv->setup);
603 priv->setup_size = 0;
604
605 av_vorbis_parse_free(&priv->vp);
607 if (!priv->vp) {
608 av_log(s, AV_LOG_ERROR, "Failed to re-initialize Vorbis parser\n");
609 return AVERROR_INVALIDDATA;
610 }
611
612 /* Reset bos_page_pos so the next packet will initialize it for the
613 * new chained stream. */
614 priv->bos_page_pos = -1;
615 }
616
617 return skip_packet;
618}
619
621 .magic = "\001vorbis",
622 .magicsize = 7,
623 .header = vorbis_header,
624 .packet = vorbis_packet,
625 .cleanup = vorbis_cleanup,
626 .nb_header = 3,
627};
static double val(void *priv, double ch)
Definition aeval.c:77
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:834
Main libavformat public API header.
#define AVSTREAM_EVENT_FLAG_METADATA_UPDATED
Definition avformat.h:884
static void BS_FUNC skip(BSCTX *bc, unsigned int n)
Skip n bits in the buffer.
static av_always_inline void bytestream2_init_writer(PutByteContext *p, uint8_t *buf, int buf_size)
Definition bytestream.h:147
static av_always_inline unsigned int bytestream2_put_buffer(PutByteContext *p, const uint8_t *src, unsigned int size)
Definition bytestream.h:286
#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
#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:836
AVChapter * avpriv_new_chapter(AVFormatContext *s, int64_t id, AVRational time_base, int64_t start, int64_t end, const char *title)
Add a new chapter.
Definition demux_utils.c:43
Public dictionary API.
const char * key
static int64_t duration
Definition ffplay.c:330
int ff_flac_parse_picture(AVFormatContext *s, uint8_t **bufp, int buf_size, int truncate_workaround)
Parse a FLAC METADATA_BLOCK_PICTURE.
@ AV_CODEC_ID_VORBIS
Definition codec_id.h:458
#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:651
uint8_t * av_packet_pack_dictionary(const AVDictionary *dict, size_t *size)
Pack a dictionary for use in side_data.
Definition packet.c:319
#define AV_BASE64_DECODE_SIZE(x)
Calculate the output size in bytes needed to decode a base64 string with length x to a data buffer.
Definition base64.h:48
int av_base64_decode(uint8_t *out, const char *in_str, int out_size)
Decode a base64-encoded string.
Definition base64.c:81
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
Definition dict.c:233
AVDictionaryEntry * av_dict_get(const AVDictionary *m, const char *key, const AVDictionaryEntry *prev, int flags)
Get a dictionary entry with matching key.
Definition dict.c:60
#define AV_DICT_APPEND
If the entry already exists, append to it.
Definition dict.h:82
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
Definition dict.c:86
#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_INFO
Standard information.
Definition log.h:221
#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:188
void * av_memdup(const void *p, size_t size)
Duplicate a buffer with av_malloc().
Definition mem.c:302
@ AVMEDIA_TYPE_AUDIO
Definition avutil.h:201
int av_strcasecmp(const char *a, const char *b)
Locale-independent case-insensitive compare.
Definition avstring.c:208
int av_strncasecmp(const char *a, const char *b, size_t n)
Locale-independent case-insensitive compare.
Definition avstring.c:218
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition avutil.h:247
#define AV_WL32(p, v)
#define AV_RL32(p)
unsigned offset
Definition libaomenc.c:763
Memory handling functions.
void ff_metadata_conv(AVDictionary **pm, const AVMetadataConv *d_conv, const AVMetadataConv *s_conv)
Definition metadata.c:26
const struct ogg_codec ff_vorbis_codec
#define OGG_FLAG_EOS
Definition oggdec.h:123
int ff_vorbis_update_metadata(AVFormatContext *s, AVStream *st, const uint8_t *buf, int size)
Parse Vorbis comments, add metadata to an AVStream.
static int vorbis_parse_header(AVFormatContext *s, AVStream *st, const uint8_t *p, unsigned int psize)
int ff_vorbis_stream_comment(AVFormatContext *as, AVStream *st, const uint8_t *buf, int size)
Parse Vorbis comments and add metadata to an AVStream.
static int fixup_vorbis_headers(AVFormatContext *as, struct oggvorbis_private *priv, uint8_t **buf)
static void vorbis_cleanup(AVFormatContext *s, int idx)
static int ogm_chapter(AVFormatContext *as, const uint8_t *key, const uint8_t *val)
static int vorbis_update_metadata(AVFormatContext *s, int idx)
int ff_vorbis_comment(AVFormatContext *as, AVDictionary **m, const uint8_t *buf, int size, int parse_picture)
Parse Vorbis comments.
static int vorbis_parse_single_comment(AVFormatContext *as, AVDictionary **m, const uint8_t *buf, uint32_t size, int *updates, int parse_picture)
This function temporarily modifies the (const qualified) input buffer and reverts its changes before ...
static int vorbis_packet(AVFormatContext *s, int idx)
static int vorbis_header(AVFormatContext *s, int idx)
#define av_realloc(p, s)
Definition ops_static.c:54
#define av_malloc(s)
Definition ops_static.c:52
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.
int64_t id
unique ID to identify the chapter
Definition avformat.h:1293
AVDictionary * metadata
Definition avformat.h:1296
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:1333
unsigned int nb_chapters
Number of chapters in AVChapter array.
Definition avformat.h:1433
AVChapter ** chapters
Definition avformat.h:1434
Rational number (pair of numerator and denominator).
Definition rational.h:58
Stream structure.
Definition avformat.h:766
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition avformat.h:789
AVDictionary * metadata
Definition avformat.h:846
int index
stream index in AVFormatContext
Definition avformat.h:772
int event_flags
Flags indicating events happening on the stream, a combination of AVSTREAM_EVENT_FLAG_*.
Definition avformat.h:877
Copyright (C) 2005 Michael Ahlberg, Måns Rullgård.
Definition oggdec.h:30
unsigned int pduration
Definition oggdec.h:74
uint8_t * new_extradata
Definition oggdec.h:99
size_t new_metadata_size
Definition oggdec.h:98
size_t new_extradata_size
Definition oggdec.h:100
int end_trimming
set the number of packets to drop from the end
Definition oggdec.h:95
unsigned int pflags
Definition oggdec.h:73
uint8_t * new_metadata
Definition oggdec.h:97
int nsegs
Definition oggdec.h:85
int page_start
current packet is the first one starting in the page
Definition oggdec.h:88
uint64_t granule
Definition oggdec.h:76
int64_t lastdts
Definition oggdec.h:79
unsigned int pstart
Definition oggdec.h:71
unsigned int psize
Definition oggdec.h:72
void * private
Definition oggdec.h:101
uint8_t * buf
Definition oggdec.h:68
int64_t page_pos
file offset of the current page
Definition oggdec.h:81
int64_t lastpts
Definition oggdec.h:78
int segp
Definition oggdec.h:85
int flags
Definition oggdec.h:82
Definition oggdec.h:112
struct ogg_stream * streams
Definition oggdec.h:113
unsigned char * packet[3]
unsigned int len[3]
AVVorbisParseContext * vp
#define av_mallocz(s)
#define av_freep(p)
#define av_log(a,...)
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
const AVMetadataConv ff_vorbiscomment_metadata_conv[]
VorbisComment metadata conversion mapping.