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
219
221 unsigned int len[3];
222 unsigned char *packet[3];
223 enum VorbisPacketType last_packet; ///< type of the last packet seen by vorbis_packet()
229};
230
232 struct oggvorbis_private *priv,
233 uint8_t **buf)
234{
235 int i, offset, len, err;
236 int buf_len;
237 unsigned char *ptr;
238 uint64_t total_len;
239
240 total_len = (uint64_t)priv->len[0] + priv->len[1] + priv->len[2];
241 if (total_len + total_len / 255 + 64 > INT_MAX)
242 return AVERROR_INVALIDDATA;
243
244 len = total_len;
245 buf_len = len + len / 255 + 64;
246
247 if (*buf)
248 return AVERROR_INVALIDDATA;
249
250 ptr = *buf = av_realloc(NULL, buf_len);
251 if (!ptr)
252 return AVERROR(ENOMEM);
253 memset(*buf, '\0', buf_len);
254
255 ptr[0] = 2;
256 offset = 1;
257 offset += av_xiphlacing(&ptr[offset], priv->len[0]);
258 offset += av_xiphlacing(&ptr[offset], priv->len[1]);
259 for (i = 0; i < 3; i++) {
260 memcpy(&ptr[offset], priv->packet[i], priv->len[i]);
261 offset += priv->len[i];
262 av_freep(&priv->packet[i]);
263 }
264 if ((err = av_reallocp(buf, offset + AV_INPUT_BUFFER_PADDING_SIZE)) < 0)
265 return err;
266 return offset;
267}
268
269static void vorbis_cleanup(AVFormatContext *s, int idx)
270{
271 struct ogg *ogg = s->priv_data;
272 struct ogg_stream *os = ogg->streams + idx;
273 struct oggvorbis_private *priv = os->private;
274 int i;
275 if (os->private) {
276 av_vorbis_parse_free(&priv->vp);
277 for (i = 0; i < 3; i++)
278 av_freep(&priv->packet[i]);
279 }
280}
281
283 const uint8_t *buf, int size)
284{
285 struct ogg *ogg = s->priv_data;
286 struct ogg_stream *os = ogg->streams + st->index;
287 int ret;
288
289 /* New metadata packet; release old data. */
292 if (ret < 0)
293 return ret;
294
295 /* Update the metadata if possible. */
297 if (st->metadata) {
299 /* Send an empty dictionary to indicate that metadata has been cleared. */
300 } else {
301 os->new_metadata = av_mallocz(1);
302 os->new_metadata_size = 0;
303 }
304
305 return ret;
306}
307
309 const uint8_t *p, unsigned int psize)
310{
311 unsigned blocksize, bs0, bs1;
312 int srate;
313 int channels;
314
315 if (psize != 30)
316 return AVERROR_INVALIDDATA;
317
318 p += 7; /* skip "\001vorbis" tag */
319
320 if (bytestream_get_le32(&p) != 0) /* vorbis_version */
321 return AVERROR_INVALIDDATA;
322
323 channels = bytestream_get_byte(&p);
324 if (st->codecpar->ch_layout.nb_channels &&
326 av_log(s, AV_LOG_ERROR, "Channel change is not supported\n");
328 }
330 srate = bytestream_get_le32(&p);
331 p += 4; // skip maximum bitrate
332 st->codecpar->bit_rate = bytestream_get_le32(&p); // nominal bitrate
333 p += 4; // skip minimum bitrate
334
335 blocksize = bytestream_get_byte(&p);
336 bs0 = blocksize & 15;
337 bs1 = blocksize >> 4;
338
339 if (bs0 > bs1)
340 return AVERROR_INVALIDDATA;
341 if (bs0 < 6 || bs1 > 13)
342 return AVERROR_INVALIDDATA;
343
344 if (bytestream_get_byte(&p) != 1) /* framing_flag */
345 return AVERROR_INVALIDDATA;
346
349
350 if (srate > 0) {
351 if (st->codecpar->sample_rate &&
352 srate != st->codecpar->sample_rate) {
353 av_log(s, AV_LOG_ERROR, "Sample rate change is not supported\n");
355 }
356
357 st->codecpar->sample_rate = srate;
358 avpriv_set_pts_info(st, 64, 1, srate);
359 }
360
361 return 1;
362}
363
365{
366 struct ogg *ogg = s->priv_data;
367 struct ogg_stream *os = ogg->streams + idx;
368 AVStream *st = s->streams[idx];
369
370 if (os->psize <= 8)
371 return 0;
372
373 return ff_vorbis_update_metadata(s, st, os->buf + os->pstart + 7,
374 os->psize - 8);
375}
376
377static int vorbis_header(AVFormatContext *s, int idx)
378{
379 struct ogg *ogg = s->priv_data;
380 AVStream *st = s->streams[idx];
381 struct ogg_stream *os = ogg->streams + idx;
382 struct oggvorbis_private *priv;
383 int pkt_type = os->buf[os->pstart];
384
385 if (!os->private)
386 os->private = av_mallocz(sizeof(struct oggvorbis_private));
387
388 if (!os->private)
389 return AVERROR(ENOMEM);
390
391 priv = os->private;
392 priv->bos_page_pos = -1;
393
394 if (!(pkt_type & 1))
395 return priv->vp ? 0 : AVERROR_INVALIDDATA;
396
397 if (pkt_type > 5) {
398 av_log(s, AV_LOG_VERBOSE, "Ignoring packet with unknown type %d\n", pkt_type);
399 return 1;
400 }
401
402 if (os->psize < 1)
403 return AVERROR_INVALIDDATA;
404
405 if (priv->packet[pkt_type >> 1])
406 return AVERROR_INVALIDDATA;
407 if (pkt_type > 1 && !priv->packet[0] || pkt_type > 3 && !priv->packet[1])
408 return priv->vp ? 0 : AVERROR_INVALIDDATA;
409
410 priv->len[pkt_type >> 1] = os->psize;
411 priv->packet[pkt_type >> 1] = av_memdup(os->buf + os->pstart, os->psize);
412 if (!priv->packet[pkt_type >> 1])
413 return AVERROR(ENOMEM);
414 if (pkt_type == 1)
415 return vorbis_parse_header(s, st, os->buf + os->pstart, os->psize);
416
417 if (pkt_type == 3) {
418 if (vorbis_update_metadata(s, idx) >= 0 && priv->len[1] > 10) {
419 unsigned new_len;
420
421 int ret = ff_replaygain_export(st, st->metadata);
422 if (ret < 0)
423 return ret;
424
425 // drop all metadata we parsed and which is not required by libvorbis
426 new_len = 7 + 4 + AV_RL32(priv->packet[1] + 7) + 4 + 1;
427 if (new_len >= 16 && new_len < os->psize) {
428 AV_WL32(priv->packet[1] + new_len - 5, 0);
429 priv->packet[1][new_len - 1] = 1;
430 priv->len[1] = new_len;
431 }
432 }
433 } else {
434 int ret;
435
436 if (priv->vp)
437 return AVERROR_INVALIDDATA;
438
440 if (ret < 0) {
441 st->codecpar->extradata_size = 0;
442 return ret;
443 }
445
447 if (!priv->vp) {
449 st->codecpar->extradata_size = 0;
450 return AVERROR_UNKNOWN;
451 }
452 }
453
454 return 1;
455}
456
457/**
458 * Check that a packet follows the identification, comment, setup order of a
459 * chained stream's headers, and record it as the last packet.
460 *
461 * An identification header starts a new set. A misplaced packet discards the
462 * buffered headers, so an incomplete or misordered set is never packed.
463 * Reserved packet types are ignored, per Vorbis I §1.3.2.
464 *
465 * @return 0 if the packet is in order, AVERROR_INVALIDDATA otherwise
466 */
468 struct oggvorbis_private *priv,
470{
471 enum VorbisPacketType last = priv->last_packet;
472 const char *error = NULL;
473
474 switch (type) {
476 return 0;
478 if (last == VORBIS_PACKET_ID || last == VORBIS_PACKET_COMMENT)
479 error = "data packet before the setup header";
480 break;
481 case VORBIS_PACKET_ID:
482 if (last == VORBIS_PACKET_ID || last == VORBIS_PACKET_COMMENT)
483 error = "identification header before the setup header";
484 break;
486 if (last != VORBIS_PACKET_ID)
487 error = "comment header without identification header";
488 break;
490 if (last != VORBIS_PACKET_COMMENT)
491 error = "setup header without comment header";
492 break;
493 }
494
495 if (error)
497 "Invalid chained stream headers: %s, discarding them\n", error);
498
499 if (error || type == VORBIS_PACKET_ID)
500 for (int i = 0; i < 3; i++)
501 av_freep(&priv->packet[i]);
502
504 return error ? AVERROR_INVALIDDATA : 0;
505}
506
507static int vorbis_packet(AVFormatContext *s, int idx)
508{
509 struct ogg *ogg = s->priv_data;
510 struct ogg_stream *os = ogg->streams + idx;
511 struct oggvorbis_private *priv = os->private;
512 int duration, flags = 0;
513 int bos, skip_packet = 0;
514 int ret;
515
516 if (os->psize == 0)
517 return AVERROR_INVALIDDATA;
518
519 if (!priv->vp)
520 return AVERROR_INVALIDDATA;
521
522 /* Track the page holding the first data packet by its file position,
523 * which stays stable when probing rescans the start of the stream. */
524 if (priv->bos_page_pos < 0)
525 priv->bos_page_pos = os->page_pos;
526
527 bos = os->page_start && os->page_pos == priv->bos_page_pos;
528
529 if (bos || (os->page_start && os->lastpts == AV_NOPTS_VALUE))
531 if (bos)
532 priv->last_page_granule = 0;
533
534 duration = av_vorbis_parse_frame_flags(priv->vp, os->buf + os->pstart, 1, &flags);
535 if (duration < 0) {
537 return 0;
538 }
539 os->pduration = duration;
540
541 /* Save ts_offset from the very first chained stream to account for the
542 * first priming packet. This only shifts timestamps; the Vorbis decoder
543 * discards the leading priming samples itself, so we do not set
544 * codecpar->initial_padding. */
545 if (!priv->ts_offset)
546 priv->ts_offset = os->pduration;
547
548 /* Initial position shift to account for encoder delay, or page scan
549 * to recover the page start timestamp after a seek. */
550 if (bos) {
551 if (os->lastpts != AV_NOPTS_VALUE) {
552 if (s->streams[idx]->start_time == AV_NOPTS_VALUE) {
553 s->streams[idx]->start_time = os->lastpts;
554 if (s->streams[idx]->duration != AV_NOPTS_VALUE)
555 s->streams[idx]->duration -= s->streams[idx]->start_time;
556 }
557 os->lastpts -= priv->ts_offset;
558 }
559 if (os->lastdts != AV_NOPTS_VALUE)
560 os->lastdts -= priv->ts_offset;
561 } else if (os->page_start && os->lastpts == AV_NOPTS_VALUE &&
562 !(os->flags & OGG_FLAG_EOS) && (int64_t)os->granule >= 0) {
563 int seg, page_duration = os->pduration;
564 uint8_t *last_pkt = os->buf + os->pstart + os->psize;
565 uint8_t *next_pkt = last_pkt;
566
567 for (seg = os->segp; seg < os->nsegs; seg++) {
568 next_pkt += os->segments[seg];
569 if (os->segments[seg] < 255 && next_pkt != last_pkt) {
570 int pkt_flags = 0;
571 int d = av_vorbis_parse_frame_flags(priv->vp, last_pkt, 1, &pkt_flags);
572 if (d < 0) {
573 page_duration = os->granule;
574 break;
575 }
576 page_duration += d;
577 last_pkt = next_pkt;
578 }
579 }
580 av_vorbis_parse_frame_flags(priv->vp, os->buf + os->pstart, 1, &flags);
581 os->lastpts =
582 os->lastdts = os->granule - page_duration;
583 }
584
585 /* Broken files may have granule=0 on pages that contain audio data.
586 * In that case timestamps are unreliable, so discard them.
587 * See https://trac.ffmpeg.org/ticket/3710 */
588 if (!os->granule && os->pduration)
589 os->lastpts = os->lastdts = AV_NOPTS_VALUE;
590
591 if (os->flags & OGG_FLAG_EOS) {
592 /* Reset at the start of the EOS page to avoid carrying over stale
593 * duration from a previously processed EOS page, as can happen on
594 * short or chained ogg streams and when probing rescans the page.
595 * os->segp has already been advanced past the current packet by
596 * ogg_packet(), so rely on os->page_start to detect the page start. */
597 if (os->page_start)
598 priv->eos_page_duration = 0;
599
600 if (os->segp != os->nsegs) {
601 priv->eos_page_duration += os->pduration;
602 } else {
604 (os->granule - priv->last_page_granule);
605 if (skip > 0)
606 os->end_trimming = skip;
607 }
608 } else
609 priv->last_page_granule = os->granule;
610
611 /* Handle in-stream header packets from chained streams. The packet is
612 * skipped; the headers are buffered and attached as extradata to the
613 * first data packet that follows. */
616
617 ret = vorbis_parse_header(s, s->streams[idx], os->buf + os->pstart, os->psize);
618 if (ret < 0)
619 return ret;
620
621 ret = av_reallocp(&priv->packet[0], os->psize);
622 if (ret < 0)
623 return ret;
624
625 memcpy(priv->packet[0], os->buf + os->pstart, os->psize);
626 priv->len[0] = os->psize;
627
628 skip_packet = 1;
629 }
630
633 return 1;
634
636 if (ret < 0)
637 return ret;
638
639 ret = av_reallocp(&priv->packet[1], os->psize);
640 if (ret < 0)
641 return ret;
642
643 memcpy(priv->packet[1], os->buf + os->pstart, os->psize);
644 priv->len[1] = os->psize;
645
646 flags = 0;
647 skip_packet = 1;
648 }
649
650 if (flags & VORBIS_FLAG_SETUP) {
652 return 1;
653
654 ret = av_reallocp(&priv->packet[2], os->psize);
655 if (ret < 0)
656 return ret;
657
658 memcpy(priv->packet[2], os->buf + os->pstart, os->psize);
659 priv->len[2] = os->psize;
660
661 skip_packet = 1;
662 }
663
664 if (!skip_packet)
665 vorbis_check_packet_order(s, priv, os->buf[os->pstart] & 1 ?
667
668 /* All three headers for the new chained stream have been collected;
669 * pack them into new extradata to be attached to the next data packet. */
670 if (priv->packet[0] && priv->packet[1] && priv->packet[2]) {
673 if (ret < 0) {
674 os->new_extradata_size = 0;
675 return ret;
676 }
678
679 av_vorbis_parse_free(&priv->vp);
681 if (!priv->vp) {
682 av_log(s, AV_LOG_ERROR, "Failed to re-initialize Vorbis parser\n");
683 return AVERROR_INVALIDDATA;
684 }
685
686 /* Reset bos_page_pos so the next packet will initialize it for the
687 * new chained stream. */
688 priv->bos_page_pos = -1;
689 }
690
691 return skip_packet;
692}
693
695 .magic = "\001vorbis",
696 .magicsize = 7,
697 .header = vorbis_header,
698 .packet = vorbis_packet,
699 .cleanup = vorbis_cleanup,
700 .nb_header = 3,
701};
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:865
Main libavformat public API header.
#define AVSTREAM_EVENT_FLAG_METADATA_UPDATED
Definition avformat.h:886
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
#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:843
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:46
Public dictionary API.
const char * key
static int64_t duration
Definition ffplay.c:359
int ret
Definition ffplay.c:391
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:463
#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
#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:86
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
Definition dict.c:236
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:61
#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:87
#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: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
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)
enum MPFType type
Definition jpegmpfenc.c:55
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)
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,...
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)
VorbisPacketType
@ VORBIS_PACKET_ID
@ VORBIS_PACKET_DATA
@ VORBIS_PACKET_COMMENT
@ VORBIS_PACKET_RESERVED
@ VORBIS_PACKET_SETUP
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:1361
AVDictionary * metadata
Definition avformat.h:1364
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
unsigned int nb_chapters
Number of chapters in AVChapter array.
Definition avformat.h:1502
AVChapter ** chapters
Definition avformat.h:1503
Rational number (pair of numerator and denominator).
Definition rational.h:58
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
int event_flags
Flags indicating events happening on the stream, a combination of AVSTREAM_EVENT_FLAG_*.
Definition avformat.h:879
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
uint8_t segments[255]
Definition oggdec.h:86
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
enum VorbisPacketType last_packet
type of the last packet seen by vorbis_packet()
#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
const AVMetadataConv ff_vorbiscomment_metadata_conv[]
VorbisComment metadata conversion mapping.