Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

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