]> git.sesse.net Git - ffmpeg/blob - libavformat/oggparsevorbis.c
Add a WebP decoder
[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/bswap.h"
28 #include "libavutil/dict.h"
29 #include "libavcodec/get_bits.h"
30 #include "libavcodec/bytestream.h"
31 #include "libavcodec/vorbis_parser.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)),
51                        AV_NOPTS_VALUE, NULL);
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,
63                          AV_DICT_DONT_STRDUP_VAL);
64     } else
65         return 0;
66
67     av_free(key);
68     return 1;
69 }
70
71 int
72 ff_vorbis_comment(AVFormatContext * as, AVDictionary **m, const uint8_t *buf, int size)
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] = av_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,
133                                    AV_DICT_DONT_STRDUP_KEY |
134                                    AV_DICT_DONT_STRDUP_VAL);
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
144     ff_metadata_conv(m, NULL, ff_vorbiscomment_metadata_conv);
145
146     return 0;
147 }
148
149
150 /** Parse the vorbis header
151  * Vorbis Identification header from Vorbis_I_spec.html#vorbis-spec-codec
152  * [vorbis_version] = read 32 bits as unsigned integer | Not used
153  * [audio_channels] = read 8 bit integer as unsigned | Used
154  * [audio_sample_rate] = read 32 bits as unsigned integer | Used
155  * [bitrate_maximum] = read 32 bits as signed integer | Not used yet
156  * [bitrate_nominal] = read 32 bits as signed integer | Not used yet
157  * [bitrate_minimum] = read 32 bits as signed integer | Used as bitrate
158  * [blocksize_0] = read 4 bits as unsigned integer | Not Used
159  * [blocksize_1] = read 4 bits as unsigned integer | Not Used
160  * [framing_flag] = read one bit | Not Used
161  *    */
162
163 struct oggvorbis_private {
164     unsigned int len[3];
165     unsigned char *packet[3];
166     VorbisParseContext vp;
167     int64_t final_pts;
168     int final_duration;
169 };
170
171
172 static unsigned int
173 fixup_vorbis_headers(AVFormatContext * as, struct oggvorbis_private *priv,
174                      uint8_t **buf)
175 {
176     int i, offset, len, err;
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     if ((err = av_reallocp(buf, offset + FF_INPUT_BUFFER_PADDING_SIZE)) < 0)
192         return err;
193     return offset;
194 }
195
196 static void vorbis_cleanup(AVFormatContext *s, int idx)
197 {
198     struct ogg *ogg = s->priv_data;
199     struct ogg_stream *os = ogg->streams + idx;
200     struct oggvorbis_private *priv = os->private;
201     int i;
202     if (os->private)
203         for (i = 0; i < 3; i++)
204             av_freep(&priv->packet[i]);
205 }
206
207 static int
208 vorbis_header (AVFormatContext * s, int idx)
209 {
210     struct ogg *ogg = s->priv_data;
211     struct ogg_stream *os = ogg->streams + idx;
212     AVStream *st = s->streams[idx];
213     struct oggvorbis_private *priv;
214     int pkt_type = os->buf[os->pstart];
215
216     if (!os->private) {
217         os->private = av_mallocz(sizeof(struct oggvorbis_private));
218         if (!os->private)
219             return 0;
220     }
221
222     if (!(pkt_type & 1))
223         return 0;
224
225     if (os->psize < 1 || pkt_type > 5)
226         return -1;
227
228     priv = os->private;
229
230     if (priv->packet[pkt_type>>1])
231         return -1;
232     if (pkt_type > 1 && !priv->packet[0] || pkt_type > 3 && !priv->packet[1])
233         return -1;
234
235     priv->len[pkt_type >> 1] = os->psize;
236     priv->packet[pkt_type >> 1] = av_mallocz(os->psize);
237     memcpy(priv->packet[pkt_type >> 1], os->buf + os->pstart, os->psize);
238     if (os->buf[os->pstart] == 1) {
239         const uint8_t *p = os->buf + os->pstart + 7; /* skip "\001vorbis" tag */
240         unsigned blocksize, bs0, bs1;
241         int srate;
242
243         if (os->psize != 30)
244             return -1;
245
246         if (bytestream_get_le32(&p) != 0) /* vorbis_version */
247             return -1;
248
249         st->codec->channels = bytestream_get_byte(&p);
250         srate = bytestream_get_le32(&p);
251         p += 4; // skip maximum bitrate
252         st->codec->bit_rate = bytestream_get_le32(&p); // nominal bitrate
253         p += 4; // skip minimum bitrate
254
255         blocksize = bytestream_get_byte(&p);
256         bs0 = blocksize & 15;
257         bs1 = blocksize >> 4;
258
259         if (bs0 > bs1)
260             return -1;
261         if (bs0 < 6 || bs1 > 13)
262             return -1;
263
264         if (bytestream_get_byte(&p) != 1) /* framing_flag */
265             return -1;
266
267         st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
268         st->codec->codec_id = AV_CODEC_ID_VORBIS;
269
270         if (srate > 0) {
271             st->codec->sample_rate = srate;
272             avpriv_set_pts_info(st, 64, 1, srate);
273         }
274     } else if (os->buf[os->pstart] == 3) {
275         if (os->psize > 8 &&
276             ff_vorbis_comment(s, &st->metadata, os->buf + os->pstart + 7, os->psize - 8) >= 0) {
277             // drop all metadata we parsed and which is not required by libvorbis
278             unsigned new_len = 7 + 4 + AV_RL32(priv->packet[1] + 7) + 4 + 1;
279             if (new_len >= 16 && new_len < os->psize) {
280                 AV_WL32(priv->packet[1] + new_len - 5, 0);
281                 priv->packet[1][new_len - 1] = 1;
282                 priv->len[1] = new_len;
283             }
284         }
285     } else {
286         int ret;
287         st->codec->extradata_size =
288             fixup_vorbis_headers(s, priv, &st->codec->extradata);
289         if ((ret = avpriv_vorbis_parse_extradata(st->codec, &priv->vp))) {
290             av_freep(&st->codec->extradata);
291             st->codec->extradata_size = 0;
292             return ret;
293         }
294     }
295
296     return 1;
297 }
298
299 static int vorbis_packet(AVFormatContext *s, int idx)
300 {
301     struct ogg *ogg = s->priv_data;
302     struct ogg_stream *os = ogg->streams + idx;
303     struct oggvorbis_private *priv = os->private;
304     int duration;
305
306     /* first packet handling
307        here we parse the duration of each packet in the first page and compare
308        the total duration to the page granule to find the encoder delay and
309        set the first timestamp */
310     if (!os->lastpts) {
311         int seg;
312         uint8_t *last_pkt = os->buf + os->pstart;
313         uint8_t *next_pkt = last_pkt;
314         int first_duration = 0;
315
316         avpriv_vorbis_parse_reset(&priv->vp);
317         duration = 0;
318         for (seg = 0; seg < os->nsegs; seg++) {
319             if (os->segments[seg] < 255) {
320                 int d = avpriv_vorbis_parse_frame(&priv->vp, last_pkt, 1);
321                 if (d < 0) {
322                     duration = os->granule;
323                     break;
324                 }
325                 if (!duration)
326                     first_duration = d;
327                 duration += d;
328                 last_pkt = next_pkt + os->segments[seg];
329             }
330             next_pkt += os->segments[seg];
331         }
332         os->lastpts = os->lastdts   = os->granule - duration;
333         s->streams[idx]->start_time = os->lastpts + first_duration;
334         if (s->streams[idx]->duration)
335             s->streams[idx]->duration -= s->streams[idx]->start_time;
336         s->streams[idx]->cur_dts    = AV_NOPTS_VALUE;
337         priv->final_pts             = AV_NOPTS_VALUE;
338         avpriv_vorbis_parse_reset(&priv->vp);
339     }
340
341     /* parse packet duration */
342     if (os->psize > 0) {
343         duration = avpriv_vorbis_parse_frame(&priv->vp, os->buf + os->pstart, 1);
344         if (duration <= 0) {
345             os->pflags |= AV_PKT_FLAG_CORRUPT;
346             return 0;
347         }
348         os->pduration = duration;
349     }
350
351     /* final packet handling
352        here we save the pts of the first packet in the final page, sum up all
353        packet durations in the final page except for the last one, and compare
354        to the page granule to find the duration of the final packet */
355     if (os->flags & OGG_FLAG_EOS) {
356         if (os->lastpts != AV_NOPTS_VALUE) {
357             priv->final_pts = os->lastpts;
358             priv->final_duration = 0;
359         }
360         if (os->segp == os->nsegs)
361             os->pduration = os->granule - priv->final_pts - priv->final_duration;
362         priv->final_duration += os->pduration;
363     }
364
365     return 0;
366 }
367
368 const struct ogg_codec ff_vorbis_codec = {
369     .magic = "\001vorbis",
370     .magicsize = 7,
371     .header = vorbis_header,
372     .packet = vorbis_packet,
373     .cleanup= vorbis_cleanup,
374     .nb_header = 3,
375 };