oggparsevorbis.c
Go to the documentation of this file.
1 
25 #include <stdlib.h>
26 #include "libavutil/avstring.h"
27 #include "libavutil/bswap.h"
28 #include "libavutil/dict.h"
29 #include "libavcodec/get_bits.h"
30 #include "libavcodec/bytestream.h"
32 #include "avformat.h"
33 #include "internal.h"
34 #include "oggdec.h"
35 #include "vorbiscomment.h"
36 
37 static int ogm_chapter(AVFormatContext *as, uint8_t *key, uint8_t *val)
38 {
39  int i, cnum, h, m, s, ms, keylen = strlen(key);
40  AVChapter *chapter = NULL;
41 
42  if (keylen < 9 || sscanf(key, "CHAPTER%02d", &cnum) != 1)
43  return 0;
44 
45  if (keylen == 9) {
46  if (sscanf(val, "%02d:%02d:%02d.%03d", &h, &m, &s, &ms) < 4)
47  return 0;
48 
49  avpriv_new_chapter(as, cnum, (AVRational){1,1000},
50  ms + 1000*(s + 60*(m + 60*h)),
52  av_free(val);
53  } else if (!strcmp(key+9, "NAME")) {
54  for(i = 0; i < as->nb_chapters; i++)
55  if (as->chapters[i]->id == cnum) {
56  chapter = as->chapters[i];
57  break;
58  }
59  if (!chapter)
60  return 0;
61 
62  av_dict_set(&chapter->metadata, "title", val,
64  } else
65  return 0;
66 
67  av_free(key);
68  return 1;
69 }
70 
71 int
73 {
74  const uint8_t *p = buf;
75  const uint8_t *end = buf + size;
76  unsigned n, j;
77  int s;
78 
79  if (size < 8) /* must have vendor_length and user_comment_list_length */
80  return -1;
81 
82  s = bytestream_get_le32(&p);
83 
84  if (end - p - 4 < s || s < 0)
85  return -1;
86 
87  p += s;
88 
89  n = bytestream_get_le32(&p);
90 
91  while (end - p >= 4 && n > 0) {
92  const char *t, *v;
93  int tl, vl;
94 
95  s = bytestream_get_le32(&p);
96 
97  if (end - p < s || s < 0)
98  break;
99 
100  t = p;
101  p += s;
102  n--;
103 
104  v = memchr(t, '=', s);
105  if (!v)
106  continue;
107 
108  tl = v - t;
109  vl = s - tl - 1;
110  v++;
111 
112  if (tl && vl) {
113  char *tt, *ct;
114 
115  tt = av_malloc(tl + 1);
116  ct = av_malloc(vl + 1);
117  if (!tt || !ct) {
118  av_freep(&tt);
119  av_freep(&ct);
120  av_log(as, AV_LOG_WARNING, "out-of-memory error. skipping VorbisComment tag.\n");
121  continue;
122  }
123 
124  for (j = 0; j < tl; j++)
125  tt[j] = toupper(t[j]);
126  tt[tl] = 0;
127 
128  memcpy(ct, v, vl);
129  ct[vl] = 0;
130 
131  if (!ogm_chapter(as, tt, ct))
132  av_dict_set(m, tt, ct,
135  }
136  }
137 
138  if (p != end)
139  av_log(as, AV_LOG_INFO, "%ti bytes of comment header remain\n", end-p);
140  if (n > 0)
141  av_log(as, AV_LOG_INFO,
142  "truncated comment header, %i comments not found\n", n);
143 
145 
146  return 0;
147 }
148 
149 
164  unsigned int len[3];
165  unsigned char *packet[3];
167  int64_t final_pts;
169 };
170 
171 
172 static unsigned int
174  uint8_t **buf)
175 {
176  int i,offset, len;
177  unsigned char *ptr;
178 
179  len = priv->len[0] + priv->len[1] + priv->len[2];
180  ptr = *buf = av_mallocz(len + len/255 + 64);
181 
182  ptr[0] = 2;
183  offset = 1;
184  offset += av_xiphlacing(&ptr[offset], priv->len[0]);
185  offset += av_xiphlacing(&ptr[offset], priv->len[1]);
186  for (i = 0; i < 3; i++) {
187  memcpy(&ptr[offset], priv->packet[i], priv->len[i]);
188  offset += priv->len[i];
189  av_freep(&priv->packet[i]);
190  }
191  *buf = av_realloc(*buf, offset + FF_INPUT_BUFFER_PADDING_SIZE);
192  return offset;
193 }
194 
195 static void vorbis_cleanup(AVFormatContext *s, int idx)
196 {
197  struct ogg *ogg = s->priv_data;
198  struct ogg_stream *os = ogg->streams + idx;
199  struct oggvorbis_private *priv = os->private;
200  int i;
201  if (os->private)
202  for (i = 0; i < 3; i++)
203  av_freep(&priv->packet[i]);
204 }
205 
206 static int
208 {
209  struct ogg *ogg = s->priv_data;
210  struct ogg_stream *os = ogg->streams + idx;
211  AVStream *st = s->streams[idx];
212  struct oggvorbis_private *priv;
213  int pkt_type = os->buf[os->pstart];
214 
215  if (!os->private) {
216  os->private = av_mallocz(sizeof(struct oggvorbis_private));
217  if (!os->private)
218  return 0;
219  }
220 
221  if (!(pkt_type & 1))
222  return 0;
223 
224  if (os->psize < 1 || pkt_type > 5)
225  return -1;
226 
227  priv = os->private;
228 
229  if (priv->packet[pkt_type>>1])
230  return -1;
231  if (pkt_type > 1 && !priv->packet[0] || pkt_type > 3 && !priv->packet[1])
232  return -1;
233 
234  priv->len[pkt_type >> 1] = os->psize;
235  priv->packet[pkt_type >> 1] = av_mallocz(os->psize);
236  memcpy(priv->packet[pkt_type >> 1], os->buf + os->pstart, os->psize);
237  if (os->buf[os->pstart] == 1) {
238  const uint8_t *p = os->buf + os->pstart + 7; /* skip "\001vorbis" tag */
239  unsigned blocksize, bs0, bs1;
240  int srate;
241 
242  if (os->psize != 30)
243  return -1;
244 
245  if (bytestream_get_le32(&p) != 0) /* vorbis_version */
246  return -1;
247 
248  st->codec->channels = bytestream_get_byte(&p);
249  srate = bytestream_get_le32(&p);
250  p += 4; // skip maximum bitrate
251  st->codec->bit_rate = bytestream_get_le32(&p); // nominal bitrate
252  p += 4; // skip minimum bitrate
253 
254  blocksize = bytestream_get_byte(&p);
255  bs0 = blocksize & 15;
256  bs1 = blocksize >> 4;
257 
258  if (bs0 > bs1)
259  return -1;
260  if (bs0 < 6 || bs1 > 13)
261  return -1;
262 
263  if (bytestream_get_byte(&p) != 1) /* framing_flag */
264  return -1;
265 
268 
269  if (srate > 0) {
270  st->codec->sample_rate = srate;
271  avpriv_set_pts_info(st, 64, 1, srate);
272  }
273  } else if (os->buf[os->pstart] == 3) {
274  if (os->psize > 8 &&
275  ff_vorbis_comment(s, &st->metadata, os->buf + os->pstart + 7, os->psize - 8) >= 0) {
276  // drop all metadata we parsed and which is not required by libvorbis
277  unsigned new_len = 7 + 4 + AV_RL32(priv->packet[1] + 7) + 4 + 1;
278  if (new_len >= 16 && new_len < os->psize) {
279  AV_WL32(priv->packet[1] + new_len - 5, 0);
280  priv->packet[1][new_len - 1] = 1;
281  priv->len[1] = new_len;
282  }
283  }
284  } else {
285  int ret;
286  st->codec->extradata_size =
287  fixup_vorbis_headers(s, priv, &st->codec->extradata);
288  if ((ret = avpriv_vorbis_parse_extradata(st->codec, &priv->vp))) {
289  av_freep(&st->codec->extradata);
290  st->codec->extradata_size = 0;
291  return ret;
292  }
293  }
294 
295  return 1;
296 }
297 
298 static int vorbis_packet(AVFormatContext *s, int idx)
299 {
300  struct ogg *ogg = s->priv_data;
301  struct ogg_stream *os = ogg->streams + idx;
302  struct oggvorbis_private *priv = os->private;
303  int duration;
304 
305  /* first packet handling
306  here we parse the duration of each packet in the first page and compare
307  the total duration to the page granule to find the encoder delay and
308  set the first timestamp */
309  if (!os->lastpts) {
310  int seg;
311  uint8_t *last_pkt = os->buf + os->pstart;
312  uint8_t *next_pkt = last_pkt;
313  int first_duration = 0;
314 
316  duration = 0;
317  for (seg = 0; seg < os->nsegs; seg++) {
318  if (os->segments[seg] < 255) {
319  int d = avpriv_vorbis_parse_frame(&priv->vp, last_pkt, 1);
320  if (d < 0) {
321  duration = os->granule;
322  break;
323  }
324  if (!duration)
325  first_duration = d;
326  duration += d;
327  last_pkt = next_pkt + os->segments[seg];
328  }
329  next_pkt += os->segments[seg];
330  }
331  os->lastpts = os->lastdts = os->granule - duration;
332  s->streams[idx]->start_time = os->lastpts + first_duration;
333  if (s->streams[idx]->duration)
334  s->streams[idx]->duration -= s->streams[idx]->start_time;
335  s->streams[idx]->cur_dts = AV_NOPTS_VALUE;
336  priv->final_pts = AV_NOPTS_VALUE;
338  }
339 
340  /* parse packet duration */
341  if (os->psize > 0) {
342  duration = avpriv_vorbis_parse_frame(&priv->vp, os->buf + os->pstart, 1);
343  if (duration <= 0) {
345  return 0;
346  }
347  os->pduration = duration;
348  }
349 
350  /* final packet handling
351  here we save the pts of the first packet in the final page, sum up all
352  packet durations in the final page except for the last one, and compare
353  to the page granule to find the duration of the final packet */
354  if (os->flags & OGG_FLAG_EOS) {
355  if (os->lastpts != AV_NOPTS_VALUE) {
356  priv->final_pts = os->lastpts;
357  priv->final_duration = 0;
358  }
359  if (os->segp == os->nsegs)
360  os->pduration = os->granule - priv->final_pts - priv->final_duration;
361  priv->final_duration += os->pduration;
362  }
363 
364  return 0;
365 }
366 
367 const struct ogg_codec ff_vorbis_codec = {
368  .magic = "\001vorbis",
369  .magicsize = 7,
370  .header = vorbis_header,
371  .packet = vorbis_packet,
372  .cleanup= vorbis_cleanup,
373  .nb_header = 3,
374 };
unsigned int nb_chapters
Definition: avformat.h:969
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:61
static int vorbis_header(AVFormatContext *s, int idx)
int size
VorbisParseContext vp
Copyright (C) 2005 Michael Ahlberg, Måns Rullgård.
Definition: oggdec.h:31
unsigned int pflags
Definition: oggdec.h:67
int avpriv_vorbis_parse_frame(VorbisParseContext *s, const uint8_t *buf, int buf_size)
Get the duration for a Vorbis packet.
int ff_vorbis_comment(AVFormatContext *as, AVDictionary **m, const uint8_t *buf, int size)
Parse the vorbis header Vorbis Identification header from Vorbis_I_spec.html::vorbis-spec-codec [vorb...
void avpriv_set_pts_info(AVStream *s, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition: utils.c:3283
static unsigned int fixup_vorbis_headers(AVFormatContext *as, struct oggvorbis_private *priv, uint8_t **buf)
void avpriv_vorbis_parse_reset(VorbisParseContext *s)
int flags
Definition: oggdec.h:76
AVDictionary * metadata
Definition: avformat.h:817
unsigned char * packet[3]
static int64_t duration
Definition: avplay.c:249
int64_t lastpts
Definition: oggdec.h:72
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
Definition: mem.c:151
AVChapter * avpriv_new_chapter(AVFormatContext *s, int id, AVRational time_base, int64_t start, int64_t end, const char *title)
Add a new chapter.
Definition: utils.c:2815
Format I/O context.
Definition: avformat.h:828
unsigned int psize
Definition: oggdec.h:66
int64_t cur_dts
Definition: avformat.h:759
Public dictionary API.
uint8_t
int id
unique ID to identify the chapter
Definition: avformat.h:814
#define AV_WL32(p, d)
Definition: intreadwrite.h:255
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:1454
AVStream ** streams
Definition: avformat.h:876
Vorbis audio parser.
bitstream reader API header.
static void vorbis_cleanup(AVFormatContext *s, int idx)
static float t
void ff_metadata_conv(AVDictionary **pm, const AVMetadataConv *d_conv, const AVMetadataConv *s_conv)
Definition: metadata.c:26
const AVMetadataConv ff_vorbiscomment_metadata_conv[]
VorbisComment metadata conversion mapping.
Definition: vorbiscomment.c:33
void av_free(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc(). ...
Definition: mem.c:139
#define OGG_FLAG_EOS
Definition: oggdec.h:106
AVChapter ** chapters
Definition: avformat.h:970
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:146
uint8_t segments[255]
Definition: oggdec.h:80
AVCodecContext * codec
Codec context associated with this stream.
Definition: avformat.h:641
int bit_rate
the average bitrate
Definition: avcodec.h:1404
uint64_t granule
Definition: oggdec.h:70
unsigned int pstart
Definition: oggdec.h:65
struct ogg_stream * streams
Definition: oggdec.h:97
int segp
Definition: oggdec.h:79
static int ogm_chapter(AVFormatContext *as, uint8_t *key, uint8_t *val)
Copyright (C) 2005 Michael Ahlberg, Måns Rullgård.
#define AV_RL32
Definition: intreadwrite.h:146
AVDictionary * metadata
Definition: avformat.h:699
Stream structure.
Definition: avformat.h:622
NULL
Definition: eval.c:52
enum AVMediaType codec_type
Definition: avcodec.h:1347
unsigned int pduration
Definition: oggdec.h:68
int nsegs
Definition: oggdec.h:79
enum AVCodecID codec_id
Definition: avcodec.h:1350
unsigned int len[3]
int sample_rate
samples per second
Definition: avcodec.h:2104
int extradata_size
Definition: avcodec.h:1455
void * private
Definition: oggdec.h:85
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:63
unsigned int av_xiphlacing(unsigned char *s, unsigned int v)
Encode extradata length to a buffer.
Definition: utils.c:1984
rational number numerator/denominator
Definition: rational.h:43
byte swapping routines
int64_t lastdts
Definition: oggdec.h:73
const int8_t * magic
Definition: oggdec.h:32
int64_t duration
Decoding: duration of the stream, in stream time base.
Definition: avformat.h:684
uint8_t * buf
Definition: oggdec.h:62
Main libavformat public API header.
void * av_realloc(void *ptr, size_t size)
Allocate or reallocate a block of memory.
Definition: mem.c:116
int64_t start_time
Decoding: pts of the first frame of the stream, in stream time base.
Definition: avformat.h:677
static int vorbis_packet(AVFormatContext *s, int idx)
Definition: oggdec.h:96
int len
int channels
number of audio channels
Definition: avcodec.h:2105
void * priv_data
Format private data.
Definition: avformat.h:848
const struct ogg_codec ff_vorbis_codec
int avpriv_vorbis_parse_extradata(AVCodecContext *avctx, VorbisParseContext *s)
Initialize the Vorbis parser using headers in the extradata.
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:158