FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
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 #include "libavutil/avstring.h"
27 #include "libavutil/base64.h"
28 #include "libavutil/bswap.h"
29 #include "libavutil/dict.h"
30 #include "libavcodec/get_bits.h"
31 #include "libavcodec/bytestream.h"
33 #include "avformat.h"
34 #include "flacdec.h"
35 #include "internal.h"
36 #include "oggdec.h"
37 #include "vorbiscomment.h"
38 
40 {
41  int i, cnum, h, m, s, ms, keylen = strlen(key);
42  AVChapter *chapter = NULL;
43 
44  if (keylen < 9 || sscanf(key, "CHAPTER%02d", &cnum) != 1)
45  return 0;
46 
47  if (keylen == 9) {
48  if (sscanf(val, "%02d:%02d:%02d.%03d", &h, &m, &s, &ms) < 4)
49  return 0;
50 
51  avpriv_new_chapter(as, cnum, (AVRational){1,1000},
52  ms + 1000*(s + 60*(m + 60*h)),
53  AV_NOPTS_VALUE, NULL);
54  av_free(val);
55  } else if (!strcmp(key+9, "NAME")) {
56  for(i = 0; i < as->nb_chapters; i++)
57  if (as->chapters[i]->id == cnum) {
58  chapter = as->chapters[i];
59  break;
60  }
61  if (!chapter)
62  return 0;
63 
64  av_dict_set(&chapter->metadata, "title", val,
66  } else
67  return 0;
68 
69  av_free(key);
70  return 1;
71 }
72 
73 int
75 {
76  const uint8_t *p = buf;
77  const uint8_t *end = buf + size;
78  unsigned n, j;
79  int s;
80 
81  if (size < 8) /* must have vendor_length and user_comment_list_length */
82  return -1;
83 
84  s = bytestream_get_le32(&p);
85 
86  if (end - p - 4 < s || s < 0)
87  return -1;
88 
89  p += s;
90 
91  n = bytestream_get_le32(&p);
92 
93  while (end - p >= 4 && n > 0) {
94  const char *t, *v;
95  int tl, vl;
96 
97  s = bytestream_get_le32(&p);
98 
99  if (end - p < s || s < 0)
100  break;
101 
102  t = p;
103  p += s;
104  n--;
105 
106  v = memchr(t, '=', s);
107  if (!v)
108  continue;
109 
110  tl = v - t;
111  vl = s - tl - 1;
112  v++;
113 
114  if (tl && vl) {
115  char *tt, *ct;
116 
117  tt = av_malloc(tl + 1);
118  ct = av_malloc(vl + 1);
119  if (!tt || !ct) {
120  av_freep(&tt);
121  av_freep(&ct);
122  av_log(as, AV_LOG_WARNING, "out-of-memory error. skipping VorbisComment tag.\n");
123  continue;
124  }
125 
126  for (j = 0; j < tl; j++)
127  tt[j] = av_toupper(t[j]);
128  tt[tl] = 0;
129 
130  memcpy(ct, v, vl);
131  ct[vl] = 0;
132 
133  if (!strcmp(tt, "METADATA_BLOCK_PICTURE")) {
134  int ret;
135  char *pict = av_malloc(vl);
136 
137  if (!pict) {
138  av_log(as, AV_LOG_WARNING, "out-of-memory error. Skipping cover art block.\n");
139  continue;
140  }
141  if ((ret = av_base64_decode(pict, ct, vl)) > 0)
142  ret = ff_flac_parse_picture(as, pict, ret);
143  av_freep(&pict);
144  if (ret < 0) {
145  av_log(as, AV_LOG_WARNING, "Failed to parse cover art block.\n");
146  continue;
147  }
148  } else if (!ogm_chapter(as, tt, ct))
149  av_dict_set(m, tt, ct,
152  }
153  }
154 
155  if (p != end)
156  av_log(as, AV_LOG_INFO, "%ti bytes of comment header remain\n", end-p);
157  if (n > 0)
158  av_log(as, AV_LOG_INFO,
159  "truncated comment header, %i comments not found\n", n);
160 
162 
163  return 0;
164 }
165 
166 
167 /** Parse the vorbis header
168  * Vorbis Identification header from Vorbis_I_spec.html#vorbis-spec-codec
169  * [vorbis_version] = read 32 bits as unsigned integer | Not used
170  * [audio_channels] = read 8 bit integer as unsigned | Used
171  * [audio_sample_rate] = read 32 bits as unsigned integer | Used
172  * [bitrate_maximum] = read 32 bits as signed integer | Not used yet
173  * [bitrate_nominal] = read 32 bits as signed integer | Not used yet
174  * [bitrate_minimum] = read 32 bits as signed integer | Used as bitrate
175  * [blocksize_0] = read 4 bits as unsigned integer | Not Used
176  * [blocksize_1] = read 4 bits as unsigned integer | Not Used
177  * [framing_flag] = read one bit | Not Used
178  * */
179 
181  unsigned int len[3];
182  unsigned char *packet[3];
184  int64_t final_pts;
186 };
187 
188 
189 static unsigned int
191  uint8_t **buf)
192 {
193  int i,offset, len, buf_len;
194  unsigned char *ptr;
195 
196  len = priv->len[0] + priv->len[1] + priv->len[2];
197  buf_len = len + len/255 + 64;
198  ptr = *buf = av_realloc(NULL, buf_len);
199  if (!*buf)
200  return 0;
201  memset(*buf, '\0', buf_len);
202 
203  ptr[0] = 2;
204  offset = 1;
205  offset += av_xiphlacing(&ptr[offset], priv->len[0]);
206  offset += av_xiphlacing(&ptr[offset], priv->len[1]);
207  for (i = 0; i < 3; i++) {
208  memcpy(&ptr[offset], priv->packet[i], priv->len[i]);
209  offset += priv->len[i];
210  av_freep(&priv->packet[i]);
211  }
212  *buf = av_realloc(*buf, offset + FF_INPUT_BUFFER_PADDING_SIZE);
213  return offset;
214 }
215 
216 static void vorbis_cleanup(AVFormatContext *s, int idx)
217 {
218  struct ogg *ogg = s->priv_data;
219  struct ogg_stream *os = ogg->streams + idx;
220  struct oggvorbis_private *priv = os->private;
221  int i;
222  if (os->private)
223  for (i = 0; i < 3; i++)
224  av_freep(&priv->packet[i]);
225 }
226 
227 static int
229 {
230  struct ogg *ogg = s->priv_data;
231  struct ogg_stream *os = ogg->streams + idx;
232  AVStream *st = s->streams[idx];
233  struct oggvorbis_private *priv;
234  int pkt_type = os->buf[os->pstart];
235 
236  if (!(pkt_type & 1))
237  return os->private ? 0 : -1;
238 
239  if (!os->private) {
240  os->private = av_mallocz(sizeof(struct oggvorbis_private));
241  if (!os->private)
242  return -1;
243  }
244 
245  if (os->psize < 1 || pkt_type > 5)
246  return -1;
247 
248  priv = os->private;
249 
250  if (priv->packet[pkt_type>>1])
251  return -1;
252  if (pkt_type > 1 && !priv->packet[0] || pkt_type > 3 && !priv->packet[1])
253  return -1;
254 
255  priv->len[pkt_type >> 1] = os->psize;
256  priv->packet[pkt_type >> 1] = av_mallocz(os->psize);
257  if (!priv->packet[pkt_type >> 1])
258  return AVERROR(ENOMEM);
259  memcpy(priv->packet[pkt_type >> 1], os->buf + os->pstart, os->psize);
260  if (os->buf[os->pstart] == 1) {
261  const uint8_t *p = os->buf + os->pstart + 7; /* skip "\001vorbis" tag */
262  unsigned blocksize, bs0, bs1;
263  int srate;
264  int channels;
265 
266  if (os->psize != 30)
267  return -1;
268 
269  if (bytestream_get_le32(&p) != 0) /* vorbis_version */
270  return -1;
271 
272  channels= bytestream_get_byte(&p);
273  if (st->codec->channels && channels != st->codec->channels) {
274  av_log(s, AV_LOG_ERROR, "Channel change is not supported\n");
275  return AVERROR_PATCHWELCOME;
276  }
277  st->codec->channels = channels;
278  srate = bytestream_get_le32(&p);
279  p += 4; // skip maximum bitrate
280  st->codec->bit_rate = bytestream_get_le32(&p); // nominal bitrate
281  p += 4; // skip minimum bitrate
282 
283  blocksize = bytestream_get_byte(&p);
284  bs0 = blocksize & 15;
285  bs1 = blocksize >> 4;
286 
287  if (bs0 > bs1)
288  return -1;
289  if (bs0 < 6 || bs1 > 13)
290  return -1;
291 
292  if (bytestream_get_byte(&p) != 1) /* framing_flag */
293  return -1;
294 
297 
298  if (srate > 0) {
299  st->codec->sample_rate = srate;
300  avpriv_set_pts_info(st, 64, 1, srate);
301  }
302  } else if (os->buf[os->pstart] == 3) {
303  if (os->psize > 8 &&
304  ff_vorbis_comment(s, &st->metadata, os->buf + os->pstart + 7, os->psize - 8) >= 0) {
305  // drop all metadata we parsed and which is not required by libvorbis
306  unsigned new_len = 7 + 4 + AV_RL32(priv->packet[1] + 7) + 4 + 1;
307  if (new_len >= 16 && new_len < os->psize) {
308  AV_WL32(priv->packet[1] + new_len - 5, 0);
309  priv->packet[1][new_len - 1] = 1;
310  priv->len[1] = new_len;
311  }
312  }
313  } else {
314  int ret;
315  st->codec->extradata_size =
316  fixup_vorbis_headers(s, priv, &st->codec->extradata);
317  if ((ret = avpriv_vorbis_parse_extradata(st->codec, &priv->vp))) {
318  av_freep(&st->codec->extradata);
319  st->codec->extradata_size = 0;
320  return ret;
321  }
322  }
323 
324  return 1;
325 }
326 
327 static int vorbis_packet(AVFormatContext *s, int idx)
328 {
329  struct ogg *ogg = s->priv_data;
330  struct ogg_stream *os = ogg->streams + idx;
331  struct oggvorbis_private *priv = os->private;
332  int duration;
333 
334  /* first packet handling
335  here we parse the duration of each packet in the first page and compare
336  the total duration to the page granule to find the encoder delay and
337  set the first timestamp */
338  if ((!os->lastpts || os->lastpts == AV_NOPTS_VALUE) && !(os->flags & OGG_FLAG_EOS)) {
339  int seg, d;
340  uint8_t *last_pkt = os->buf + os->pstart;
341  uint8_t *next_pkt = last_pkt;
342 
344  duration = 0;
345  seg = os->segp;
346  d = avpriv_vorbis_parse_frame(&priv->vp, last_pkt, 1);
347  if (d < 0) {
349  return 0;
350  }
351  duration += d;
352  last_pkt = next_pkt = next_pkt + os->psize;
353  for (; seg < os->nsegs; seg++) {
354  if (os->segments[seg] < 255) {
355  int d = avpriv_vorbis_parse_frame(&priv->vp, last_pkt, 1);
356  if (d < 0) {
357  duration = os->granule;
358  break;
359  }
360  duration += d;
361  last_pkt = next_pkt + os->segments[seg];
362  }
363  next_pkt += os->segments[seg];
364  }
365  os->lastpts = os->lastdts = os->granule - duration;
366  if(s->streams[idx]->start_time == AV_NOPTS_VALUE) {
367  s->streams[idx]->start_time = FFMAX(os->lastpts, 0);
368  if (s->streams[idx]->duration)
369  s->streams[idx]->duration -= s->streams[idx]->start_time;
370  }
371  priv->final_pts = AV_NOPTS_VALUE;
373  }
374 
375  /* parse packet duration */
376  if (os->psize > 0) {
377  duration = avpriv_vorbis_parse_frame(&priv->vp, os->buf + os->pstart, 1);
378  if (duration < 0) {
380  return 0;
381  }
382  os->pduration = duration;
383  }
384 
385  /* final packet handling
386  here we save the pts of the first packet in the final page, sum up all
387  packet durations in the final page except for the last one, and compare
388  to the page granule to find the duration of the final packet */
389  if (os->flags & OGG_FLAG_EOS) {
390  if (os->lastpts != AV_NOPTS_VALUE) {
391  priv->final_pts = os->lastpts;
392  priv->final_duration = 0;
393  }
394  if (os->segp == os->nsegs)
395  os->pduration = os->granule - priv->final_pts - priv->final_duration;
396  priv->final_duration += os->pduration;
397  }
398 
399  return 0;
400 }
401 
402 const struct ogg_codec ff_vorbis_codec = {
403  .magic = "\001vorbis",
404  .magicsize = 7,
405  .header = vorbis_header,
406  .packet = vorbis_packet,
407  .cleanup= vorbis_cleanup,
408  .nb_header = 3,
409 };