Statistics
| Branch: | Revision:

ffmpeg / libavformat / oggparsevorbis.c @ 19711af5

History | View | Annotate | Download (8.23 KB)

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 "libavcodec/get_bits.h"
29
#include "libavcodec/bytestream.h"
30
#include "avformat.h"
31
#include "internal.h"
32
#include "oggdec.h"
33
#include "vorbiscomment.h"
34

    
35
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
int
70
ff_vorbis_comment(AVFormatContext * as, AVMetadata **m, const uint8_t *buf, int size)
71
{
72
    const uint8_t *p = buf;
73
    const uint8_t *end = buf + size;
74
    unsigned n, j;
75
    int s;
76

    
77
    if (size < 8) /* must have vendor_length and user_comment_list_length */
78
        return -1;
79

    
80
    s = bytestream_get_le32(&p);
81

    
82
    if (end - p - 4 < s || s < 0)
83
        return -1;
84

    
85
    p += s;
86

    
87
    n = bytestream_get_le32(&p);
88

    
89
    while (end - p >= 4 && n > 0) {
90
        const char *t, *v;
91
        int tl, vl;
92

    
93
        s = bytestream_get_le32(&p);
94

    
95
        if (end - p < s || s < 0)
96
            break;
97

    
98
        t = p;
99
        p += s;
100
        n--;
101

    
102
        v = memchr(t, '=', s);
103
        if (!v)
104
            continue;
105

    
106
        tl = v - t;
107
        vl = s - tl - 1;
108
        v++;
109

    
110
        if (tl && vl) {
111
            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

    
122
            for (j = 0; j < tl; j++)
123
                tt[j] = toupper(t[j]);
124
            tt[tl] = 0;
125

    
126
            memcpy(ct, v, vl);
127
            ct[vl] = 0;
128

    
129
            if (!ogm_chapter(as, tt, ct))
130
                av_metadata_set2(m, tt, ct,
131
                                   AV_METADATA_DONT_STRDUP_KEY |
132
                                   AV_METADATA_DONT_STRDUP_VAL);
133
        }
134
    }
135

    
136
    if (p != end)
137
        av_log(as, AV_LOG_INFO, "%ti bytes of comment header remain\n", end-p);
138
    if (n > 0)
139
        av_log(as, AV_LOG_INFO,
140
               "truncated comment header, %i comments not found\n", n);
141

    
142
    ff_metadata_conv(m, NULL, ff_vorbiscomment_metadata_conv);
143

    
144
    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
 * [audio_sample_rate] = read 32 bits as unsigned integer | Used
153
 * [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
struct oggvorbis_private {
162
    unsigned int len[3];
163
    unsigned char *packet[3];
164
};
165

    
166

    
167
static unsigned int
168
fixup_vorbis_headers(AVFormatContext * as, struct oggvorbis_private *priv,
169
                     uint8_t **buf)
170
{
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
    for (i = 0; i < 3; i++) {
182
        memcpy(&ptr[offset], priv->packet[i], priv->len[i]);
183
        offset += priv->len[i];
184
        av_freep(&priv->packet[i]);
185
    }
186
    *buf = av_realloc(*buf, offset + FF_INPUT_BUFFER_PADDING_SIZE);
187
    return offset;
188
}
189

    
190

    
191
static int
192
vorbis_header (AVFormatContext * s, int idx)
193
{
194
    struct ogg *ogg = s->priv_data;
195
    struct ogg_stream *os = ogg->streams + idx;
196
    AVStream *st = s->streams[idx];
197
    struct oggvorbis_private *priv;
198
    int pkt_type = os->buf[os->pstart];
199

    
200
    if (!(pkt_type & 1))
201
        return 0;
202

    
203
    if (!os->private) {
204
        os->private = av_mallocz(sizeof(struct oggvorbis_private));
205
        if (!os->private)
206
            return 0;
207
    }
208

    
209
    if (os->psize < 1 || pkt_type > 5)
210
        return -1;
211

    
212
    priv = os->private;
213

    
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
    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
    if (os->buf[os->pstart] == 1) {
223
        const uint8_t *p = os->buf + os->pstart + 7; /* skip "\001vorbis" tag */
224
        unsigned blocksize, bs0, bs1;
225
        int srate;
226

    
227
        if (os->psize != 30)
228
            return -1;
229

    
230
        if (bytestream_get_le32(&p) != 0) /* vorbis_version */
231
            return -1;
232

    
233
        st->codec->channels = bytestream_get_byte(&p);
234
        srate = bytestream_get_le32(&p);
235
        p += 4; // skip maximum bitrate
236
        st->codec->bit_rate = bytestream_get_le32(&p); // nominal bitrate
237
        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

    
251
        st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
252
        st->codec->codec_id = CODEC_ID_VORBIS;
253

    
254
        if (srate > 0) {
255
            st->codec->sample_rate = srate;
256
            av_set_pts_info(st, 64, 1, srate);
257
        }
258
    } else if (os->buf[os->pstart] == 3) {
259
        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
    } else {
270
        st->codec->extradata_size =
271
            fixup_vorbis_headers(s, priv, &st->codec->extradata);
272
    }
273

    
274
    return 1;
275
}
276

    
277
const struct ogg_codec ff_vorbis_codec = {
278
    .magic = "\001vorbis",
279
    .magicsize = 7,
280
    .header = vorbis_header
281
};