Statistics
| Branch: | Revision:

ffmpeg / libavformat / ogg2.c @ 68bf8d83

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 e1203ac0 Måns Rullgård
    &ogm_video_codec,
45
    &ogm_audio_codec,
46
    &ogm_old_codec,
47 9146ca37 Måns Rullgård
    NULL
48
};
49
50 a9e35095 Diego Biurrun
#if 0                           // CONFIG_MUXERS
51 9146ca37 Måns Rullgård
static int
52
ogg_write_header (AVFormatContext * avfcontext)
53
{
54
}
55

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

61

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

67

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

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

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