Statistics
| Branch: | Revision:

ffmpeg / libavformat / oggparsevorbis.c @ 9dd94f83

History | View | Annotate | Download (8.23 KB)

1 9146ca37 Måns Rullgård
/**
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 245976da Diego Biurrun
#include "libavutil/avstring.h"
27
#include "libavutil/bswap.h"
28 9106a698 Stefano Sabatini
#include "libavcodec/get_bits.h"
29 245976da Diego Biurrun
#include "libavcodec/bytestream.h"
30 9146ca37 Måns Rullgård
#include "avformat.h"
31 19711af5 Anton Khirnov
#include "internal.h"
32 a0ddef24 Diego Biurrun
#include "oggdec.h"
33 fb66c31d Martin Storsjö
#include "vorbiscomment.h"
34 9146ca37 Måns Rullgård
35 8730fad5 David Conrad
static int ogm_chapter(AVFormatContext *as, uint8_t *key, uint8_t *val)
36
{
37
    int i, cnum, h, m, s, ms, keylen = strlen(key);
38
    AVChapter *chapter = NULL;
39
40
    if (keylen < 9 || sscanf(key, "CHAPTER%02d", &cnum) != 1)
41
        return 0;
42
43
    if (keylen == 9) {
44
        if (sscanf(val, "%02d:%02d:%02d.%03d", &h, &m, &s, &ms) < 4)
45
            return 0;
46
47
        ff_new_chapter(as, cnum, (AVRational){1,1000},
48
                       ms + 1000*(s + 60*(m + 60*h)),
49
                       AV_NOPTS_VALUE, NULL);
50
        av_free(val);
51
    } else if (!strcmp(key+9, "NAME")) {
52
        for(i = 0; i < as->nb_chapters; i++)
53
            if (as->chapters[i]->id == cnum) {
54
                chapter = as->chapters[i];
55
                break;
56
            }
57
        if (!chapter)
58
            return 0;
59
60
        av_metadata_set2(&chapter->metadata, "title", val,
61
                         AV_METADATA_DONT_STRDUP_VAL);
62
    } else
63
        return 0;
64
65
    av_free(key);
66
    return 1;
67
}
68
69 9686df2b Diego Biurrun
int
70 533c30fc David Conrad
ff_vorbis_comment(AVFormatContext * as, AVMetadata **m, const uint8_t *buf, int size)
71 9146ca37 Måns Rullgård
{
72 47a0513b Baptiste Coudurier
    const uint8_t *p = buf;
73
    const uint8_t *end = buf + size;
74 98422c44 Reimar Döffinger
    unsigned n, j;
75
    int s;
76 9146ca37 Måns Rullgård
77 f5475e1b Måns Rullgård
    if (size < 8) /* must have vendor_length and user_comment_list_length */
78 9146ca37 Måns Rullgård
        return -1;
79
80 0a770ae7 Måns Rullgård
    s = bytestream_get_le32(&p);
81 9146ca37 Måns Rullgård
82 98422c44 Reimar Döffinger
    if (end - p - 4 < s || s < 0)
83 9146ca37 Måns Rullgård
        return -1;
84
85
    p += s;
86
87 0a770ae7 Måns Rullgård
    n = bytestream_get_le32(&p);
88 9146ca37 Måns Rullgård
89 98422c44 Reimar Döffinger
    while (end - p >= 4 && n > 0) {
90 47a0513b Baptiste Coudurier
        const char *t, *v;
91 9146ca37 Måns Rullgård
        int tl, vl;
92
93 0a770ae7 Måns Rullgård
        s = bytestream_get_le32(&p);
94 9146ca37 Måns Rullgård
95 98422c44 Reimar Döffinger
        if (end - p < s || s < 0)
96 9146ca37 Måns Rullgård
            break;
97
98
        t = p;
99
        p += s;
100
        n--;
101
102 4bd684bc Måns Rullgård
        v = memchr(t, '=', s);
103 9146ca37 Måns Rullgård
        if (!v)
104
            continue;
105
106
        tl = v - t;
107
        vl = s - tl - 1;
108
        v++;
109
110 4bd684bc Måns Rullgård
        if (tl && vl) {
111 e3b44649 Justin Ruggles
            char *tt, *ct;
112
113
            tt = av_malloc(tl + 1);
114
            ct = av_malloc(vl + 1);
115
            if (!tt || !ct) {
116
                av_freep(&tt);
117
                av_freep(&ct);
118
                av_log(as, AV_LOG_WARNING, "out-of-memory error. skipping VorbisComment tag.\n");
119
                continue;
120
            }
121 9146ca37 Måns Rullgård
122
            for (j = 0; j < tl; j++)
123 4bd684bc Måns Rullgård
                tt[j] = toupper(t[j]);
124 9146ca37 Måns Rullgård
            tt[tl] = 0;
125
126 4bd684bc Måns Rullgård
            memcpy(ct, v, vl);
127 9146ca37 Måns Rullgård
            ct[vl] = 0;
128
129 8730fad5 David Conrad
            if (!ogm_chapter(as, tt, ct))
130
                av_metadata_set2(m, tt, ct,
131 12ad6671 Michael Niedermayer
                                   AV_METADATA_DONT_STRDUP_KEY |
132
                                   AV_METADATA_DONT_STRDUP_VAL);
133 9146ca37 Måns Rullgård
        }
134
    }
135
136 972c5f9e Måns Rullgård
    if (p != end)
137 7d507ceb Reimar Döffinger
        av_log(as, AV_LOG_INFO, "%ti bytes of comment header remain\n", end-p);
138 9146ca37 Måns Rullgård
    if (n > 0)
139 4bd684bc Måns Rullgård
        av_log(as, AV_LOG_INFO,
140
               "truncated comment header, %i comments not found\n", n);
141 9146ca37 Måns Rullgård
142 ad7768f4 Anton Khirnov
    ff_metadata_conv(m, NULL, ff_vorbiscomment_metadata_conv);
143 03700d39 Anton Khirnov
144 9146ca37 Måns Rullgård
    return 0;
145
}
146
147
148
/** Parse the vorbis header
149
 * Vorbis Identification header from Vorbis_I_spec.html#vorbis-spec-codec
150
 * [vorbis_version] = read 32 bits as unsigned integer | Not used
151
 * [audio_channels] = read 8 bit integer as unsigned | Used
152 115329f1 Diego Biurrun
 * [audio_sample_rate] = read 32 bits as unsigned integer | Used
153 9146ca37 Måns Rullgård
 * [bitrate_maximum] = read 32 bits as signed integer | Not used yet
154
 * [bitrate_nominal] = read 32 bits as signed integer | Not used yet
155
 * [bitrate_minimum] = read 32 bits as signed integer | Used as bitrate
156
 * [blocksize_0] = read 4 bits as unsigned integer | Not Used
157
 * [blocksize_1] = read 4 bits as unsigned integer | Not Used
158
 * [framing_flag] = read one bit | Not Used
159
 *    */
160
161 77be08ee Måns Rullgård
struct oggvorbis_private {
162 ad2b531d Måns Rullgård
    unsigned int len[3];
163
    unsigned char *packet[3];
164 77be08ee Måns Rullgård
};
165 ad2b531d Måns Rullgård
166
167
static unsigned int
168 77be08ee Måns Rullgård
fixup_vorbis_headers(AVFormatContext * as, struct oggvorbis_private *priv,
169 19f4ceca Måns Rullgård
                     uint8_t **buf)
170 ad2b531d Måns Rullgård
{
171
    int i,offset, len;
172
    unsigned char *ptr;
173
174
    len = priv->len[0] + priv->len[1] + priv->len[2];
175
    ptr = *buf = av_mallocz(len + len/255 + 64);
176
177
    ptr[0] = 2;
178
    offset = 1;
179
    offset += av_xiphlacing(&ptr[offset], priv->len[0]);
180
    offset += av_xiphlacing(&ptr[offset], priv->len[1]);
181 4bd684bc Måns Rullgård
    for (i = 0; i < 3; i++) {
182 ad2b531d Måns Rullgård
        memcpy(&ptr[offset], priv->packet[i], priv->len[i]);
183
        offset += priv->len[i];
184 2ac41150 David Conrad
        av_freep(&priv->packet[i]);
185 ad2b531d Måns Rullgård
    }
186 589790c2 Siarhei Siamashka
    *buf = av_realloc(*buf, offset + FF_INPUT_BUFFER_PADDING_SIZE);
187 ad2b531d Måns Rullgård
    return offset;
188
}
189
190
191 9146ca37 Måns Rullgård
static int
192
vorbis_header (AVFormatContext * s, int idx)
193
{
194 77be08ee Måns Rullgård
    struct ogg *ogg = s->priv_data;
195
    struct ogg_stream *os = ogg->streams + idx;
196 9146ca37 Måns Rullgård
    AVStream *st = s->streams[idx];
197 77be08ee Måns Rullgård
    struct oggvorbis_private *priv;
198 8f8320d7 David Conrad
    int pkt_type = os->buf[os->pstart];
199 9146ca37 Måns Rullgård
200 8f8320d7 David Conrad
    if (!(pkt_type & 1))
201 9146ca37 Måns Rullgård
        return 0;
202
203 8f8320d7 David Conrad
    if (!os->private) {
204 77be08ee Måns Rullgård
        os->private = av_mallocz(sizeof(struct oggvorbis_private));
205 4bd684bc Måns Rullgård
        if (!os->private)
206 ad2b531d Måns Rullgård
            return 0;
207
    }
208 9146ca37 Måns Rullgård
209 8f8320d7 David Conrad
    if (os->psize < 1 || pkt_type > 5)
210 f5475e1b Måns Rullgård
        return -1;
211
212 ad2b531d Måns Rullgård
    priv = os->private;
213 73c44cb2 Alex Converse
214
    if (priv->packet[pkt_type>>1])
215
        return -1;
216
    if (pkt_type > 1 && !priv->packet[0] || pkt_type > 3 && !priv->packet[1])
217
        return -1;
218
219 8f8320d7 David Conrad
    priv->len[pkt_type >> 1] = os->psize;
220
    priv->packet[pkt_type >> 1] = av_mallocz(os->psize);
221
    memcpy(priv->packet[pkt_type >> 1], os->buf + os->pstart, os->psize);
222 9146ca37 Måns Rullgård
    if (os->buf[os->pstart] == 1) {
223 47a0513b Baptiste Coudurier
        const uint8_t *p = os->buf + os->pstart + 7; /* skip "\001vorbis" tag */
224 736e63ed Måns Rullgård
        unsigned blocksize, bs0, bs1;
225 ce20edb7 Reimar Döffinger
        int srate;
226 f5475e1b Måns Rullgård
227
        if (os->psize != 30)
228
            return -1;
229
230 736e63ed Måns Rullgård
        if (bytestream_get_le32(&p) != 0) /* vorbis_version */
231
            return -1;
232
233 739587bf Måns Rullgård
        st->codec->channels = bytestream_get_byte(&p);
234 ce20edb7 Reimar Döffinger
        srate = bytestream_get_le32(&p);
235 739587bf Måns Rullgård
        p += 4; // skip maximum bitrate
236
        st->codec->bit_rate = bytestream_get_le32(&p); // nominal bitrate
237 736e63ed Måns Rullgård
        p += 4; // skip minimum bitrate
238
239
        blocksize = bytestream_get_byte(&p);
240
        bs0 = blocksize & 15;
241
        bs1 = blocksize >> 4;
242
243
        if (bs0 > bs1)
244
            return -1;
245
        if (bs0 < 6 || bs1 > 13)
246
            return -1;
247
248
        if (bytestream_get_byte(&p) != 1) /* framing_flag */
249
            return -1;
250 9146ca37 Måns Rullgård
251 72415b2a Stefano Sabatini
        st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
252 01f4895c Michael Niedermayer
        st->codec->codec_id = CODEC_ID_VORBIS;
253 9146ca37 Måns Rullgård
254 ce20edb7 Reimar Döffinger
        if (srate > 0) {
255
            st->codec->sample_rate = srate;
256 a351110e Reimar Döffinger
            av_set_pts_info(st, 64, 1, srate);
257 ce20edb7 Reimar Döffinger
        }
258 9146ca37 Måns Rullgård
    } else if (os->buf[os->pstart] == 3) {
259 8cb3c557 Reimar Döffinger
        if (os->psize > 8 &&
260
            ff_vorbis_comment(s, &st->metadata, os->buf + os->pstart + 7, os->psize - 8) >= 0) {
261
            // drop all metadata we parsed and which is not required by libvorbis
262
            unsigned new_len = 7 + 4 + AV_RL32(priv->packet[1] + 7) + 4 + 1;
263
            if (new_len >= 16 && new_len < os->psize) {
264
                AV_WL32(priv->packet[1] + new_len - 5, 0);
265
                priv->packet[1][new_len - 1] = 1;
266
                priv->len[1] = new_len;
267
            }
268
        }
269 ad2b531d Måns Rullgård
    } else {
270 01f4895c Michael Niedermayer
        st->codec->extradata_size =
271
            fixup_vorbis_headers(s, priv, &st->codec->extradata);
272 9146ca37 Måns Rullgård
    }
273
274 8f8320d7 David Conrad
    return 1;
275 9146ca37 Måns Rullgård
}
276
277 77be08ee Måns Rullgård
const struct ogg_codec ff_vorbis_codec = {
278 9146ca37 Måns Rullgård
    .magic = "\001vorbis",
279
    .magicsize = 7,
280
    .header = vorbis_header
281
};