]> git.sesse.net Git - ffmpeg/blob - libavformat/oggparsevorbis.c
avcodec/pnmdec: fix unaligned read
[ffmpeg] / libavformat / oggparsevorbis.c
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"
32 #include "libavcodec/vorbis_parser.h"
33 #include "avformat.h"
34 #include "flacdec.h"
35 #include "internal.h"
36 #include "oggdec.h"
37 #include "vorbiscomment.h"
38
39 static int ogm_chapter(AVFormatContext *as, uint8_t *key, uint8_t *val)
40 {
41     int i, cnum, h, m, s, ms, keylen = strlen(key);
42     AVChapter *chapter = NULL;
43
44     if (keylen < 9 || sscanf(key, "CHAPTER%03d", &cnum) != 1)
45         return 0;
46
47     if (keylen <= 10) {
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+(keylen-4), "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,
65                          AV_DICT_DONT_STRDUP_VAL);
66     } else
67         return 0;
68
69     av_free(key);
70     return 1;
71 }
72
73 int
74 ff_vorbis_comment(AVFormatContext * as, AVDictionary **m, const uint8_t *buf, int size)
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                     av_freep(&tt);
140                     av_freep(&ct);
141                     continue;
142                 }
143                 if ((ret = av_base64_decode(pict, ct, vl)) > 0)
144                     ret = ff_flac_parse_picture(as, pict, ret);
145                 av_freep(&pict);
146                 av_freep(&tt);
147                 av_freep(&ct);
148                 if (ret < 0) {
149                     av_log(as, AV_LOG_WARNING, "Failed to parse cover art block.\n");
150                     continue;
151                 }
152             } else if (!ogm_chapter(as, tt, ct))
153                 av_dict_set(m, tt, ct,
154                                    AV_DICT_DONT_STRDUP_KEY |
155                                    AV_DICT_DONT_STRDUP_VAL);
156         }
157     }
158
159     if (p != end)
160         av_log(as, AV_LOG_INFO, "%ti bytes of comment header remain\n", end-p);
161     if (n > 0)
162         av_log(as, AV_LOG_INFO,
163                "truncated comment header, %i comments not found\n", n);
164
165     ff_metadata_conv(m, NULL, ff_vorbiscomment_metadata_conv);
166
167     return 0;
168 }
169
170
171 /** Parse the vorbis header
172  * Vorbis Identification header from Vorbis_I_spec.html#vorbis-spec-codec
173  * [vorbis_version] = read 32 bits as unsigned integer | Not used
174  * [audio_channels] = read 8 bit integer as unsigned | Used
175  * [audio_sample_rate] = read 32 bits as unsigned integer | Used
176  * [bitrate_maximum] = read 32 bits as signed integer | Not used yet
177  * [bitrate_nominal] = read 32 bits as signed integer | Not used yet
178  * [bitrate_minimum] = read 32 bits as signed integer | Used as bitrate
179  * [blocksize_0] = read 4 bits as unsigned integer | Not Used
180  * [blocksize_1] = read 4 bits as unsigned integer | Not Used
181  * [framing_flag] = read one bit | Not Used
182  *    */
183
184 struct oggvorbis_private {
185     unsigned int len[3];
186     unsigned char *packet[3];
187     VorbisParseContext vp;
188     int64_t final_pts;
189     int final_duration;
190 };
191
192
193 static unsigned int
194 fixup_vorbis_headers(AVFormatContext * as, struct oggvorbis_private *priv,
195                      uint8_t **buf)
196 {
197     int i,offset, len, buf_len;
198     unsigned char *ptr;
199
200     len = priv->len[0] + priv->len[1] + priv->len[2];
201     buf_len = len + len/255 + 64;
202     ptr = *buf = av_realloc(NULL, buf_len);
203     if (!*buf)
204         return 0;
205     memset(*buf, '\0', buf_len);
206
207     ptr[0] = 2;
208     offset = 1;
209     offset += av_xiphlacing(&ptr[offset], priv->len[0]);
210     offset += av_xiphlacing(&ptr[offset], priv->len[1]);
211     for (i = 0; i < 3; i++) {
212         memcpy(&ptr[offset], priv->packet[i], priv->len[i]);
213         offset += priv->len[i];
214         av_freep(&priv->packet[i]);
215     }
216     *buf = av_realloc(*buf, offset + FF_INPUT_BUFFER_PADDING_SIZE);
217     return offset;
218 }
219
220 static void vorbis_cleanup(AVFormatContext *s, int idx)
221 {
222     struct ogg *ogg = s->priv_data;
223     struct ogg_stream *os = ogg->streams + idx;
224     struct oggvorbis_private *priv = os->private;
225     int i;
226     if (os->private)
227         for (i = 0; i < 3; i++)
228             av_freep(&priv->packet[i]);
229 }
230
231 static int
232 vorbis_header (AVFormatContext * s, int idx)
233 {
234     struct ogg *ogg = s->priv_data;
235     struct ogg_stream *os = ogg->streams + idx;
236     AVStream *st = s->streams[idx];
237     struct oggvorbis_private *priv;
238     int pkt_type = os->buf[os->pstart];
239
240     if (!os->private) {
241         os->private = av_mallocz(sizeof(struct oggvorbis_private));
242         if (!os->private)
243             return -1;
244     }
245
246     if (!(pkt_type & 1))
247         return 0;
248
249     if (os->psize < 1 || pkt_type > 5)
250         return -1;
251
252     priv = os->private;
253
254     if (priv->packet[pkt_type>>1])
255         return -1;
256     if (pkt_type > 1 && !priv->packet[0] || pkt_type > 3 && !priv->packet[1])
257         return -1;
258
259     priv->len[pkt_type >> 1] = os->psize;
260     priv->packet[pkt_type >> 1] = av_mallocz(os->psize);
261     if (!priv->packet[pkt_type >> 1])
262         return AVERROR(ENOMEM);
263     memcpy(priv->packet[pkt_type >> 1], os->buf + os->pstart, os->psize);
264     if (os->buf[os->pstart] == 1) {
265         const uint8_t *p = os->buf + os->pstart + 7; /* skip "\001vorbis" tag */
266         unsigned blocksize, bs0, bs1;
267         int srate;
268         int channels;
269
270         if (os->psize != 30)
271             return -1;
272
273         if (bytestream_get_le32(&p) != 0) /* vorbis_version */
274             return -1;
275
276         channels= bytestream_get_byte(&p);
277         if (st->codec->channels && channels != st->codec->channels) {
278             av_log(s, AV_LOG_ERROR, "Channel change is not supported\n");
279             return AVERROR_PATCHWELCOME;
280         }
281         st->codec->channels = channels;
282         srate = bytestream_get_le32(&p);
283         p += 4; // skip maximum bitrate
284         st->codec->bit_rate = bytestream_get_le32(&p); // nominal bitrate
285         p += 4; // skip minimum bitrate
286
287         blocksize = bytestream_get_byte(&p);
288         bs0 = blocksize & 15;
289         bs1 = blocksize >> 4;
290
291         if (bs0 > bs1)
292             return -1;
293         if (bs0 < 6 || bs1 > 13)
294             return -1;
295
296         if (bytestream_get_byte(&p) != 1) /* framing_flag */
297             return -1;
298
299         st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
300         st->codec->codec_id = AV_CODEC_ID_VORBIS;
301
302         if (srate > 0) {
303             st->codec->sample_rate = srate;
304             avpriv_set_pts_info(st, 64, 1, srate);
305         }
306     } else if (os->buf[os->pstart] == 3) {
307         if (os->psize > 8 &&
308             ff_vorbis_comment(s, &st->metadata, os->buf + os->pstart + 7, os->psize - 8) >= 0) {
309             // drop all metadata we parsed and which is not required by libvorbis
310             unsigned new_len = 7 + 4 + AV_RL32(priv->packet[1] + 7) + 4 + 1;
311             if (new_len >= 16 && new_len < os->psize) {
312                 AV_WL32(priv->packet[1] + new_len - 5, 0);
313                 priv->packet[1][new_len - 1] = 1;
314                 priv->len[1] = new_len;
315             }
316         }
317     } else {
318         int ret;
319         st->codec->extradata_size =
320             fixup_vorbis_headers(s, priv, &st->codec->extradata);
321         if ((ret = avpriv_vorbis_parse_extradata(st->codec, &priv->vp))) {
322             av_freep(&st->codec->extradata);
323             st->codec->extradata_size = 0;
324             return ret;
325         }
326     }
327
328     return 1;
329 }
330
331 static int vorbis_packet(AVFormatContext *s, int idx)
332 {
333     struct ogg *ogg = s->priv_data;
334     struct ogg_stream *os = ogg->streams + idx;
335     struct oggvorbis_private *priv = os->private;
336     int duration;
337
338     /* first packet handling
339        here we parse the duration of each packet in the first page and compare
340        the total duration to the page granule to find the encoder delay and
341        set the first timestamp */
342     if ((!os->lastpts || os->lastpts == AV_NOPTS_VALUE) && !(os->flags & OGG_FLAG_EOS)) {
343         int seg, d;
344         uint8_t *last_pkt = os->buf + os->pstart;
345         uint8_t *next_pkt = last_pkt;
346
347         avpriv_vorbis_parse_reset(&priv->vp);
348         duration = 0;
349         seg = os->segp;
350         d = avpriv_vorbis_parse_frame(&priv->vp, last_pkt, 1);
351         if (d < 0) {
352             os->pflags |= AV_PKT_FLAG_CORRUPT;
353             return 0;
354         }
355         duration += d;
356         last_pkt = next_pkt =  next_pkt + os->psize;
357         for (; seg < os->nsegs; seg++) {
358             if (os->segments[seg] < 255) {
359                 int d = avpriv_vorbis_parse_frame(&priv->vp, last_pkt, 1);
360                 if (d < 0) {
361                     duration = os->granule;
362                     break;
363                 }
364                 duration += d;
365                 last_pkt = next_pkt + os->segments[seg];
366             }
367             next_pkt += os->segments[seg];
368         }
369         os->lastpts = os->lastdts   = os->granule - duration;
370         if(s->streams[idx]->start_time == AV_NOPTS_VALUE) {
371             s->streams[idx]->start_time = FFMAX(os->lastpts, 0);
372             if (s->streams[idx]->duration)
373                 s->streams[idx]->duration -= s->streams[idx]->start_time;
374         }
375         priv->final_pts             = AV_NOPTS_VALUE;
376         avpriv_vorbis_parse_reset(&priv->vp);
377     }
378
379     /* parse packet duration */
380     if (os->psize > 0) {
381         duration = avpriv_vorbis_parse_frame(&priv->vp, os->buf + os->pstart, 1);
382         if (duration < 0) {
383             os->pflags |= AV_PKT_FLAG_CORRUPT;
384             return 0;
385         }
386         os->pduration = duration;
387     }
388
389     /* final packet handling
390        here we save the pts of the first packet in the final page, sum up all
391        packet durations in the final page except for the last one, and compare
392        to the page granule to find the duration of the final packet */
393     if (os->flags & OGG_FLAG_EOS) {
394         if (os->lastpts != AV_NOPTS_VALUE) {
395             priv->final_pts = os->lastpts;
396             priv->final_duration = 0;
397         }
398         if (os->segp == os->nsegs)
399             os->pduration = os->granule - priv->final_pts - priv->final_duration;
400         priv->final_duration += os->pduration;
401     }
402
403     return 0;
404 }
405
406 const struct ogg_codec ff_vorbis_codec = {
407     .magic = "\001vorbis",
408     .magicsize = 7,
409     .header = vorbis_header,
410     .packet = vorbis_packet,
411     .cleanup= vorbis_cleanup,
412     .nb_header = 3,
413 };