Statistics
| Branch: | Revision:

ffmpeg / libavformat / ogg2.c @ 7e33d3fe

History | View | Annotate | Download (15.5 KB)

1 9146ca37 Måns Rullgård
/*
2
 * Ogg bitstream support
3
 * Luca Barbato <lu_zero@gentoo.org>
4
 * Based on tcvp implementation
5 115329f1 Diego Biurrun
 *
6 9146ca37 Måns Rullgård
 */
7
8
/**
9
    Copyright (C) 2005  Michael Ahlberg, Måns Rullgård
10

11
    Permission is hereby granted, free of charge, to any person
12
    obtaining a copy of this software and associated documentation
13
    files (the "Software"), to deal in the Software without
14
    restriction, including without limitation the rights to use, copy,
15
    modify, merge, publish, distribute, sublicense, and/or sell copies
16
    of the Software, and to permit persons to whom the Software is
17
    furnished to do so, subject to the following conditions:
18

19
    The above copyright notice and this permission notice shall be
20
    included in all copies or substantial portions of the Software.
21

22
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23
    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24
    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25
    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
26
    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
27
    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28
    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29
    DEALINGS IN THE SOFTWARE.
30
**/
31
32
33
#include <stdio.h>
34
#include "ogg2.h"
35
#include "avformat.h"
36
37
#define MAX_PAGE_SIZE 65307
38
#define DECODER_BUFFER_SIZE MAX_PAGE_SIZE
39
40
static ogg_codec_t *ogg_codecs[] = {
41
    &vorbis_codec,
42 1ed923ea Måns Rullgård
    &theora_codec,
43 bcfc40ae Måns Rullgård
    &flac_codec,
44 880e3ef4 Michael Niedermayer
    &old_flac_codec,
45 e1203ac0 Måns Rullgård
    &ogm_video_codec,
46
    &ogm_audio_codec,
47
    &ogm_old_codec,
48 9146ca37 Måns Rullgård
    NULL
49
};
50
51 a9e35095 Diego Biurrun
#if 0                           // CONFIG_MUXERS
52 9146ca37 Måns Rullgård
static int
53
ogg_write_header (AVFormatContext * avfcontext)
54
{
55
}
56

57
static int
58
ogg_write_packet (AVFormatContext * avfcontext, AVPacket * pkt)
59
{
60
}
61

62

63
static int
64
ogg_write_trailer (AVFormatContext * avfcontext)
65
{
66
}
67

68

69 ff70e601 Måns Rullgård
AVOutputFormat ogg_muxer = {
70 9146ca37 Måns Rullgård
    "ogg",
71 1367cffd Diego Biurrun
    "Ogg format",
72
    "application/ogg",
73 9146ca37 Måns Rullgård
    "ogg",
74
    sizeof (OggContext),
75
    CODEC_ID_VORBIS,
76
    0,
77
    ogg_write_header,
78
    ogg_write_packet,
79
    ogg_write_trailer,
80
};
81 a9e35095 Diego Biurrun
#endif //CONFIG_MUXERS
82 9146ca37 Måns Rullgård
83
//FIXME We could avoid some structure duplication
84
static int
85
ogg_save (AVFormatContext * s)
86
{
87
    ogg_t *ogg = s->priv_data;
88
    ogg_state_t *ost =
89 ad3aa874 Måns Rullgård
        av_malloc(sizeof (*ost) + (ogg->nstreams-1) * sizeof (*ogg->streams));
90 9146ca37 Måns Rullgård
    int i;
91
    ost->pos = url_ftell (&s->pb);;
92
    ost->curidx = ogg->curidx;
93
    ost->next = ogg->state;
94 20be72c8 Måns Rullgård
    ost->nstreams = ogg->nstreams;
95 9146ca37 Måns Rullgård
    memcpy(ost->streams, ogg->streams, ogg->nstreams * sizeof(*ogg->streams));
96
97
    for (i = 0; i < ogg->nstreams; i++){
98
        ogg_stream_t *os = ogg->streams + i;
99
        os->buf = av_malloc (os->bufsize);
100
        memset (os->buf, 0, os->bufsize);
101
        memcpy (os->buf, ost->streams[i].buf, os->bufpos);
102
    }
103
104
    ogg->state = ost;
105
106
    return 0;
107
}
108
109
static int
110
ogg_restore (AVFormatContext * s, int discard)
111
{
112
    ogg_t *ogg = s->priv_data;
113
    ByteIOContext *bc = &s->pb;
114
    ogg_state_t *ost = ogg->state;
115
    int i;
116
117
    if (!ost)
118
        return 0;
119
120
    ogg->state = ost->next;
121
122
    if (!discard){
123
        for (i = 0; i < ogg->nstreams; i++)
124
            av_free (ogg->streams[i].buf);
125
126
        url_fseek (bc, ost->pos, SEEK_SET);
127
        ogg->curidx = ost->curidx;
128 20be72c8 Måns Rullgård
        ogg->nstreams = ost->nstreams;
129
        memcpy(ogg->streams, ost->streams,
130
               ost->nstreams * sizeof(*ogg->streams));
131 9146ca37 Måns Rullgård
    }
132
133
    av_free (ost);
134
135
    return 0;
136
}
137
138
static int
139
ogg_reset (ogg_t * ogg)
140
{
141
    int i;
142
143
    for (i = 0; i < ogg->nstreams; i++){
144
        ogg_stream_t *os = ogg->streams + i;
145
        os->bufpos = 0;
146
        os->pstart = 0;
147
        os->psize = 0;
148
        os->granule = -1;
149
        os->lastgp = -1;
150
        os->nsegs = 0;
151
        os->segp = 0;
152
    }
153
154
    ogg->curidx = -1;
155
156
    return 0;
157
}
158
159
static ogg_codec_t *
160 2d2f443d Måns Rullgård
ogg_find_codec (uint8_t * buf, int size)
161 9146ca37 Måns Rullgård
{
162
    int i;
163
164
    for (i = 0; ogg_codecs[i]; i++)
165
        if (size >= ogg_codecs[i]->magicsize &&
166
            !memcmp (buf, ogg_codecs[i]->magic, ogg_codecs[i]->magicsize))
167
            return ogg_codecs[i];
168
169
    return NULL;
170
}
171
172
static int
173
ogg_find_stream (ogg_t * ogg, int serial)
174
{
175
    int i;
176
177
    for (i = 0; i < ogg->nstreams; i++)
178
        if (ogg->streams[i].serial == serial)
179
            return i;
180
181
    return -1;
182
}
183
184
static int
185
ogg_new_stream (AVFormatContext * s, uint32_t serial)
186
{
187
188
    ogg_t *ogg = s->priv_data;
189
    int idx = ogg->nstreams++;
190
    AVStream *st;
191
    ogg_stream_t *os;
192
193
    ogg->streams = av_realloc (ogg->streams,
194
                               ogg->nstreams * sizeof (*ogg->streams));
195
    memset (ogg->streams + idx, 0, sizeof (*ogg->streams));
196
    os = ogg->streams + idx;
197
    os->serial = serial;
198
    os->bufsize = DECODER_BUFFER_SIZE;
199 40c5e1fa Måns Rullgård
    os->buf = av_malloc(os->bufsize);
200 9146ca37 Måns Rullgård
    os->header = -1;
201
202
    st = av_new_stream (s, idx);
203
    if (!st)
204 769e10f0 Panagiotis Issaris
        return AVERROR(ENOMEM);
205 9146ca37 Måns Rullgård
206
    av_set_pts_info(st, 64, 1, 1000000);
207
208
    return idx;
209
}
210
211
static int
212 12a195e3 Måns Rullgård
ogg_new_buf(ogg_t *ogg, int idx)
213
{
214
    ogg_stream_t *os = ogg->streams + idx;
215 ea02862a Måns Rullgård
    uint8_t *nb = av_malloc(os->bufsize);
216 12a195e3 Måns Rullgård
    int size = os->bufpos - os->pstart;
217
    if(os->buf){
218
        memcpy(nb, os->buf + os->pstart, size);
219
        av_free(os->buf);
220
    }
221
    os->buf = nb;
222
    os->bufpos = size;
223
    os->pstart = 0;
224
225
    return 0;
226
}
227
228
static int
229 9146ca37 Måns Rullgård
ogg_read_page (AVFormatContext * s, int *str)
230
{
231
    ByteIOContext *bc = &s->pb;
232
    ogg_t *ogg = s->priv_data;
233
    ogg_stream_t *os;
234
    int i = 0;
235
    int flags, nsegs;
236
    uint64_t gp;
237
    uint32_t serial;
238
    uint32_t seq;
239
    uint32_t crc;
240
    int size, idx;
241 191e8ca7 Måns Rullgård
    uint8_t sync[4];
242 9146ca37 Måns Rullgård
    int sp = 0;
243
244
    if (get_buffer (bc, sync, 4) < 4)
245
        return -1;
246
247
    do{
248
        int c;
249
250
        if (sync[sp & 3] == 'O' &&
251
            sync[(sp + 1) & 3] == 'g' &&
252
            sync[(sp + 2) & 3] == 'g' && sync[(sp + 3) & 3] == 'S')
253
            break;
254
255
        c = url_fgetc (bc);
256
        if (c < 0)
257
            return -1;
258
        sync[sp++ & 3] = c;
259
    }while (i++ < MAX_PAGE_SIZE);
260
261
    if (i >= MAX_PAGE_SIZE){
262
        av_log (s, AV_LOG_INFO, "ogg, can't find sync word\n");
263
        return -1;
264
    }
265
266
    if (url_fgetc (bc) != 0)      /* version */
267
        return -1;
268
269
    flags = url_fgetc (bc);
270
    gp = get_le64 (bc);
271
    serial = get_le32 (bc);
272
    seq = get_le32 (bc);
273
    crc = get_le32 (bc);
274
    nsegs = url_fgetc (bc);
275
276
    idx = ogg_find_stream (ogg, serial);
277
    if (idx < 0){
278
        idx = ogg_new_stream (s, serial);
279
        if (idx < 0)
280
            return -1;
281
    }
282
283
    os = ogg->streams + idx;
284
285 40c5e1fa Måns Rullgård
    if(os->psize > 0)
286 12a195e3 Måns Rullgård
        ogg_new_buf(ogg, idx);
287
288 9146ca37 Måns Rullgård
    if (get_buffer (bc, os->segments, nsegs) < nsegs)
289
        return -1;
290
291
    os->nsegs = nsegs;
292
    os->segp = 0;
293
294
    size = 0;
295
    for (i = 0; i < nsegs; i++)
296
        size += os->segments[i];
297
298
    if (flags & OGG_FLAG_CONT){
299
        if (!os->psize){
300
            while (os->segp < os->nsegs){
301
                int seg = os->segments[os->segp++];
302
                os->pstart += seg;
303
                if (seg < 255)
304
                  break;
305
            }
306
        }
307
    }else{
308
      os->psize = 0;
309
    }
310
311
    if (os->bufsize - os->bufpos < size){
312 2d2f443d Måns Rullgård
        uint8_t *nb = av_malloc (os->bufsize *= 2);
313 9146ca37 Måns Rullgård
        memcpy (nb, os->buf, os->bufpos);
314
        av_free (os->buf);
315
        os->buf = nb;
316
    }
317
318
    if (get_buffer (bc, os->buf + os->bufpos, size) < size)
319
        return -1;
320
321
    os->lastgp = os->granule;
322
    os->bufpos += size;
323
    os->granule = gp;
324
    os->flags = flags;
325
326
    if (str)
327
        *str = idx;
328
329
    return 0;
330
}
331
332
static int
333 12a195e3 Måns Rullgård
ogg_packet (AVFormatContext * s, int *str, int *dstart, int *dsize)
334 9146ca37 Måns Rullgård
{
335
    ogg_t *ogg = s->priv_data;
336
    int idx;
337
    ogg_stream_t *os;
338
    int complete = 0;
339
    int segp = 0, psize = 0;
340
341
#if 0
342
    av_log (s, AV_LOG_DEBUG, "ogg_packet: curidx=%i\n", ogg->curidx);
343
#endif
344
345
    do{
346
        idx = ogg->curidx;
347
348
        while (idx < 0){
349
            if (ogg_read_page (s, &idx) < 0)
350
                return -1;
351
        }
352
353
        os = ogg->streams + idx;
354
355
#if 0
356
        av_log (s, AV_LOG_DEBUG,
357
                "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
358
                idx, os->pstart, os->psize, os->segp, os->nsegs);
359
#endif
360
361
        if (!os->codec){
362
            if (os->header < 0){
363
                os->codec = ogg_find_codec (os->buf, os->bufpos);
364
                if (!os->codec){
365
                    os->header = 0;
366
                    return 0;
367
                }
368
            }else{
369
                return 0;
370
            }
371
        }
372
373
        segp = os->segp;
374
        psize = os->psize;
375
376
        while (os->segp < os->nsegs){
377
            int ss = os->segments[os->segp++];
378
            os->psize += ss;
379
            if (ss < 255){
380
                complete = 1;
381
                break;
382
            }
383
        }
384
385
        if (!complete && os->segp == os->nsegs){
386
            ogg->curidx = -1;
387
        }
388
    }while (!complete);
389
390
#if 0
391
    av_log (s, AV_LOG_DEBUG,
392
            "ogg_packet: idx %i, frame size %i, start %i\n",
393
            idx, os->psize, os->pstart);
394
#endif
395
396
    ogg->curidx = idx;
397
398
    if (os->header < 0){
399
        int hdr = os->codec->header (s, idx);
400
        if (!hdr){
401
          os->header = os->seq;
402
          os->segp = segp;
403
          os->psize = psize;
404
          ogg->headers = 1;
405
        }else{
406
          os->pstart += os->psize;
407
          os->psize = 0;
408
        }
409
    }
410
411
    if (os->header > -1 && os->seq > os->header){
412
        if (os->codec && os->codec->packet)
413
            os->codec->packet (s, idx);
414
        if (str)
415
            *str = idx;
416 12a195e3 Måns Rullgård
        if (dstart)
417
            *dstart = os->pstart;
418
        if (dsize)
419
            *dsize = os->psize;
420
        os->pstart += os->psize;
421
        os->psize = 0;
422 9146ca37 Måns Rullgård
    }
423
424
    os->seq++;
425
    if (os->segp == os->nsegs)
426
        ogg->curidx = -1;
427
428
    return 0;
429
}
430
431
static int
432
ogg_get_headers (AVFormatContext * s)
433
{
434
    ogg_t *ogg = s->priv_data;
435
436
    do{
437 12a195e3 Måns Rullgård
        if (ogg_packet (s, NULL, NULL, NULL) < 0)
438 9146ca37 Måns Rullgård
            return -1;
439
    }while (!ogg->headers);
440
441
#if 0
442
    av_log (s, AV_LOG_DEBUG, "found headers\n");
443
#endif
444
445
    return 0;
446
}
447
448
static uint64_t
449
ogg_gptopts (AVFormatContext * s, int i, uint64_t gp)
450
{
451 1ed923ea Måns Rullgård
    ogg_t *ogg = s->priv_data;
452
    ogg_stream_t *os = ogg->streams + i;
453 9146ca37 Måns Rullgård
    uint64_t pts = AV_NOPTS_VALUE;
454
455 1ed923ea Måns Rullgård
    if(os->codec->gptopts){
456 bb270c08 Diego Biurrun
        pts = os->codec->gptopts(s, i, gp);
457 3644cb8f Måns Rullgård
    } else {
458 1ed923ea Måns Rullgård
        pts = gp;
459 9146ca37 Måns Rullgård
    }
460
461
    return pts;
462
}
463
464
465
static int
466
ogg_get_length (AVFormatContext * s)
467
{
468
    ogg_t *ogg = s->priv_data;
469
    int idx = -1, i;
470 56466d7b Måns Rullgård
    offset_t size, end;
471 69599eea Måns Rullgård
472
    if(s->pb.is_streamed)
473
        return 0;
474 9146ca37 Måns Rullgård
475
// already set
476
    if (s->duration != AV_NOPTS_VALUE)
477
        return 0;
478
479 56466d7b Måns Rullgård
    size = url_fsize(&s->pb);
480
    if(size < 0)
481
        return 0;
482
    end = size > MAX_PAGE_SIZE? size - MAX_PAGE_SIZE: size;
483
484 9146ca37 Måns Rullgård
    ogg_save (s);
485 56466d7b Måns Rullgård
    url_fseek (&s->pb, end, SEEK_SET);
486 9146ca37 Måns Rullgård
487
    while (!ogg_read_page (s, &i)){
488 e22f2aaf Måns Rullgård
        if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
489
            ogg->streams[i].codec)
490 9146ca37 Måns Rullgård
            idx = i;
491
    }
492
493
    if (idx != -1){
494
        s->streams[idx]->duration =
495
            ogg_gptopts (s, idx, ogg->streams[idx].granule);
496
    }
497
498 56466d7b Måns Rullgård
    ogg->size = size;
499 9146ca37 Måns Rullgård
    ogg_restore (s, 0);
500 22ffac70 Reimar Döffinger
    ogg_save (s);
501 595da759 Aurelien Jacobs
    while (!ogg_read_page (s, &i)) {
502 22ffac70 Reimar Döffinger
        if (i == idx && ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0)
503
            break;
504
    }
505
    if (i == idx) {
506
        s->streams[idx]->start_time = ogg_gptopts (s, idx, ogg->streams[idx].granule);
507
        s->streams[idx]->duration -= s->streams[idx]->start_time;
508
    }
509
    ogg_restore (s, 0);
510 9146ca37 Måns Rullgård
511
    return 0;
512
}
513
514
515
static int
516
ogg_read_header (AVFormatContext * s, AVFormatParameters * ap)
517
{
518
    ogg_t *ogg = s->priv_data;
519
    ogg->curidx = -1;
520
    //linear headers seek from start
521
    if (ogg_get_headers (s) < 0){
522
      return -1;
523
    }
524
525
    //linear granulepos seek from end
526
    ogg_get_length (s);
527
528
    //fill the extradata in the per codec callbacks
529
    return 0;
530
}
531
532
533
static int
534
ogg_read_packet (AVFormatContext * s, AVPacket * pkt)
535
{
536
    ogg_t *ogg;
537
    ogg_stream_t *os;
538
    int idx = -1;
539 12a195e3 Måns Rullgård
    int pstart, psize;
540 9146ca37 Måns Rullgård
541 115329f1 Diego Biurrun
    //Get an ogg packet
542 9146ca37 Måns Rullgård
    do{
543 12a195e3 Måns Rullgård
        if (ogg_packet (s, &idx, &pstart, &psize) < 0)
544 6f3e0b21 Panagiotis Issaris
            return AVERROR(EIO);
545 9146ca37 Måns Rullgård
    }while (idx < 0 || !s->streams[idx]);
546
547
    ogg = s->priv_data;
548
    os = ogg->streams + idx;
549
550
    //Alloc a pkt
551 12a195e3 Måns Rullgård
    if (av_new_packet (pkt, psize) < 0)
552 6f3e0b21 Panagiotis Issaris
        return AVERROR(EIO);
553 9146ca37 Måns Rullgård
    pkt->stream_index = idx;
554 12a195e3 Måns Rullgård
    memcpy (pkt->data, os->buf + pstart, psize);
555 9146ca37 Måns Rullgård
    if (os->lastgp != -1LL){
556
        pkt->pts = ogg_gptopts (s, idx, os->lastgp);
557
        os->lastgp = -1;
558
    }
559 12a195e3 Måns Rullgård
560
    return psize;
561 9146ca37 Måns Rullgård
}
562
563
564
static int
565
ogg_read_close (AVFormatContext * s)
566
{
567
    ogg_t *ogg = s->priv_data;
568
    int i;
569
570
    for (i = 0; i < ogg->nstreams; i++){
571
        av_free (ogg->streams[i].buf);
572 1ed923ea Måns Rullgård
        av_free (ogg->streams[i].private);
573 9146ca37 Måns Rullgård
    }
574
    av_free (ogg->streams);
575
    return 0;
576
}
577
578
579
static int
580
ogg_read_seek (AVFormatContext * s, int stream_index, int64_t target_ts,
581
               int flags)
582
{
583 56466d7b Måns Rullgård
    AVStream *st = s->streams[stream_index];
584 9146ca37 Måns Rullgård
    ogg_t *ogg = s->priv_data;
585
    ByteIOContext *bc = &s->pb;
586
    uint64_t min = 0, max = ogg->size;
587 22ffac70 Reimar Döffinger
    uint64_t tmin = st->start_time, tmax = st->start_time + st->duration;
588 9146ca37 Måns Rullgård
    int64_t pts = AV_NOPTS_VALUE;
589
590
    ogg_save (s);
591
592 22ffac70 Reimar Döffinger
    if ((uint64_t)target_ts < tmin || target_ts < 0)
593
        target_ts = tmin;
594
    while (min <= max && tmin < tmax){
595 17929c04 Måns Rullgård
        uint64_t p = min + (max - min) * (target_ts - tmin) / (tmax - tmin);
596 9146ca37 Måns Rullgård
        int i = -1;
597
598
        url_fseek (bc, p, SEEK_SET);
599
600
        while (!ogg_read_page (s, &i)){
601 56466d7b Måns Rullgård
            if (i == stream_index && ogg->streams[i].granule != 0 &&
602
                ogg->streams[i].granule != -1)
603 9146ca37 Måns Rullgård
                break;
604
        }
605
606
        if (i == -1)
607
            break;
608
609
        pts = ogg_gptopts (s, i, ogg->streams[i].granule);
610
        p = url_ftell (bc);
611
612 c26abfa5 Diego Biurrun
        if (FFABS (pts - target_ts) * st->time_base.num < st->time_base.den)
613 9146ca37 Måns Rullgård
            break;
614
615
        if (pts > target_ts){
616 22ffac70 Reimar Döffinger
            if (max == p && tmax == pts) {
617
                // probably our tmin is wrong, causing us to always end up too late in the file
618
                tmin = (target_ts + tmin + 1) / 2;
619
                if (tmin == target_ts) {
620
                    url_fseek(bc, min, SEEK_SET);
621
                    break;
622
                }
623
            }
624 9146ca37 Måns Rullgård
            max = p;
625
            tmax = pts;
626
        }else{
627 22ffac70 Reimar Döffinger
            if (min == p && tmin == pts) {
628
                // probably our tmax is wrong, causing us to always end up too early in the file
629
                tmax = (target_ts + tmax) / 2;
630
                if (tmax == target_ts) {
631
                    url_fseek(bc, max, SEEK_SET);
632
                    break;
633
                }
634
            }
635 9146ca37 Måns Rullgård
            min = p;
636
            tmin = pts;
637
        }
638
    }
639
640 c26abfa5 Diego Biurrun
    if (FFABS (pts - target_ts) * st->time_base.num < st->time_base.den){
641 9146ca37 Måns Rullgård
        ogg_restore (s, 1);
642
        ogg_reset (ogg);
643
    }else{
644
        ogg_restore (s, 0);
645
        pts = AV_NOPTS_VALUE;
646
    }
647
648 22ffac70 Reimar Döffinger
    av_update_cur_dts(s, st, pts);
649
    return 0;
650 9146ca37 Måns Rullgård
651
#if 0
652
    //later...
653
    int64_t pos;
654
    if (av_seek_frame_binary (s, stream_index, target_ts, flags) < 0)
655
        return -1;
656
    pos = url_ftell (&s->pb);
657
    ogg_read_timestamp (s, stream_index, &pos, pos - 1);
658
#endif
659
660
}
661
662
#if 0
663
static int64_t
664
ogg_read_timestamp (AVFormatContext * s, int stream_index, int64_t * pos_arg,
665
                    int64_t pos_limit)
666
{
667
    ogg_t *ogg = s->priv_data;
668
    ByteIOContext *bc = &s->pb;
669
    int64_t pos, pts;
670

671
    if (*pos_arg < 0)
672
        return AV_NOPTS_VALUE;
673

674
    pos = *pos_arg;
675
}
676
#endif
677
678 2e70e4aa Måns Rullgård
static int ogg_probe(AVProbeData *p)
679
{
680
    if (p->buf[0] == 'O' && p->buf[1] == 'g' &&
681
        p->buf[2] == 'g' && p->buf[3] == 'S' &&
682
        p->buf[4] == 0x0 && p->buf[5] <= 0x7 )
683
        return AVPROBE_SCORE_MAX;
684
    else
685
        return 0;
686
}
687
688 ff70e601 Måns Rullgård
AVInputFormat ogg_demuxer = {
689 9146ca37 Måns Rullgård
    "ogg",
690
    "Ogg",
691
    sizeof (ogg_t),
692 2e70e4aa Måns Rullgård
    ogg_probe,
693 9146ca37 Måns Rullgård
    ogg_read_header,
694
    ogg_read_packet,
695
    ogg_read_close,
696
    ogg_read_seek,
697 115329f1 Diego Biurrun
// ogg_read_timestamp,
698 9146ca37 Måns Rullgård
    .extensions = "ogg",
699
};