]> git.sesse.net Git - ffmpeg/blob - libavformat/oggdec.c
Merge remote-tracking branch 'qatar/master'
[ffmpeg] / libavformat / oggdec.c
1 /*
2  * Ogg bitstream support
3  * Luca Barbato <lu_zero@gentoo.org>
4  * Based on tcvp implementation
5  */
6
7 /*
8     Copyright (C) 2005  Michael Ahlberg, Måns Rullgård
9
10     Permission is hereby granted, free of charge, to any person
11     obtaining a copy of this software and associated documentation
12     files (the "Software"), to deal in the Software without
13     restriction, including without limitation the rights to use, copy,
14     modify, merge, publish, distribute, sublicense, and/or sell copies
15     of the Software, and to permit persons to whom the Software is
16     furnished to do so, subject to the following conditions:
17
18     The above copyright notice and this permission notice shall be
19     included in all copies or substantial portions of the Software.
20
21     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23     MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
25     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27     OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28     DEALINGS IN THE SOFTWARE.
29  */
30
31 #include <stdio.h>
32 #include "oggdec.h"
33 #include "avformat.h"
34 #include "internal.h"
35 #include "vorbiscomment.h"
36
37 #define MAX_PAGE_SIZE 65307
38 #define DECODER_BUFFER_SIZE MAX_PAGE_SIZE
39
40 static const struct ogg_codec * const ogg_codecs[] = {
41     &ff_skeleton_codec,
42     &ff_dirac_codec,
43     &ff_speex_codec,
44     &ff_vorbis_codec,
45     &ff_theora_codec,
46     &ff_flac_codec,
47     &ff_celt_codec,
48     &ff_old_dirac_codec,
49     &ff_old_flac_codec,
50     &ff_ogm_video_codec,
51     &ff_ogm_audio_codec,
52     &ff_ogm_text_codec,
53     &ff_ogm_old_codec,
54     NULL
55 };
56
57 //FIXME We could avoid some structure duplication
58 static int ogg_save(AVFormatContext *s)
59 {
60     struct ogg *ogg = s->priv_data;
61     struct ogg_state *ost =
62         av_malloc(sizeof (*ost) + (ogg->nstreams-1) * sizeof (*ogg->streams));
63     int i;
64     ost->pos = avio_tell (s->pb);
65     ost->curidx = ogg->curidx;
66     ost->next = ogg->state;
67     ost->nstreams = ogg->nstreams;
68     memcpy(ost->streams, ogg->streams, ogg->nstreams * sizeof(*ogg->streams));
69
70     for (i = 0; i < ogg->nstreams; i++){
71         struct ogg_stream *os = ogg->streams + i;
72         os->buf = av_mallocz (os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
73         memcpy (os->buf, ost->streams[i].buf, os->bufpos);
74     }
75
76     ogg->state = ost;
77
78     return 0;
79 }
80
81 static int ogg_restore(AVFormatContext *s, int discard)
82 {
83     struct ogg *ogg = s->priv_data;
84     AVIOContext *bc = s->pb;
85     struct ogg_state *ost = ogg->state;
86     int i;
87
88     if (!ost)
89         return 0;
90
91     ogg->state = ost->next;
92
93     if (!discard){
94         struct ogg_stream *old_streams = ogg->streams;
95
96         for (i = 0; i < ogg->nstreams; i++)
97             av_free (ogg->streams[i].buf);
98
99         avio_seek (bc, ost->pos, SEEK_SET);
100         ogg->curidx = ost->curidx;
101         ogg->nstreams = ost->nstreams;
102         ogg->streams = av_realloc (ogg->streams,
103                                    ogg->nstreams * sizeof (*ogg->streams));
104
105         if (ogg->streams) {
106             memcpy(ogg->streams, ost->streams,
107                    ost->nstreams * sizeof(*ogg->streams));
108         } else {
109             av_free(old_streams);
110             ogg->nstreams = 0;
111         }
112     }
113
114     av_free (ost);
115
116     return 0;
117 }
118
119 static int ogg_reset(struct ogg *ogg)
120 {
121     int i;
122
123     for (i = 0; i < ogg->nstreams; i++){
124         struct ogg_stream *os = ogg->streams + i;
125         os->bufpos = 0;
126         os->pstart = 0;
127         os->psize = 0;
128         os->granule = -1;
129         os->lastpts = AV_NOPTS_VALUE;
130         os->lastdts = AV_NOPTS_VALUE;
131         os->sync_pos = -1;
132         os->page_pos = 0;
133         os->nsegs = 0;
134         os->segp = 0;
135         os->incomplete = 0;
136     }
137
138     ogg->curidx = -1;
139
140     return 0;
141 }
142
143 static const struct ogg_codec *ogg_find_codec(uint8_t *buf, int size)
144 {
145     int i;
146
147     for (i = 0; ogg_codecs[i]; i++)
148         if (size >= ogg_codecs[i]->magicsize &&
149             !memcmp (buf, ogg_codecs[i]->magic, ogg_codecs[i]->magicsize))
150             return ogg_codecs[i];
151
152     return NULL;
153 }
154
155 static int ogg_new_stream(AVFormatContext *s, uint32_t serial, int new_avstream)
156 {
157
158     struct ogg *ogg = s->priv_data;
159     int idx = ogg->nstreams++;
160     AVStream *st;
161     struct ogg_stream *os;
162
163     ogg->streams = av_realloc (ogg->streams,
164                                ogg->nstreams * sizeof (*ogg->streams));
165     memset (ogg->streams + idx, 0, sizeof (*ogg->streams));
166     os = ogg->streams + idx;
167     os->serial = serial;
168     os->bufsize = DECODER_BUFFER_SIZE;
169     os->buf = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
170     os->header = -1;
171
172     if (new_avstream) {
173         st = avformat_new_stream(s, NULL);
174         if (!st)
175             return AVERROR(ENOMEM);
176
177         st->id = idx;
178         avpriv_set_pts_info(st, 64, 1, 1000000);
179     }
180
181     return idx;
182 }
183
184 static int ogg_new_buf(struct ogg *ogg, int idx)
185 {
186     struct ogg_stream *os = ogg->streams + idx;
187     uint8_t *nb = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE);
188     int size = os->bufpos - os->pstart;
189     if(os->buf){
190         memcpy(nb, os->buf + os->pstart, size);
191         av_free(os->buf);
192     }
193     os->buf = nb;
194     os->bufpos = size;
195     os->pstart = 0;
196
197     return 0;
198 }
199
200 static int ogg_read_page(AVFormatContext *s, int *str)
201 {
202     AVIOContext *bc = s->pb;
203     struct ogg *ogg = s->priv_data;
204     struct ogg_stream *os;
205     int ret, i = 0;
206     int flags, nsegs;
207     uint64_t gp;
208     uint32_t serial;
209     int size, idx;
210     uint8_t sync[4];
211     int sp = 0;
212
213     ret = avio_read(bc, sync, 4);
214     if (ret < 4)
215         return ret < 0 ? ret : AVERROR_EOF;
216
217     do{
218         int c;
219
220         if (sync[sp & 3] == 'O' &&
221             sync[(sp + 1) & 3] == 'g' &&
222             sync[(sp + 2) & 3] == 'g' && sync[(sp + 3) & 3] == 'S')
223             break;
224
225         c = avio_r8(bc);
226         if (url_feof(bc))
227             return AVERROR_EOF;
228         sync[sp++ & 3] = c;
229     }while (i++ < MAX_PAGE_SIZE);
230
231     if (i >= MAX_PAGE_SIZE){
232         av_log (s, AV_LOG_INFO, "ogg, can't find sync word\n");
233         return AVERROR_INVALIDDATA;
234     }
235
236     if (avio_r8(bc) != 0)      /* version */
237         return AVERROR_INVALIDDATA;
238
239     flags = avio_r8(bc);
240     gp = avio_rl64 (bc);
241     serial = avio_rl32 (bc);
242     avio_skip(bc, 8); /* seq, crc */
243     nsegs = avio_r8(bc);
244
245     idx = ogg_find_stream (ogg, serial);
246     if (idx < 0){
247         if (ogg->headers) {
248             int n;
249
250             for (n = 0; n < ogg->nstreams; n++) {
251                 av_freep(&ogg->streams[n].buf);
252                 if (!ogg->state || ogg->state->streams[n].private != ogg->streams[n].private)
253                     av_freep(&ogg->streams[n].private);
254             }
255             ogg->curidx   = -1;
256             ogg->nstreams = 0;
257             idx = ogg_new_stream(s, serial, 0);
258         } else {
259             idx = ogg_new_stream(s, serial, 1);
260         }
261         if (idx < 0)
262             return idx;
263     }
264
265     os = ogg->streams + idx;
266     os->page_pos = avio_tell(bc) - 27;
267
268     if(os->psize > 0)
269         ogg_new_buf(ogg, idx);
270
271     ret = avio_read(bc, os->segments, nsegs);
272     if (ret < nsegs)
273         return ret < 0 ? ret : AVERROR_EOF;
274
275     os->nsegs = nsegs;
276     os->segp = 0;
277
278     size = 0;
279     for (i = 0; i < nsegs; i++)
280         size += os->segments[i];
281
282     if (flags & OGG_FLAG_CONT || os->incomplete){
283         if (!os->psize){
284             // If this is the very first segment we started
285             // playback in the middle of a continuation packet.
286             // Discard it since we missed the start of it.
287             while (os->segp < os->nsegs){
288                 int seg = os->segments[os->segp++];
289                 os->pstart += seg;
290                 if (seg < 255)
291                     break;
292             }
293             os->sync_pos = os->page_pos;
294         }
295     }else{
296         os->psize = 0;
297         os->sync_pos = os->page_pos;
298     }
299
300     if (os->bufsize - os->bufpos < size){
301         uint8_t *nb = av_malloc ((os->bufsize *= 2) + FF_INPUT_BUFFER_PADDING_SIZE);
302         memcpy (nb, os->buf, os->bufpos);
303         av_free (os->buf);
304         os->buf = nb;
305     }
306
307     ret = avio_read(bc, os->buf + os->bufpos, size);
308     if (ret < size)
309         return ret < 0 ? ret : AVERROR_EOF;
310
311     os->bufpos += size;
312     os->granule = gp;
313     os->flags = flags;
314
315     memset(os->buf + os->bufpos, 0, FF_INPUT_BUFFER_PADDING_SIZE);
316     if (str)
317         *str = idx;
318
319     return 0;
320 }
321
322 static int ogg_packet(AVFormatContext *s, int *str, int *dstart, int *dsize,
323                       int64_t *fpos)
324 {
325     struct ogg *ogg = s->priv_data;
326     int idx, i, ret;
327     struct ogg_stream *os;
328     int complete = 0;
329     int segp = 0, psize = 0;
330
331     av_dlog(s, "ogg_packet: curidx=%i\n", ogg->curidx);
332
333     do{
334         idx = ogg->curidx;
335
336         while (idx < 0){
337             ret = ogg_read_page(s, &idx);
338             if (ret < 0)
339                 return ret;
340         }
341
342         os = ogg->streams + idx;
343
344         av_dlog(s, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n",
345                 idx, os->pstart, os->psize, os->segp, os->nsegs);
346
347         if (!os->codec){
348             if (os->header < 0){
349                 os->codec = ogg_find_codec (os->buf, os->bufpos);
350                 if (!os->codec){
351                     av_log(s, AV_LOG_WARNING, "Codec not found\n");
352                     os->header = 0;
353                     return 0;
354                 }
355             }else{
356                 return 0;
357             }
358         }
359
360         segp = os->segp;
361         psize = os->psize;
362
363         while (os->segp < os->nsegs){
364             int ss = os->segments[os->segp++];
365             os->psize += ss;
366             if (ss < 255){
367                 complete = 1;
368                 break;
369             }
370         }
371
372         if (!complete && os->segp == os->nsegs){
373             ogg->curidx = -1;
374             // Do not set incomplete for empty packets.
375             // Together with the code in ogg_read_page
376             // that discards all continuation of empty packets
377             // we would get an infinite loop.
378             os->incomplete = !!os->psize;
379         }
380     }while (!complete);
381
382
383     if (os->granule == -1)
384         av_log(s, AV_LOG_WARNING, "Page at %"PRId64" is missing granule\n", os->page_pos);
385
386     ogg->curidx = idx;
387     os->incomplete = 0;
388
389     if (os->header) {
390         os->header = os->codec->header (s, idx);
391         if (!os->header){
392             os->segp = segp;
393             os->psize = psize;
394
395             // We have reached the first non-header packet in this stream.
396             // Unfortunately more header packets may still follow for others,
397             // but if we continue with header parsing we may lose data packets.
398             ogg->headers = 1;
399
400             // Update the header state for all streams and
401             // compute the data_offset.
402             if (!s->data_offset)
403                 s->data_offset = os->sync_pos;
404             for (i = 0; i < ogg->nstreams; i++) {
405                 struct ogg_stream *cur_os = ogg->streams + i;
406
407                 // if we have a partial non-header packet, its start is
408                 // obviously at or after the data start
409                 if (cur_os->incomplete)
410                     s->data_offset = FFMIN(s->data_offset, cur_os->sync_pos);
411             }
412         }else{
413             os->pstart += os->psize;
414             os->psize = 0;
415         }
416     } else {
417         os->pflags = 0;
418         os->pduration = 0;
419         if (os->codec && os->codec->packet)
420             os->codec->packet (s, idx);
421         if (str)
422             *str = idx;
423         if (dstart)
424             *dstart = os->pstart;
425         if (dsize)
426             *dsize = os->psize;
427         if (fpos)
428             *fpos = os->sync_pos;
429         os->pstart += os->psize;
430         os->psize = 0;
431         if(os->pstart == os->bufpos)
432             os->bufpos = os->pstart = 0;
433         os->sync_pos = os->page_pos;
434     }
435
436     // determine whether there are more complete packets in this page
437     // if not, the page's granule will apply to this packet
438     os->page_end = 1;
439     for (i = os->segp; i < os->nsegs; i++)
440         if (os->segments[i] < 255) {
441             os->page_end = 0;
442             break;
443         }
444
445     if (os->segp == os->nsegs)
446         ogg->curidx = -1;
447
448     return 0;
449 }
450
451 static int ogg_get_headers(AVFormatContext *s)
452 {
453     struct ogg *ogg = s->priv_data;
454     int ret;
455
456     do{
457         ret = ogg_packet(s, NULL, NULL, NULL, NULL);
458         if (ret < 0)
459             return ret;
460     }while (!ogg->headers);
461
462     av_dlog(s, "found headers\n");
463
464     return 0;
465 }
466
467 static int ogg_get_length(AVFormatContext *s)
468 {
469     struct ogg *ogg = s->priv_data;
470     int i;
471     int64_t size, end;
472     int streams_left=0;
473
474     if(!s->pb->seekable)
475         return 0;
476
477 // already set
478     if (s->duration != AV_NOPTS_VALUE)
479         return 0;
480
481     size = avio_size(s->pb);
482     if(size < 0)
483         return 0;
484     end = size > MAX_PAGE_SIZE? size - MAX_PAGE_SIZE: 0;
485
486     ogg_save (s);
487     avio_seek (s->pb, end, SEEK_SET);
488
489     while (!ogg_read_page (s, &i)){
490         if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
491             ogg->streams[i].codec) {
492             s->streams[i]->duration =
493                 ogg_gptopts (s, i, ogg->streams[i].granule, NULL);
494             if (s->streams[i]->start_time != AV_NOPTS_VALUE){
495                 s->streams[i]->duration -= s->streams[i]->start_time;
496                 streams_left-= (ogg->streams[i].got_start==-1);
497                 ogg->streams[i].got_start= 1;
498             }else if(!ogg->streams[i].got_start){
499                 ogg->streams[i].got_start= -1;
500                 streams_left++;
501             }
502         }
503     }
504
505     ogg_restore (s, 0);
506
507     ogg_save (s);
508     avio_seek (s->pb, 0, SEEK_SET);
509     while (!ogg_read_page (s, &i)){
510         if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 &&
511             ogg->streams[i].codec) {
512             if(s->streams[i]->duration && s->streams[i]->start_time == AV_NOPTS_VALUE && !ogg->streams[i].got_start){
513                 int64_t start= ogg_gptopts (s, i, ogg->streams[i].granule, NULL);
514                 if(av_rescale_q(start, s->streams[i]->time_base, AV_TIME_BASE_Q) > AV_TIME_BASE)
515                     s->streams[i]->duration -= start;
516                 ogg->streams[i].got_start= 1;
517                 streams_left--;
518             }
519             if(streams_left<=0)
520                 break;
521         }
522     }
523     ogg_restore (s, 0);
524
525     return 0;
526 }
527
528 static int ogg_read_header(AVFormatContext *s)
529 {
530     struct ogg *ogg = s->priv_data;
531     int ret, i;
532     ogg->curidx = -1;
533     //linear headers seek from start
534     ret = ogg_get_headers(s);
535     if (ret < 0)
536         return ret;
537
538     for (i = 0; i < ogg->nstreams; i++)
539         if (ogg->streams[i].header < 0)
540             ogg->streams[i].codec = NULL;
541
542     //linear granulepos seek from end
543     ogg_get_length (s);
544
545     //fill the extradata in the per codec callbacks
546     return 0;
547 }
548
549 static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
550 {
551     struct ogg *ogg = s->priv_data;
552     struct ogg_stream *os = ogg->streams + idx;
553     int64_t pts = AV_NOPTS_VALUE;
554
555     if (dts)
556         *dts = AV_NOPTS_VALUE;
557
558     if (os->lastpts != AV_NOPTS_VALUE) {
559         pts = os->lastpts;
560         os->lastpts = AV_NOPTS_VALUE;
561     }
562     if (os->lastdts != AV_NOPTS_VALUE) {
563         if (dts)
564             *dts = os->lastdts;
565         os->lastdts = AV_NOPTS_VALUE;
566     }
567     if (os->page_end) {
568         if (os->granule != -1LL) {
569             if (os->codec && os->codec->granule_is_start)
570                 pts = ogg_gptopts(s, idx, os->granule, dts);
571             else
572                 os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts);
573             os->granule = -1LL;
574         }
575     }
576     return pts;
577 }
578
579 static void ogg_validate_keyframe(AVFormatContext *s, int idx, int pstart, int psize)
580 {
581     struct ogg *ogg = s->priv_data;
582     struct ogg_stream *os = ogg->streams + idx;
583     if (psize && s->streams[idx]->codec->codec_id == CODEC_ID_THEORA) {
584         if (!!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 0x40)) {
585             os->pflags ^= AV_PKT_FLAG_KEY;
586             av_log(s, AV_LOG_WARNING, "Broken file, %skeyframe not correctly marked.\n",
587                    (os->pflags & AV_PKT_FLAG_KEY) ? "" : "non-");
588         }
589     }
590 }
591
592 static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
593 {
594     struct ogg *ogg;
595     struct ogg_stream *os;
596     int idx = -1, ret;
597     int pstart, psize;
598     int64_t fpos, pts, dts;
599
600     //Get an ogg packet
601 retry:
602     do{
603         ret = ogg_packet(s, &idx, &pstart, &psize, &fpos);
604         if (ret < 0)
605             return ret;
606     }while (idx < 0 || !s->streams[idx]);
607
608     ogg = s->priv_data;
609     os = ogg->streams + idx;
610
611     // pflags might not be set until after this
612     pts = ogg_calc_pts(s, idx, &dts);
613     ogg_validate_keyframe(s, idx, pstart, psize);
614
615     if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
616         goto retry;
617     os->keyframe_seek = 0;
618
619     //Alloc a pkt
620     ret = av_new_packet(pkt, psize);
621     if (ret < 0)
622         return ret;
623     pkt->stream_index = idx;
624     memcpy (pkt->data, os->buf + pstart, psize);
625
626     pkt->pts = pts;
627     pkt->dts = dts;
628     pkt->flags = os->pflags;
629     pkt->duration = os->pduration;
630     pkt->pos = fpos;
631
632     return psize;
633 }
634
635 static int ogg_read_close(AVFormatContext *s)
636 {
637     struct ogg *ogg = s->priv_data;
638     int i;
639
640     for (i = 0; i < ogg->nstreams; i++){
641         av_free (ogg->streams[i].buf);
642         av_free (ogg->streams[i].private);
643     }
644     av_free (ogg->streams);
645     return 0;
646 }
647
648 static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
649                                   int64_t *pos_arg, int64_t pos_limit)
650 {
651     struct ogg *ogg = s->priv_data;
652     AVIOContext *bc = s->pb;
653     int64_t pts = AV_NOPTS_VALUE;
654     int64_t keypos = -1;
655     int i = -1;
656     int pstart, psize;
657     avio_seek(bc, *pos_arg, SEEK_SET);
658     ogg_reset(ogg);
659
660     while (avio_tell(bc) < pos_limit && !ogg_packet(s, &i, &pstart, &psize, pos_arg)) {
661         if (i == stream_index) {
662             struct ogg_stream *os = ogg->streams + stream_index;
663             pts = ogg_calc_pts(s, i, NULL);
664             ogg_validate_keyframe(s, i, pstart, psize);
665             if (os->pflags & AV_PKT_FLAG_KEY) {
666                 keypos = *pos_arg;
667             } else if (os->keyframe_seek) {
668                 // if we had a previous keyframe but no pts for it,
669                 // return that keyframe with this pts value.
670                 if (keypos >= 0)
671                     *pos_arg = keypos;
672                 else
673                     pts = AV_NOPTS_VALUE;
674             }
675         }
676         if (pts != AV_NOPTS_VALUE)
677             break;
678     }
679     ogg_reset(ogg);
680     return pts;
681 }
682
683 static int ogg_read_seek(AVFormatContext *s, int stream_index,
684                          int64_t timestamp, int flags)
685 {
686     struct ogg *ogg = s->priv_data;
687     struct ogg_stream *os = ogg->streams + stream_index;
688     int ret;
689
690     // Ensure everything is reset even when seeking via
691     // the generated index.
692     ogg_reset(ogg);
693
694     // Try seeking to a keyframe first. If this fails (very possible),
695     // av_seek_frame will fall back to ignoring keyframes
696     if (s->streams[stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO
697         && !(flags & AVSEEK_FLAG_ANY))
698         os->keyframe_seek = 1;
699
700     ret = ff_seek_frame_binary(s, stream_index, timestamp, flags);
701     os = ogg->streams + stream_index;
702     if (ret < 0)
703         os->keyframe_seek = 0;
704     return ret;
705 }
706
707 static int ogg_probe(AVProbeData *p)
708 {
709     if (!memcmp("OggS", p->buf, 5) && p->buf[5] <= 0x7)
710         return AVPROBE_SCORE_MAX;
711     return 0;
712 }
713
714 AVInputFormat ff_ogg_demuxer = {
715     .name           = "ogg",
716     .long_name      = NULL_IF_CONFIG_SMALL("Ogg"),
717     .priv_data_size = sizeof(struct ogg),
718     .read_probe     = ogg_probe,
719     .read_header    = ogg_read_header,
720     .read_packet    = ogg_read_packet,
721     .read_close     = ogg_read_close,
722     .read_seek      = ogg_read_seek,
723     .read_timestamp = ogg_read_timestamp,
724     .extensions     = "ogg",
725     .flags          = AVFMT_GENERIC_INDEX,
726 };