Update to MPlayer SVN rev 34578.
[vaapi:athaifas-mplayer.git] / libmpdemux / .svn / text-base / demux_ogg.c.svn-base
1 /*
2  * This file is part of MPlayer.
3  *
4  * MPlayer is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * MPlayer is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with MPlayer; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18
19 #include "config.h"
20
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <assert.h>
25 #include <math.h>
26 #include <inttypes.h>
27
28 #include "mp_msg.h"
29 #include "help_mp.h"
30 #include "mpcommon.h"
31 #include "stream/stream.h"
32 #include "demuxer.h"
33 #include "stheader.h"
34 #include "libavutil/intreadwrite.h"
35 #include "aviprint.h"
36 #include "demux_mov.h"
37 #include "demux_ogg.h"
38
39 #define FOURCC_VORBIS mmioFOURCC('v', 'r', 'b', 's')
40 #define FOURCC_SPEEX  mmioFOURCC('s', 'p', 'x', ' ')
41 #define FOURCC_THEORA mmioFOURCC('t', 'h', 'e', 'o')
42
43 #ifdef CONFIG_TREMOR
44 #include <tremor/ogg.h>
45 #include <tremor/ivorbiscodec.h>
46 #else
47 #include <ogg/ogg.h>
48 #include <vorbis/codec.h>
49 #endif
50
51 #ifdef CONFIG_OGGTHEORA
52 #include <theora/theoradec.h>
53 #endif
54
55 #define BLOCK_SIZE 4096
56
57 /* Theora decoder context : we won't be able to interpret granule positions
58  * without using th_granule_time with the th_dec_ctx of the stream.
59  * This is duplicated in `vd_theora.c'; put this in a common header?
60  */
61 #ifdef CONFIG_OGGTHEORA
62 typedef struct theora_struct_st {
63     th_setup_info *tsi;
64     th_dec_ctx    *tctx;
65     th_comment     tc;
66     th_info        ti;
67 } theora_struct_t;
68 #endif
69
70 //// OggDS headers
71 // Header for the new header format
72 typedef struct stream_header_video {
73     ogg_int32_t width;
74     ogg_int32_t height;
75 } stream_header_video;
76
77 typedef struct stream_header_audio {
78     ogg_int16_t channels;
79     ogg_int16_t blockalign;
80     ogg_int32_t avgbytespersec;
81 } stream_header_audio;
82
83 typedef struct __attribute__((__packed__)) stream_header {
84     char streamtype[8];
85     char subtype[4];
86
87     ogg_int32_t size;               // size of the structure
88
89     ogg_int64_t time_unit;          // in reference time
90     ogg_int64_t samples_per_unit;
91     ogg_int32_t default_len;        // in media time
92
93     ogg_int32_t buffersize;
94     ogg_int16_t bits_per_sample;
95
96     ogg_int16_t padding;
97
98     union {
99         // Video specific
100         stream_header_video     video;
101         // Audio specific
102         stream_header_audio     audio;
103     } sh;
104 } stream_header;
105
106 /// Our private datas
107
108 typedef struct ogg_syncpoint {
109     int64_t granulepos;
110     off_t   page_pos;
111 } ogg_syncpoint_t;
112
113 /// A logical stream
114 typedef struct ogg_stream {
115     /// Timestamping stuff
116     float   samplerate; /// granulpos 2 time
117     int64_t lastpos;
118     int32_t lastsize;
119     int     keyframe_granule_shift;
120
121     // Logical stream state
122     ogg_stream_state stream;
123     int hdr_packets;
124     int vorbis;
125     int speex;
126     int theora;
127     int flac;
128     int text;
129     int id;
130
131     vorbis_info vi;
132     int         vi_initialized;
133
134     void *ogg_d;
135 } ogg_stream_t;
136
137 typedef struct ogg_demuxer {
138     /// Physical stream state
139     ogg_sync_state   sync;
140     /// Current page
141     ogg_page         page;
142     /// Logical streams
143     ogg_stream_t    *subs;
144     int              num_sub;
145     ogg_syncpoint_t *syncpoints;
146     int              num_syncpoint;
147     off_t            pos, last_size;
148     int64_t          initial_granulepos;
149     int64_t          final_granulepos;
150     int64_t          duration;
151
152     /* Used for subtitle switching. */
153     int    n_text;
154     int   *text_ids;
155     char **text_langs;
156 } ogg_demuxer_t;
157
158 #define NUM_VORBIS_HDR_PACKETS 3
159
160 /// Some defines from OggDS
161 #define PACKET_TYPE_HEADER  0x01
162 #define PACKET_TYPE_BITS    0x07
163 #define PACKET_LEN_BITS01   0xc0
164 #define PACKET_LEN_BITS2    0x02
165 #define PACKET_IS_SYNCPOINT 0x08
166
167 //-------- subtitle support - should be moved to decoder layer, and queue
168 //                          - subtitles up in demuxer buffer...
169
170 #include "sub/subreader.h"
171 #include "sub/sub.h"
172 #define OGG_SUB_MAX_LINE 128
173
174 static subtitle ogg_sub;
175 //FILE* subout;
176
177 static void demux_ogg_add_sub(ogg_stream_t *os, ogg_packet *pack)
178 {
179     int lcv;
180     char *packet = pack->packet;
181
182     if (pack->bytes < 4)
183         return;
184     mp_msg(MSGT_DEMUX, MSGL_DBG2, "\ndemux_ogg_add_sub %02X %02X %02X '%s'\n",
185            (unsigned char)packet[0],
186            (unsigned char)packet[1],
187            (unsigned char)packet[2],
188            &packet[3]);
189
190     if (((unsigned char)packet[0]) == 0x88) { // some subtitle text
191         // Find data start
192         double endpts = MP_NOPTS_VALUE;
193         int32_t duration = 0;
194         int16_t hdrlen = (*packet & PACKET_LEN_BITS01) >> 6, i;
195
196         hdrlen |= (*packet & PACKET_LEN_BITS2) << 1;
197         lcv = 1 + hdrlen;
198         if (pack->bytes < lcv)
199             return;
200         for (i = hdrlen; i > 0; i--) {
201             duration <<= 8;
202             duration  |= (unsigned char)packet[i];
203         }
204         if (hdrlen > 0 && duration > 0) {
205             double pts;
206
207             if (pack->granulepos == -1)
208                 pack->granulepos = os->lastpos + os->lastsize;
209             pts    = (double)pack->granulepos / (double)os->samplerate;
210             endpts = 1.0 + pts + (double)duration / 1000.0;
211         }
212         sub_clear_text(&ogg_sub, MP_NOPTS_VALUE);
213         sub_add_text(&ogg_sub, &packet[lcv], pack->bytes - lcv, endpts, 1);
214     }
215
216     mp_msg(MSGT_DEMUX, MSGL_DBG2, "Ogg sub lines: %d  first: '%s'\n",
217             ogg_sub.lines, ogg_sub.text[0]);
218 #ifdef CONFIG_ICONV
219     subcp_recode(&ogg_sub);
220 #endif
221     vo_sub = &ogg_sub;
222     vo_osd_changed(OSDTYPE_SUBTITLE);
223 }
224
225
226 // get the logical stream of the current page
227 // fill os if non NULL and return the stream id
228 static int demux_ogg_get_page_stream(ogg_demuxer_t *ogg_d,
229                                      ogg_stream_state **os)
230 {
231     int id, s_no;
232     ogg_page *page = &ogg_d->page;
233
234     s_no = ogg_page_serialno(page);
235
236     for (id = 0; id < ogg_d->num_sub; id++)
237         if (s_no == ogg_d->subs[id].stream.serialno)
238             break;
239
240     if (id == ogg_d->num_sub) {
241         // If we have only one vorbis stream allow the stream id to change
242         // it's normal on radio stream (each song have an different id).
243         // But we (or the codec?) should check that the samplerate, etc
244         // doesn't change (for radio stream it's ok)
245         if (ogg_d->num_sub == 1 && ogg_d->subs[0].vorbis) {
246             ogg_stream_reset(&ogg_d->subs[0].stream);
247             ogg_stream_init(&ogg_d->subs[0].stream, s_no);
248             id = 0;
249         } else
250             return -1;
251     }
252
253     if (os)
254         *os = &ogg_d->subs[id].stream;
255
256     return id;
257 }
258
259 static unsigned char *demux_ogg_read_packet(ogg_stream_t *os, ogg_packet *pack,
260                                             double *pts, int *flags,
261                                             int samplesize)
262 {
263     unsigned char *data = pack->packet;
264
265     *pts = MP_NOPTS_VALUE;
266     *flags = 0;
267
268     if (os->vorbis) {
269         if (*pack->packet & PACKET_TYPE_HEADER) {
270             os->hdr_packets++;
271         } else {
272             vorbis_info *vi;
273             int32_t blocksize = 0;
274
275             // When we dump the audio, there is no vi, but we don't care of timestamp in this case
276             vi = os->vi_initialized ? &os->vi : NULL;
277             if (vi)
278                 blocksize = vorbis_packet_blocksize(vi, pack) / samplesize;
279             // Calculate the timestamp if the packet don't have any
280             if (pack->granulepos == -1) {
281                 pack->granulepos = os->lastpos;
282                 if (os->lastsize > 0)
283                     pack->granulepos += os->lastsize;
284             } else
285                 *flags = 1;
286             if (vi)
287                 *pts = pack->granulepos / (double)vi->rate;
288             os->lastsize = blocksize;
289             os->lastpos  = pack->granulepos;
290         }
291     } else if (os->speex) {
292         // whole packet (default)
293 # ifdef CONFIG_OGGTHEORA
294     } else if (os->theora) {
295         /* we pass complete packets to theora, mustn't strip the header! */
296         os->lastsize = 1;
297
298         /* header packets begin on 1-bit: thus check (*data&0x80).  We don't
299            have theora_state st, until all header packets were passed to the
300            decoder. */
301         if (!pack->bytes || !(*data&0x80)) {
302             int64_t iframemask = (1 << os->keyframe_granule_shift) - 1;
303
304             if (pack->granulepos >= 0) {
305                 os->lastpos  = pack->granulepos >> os->keyframe_granule_shift;
306                 os->lastpos += pack->granulepos & iframemask;
307                 *flags = (pack->granulepos & iframemask) == 0;
308             } else {
309                 os->lastpos++;
310             }
311             pack->granulepos = os->lastpos;
312             *pts = (double)os->lastpos / (double)os->samplerate;
313         }
314 #endif /* CONFIG_OGGTHEORA */
315     } else if (os->flac) {
316         /* we pass complete packets to flac, mustn't strip the header! */
317         if (os->flac == 2 && pack->packet[0] != 0xff)
318             return NULL;
319     } else {
320         if (*pack->packet & PACKET_TYPE_HEADER) {
321             os->hdr_packets++;
322         } else {
323             // Find data start
324             int16_t hdrlen = (*pack->packet & PACKET_LEN_BITS01) >> 6;
325
326             hdrlen |= (*pack->packet & PACKET_LEN_BITS2) << 1;
327             data = pack->packet + 1 + hdrlen;
328             // Calculate the timestamp
329             if (pack->granulepos == -1)
330                 pack->granulepos = os->lastpos + (os->lastsize ? os->lastsize : 1);
331             // If we already have a timestamp it can be a syncpoint
332             if (*pack->packet & PACKET_IS_SYNCPOINT)
333                 *flags = 1;
334             *pts = pack->granulepos / os->samplerate;
335             // Save the packet length and timestamp
336             os->lastsize = 0;
337             while (hdrlen) {
338                 os->lastsize <<= 8;
339                 os->lastsize  |= pack->packet[hdrlen];
340                 hdrlen--;
341             }
342             os->lastpos = pack->granulepos;
343         }
344     }
345     return data;
346 }
347
348 // check if clang has substring from comma separated langlist
349 static int demux_ogg_check_lang(const char *clang, const char *langlist)
350 {
351     const char *c;
352
353     if (!langlist || !*langlist)
354         return 0;
355     while ((c = strchr(langlist, ','))) {
356         if (!strncasecmp(clang, langlist, c - langlist))
357             return 1;
358         langlist = &c[1];
359     }
360     if (!strncasecmp(clang, langlist, strlen(langlist)))
361         return 1;
362     return 0;
363 }
364
365 /** \brief Change the current subtitle stream and return its ID.
366
367   \param demuxer The demuxer whose subtitle stream will be changed.
368   \param new_num The number of the new subtitle track. The number must be
369   between 0 and ogg_d->n_text - 1.
370
371   \returns The Ogg stream number ( = page serial number) of the newly selected
372   track.
373   */
374 static int demux_ogg_sub_id(demuxer_t *demuxer, int index)
375 {
376     ogg_demuxer_t *ogg_d = demuxer->priv;
377     return (index < 0) ? index : (index >= ogg_d->n_text) ? -1 : ogg_d->text_ids[index];
378 }
379
380 /** \brief Translate the ogg track number into the subtitle number.
381  *  \param demuxer The demuxer about whose subtitles we are inquiring.
382  *  \param id The ogg track number of the subtitle track.
383  */
384 static int demux_ogg_sub_reverse_id(demuxer_t *demuxer, int id)
385 {
386     ogg_demuxer_t *ogg_d = demuxer->priv;
387     int i;
388
389     for (i = 0; i < ogg_d->n_text; i++)
390         if (ogg_d->text_ids[i] == id)
391             return i;
392     return -1;
393 }
394
395 /// Try to print out comments and also check for LANGUAGE= tag
396 static void demux_ogg_check_comments(demuxer_t *d, ogg_stream_t *os,
397                                      int id, vorbis_comment *vc)
398 {
399     const char *hdr, *val;
400     char **cmt = vc->user_comments;
401     int index, i;
402     ogg_demuxer_t *ogg_d = d->priv;
403     static const struct table {
404         const char *ogg;
405         const char *mp;
406     } table[] = {
407         { "ENCODED_USING", "Software"      },
408         { "ENCODER_URL",   "Encoder URL"   },
409         { "TITLE",         "Title"         },
410         { "ARTIST",        "Artist"        },
411         { "COMMENT",       "Comments"      },
412         { "DATE",          "Creation Date" },
413         { "GENRE",         "Genre"         },
414         { "ALBUM",         "Album"         },
415         { "TRACKNUMBER",   "Track"         },
416         { NULL, NULL },
417     };
418
419     while (*cmt) {
420         hdr = NULL;
421         if (!strncasecmp(*cmt, "LANGUAGE=", 9)) {
422             val = *cmt + 9;
423             if (ogg_d->subs[id].text)
424                 mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_SID_%d_LANG=%s\n",
425                        ogg_d->subs[id].id, val);
426             else if (id != d->video->id)
427                 mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_AID_%d_LANG=%s\n",
428                        ogg_d->subs[id].id, val);
429             if (ogg_d->subs[id].text)
430                 mp_msg(MSGT_DEMUX, MSGL_INFO,
431                        "[Ogg] Language for -sid %d is '-slang \"%s\"'\n",
432                        ogg_d->subs[id].id, val);
433             // copy this language name into the array
434             index = demux_ogg_sub_reverse_id(d, id);
435             if (index >= 0) {
436                 sh_sub_t *sh;
437
438                 // in case of malicious files with more than one lang per track:
439                 free(ogg_d->text_langs[index]);
440                 ogg_d->text_langs[index] = strdup(val);
441                 sh = d->s_streams[index];
442                 if (sh)
443                     free(sh->lang);
444                 if (sh)
445                     sh->lang = strdup(val);
446             }
447             // check for -slang if subs are uninitialized yet
448             if (os->text && d->sub->id < 0 && demux_ogg_check_lang(val, dvdsub_lang)) {
449                 d->sub->id = index;
450                 dvdsub_id  = index;
451                 mp_msg(MSGT_DEMUX, MSGL_V,
452                        "Ogg demuxer: Displaying subtitle stream id %d which matched -slang %s\n",
453                        id, val);
454             }
455             else
456                 hdr = "Language";
457         }
458         else {
459             for (i = 0; table[i].ogg; i++) {
460                 if (!strncasecmp(*cmt, table[i].ogg, strlen(table[i].ogg)) &&
461                         (*cmt)[strlen(table[i].ogg)] == '=') {
462                     hdr = table[i].mp;
463                     val = *cmt + strlen(table[i].ogg) + 1;
464                 }
465             }
466         }
467         if (hdr)
468             demux_info_add(d, hdr, val);
469         mp_dbg(MSGT_DEMUX, MSGL_DBG2, " %s: %s\n", hdr, val);
470         cmt++;
471     }
472 }
473
474 /// Calculate the timestamp and add the packet to the demux stream
475 // return 1 if the packet was added, 0 otherwise
476 static int demux_ogg_add_packet(demux_stream_t *ds, ogg_stream_t *os,
477                                 int id, ogg_packet *pack)
478 {
479     demuxer_t *d = ds->demuxer;
480     demux_packet_t *dp;
481     unsigned char *data;
482     double pts = 0;
483     int flags = 0;
484     int samplesize = 1;
485
486     // If packet is an comment header then we try to get comments at first
487     if (pack->bytes >= 7 && !memcmp(pack->packet, "\003vorbis", 7)) {
488         vorbis_info vi;
489         vorbis_comment vc;
490
491         vorbis_info_init(&vi);
492         vorbis_comment_init(&vc);
493         vi.rate = 1L; // it's checked by vorbis_synthesis_headerin()
494         if (vorbis_synthesis_headerin(&vi, &vc, pack) == 0) // if no errors
495             demux_ogg_check_comments(d, os, id, &vc);
496         vorbis_comment_clear(&vc);
497         vorbis_info_clear(&vi);
498     }
499     if (os->text) {
500         if (id == demux_ogg_sub_id(d, d->sub->id)) // don't want to add subtitles to the demuxer for now
501             demux_ogg_add_sub(os, pack);
502         return 0;
503     }
504     if (os->speex) {
505         // discard first two packets, they contain the header and comment
506         if (os->hdr_packets < 2) {
507             os->hdr_packets++;
508             return 0;
509         }
510     } else {
511         // If packet is an header we jump it except for vorbis and theora
512         // (PACKET_TYPE_HEADER bit doesn't even exist for theora ?!)
513         // We jump nothing for FLAC. Ain't this great? Packet contents have to be
514         // handled differently for each and every stream type. The joy! The joy!
515         if (!os->flac && (*pack->packet & PACKET_TYPE_HEADER) &&
516                 (ds != d->audio || ((sh_audio_t*)ds->sh)->format != FOURCC_VORBIS || os->hdr_packets >= NUM_VORBIS_HDR_PACKETS ) &&
517                 (ds != d->video || (((sh_video_t*)ds->sh)->format != FOURCC_THEORA)))
518             return 0;
519     }
520
521     // For vorbis packet the packet is the data, for other codec we must jump
522     // the header
523     if (ds == d->audio && ((sh_audio_t*)ds->sh)->format == FOURCC_VORBIS) {
524         samplesize = ((sh_audio_t *)ds->sh)->samplesize;
525     }
526     data = demux_ogg_read_packet(os, pack, &pts, &flags, samplesize);
527     if (!data)
528         return 0;
529
530     /// Clear subtitles if necessary (for broken files)
531     if (sub_clear_text(&ogg_sub, pts)) {
532         vo_sub = &ogg_sub;
533         vo_osd_changed(OSDTYPE_SUBTITLE);
534     }
535     /// Send the packet
536     dp = new_demux_packet(pack->bytes - (data - pack->packet));
537     memcpy(dp->buffer, data, pack->bytes - (data - pack->packet));
538     dp->pts   = pts;
539     dp->flags = flags;
540     ds_add_packet(ds, dp);
541     mp_msg(MSGT_DEMUX, MSGL_DBG2,
542            "New dp: %p  ds=%p  pts=%5.3f  len=%d  flag=%d  \n",
543            dp, ds, pts, dp->len, flags);
544     return 1;
545 }
546
547 /// if -forceidx build a table of all syncpoints to make seeking easier
548 /// otherwise try to get at least the final_granulepos
549 static void demux_ogg_scan_stream(demuxer_t *demuxer)
550 {
551     ogg_demuxer_t *ogg_d = demuxer->priv;
552     stream_t      *s     = demuxer->stream;
553     ogg_sync_state *sync = &ogg_d->sync;
554     ogg_page       *page = &ogg_d->page;
555     ogg_stream_state *oss;
556     ogg_stream_t *os;
557     ogg_packet op;
558     int np, sid, p, samplesize = 1;
559     off_t pos, last_pos;
560
561     pos = last_pos = demuxer->movi_start;
562
563     // Reset the stream
564     stream_seek(s, demuxer->movi_start);
565     ogg_sync_reset(sync);
566
567     // Get the serial number of the stream we use
568     if (demuxer->video->id >= 0) {
569         sid = demuxer->video->id;
570     } else if (demuxer->audio->id >= 0) {
571         sid = demuxer->audio->id;
572         if (((sh_audio_t*)demuxer->audio->sh)->format == FOURCC_VORBIS)
573             samplesize = ((sh_audio_t*)demuxer->audio->sh)->samplesize;
574     } else
575         return;
576     os  = &ogg_d->subs[sid];
577     oss = &os->stream;
578
579     while (1) {
580         np = ogg_sync_pageseek(sync, page);
581         if (np < 0) { // We had to skip some bytes
582             if (index_mode == 2)
583                 mp_msg(MSGT_DEMUX, MSGL_ERR,
584                        "Bad page sync while building syncpoints table (%d)\n",
585                        -np);
586             pos += -np;
587             continue;
588         }
589         if (np <= 0) { // We need more data
590             char *buf = ogg_sync_buffer(sync, BLOCK_SIZE);
591             int len   = stream_read(s, buf, BLOCK_SIZE);
592
593             if (len == 0 && s->eof)
594                 break;
595             ogg_sync_wrote(sync, len);
596             continue;
597         }
598         // The page is ready
599         //ogg_sync_pageout(sync, page);
600         if (ogg_page_serialno(page) != os->stream.serialno) { // It isn't a page from the stream we want
601             pos += np;
602             continue;
603         }
604         if (ogg_stream_pagein(oss, page) != 0) {
605             mp_msg(MSGT_DEMUX, MSGL_ERR, "Pagein error ????\n");
606             pos += np;
607             continue;
608         }
609         p = 0;
610         while (ogg_stream_packetout(oss, &op) == 1) {
611             double pts;
612             int flags;
613
614             demux_ogg_read_packet(os, &op, &pts, &flags, samplesize);
615             if (op.granulepos >= 0) {
616                 ogg_d->final_granulepos = op.granulepos;
617                 if (ogg_d->initial_granulepos == MP_NOPTS_VALUE && (flags & 1)) {
618                     ogg_d->initial_granulepos = op.granulepos;
619                     if (index_mode != 2 && ogg_d->pos < demuxer->movi_end - 2 * 270000) {
620                         //the 270000 are just a wild guess
621                         stream_seek(s, FFMAX(ogg_d->pos, demuxer->movi_end - 270000));
622                         ogg_sync_reset(sync);
623                         continue;
624                     }
625                 }
626             }
627             if (index_mode == 2 && (flags || (os->vorbis && op.granulepos >= 0))) {
628                 if (ogg_d->num_syncpoint > SIZE_MAX / sizeof(ogg_syncpoint_t) - 1)
629                     break;
630                 ogg_d->syncpoints = realloc_struct(ogg_d->syncpoints, (ogg_d->num_syncpoint + 1), sizeof(ogg_syncpoint_t));
631                 ogg_d->syncpoints[ogg_d->num_syncpoint].granulepos = op.granulepos;
632                 ogg_d->syncpoints[ogg_d->num_syncpoint].page_pos   = (ogg_page_continued(page) && p == 0) ? last_pos : pos;
633                 ogg_d->num_syncpoint++;
634             }
635             p++;
636         }
637         if (p > 1 || (p == 1 && !ogg_page_continued(page)))
638             last_pos = pos;
639         pos += np;
640         if (index_mode == 2)
641             mp_msg(MSGT_DEMUX, MSGL_INFO, "Building syncpoint table %d%%\r",
642                    (int)(pos * 100 / s->end_pos));
643     }
644
645     if (index_mode == 2) {
646         mp_msg(MSGT_DEMUX, MSGL_INFO, "\n");
647         mp_msg(MSGT_DEMUX, MSGL_V,
648                "Ogg syncpoints table builed: %d syncpoints\n",
649                ogg_d->num_syncpoint);
650     }
651
652     mp_msg(MSGT_DEMUX, MSGL_V, "Ogg stream length (granulepos): %"PRId64"\n",
653            ogg_d->final_granulepos);
654
655     stream_reset(s);
656     stream_seek(s, demuxer->movi_start);
657     ogg_sync_reset(sync);
658     for (np = 0; np < ogg_d->num_sub; np++) {
659         ogg_stream_reset(&ogg_d->subs[np].stream);
660         ogg_d->subs[np].lastpos = ogg_d->subs[np].lastsize = ogg_d->subs[np].hdr_packets = 0;
661     }
662
663     // Get the first page
664     while (1) {
665         np = ogg_sync_pageout(sync, page);
666         if (np <= 0) { // We need more data
667             char *buf = ogg_sync_buffer(sync, BLOCK_SIZE);
668             int len = stream_read(s, buf, BLOCK_SIZE);
669
670             if (len == 0 && s->eof) {
671                 mp_msg(MSGT_DEMUX, MSGL_ERR, "EOF while trying to get the first page !!!!\n");
672                 break;
673             }
674             ogg_sync_wrote(sync, len);
675             continue;
676         }
677         demux_ogg_get_page_stream(ogg_d, &oss);
678         ogg_stream_pagein(oss, page);
679         break;
680     }
681 }
682
683 static void fixup_vorbis_wf(sh_audio_t *sh, ogg_demuxer_t *od)
684 {
685     int i, offset;
686     int ris, init_error = 0;
687     ogg_packet op[3];
688     unsigned char *buf[3];
689     unsigned char *ptr;
690     unsigned int len;
691     ogg_stream_t *os = &od->subs[sh->ds->id];
692     vorbis_comment vc;
693
694     vorbis_info_init(&os->vi);
695     vorbis_comment_init(&vc);
696     for (i = 0; i < 3; i++) {
697         op[i].bytes = ds_get_packet(sh->ds, &(op[i].packet));
698         mp_msg(MSGT_DEMUX, MSGL_V, "fixup_vorbis_wf: i=%d, size=%ld\n", i, op[i].bytes);
699         if (op[i].bytes < 0) {
700             mp_msg(MSGT_DEMUX, MSGL_ERR, "Ogg demuxer error!, fixup_vorbis_wf: bad packet n. %d\n", i);
701             return;
702         }
703         buf[i] = malloc(op[i].bytes);
704         if (!buf[i])
705             return;
706         memcpy(buf[i], op[i].packet, op[i].bytes);
707
708         op[i].b_o_s = (i == 0);
709         ris = vorbis_synthesis_headerin(&os->vi, &vc, &op[i]);
710         if (ris < 0) {
711             init_error = 1;
712             mp_msg(MSGT_DECAUDIO, MSGL_ERR, "DEMUX_OGG: header n. %d broken! len=%ld, code: %d\n", i, op[i].bytes, ris);
713         }
714     }
715     vorbis_comment_clear(&vc);
716     if (!init_error)
717         os->vi_initialized = 1;
718
719     len = op[0].bytes + op[1].bytes + op[2].bytes;
720     sh->wf = calloc(1, sizeof(*sh->wf) + len + len / 255 + 64);
721     ptr = (unsigned char*)(sh->wf + 1);
722
723     ptr[0] = 2;
724     offset = 1;
725     offset += store_ughvlc(&ptr[offset], op[0].bytes);
726     mp_msg(MSGT_DEMUX, MSGL_V, "demux_ogg, offset after 1st len = %u\n", offset);
727     offset += store_ughvlc(&ptr[offset], op[1].bytes);
728     mp_msg(MSGT_DEMUX, MSGL_V, "demux_ogg, offset after 2nd len = %u\n", offset);
729     for (i = 0; i < 3; i++) {
730         mp_msg(MSGT_DEMUX, MSGL_V, "demux_ogg, i=%d, bytes: %ld, offset: %u\n", i, op[i].bytes, offset);
731         memcpy(&ptr[offset], buf[i], op[i].bytes);
732         offset += op[i].bytes;
733     }
734     sh->wf->cbSize = offset;
735     mp_msg(MSGT_DEMUX, MSGL_V, "demux_ogg, extradata size: %d\n", sh->wf->cbSize);
736     sh->wf = realloc(sh->wf, sizeof(*sh->wf) + sh->wf->cbSize);
737
738     if (op[0].bytes >= 29) {
739         unsigned int br;
740         int nombr, minbr, maxbr;
741
742         ptr = buf[0];
743         sh->channels   = ptr[11];
744         sh->samplerate = sh->wf->nSamplesPerSec = AV_RL32(&ptr[12]);
745         maxbr = AV_RL32(&ptr[16]);  //max
746         nombr = AV_RL32(&ptr[20]);  //nominal
747         minbr = AV_RL32(&ptr[24]);  //minimum
748
749         if (maxbr == -1)
750             maxbr = 0;
751         if (nombr == -1)
752             nombr = 0;
753         if (minbr == -1)
754             minbr = 0;
755
756         br = maxbr / 8;
757         if (!br)
758             br = nombr / 8;
759         if (!br)
760             br = minbr / 8;
761         sh->wf->nAvgBytesPerSec = br;
762         sh->wf->wBitsPerSample  = 16;
763         sh->samplesize = (sh->wf->wBitsPerSample + 7) / 8;
764
765         mp_msg(MSGT_DEMUX, MSGL_V,
766                "demux_ogg, vorbis stream features are: channels: %d, srate: %d, bitrate: %d, max: %u, nominal: %u, min: %u\n",
767                sh->channels, sh->samplerate, sh->wf->nAvgBytesPerSec,
768                maxbr, nombr, minbr);
769     }
770     free(buf[2]);
771     free(buf[1]);
772     free(buf[0]);
773 }
774
775 /// Open an ogg physical stream
776 // Not static because it's used also in demuxer_avi.c
777 int demux_ogg_open(demuxer_t *demuxer)
778 {
779     ogg_demuxer_t *ogg_d;
780     stream_t *s;
781     char *buf;
782     int np, s_no, n_audio = 0, n_video = 0;
783     int audio_id = -1, video_id = -1, text_id = -1;
784     ogg_sync_state *sync;
785     ogg_page *page;
786     ogg_packet pack;
787     sh_audio_t *sh_a;
788     sh_video_t *sh_v;
789
790 #ifdef CONFIG_ICONV
791     subcp_open(NULL);
792 #endif
793
794     s = demuxer->stream;
795
796     demuxer->priv = ogg_d = calloc(1, sizeof(*ogg_d));
797     sync = &ogg_d->sync;
798     page = &ogg_d->page;
799
800     ogg_sync_init(sync);
801
802     while (1) {
803         /// Try to get a page
804         ogg_d->pos += ogg_d->last_size;
805         np = ogg_sync_pageseek(sync, page);
806         /// Error
807         if (np < 0) {
808             mp_msg(MSGT_DEMUX, MSGL_DBG2, "Ogg demuxer : Bad page sync\n");
809             goto err_out;
810         }
811         /// Need some more data
812         if (np == 0) {
813             int len;
814
815             buf = ogg_sync_buffer(sync, BLOCK_SIZE);
816             len = stream_read(s, buf, BLOCK_SIZE);
817             if (len == 0 && s->eof) {
818                 goto err_out;
819             }
820             ogg_sync_wrote(sync, len);
821             continue;
822         }
823         ogg_d->last_size = np;
824         // We got one page now
825
826         if (!ogg_page_bos(page)) { // It's not a beginning page
827             // Header parsing end here, we need to get the page otherwise it will be lost
828             int id = demux_ogg_get_page_stream(ogg_d, NULL);
829             if (id >= 0)
830                 ogg_stream_pagein(&ogg_d->subs[id].stream, page);
831             else
832                 mp_msg(MSGT_DEMUX, MSGL_ERR,
833                        "Ogg : Warning found none bos page from unknown stream %d\n",
834                        ogg_page_serialno(page));
835             break;
836         }
837
838         /// Init  the data structure needed for a logical stream
839         ogg_d->subs = realloc_struct(ogg_d->subs, ogg_d->num_sub+1,
840                                      sizeof(ogg_stream_t));
841         memset(&ogg_d->subs[ogg_d->num_sub], 0, sizeof(ogg_stream_t));
842         /// Get the stream serial number
843         s_no = ogg_page_serialno(page);
844         ogg_stream_init(&ogg_d->subs[ogg_d->num_sub].stream, s_no);
845         mp_msg(MSGT_DEMUX, MSGL_DBG2,
846                "Ogg : Found a stream with serial=%d\n", s_no);
847         // Take the first page
848         ogg_stream_pagein(&ogg_d->subs[ogg_d->num_sub].stream, page);
849         // Get first packet of the page
850         ogg_stream_packetout(&ogg_d->subs[ogg_d->num_sub].stream, &pack);
851
852         // Reset our vars
853         sh_a = NULL;
854         sh_v = NULL;
855
856         ogg_d->subs[ogg_d->num_sub].ogg_d = ogg_d;
857
858         // Check for Vorbis
859         if (pack.bytes >= 7 && !strncmp(&pack.packet[1], "vorbis", 6)) {
860             sh_a = new_sh_audio_aid(demuxer, ogg_d->num_sub, n_audio, NULL);
861             sh_a->format = FOURCC_VORBIS;
862             ogg_d->subs[ogg_d->num_sub].vorbis = 1;
863             ogg_d->subs[ogg_d->num_sub].id     = n_audio;
864             n_audio++;
865             mp_msg(MSGT_DEMUX, MSGL_INFO,
866                    "[Ogg] stream %d: audio (Vorbis), -aid %d\n",
867                    ogg_d->num_sub, n_audio - 1);
868         } else if (pack.bytes >= 80 && !strncmp(pack.packet, "Speex", 5)) {
869             sh_a = new_sh_audio_aid(demuxer, ogg_d->num_sub, n_audio, NULL);
870             sh_a->wf         = calloc(1, sizeof(*sh_a->wf) + pack.bytes);
871             sh_a->format     = FOURCC_SPEEX;
872             sh_a->samplerate = sh_a->wf->nSamplesPerSec = AV_RL32(&pack.packet[36]);
873             sh_a->channels   = sh_a->wf->nChannels = AV_RL32(&pack.packet[48]);
874             sh_a->wf->wFormatTag      = sh_a->format;
875             sh_a->wf->nAvgBytesPerSec = AV_RL32(&pack.packet[52]);
876             sh_a->wf->nBlockAlign     = 0;
877             sh_a->wf->wBitsPerSample  = 16;
878             sh_a->samplesize = 2;
879             sh_a->wf->cbSize = pack.bytes;
880             memcpy(&sh_a->wf[1], pack.packet, pack.bytes);
881
882             ogg_d->subs[ogg_d->num_sub].samplerate = sh_a->samplerate;
883             ogg_d->subs[ogg_d->num_sub].speex      = 1;
884             ogg_d->subs[ogg_d->num_sub].id         = n_audio;
885             n_audio++;
886             mp_msg(MSGT_DEMUX, MSGL_INFO,
887                    "[Ogg] stream %d: audio (Speex), -aid %d\n",
888                    ogg_d->num_sub, n_audio - 1);
889
890             // check for Theora
891 #ifdef CONFIG_OGGTHEORA
892         } else if (pack.bytes >= 7 && !strncmp (&pack.packet[1], "theora", 6)) {
893             int errorCode = 0;
894             th_info ti;
895             th_comment tc;
896             th_setup_info *tsi = NULL;
897
898             th_info_init (&ti);
899             th_comment_init (&tc);
900
901             errorCode = th_decode_headerin(&ti, &tc, &tsi, &pack);
902             if (errorCode < 0) {
903                 mp_msg(MSGT_DEMUX, MSGL_ERR,
904                        "Theora header parsing failed: %i \n", errorCode);
905             } else {
906                 sh_v = new_sh_video_vid(demuxer, ogg_d->num_sub, n_video);
907
908                 sh_v->bih = calloc(1, sizeof(*sh_v->bih));
909                 sh_v->bih->biSize        = sizeof(*sh_v->bih);
910                 sh_v->bih->biCompression = sh_v->format = FOURCC_THEORA;
911                 sh_v->fps = ((double)ti.fps_numerator) / (double)ti.fps_denominator;
912                 sh_v->frametime = ((double)ti.fps_denominator) / (double)ti.fps_numerator;
913                 sh_v->i_bps  = ti.target_bitrate / 8;
914                 sh_v->disp_w = sh_v->bih->biWidth  = ti.frame_width;
915                 sh_v->disp_h = sh_v->bih->biHeight = ti.frame_height;
916                 sh_v->bih->biBitCount  = 24;
917                 sh_v->bih->biPlanes    = 3;
918                 sh_v->bih->biSizeImage = ((sh_v->bih->biBitCount / 8) * sh_v->bih->biWidth * sh_v->bih->biHeight);
919                 ogg_d->subs[ogg_d->num_sub].samplerate               = sh_v->fps;
920                 ogg_d->subs[ogg_d->num_sub].theora                   = 1;
921                 ogg_d->subs[ogg_d->num_sub].keyframe_granule_shift   = ti.keyframe_granule_shift;
922                 ogg_d->subs[ogg_d->num_sub].id                       = n_video;
923                 n_video++;
924                 mp_msg(MSGT_DEMUX, MSGL_INFO,
925                        "[Ogg] stream %d: video (Theora v%d.%d.%d), -vid %d\n",
926                        ogg_d->num_sub,
927                        (int)ti.version_major,
928                        (int)ti.version_minor,
929                        (int)ti.version_subminor,
930                        n_video - 1);
931                 if (mp_msg_test(MSGT_HEADER, MSGL_V))
932                     print_video_header(sh_v->bih, MSGL_V);
933             }
934             th_comment_clear(&tc);
935             th_info_clear(&ti);
936             th_setup_free(tsi);
937 #endif /* CONFIG_OGGTHEORA */
938         } else if (pack.bytes >= 4 && !strncmp (&pack.packet[0], "fLaC", 4)) {
939             sh_a = new_sh_audio_aid(demuxer, ogg_d->num_sub, n_audio, NULL);
940             sh_a->format = mmioFOURCC('f', 'L', 'a', 'C');
941             ogg_d->subs[ogg_d->num_sub].id = n_audio;
942             n_audio++;
943             ogg_d->subs[ogg_d->num_sub].flac = 1;
944             sh_a->wf = NULL;
945             mp_msg(MSGT_DEMUX, MSGL_INFO,
946                    "[Ogg] stream %d: audio (FLAC), -aid %d\n",
947                    ogg_d->num_sub, n_audio - 1);
948         } else if (pack.bytes >= 51 && !strncmp(&pack.packet[1], "FLAC", 4)) {
949             sh_a = new_sh_audio_aid(demuxer, ogg_d->num_sub, n_audio, NULL);
950             sh_a->format = mmioFOURCC('f', 'L', 'a', 'C');
951             ogg_d->subs[ogg_d->num_sub].id = n_audio;
952             n_audio++;
953             ogg_d->subs[ogg_d->num_sub].flac = 2;
954             sh_a->wf = calloc(1, sizeof(*sh_a->wf) + 34);
955             sh_a->wf->wFormatTag = sh_a->format;
956             sh_a->wf->cbSize     = 34;
957             memcpy(&sh_a->wf[1], &pack.packet[17], 34);
958             mp_msg(MSGT_DEMUX, MSGL_INFO,
959                    "[Ogg] stream %d: audio (FLAC, try 2), -aid %d\n",
960                    ogg_d->num_sub, n_audio - 1);
961
962             /// Check for old header
963         } else if (pack.bytes >= 142 &&
964                    !strncmp(&pack.packet[1], "Direct Show Samples embedded in Ogg", 35)) {
965
966             // Old video header
967             if (AV_RL32(pack.packet + 96) == 0x05589f80 && pack.bytes >= 184) {
968                 sh_v = new_sh_video_vid(demuxer, ogg_d->num_sub, n_video);
969                 sh_v->bih = calloc(1, sizeof(*sh_v->bih));
970                 sh_v->bih->biSize        = sizeof(*sh_v->bih);
971                 sh_v->bih->biCompression = sh_v->format = mmioFOURCC(pack.packet[68], pack.packet[69],
972                                                                      pack.packet[70], pack.packet[71]);
973                 sh_v->frametime = AV_RL64(pack.packet + 164) * 0.0000001;
974                 sh_v->fps    = 1 / sh_v->frametime;
975                 sh_v->disp_w = sh_v->bih->biWidth = AV_RL32(pack.packet + 176);
976                 sh_v->disp_h = sh_v->bih->biHeight = AV_RL32(pack.packet + 180);
977                 sh_v->bih->biBitCount = AV_RL16(pack.packet + 182);
978                 if (!sh_v->bih->biBitCount)
979                     sh_v->bih->biBitCount = 24; // hack, FIXME
980                 sh_v->bih->biPlanes    = 1;
981                 sh_v->bih->biSizeImage = (sh_v->bih->biBitCount >> 3) * sh_v->bih->biWidth * sh_v->bih->biHeight;
982
983                 ogg_d->subs[ogg_d->num_sub].samplerate = sh_v->fps;
984                 ogg_d->subs[ogg_d->num_sub].id         = n_video;
985                 n_video++;
986                 mp_msg(MSGT_DEMUX, MSGL_INFO,
987                        "[Ogg] stream %d: video (FOURCC %c%c%c%c), -vid %d\n",
988                        ogg_d->num_sub, pack.packet[68], pack.packet[69],
989                        pack.packet[70], pack.packet[71], n_video - 1);
990                 if (mp_msg_test(MSGT_HEADER, MSGL_V))
991                     print_video_header(sh_v->bih, MSGL_V);
992                 // Old audio header
993             } else if (AV_RL32(pack.packet + 96) == 0x05589F81) {
994                 unsigned int extra_size;
995
996                 sh_a = new_sh_audio_aid(demuxer, ogg_d->num_sub, n_audio, NULL);
997                 extra_size = AV_RL16(pack.packet + 140);
998                 sh_a->wf         = calloc(1, sizeof(*sh_a->wf) + extra_size);
999                 sh_a->format     = sh_a->wf->wFormatTag     = AV_RL16(pack.packet + 124);
1000                 sh_a->channels   = sh_a->wf->nChannels      = AV_RL16(pack.packet + 126);
1001                 sh_a->samplerate = sh_a->wf->nSamplesPerSec = AV_RL32(pack.packet + 128);
1002                 sh_a->wf->nAvgBytesPerSec = AV_RL32(pack.packet + 132);
1003                 sh_a->wf->nBlockAlign     = AV_RL16(pack.packet + 136);
1004                 sh_a->wf->wBitsPerSample  = AV_RL16(pack.packet + 138);
1005                 sh_a->samplesize = (sh_a->wf->wBitsPerSample + 7) / 8;
1006                 sh_a->wf->cbSize = extra_size;
1007                 if (extra_size > 0)
1008                     memcpy(sh_a->wf + 1,
1009                            pack.packet + 142, extra_size);
1010
1011                 ogg_d->subs[ogg_d->num_sub].samplerate = sh_a->samplerate; // * sh_a->channels;
1012                 ogg_d->subs[ogg_d->num_sub].id         = n_audio;
1013                 n_audio++;
1014                 mp_msg(MSGT_DEMUX, MSGL_INFO,
1015                        "[Ogg] stream %d: audio (format 0x%04x), -aid %d\n",
1016                        ogg_d->num_sub, sh_a->format, n_audio - 1);
1017                 if (mp_msg_test(MSGT_HEADER, MSGL_V))
1018                     print_wave_header(sh_a->wf, MSGL_V);
1019             } else
1020                 mp_msg(MSGT_DEMUX, MSGL_WARN,
1021                        "Ogg stream %d contains an old header but the header type is unknown\n",
1022                        ogg_d->num_sub);
1023
1024             // Check new header
1025         } else if ((*pack.packet & PACKET_TYPE_BITS ) == PACKET_TYPE_HEADER &&
1026                    pack.bytes >= (int)sizeof(stream_header) + 1) {
1027             stream_header *st = (stream_header*)(pack.packet + 1);
1028             /// New video header
1029             if (strncmp(st->streamtype, "video", 5) == 0) {
1030                 sh_v = new_sh_video_vid(demuxer, ogg_d->num_sub, n_video);
1031                 sh_v->bih         = calloc(1, sizeof(*sh_v->bih));
1032                 sh_v->bih->biSize = sizeof(*sh_v->bih);
1033                 sh_v->bih->biCompression = sh_v->format = mmioFOURCC(st->subtype[0], st->subtype[1],
1034                                                                      st->subtype[2], st->subtype[3]);
1035                 sh_v->frametime = AV_RL64(&st->time_unit) * 0.0000001;
1036                 sh_v->fps       = 1.0 / sh_v->frametime;
1037                 sh_v->bih->biBitCount = AV_RL16(&st->bits_per_sample);
1038                 sh_v->disp_w = sh_v->bih->biWidth  = AV_RL32(&st->sh.video.width);
1039                 sh_v->disp_h = sh_v->bih->biHeight = AV_RL32(&st->sh.video.height);
1040                 if (!sh_v->bih->biBitCount)
1041                     sh_v->bih->biBitCount = 24; // hack, FIXME
1042                 sh_v->bih->biPlanes    = 1;
1043                 sh_v->bih->biSizeImage = (sh_v->bih->biBitCount >> 3) * sh_v->bih->biWidth * sh_v->bih->biHeight;
1044
1045                 ogg_d->subs[ogg_d->num_sub].samplerate = sh_v->fps;
1046                 ogg_d->subs[ogg_d->num_sub].id         = n_video;
1047                 n_video++;
1048                 mp_msg(MSGT_DEMUX, MSGL_INFO,
1049                        "[Ogg] stream %d: video (FOURCC %c%c%c%c), -vid %d\n",
1050                        ogg_d->num_sub, st->subtype[0], st->subtype[1],
1051                        st->subtype[2], st->subtype[3], n_video - 1);
1052                 if (mp_msg_test(MSGT_HEADER, MSGL_V))
1053                     print_video_header(sh_v->bih, MSGL_V);
1054                 /// New audio header
1055             } else if (strncmp(st->streamtype, "audio", 5) == 0) {
1056                 char buffer[5];
1057                 unsigned int extra_size = AV_RL32(&st->size) - sizeof(stream_header);
1058                 unsigned int extra_offset = 0;
1059
1060                 memcpy(buffer, st->subtype, 4);
1061                 buffer[4] = '\0';
1062
1063                 /* Nasty workaround. stream_header.size seems not to contain the real
1064                    size in all cases. There are four extra bytes that are unaccounted
1065                    for in front of the real codec initialization data _at least_ for
1066                    AAC. So far I've only seen those bytes being all 0, so we can
1067                    just skip them here. */
1068                 if ((strtol(buffer, NULL, 16) == 0xff) && (extra_size >= 4)) {
1069                     extra_size   -= 4;
1070                     extra_offset  = 4;
1071                 }
1072
1073                 sh_a = new_sh_audio_aid(demuxer, ogg_d->num_sub, n_audio, NULL);
1074                 sh_a->wf         = calloc(1, sizeof(*sh_a->wf) + extra_size);
1075                 sh_a->format     = sh_a->wf->wFormatTag = strtol(buffer, NULL, 16);
1076                 sh_a->channels   = sh_a->wf->nChannels  = AV_RL16(&st->sh.audio.channels);
1077                 sh_a->samplerate = sh_a->wf->nSamplesPerSec = AV_RL64(&st->samples_per_unit);
1078                 sh_a->wf->nAvgBytesPerSec = AV_RL32(&st->sh.audio.avgbytespersec);
1079                 sh_a->wf->nBlockAlign     = AV_RL16(&st->sh.audio.blockalign);
1080                 sh_a->wf->wBitsPerSample  = AV_RL16(&st->bits_per_sample);
1081                 sh_a->samplesize = (sh_a->wf->wBitsPerSample + 7) / 8;
1082                 sh_a->wf->cbSize = extra_size;
1083                 if (extra_size)
1084                     memcpy(sh_a->wf+1,
1085                            ((char *)(st+1))+extra_offset, extra_size);
1086
1087                 ogg_d->subs[ogg_d->num_sub].samplerate = sh_a->samplerate; // * sh_a->channels;
1088                 ogg_d->subs[ogg_d->num_sub].id = n_audio;
1089                 n_audio++;
1090                 mp_msg(MSGT_DEMUX, MSGL_INFO,
1091                        "[Ogg] stream %d: audio (format 0x%04x), -aid %d\n",
1092                        ogg_d->num_sub, sh_a->format, n_audio - 1);
1093                 if (mp_msg_test(MSGT_HEADER, MSGL_V))
1094                     print_wave_header(sh_a->wf, MSGL_V);
1095
1096                 /// Check for text (subtitles) header
1097             } else if (strncmp(st->streamtype, "text", 4) == 0) {
1098                 mp_msg(MSGT_DEMUX, MSGL_INFO,
1099                        "[Ogg] stream %d: subtitles (SRT-like text subtitles), -sid %d\n",
1100                        ogg_d->num_sub, ogg_d->n_text);
1101                 ogg_d->subs[ogg_d->num_sub].samplerate = AV_RL64(&st->time_unit) / 10;
1102                 ogg_d->subs[ogg_d->num_sub].text       = 1;
1103                 ogg_d->subs[ogg_d->num_sub].id         = ogg_d->n_text;
1104                 if (demuxer->sub->id == ogg_d->n_text)
1105                     text_id = ogg_d->num_sub;
1106                 new_sh_sub(demuxer, ogg_d->n_text, NULL);
1107                 ogg_d->n_text++;
1108                 ogg_d->text_ids = realloc_struct(ogg_d->text_ids, ogg_d->n_text, sizeof(*ogg_d->text_ids));
1109                 ogg_d->text_ids[ogg_d->n_text - 1] = ogg_d->num_sub;
1110                 ogg_d->text_langs = realloc_struct(ogg_d->text_langs, ogg_d->n_text, sizeof(*ogg_d->text_langs));
1111                 ogg_d->text_langs[ogg_d->n_text - 1] = NULL;
1112                 //// Unknown header type
1113             } else
1114                 mp_msg(MSGT_DEMUX, MSGL_ERR,
1115                        "Ogg stream %d has a header marker but is of an unknown type\n",
1116                        ogg_d->num_sub);
1117             /// Unknown (invalid ?) header
1118         } else
1119             mp_msg(MSGT_DEMUX, MSGL_ERR,
1120                    "Ogg stream %d is of an unknown type\n",
1121                    ogg_d->num_sub);
1122
1123         if (sh_a || sh_v) {
1124             demux_stream_t *ds = NULL;
1125             if (sh_a) {
1126                 // If the audio stream is not defined we took the first one
1127                 if (demuxer->audio->id == -1) {
1128                     demuxer->audio->id = n_audio - 1;
1129                     //if (sh_a->wf) print_wave_header(sh_a->wf, MSGL_INFO);
1130                 }
1131                 /// Is it the stream we want
1132                 if (demuxer->audio->id == n_audio - 1) {
1133                     demuxer->audio->sh = sh_a;
1134                     sh_a->ds = demuxer->audio;
1135                     ds = demuxer->audio;
1136                     audio_id = ogg_d->num_sub;
1137                 }
1138             }
1139             if (sh_v) {
1140                 /// Also for video
1141                 if (demuxer->video->id == -1) {
1142                     demuxer->video->id = n_video - 1;
1143                     //if (sh_v->bih) print_video_header(sh_v->bih, MSGL_INFO);
1144                 }
1145                 if (demuxer->video->id == n_video - 1) {
1146                     demuxer->video->sh = sh_v;
1147                     sh_v->ds = demuxer->video;
1148                     ds = demuxer->video;
1149                     video_id = ogg_d->num_sub;
1150                 }
1151             }
1152             /// Add the header packets if the stream isn't seekable
1153             if (ds && !s->end_pos) {
1154                 /// Finish the page, otherwise packets will be lost
1155                 do {
1156                     demux_ogg_add_packet(ds, &ogg_d->subs[ogg_d->num_sub],
1157                                          ogg_d->num_sub, &pack);
1158                 } while (ogg_stream_packetout(&ogg_d->subs[ogg_d->num_sub].stream, &pack) == 1);
1159             }
1160         }
1161         ogg_d->num_sub++;
1162     }
1163
1164     if (!n_video && !n_audio) {
1165         goto err_out;
1166     }
1167
1168     if (!n_video || video_id < 0)
1169         demuxer->video->id = -2;
1170     else
1171         demuxer->video->id = video_id;
1172     if (!n_audio || audio_id < 0)
1173         demuxer->audio->id = -2;
1174     else
1175         demuxer->audio->id = audio_id;
1176     /* Disable the subs only if there are no text streams at all.
1177        Otherwise the stream to display might be chosen later when the comment
1178        packet is encountered and the user used -slang instead of -sid. */
1179     if (!ogg_d->n_text)
1180         demuxer->sub->id = -2;
1181     else if (text_id >= 0) {
1182         demuxer->sub->id = text_id;
1183         mp_msg(MSGT_DEMUX, MSGL_V,
1184                "Ogg demuxer: Displaying subtitle stream id %d\n", text_id);
1185     }
1186
1187     ogg_d->final_granulepos   = 0;
1188     ogg_d->initial_granulepos = MP_NOPTS_VALUE;
1189     if (!s->end_pos) {
1190         demuxer->seekable = 0;
1191     } else {
1192         demuxer->movi_start = s->start_pos; // Needed for XCD (Ogg written in MODE2)
1193         demuxer->movi_end   = s->end_pos;
1194         demuxer->seekable   = 1;
1195         demux_ogg_scan_stream(demuxer);
1196     }
1197     if (ogg_d->initial_granulepos == MP_NOPTS_VALUE)
1198         ogg_d->initial_granulepos = 0;
1199     ogg_d->duration = ogg_d->final_granulepos - ogg_d->initial_granulepos;
1200
1201     mp_msg(MSGT_DEMUX, MSGL_V,
1202            "Ogg demuxer : found %d audio stream%s, %d video stream%s and %d text stream%s\n",
1203            n_audio, n_audio > 1 ? "s" : "",
1204            n_video, n_video > 1 ? "s" : "",
1205            ogg_d->n_text, ogg_d->n_text > 1 ? "s" : "");
1206
1207     sh_a = demuxer->audio->sh;
1208     if (sh_a && sh_a->format == FOURCC_VORBIS)
1209         fixup_vorbis_wf(sh_a, ogg_d);
1210
1211     return DEMUXER_TYPE_OGG;
1212
1213 err_out:
1214     return 0;
1215 }
1216
1217 static int demux_ogg_fill_buffer(demuxer_t *d, demux_stream_t *dsds)
1218 {
1219     ogg_demuxer_t *ogg_d;
1220     stream_t *s;
1221     demux_stream_t *ds;
1222     ogg_sync_state *sync;
1223     ogg_stream_state *os;
1224     ogg_page *page;
1225     ogg_packet pack;
1226     int np = 0, id=0;
1227
1228     s = d->stream;
1229     ogg_d = d->priv;
1230     sync = &ogg_d->sync;
1231     page = &ogg_d->page;
1232
1233     /// Find the stream we are working on
1234     if ((id = demux_ogg_get_page_stream(ogg_d, &os)) < 0) {
1235         mp_msg(MSGT_DEMUX, MSGL_ERR, "Ogg demuxer : can't get current stream\n");
1236         return 0;
1237     }
1238
1239     while (1) {
1240         np = 0;
1241         ds = NULL;
1242         /// Try to get some packet from the current page
1243         while ((np = ogg_stream_packetout(os, &pack)) != 1) {
1244             /// No packet we go the next page
1245             if (np == 0) {
1246                 while (1) {
1247                     int pa, len;
1248                     char *buf;
1249
1250                     ogg_d->pos += ogg_d->last_size;
1251                     /// Get the next page from the physical stream
1252                     while ((pa = ogg_sync_pageseek(sync, page)) <= 0) {
1253                         /// Error : we skip some bytes
1254                         if (pa < 0) {
1255                             mp_msg(MSGT_DEMUX, MSGL_WARN,
1256                                    "Ogg : Page out not synced, we skip some bytes\n");
1257                             ogg_d->pos -= pa;
1258                             continue;
1259                         }
1260                         /// We need more data
1261                         buf = ogg_sync_buffer(sync, BLOCK_SIZE);
1262                         len = stream_read(s, buf, BLOCK_SIZE);
1263                         if (len == 0 && s->eof) {
1264                             mp_msg(MSGT_DEMUX, MSGL_DBG2, "Ogg : Stream EOF !!!!\n");
1265                             return 0;
1266                         }
1267                         ogg_sync_wrote(sync, len);
1268                     } /// Page loop
1269                     ogg_d->last_size = pa;
1270                     /// Find the page's logical stream
1271                     if ((id = demux_ogg_get_page_stream(ogg_d, &os)) < 0) {
1272                         mp_msg(MSGT_DEMUX, MSGL_ERR,
1273                                "Ogg demuxer error : we met an unknown stream\n");
1274                         return 0;
1275                     }
1276                     /// Take the page
1277                     if (ogg_stream_pagein(os, page) == 0)
1278                         break;
1279                     /// Page was invalid => retry
1280                     mp_msg(MSGT_DEMUX, MSGL_WARN,
1281                            "Ogg demuxer : got invalid page !!!!!\n");
1282                     ogg_d->pos += ogg_d->last_size;
1283                 }
1284             } else /// Packet was corrupted
1285                 mp_msg(MSGT_DEMUX, MSGL_WARN,
1286                        "Ogg : bad packet in stream %d\n", id);
1287         } /// Packet loop
1288
1289         /// Is the actual logical stream in use ?
1290         if (id == d->audio->id)
1291             ds = d->audio;
1292         else if (id == d->video->id)
1293             ds = d->video;
1294         else if (ogg_d->subs[id].text)
1295             ds = d->sub;
1296
1297         if (ds) {
1298             if (!demux_ogg_add_packet(ds, &ogg_d->subs[id], id, &pack))
1299                 continue; /// Unuseful packet, get another
1300             d->filepos = ogg_d->pos;
1301             return 1;
1302         }
1303     } /// while (1)
1304 }
1305
1306 /// For avi with Ogg audio stream we have to create an ogg demuxer for this
1307 // stream, then we join the avi and ogg demuxer with a demuxers demuxer
1308 demuxer_t *init_avi_with_ogg(demuxer_t *demuxer)
1309 {
1310     demuxer_t *od;
1311     ogg_demuxer_t *ogg_d;
1312     stream_t *s;
1313     uint32_t hdrsizes[3];
1314     demux_packet_t *dp;
1315     sh_audio_t *sh_audio = demuxer->audio->sh;
1316     int np;
1317     uint8_t *extradata = (uint8_t *)(sh_audio->wf + 1);
1318     int i;
1319     unsigned char *p = NULL, *buf;
1320     int plen;
1321
1322     /// Check that the cbSize is big enough for the following reads
1323     if (sh_audio->wf->cbSize < 22 + 3 * 4) {
1324         mp_msg(MSGT_DEMUX, MSGL_ERR,
1325                "AVI Ogg : Initial audio header is too small !!!!!\n");
1326         goto fallback;
1327     }
1328     /// Get the size of the 3 header packet
1329     extradata += 22;
1330     for (i = 0; i < 3; i++) {
1331         hdrsizes[i] = AV_RL32(extradata);
1332         extradata += 4;
1333     }
1334     //  printf("\n!!!!!! hdr sizes: %d %d %d   \n", hdrsizes[0], hdrsizes[1], hdrsizes[2]);
1335
1336     /// Check the size
1337     if (sh_audio->wf->cbSize < 22 + 3 * 4 + hdrsizes[0] + hdrsizes[1] + hdrsizes[2]) {
1338         mp_msg(MSGT_DEMUX, MSGL_ERR,
1339                "AVI Ogg : Audio header is too small !!!!!\n");
1340         goto fallback;
1341     }
1342
1343     // Build the ogg demuxer private datas
1344     ogg_d = calloc(1, sizeof(*ogg_d));
1345     ogg_d->num_sub = 1;
1346     ogg_d->subs    = malloc(sizeof(*ogg_d->subs));
1347     ogg_d->subs[0].vorbis = 1;
1348
1349     // Init the ogg physical stream
1350     ogg_sync_init(&ogg_d->sync);
1351
1352     // Get the first page of the stream : we assume there only 1 logical stream
1353     while ((np = ogg_sync_pageout(&ogg_d->sync, &ogg_d->page)) <= 0 ) {
1354         if (np < 0) {
1355             mp_msg(MSGT_DEMUX, MSGL_ERR,
1356                    "AVI Ogg error : Can't init using first stream packets\n");
1357             free(ogg_d);
1358             goto fallback;
1359         }
1360         // Add some data
1361         plen = ds_get_packet(demuxer->audio, &p);
1362         buf  = ogg_sync_buffer(&ogg_d->sync, plen);
1363         memcpy(buf, p, plen);
1364         ogg_sync_wrote(&ogg_d->sync, plen);
1365     }
1366     // Init the logical stream
1367     mp_msg(MSGT_DEMUX, MSGL_DBG2,
1368            "AVI Ogg found page with serial %d\n",
1369            ogg_page_serialno(&ogg_d->page));
1370     ogg_stream_init(&ogg_d->subs[0].stream, ogg_page_serialno(&ogg_d->page));
1371     // Write the page
1372     ogg_stream_pagein(&ogg_d->subs[0].stream, &ogg_d->page);
1373
1374     // Create the ds_stream and the ogg demuxer
1375     s = new_ds_stream(demuxer->audio);
1376     od = new_demuxer(s, DEMUXER_TYPE_OGG, 0, -2, -2, NULL);
1377
1378     /// Add the header packets in the ogg demuxer audio stream
1379     for (i = 0; i < 3; i++) {
1380         dp = new_demux_packet(hdrsizes[i]);
1381         memcpy(dp->buffer, extradata, hdrsizes[i]);
1382         ds_add_packet(od->audio, dp);
1383         extradata += hdrsizes[i];
1384     }
1385
1386     // Finish setting up the ogg demuxer
1387     od->priv = ogg_d;
1388     sh_audio = new_sh_audio(od, 0, NULL);
1389     od->audio->id = 0;
1390     od->video->id = -2;
1391     od->audio->sh = sh_audio;
1392     sh_audio->ds     = od->audio;
1393     sh_audio->format = FOURCC_VORBIS;
1394     fixup_vorbis_wf(sh_audio, ogg_d);
1395
1396     /// Return the joined demuxers
1397     return new_demuxers_demuxer(demuxer, od, demuxer);
1398
1399 fallback:
1400     demuxer->audio->id = -2;
1401     return demuxer;
1402
1403 }
1404
1405 static void demux_ogg_seek(demuxer_t *demuxer, float rel_seek_secs,
1406                            float audio_delay, int flags)
1407 {
1408     ogg_demuxer_t *ogg_d = demuxer->priv;
1409     ogg_sync_state *sync = &ogg_d->sync;
1410     ogg_page* page= &ogg_d->page;
1411     ogg_stream_state *oss;
1412     ogg_stream_t *os;
1413     demux_stream_t *ds;
1414     ogg_packet op;
1415     double rate;
1416     int i, sp, first, precision = 1, do_seek = 1;
1417     vorbis_info *vi = NULL;
1418     int64_t gp = 0, old_gp;
1419     off_t pos, old_pos;
1420     int np;
1421     int is_gp_valid;
1422     double pts;
1423     int is_keyframe;
1424     int samplesize = 1;
1425     ogg_int64_t granulepos_orig;
1426
1427     if (demuxer->video->id >= 0) {
1428         ds   = demuxer->video;
1429         rate = ogg_d->subs[ds->id].samplerate;
1430     } else {
1431         ds         = demuxer->audio;
1432         os         = &ogg_d->subs[ds->id];
1433         vi         = &(os->vi);
1434         rate       = vi->rate;
1435         samplesize = ((sh_audio_t*)ds->sh)->samplesize;
1436     }
1437
1438     os  = &ogg_d->subs[ds->id];
1439     oss = &os->stream;
1440
1441     old_gp  = os->lastpos;
1442     old_pos = ogg_d->pos;
1443
1444     //calculate the granulepos to seek to
1445     gp = flags & SEEK_ABSOLUTE ? ogg_d->initial_granulepos : os->lastpos;
1446     if (flags & SEEK_FACTOR) {
1447         if (ogg_d->duration > 0)
1448             gp += ogg_d->duration * rel_seek_secs;
1449         else
1450             gp += rel_seek_secs * (demuxer->movi_end - demuxer->movi_start) * os->lastpos / ogg_d->pos;
1451     } else
1452         gp += rel_seek_secs * rate;
1453     if (gp < 0)
1454         gp = 0;
1455
1456     //calculate the filepos to seek to
1457     if (ogg_d->syncpoints) {
1458         for (sp = 0; sp < ogg_d->num_syncpoint; sp++)
1459             if (ogg_d->syncpoints[sp].granulepos >= gp)
1460                 break;
1461
1462         if (sp >= ogg_d->num_syncpoint)
1463             return;
1464         if (sp > 0 && ogg_d->syncpoints[sp].granulepos - gp > gp - ogg_d->syncpoints[sp - 1].granulepos)
1465             sp--;
1466         if (ogg_d->syncpoints[sp].granulepos == os->lastpos) {
1467             if (sp > 0 && gp < os->lastpos)
1468                 sp--;
1469             if (sp < ogg_d->num_syncpoint - 1 && gp > os->lastpos)
1470                 sp++;
1471         }
1472         pos = ogg_d->syncpoints[sp].page_pos;
1473         precision = 0;
1474     } else {
1475         pos = flags & SEEK_ABSOLUTE ? 0 : ogg_d->pos;
1476         if (flags & SEEK_FACTOR)
1477             pos += (demuxer->movi_end - demuxer->movi_start) * rel_seek_secs;
1478         else {
1479             if (ogg_d->duration > 0) {
1480                 pos += rel_seek_secs * (demuxer->movi_end - demuxer->movi_start) / (ogg_d->duration / rate);
1481             } else if (os->lastpos > 0) {
1482                 pos += rel_seek_secs * ogg_d->pos / (os->lastpos / rate);
1483             }
1484         }
1485         if (pos < 0)
1486             pos = 0;
1487         if (pos > (demuxer->movi_end - demuxer->movi_start))
1488             pos = demuxer->movi_end - demuxer->movi_start;
1489     } // if (ogg_d->syncpoints)
1490
1491     while (1) {
1492         if (do_seek) {
1493             stream_seek(demuxer->stream, pos+demuxer->movi_start);
1494             ogg_sync_reset(sync);
1495             for (i = 0; i < ogg_d->num_sub; i++) {
1496                 ogg_stream_reset(&ogg_d->subs[i].stream);
1497                 ogg_d->subs[i].lastpos = ogg_d->subs[i].lastsize = 0;
1498             }
1499             ogg_d->pos = pos;
1500             ogg_d->last_size = 0;
1501             /* we just guess that we reached correct granulepos, in case a
1502                subsequent search occurs before we read a valid granulepos */
1503             os->lastpos = gp;
1504             first = !(ogg_d->syncpoints);
1505             do_seek=0;
1506         }
1507         ogg_d->pos += ogg_d->last_size;
1508         ogg_d->last_size = 0;
1509         np = ogg_sync_pageseek(sync, page);
1510
1511         if (np < 0)
1512             ogg_d->pos -= np;
1513         if (np <= 0) { // We need more data
1514             char *buf = ogg_sync_buffer(sync, BLOCK_SIZE);
1515             int len = stream_read(demuxer->stream, buf, BLOCK_SIZE);
1516
1517             if (len == 0 && demuxer->stream->eof) {
1518                 mp_msg(MSGT_DEMUX, MSGL_V, "EOF while trying to seek !!!!\n");
1519                 return;
1520             }
1521             ogg_sync_wrote(sync, len);
1522             continue;
1523         }
1524         ogg_d->last_size = np;
1525         if (ogg_page_serialno(page) != oss->serialno)
1526             continue;
1527
1528         if (ogg_stream_pagein(oss, page) != 0)
1529             continue;
1530
1531         while (1) {
1532             np = ogg_stream_packetout(oss, &op);
1533             if (np < 0)
1534                 continue;
1535             else if (np == 0)
1536                 break;
1537             if (first) { /* Discard the first packet as it's probably broken,
1538                             and we don't have any other means to decide whether it is
1539                             complete or not. */
1540                 first = 0;
1541                 break;
1542             }
1543             is_gp_valid = (op.granulepos >= 0);
1544             granulepos_orig=op.granulepos;
1545             demux_ogg_read_packet(os, &op, &pts, &is_keyframe, samplesize);
1546             if (precision && is_gp_valid) {
1547                 precision--;
1548                 if (abs(gp - op.granulepos) > rate && (op.granulepos != old_gp)) {
1549                     //prepare another seek because we are off by more than 1s
1550                     pos += (gp - op.granulepos) * (pos - old_pos) / (op.granulepos - old_gp);
1551                     if (pos < 0)
1552                         pos = 0;
1553                     if (pos < demuxer->movi_end - demuxer->movi_start) {
1554                         do_seek=1;
1555                         break;
1556                     }
1557                 }
1558             }
1559             if (is_gp_valid && pos > 0 && old_gp > gp
1560                     && 2 * (old_gp - op.granulepos) < old_gp - gp) {
1561                 /* prepare another seek because looking for a syncpoint
1562                    destroyed the backward search */
1563                 pos = old_pos - 1.5 * (old_pos - pos);
1564                 if (pos < 0)
1565                     pos = 0;
1566                 if (pos < demuxer->movi_end - demuxer->movi_start) {
1567                     do_seek=1;
1568                     break;
1569                 }
1570             }
1571             if (!precision && (is_keyframe || os->vorbis || os->speex)) {
1572                 if (sub_clear_text(&ogg_sub, MP_NOPTS_VALUE)) {
1573                     vo_sub = &ogg_sub;
1574                     vo_osd_changed(OSDTYPE_SUBTITLE);
1575                 }
1576                 op.granulepos=granulepos_orig;
1577                 demux_ogg_add_packet(ds, os, ds->id, &op);
1578                 return;
1579             }
1580         }
1581     }
1582
1583     mp_msg(MSGT_DEMUX, MSGL_ERR, "Can't find the good packet :(\n");
1584 }
1585
1586 static void demux_close_ogg(demuxer_t *demuxer)
1587 {
1588     ogg_demuxer_t *ogg_d = demuxer->priv;
1589     ogg_stream_t *os = NULL;
1590     int i;
1591
1592     if (!ogg_d)
1593         return;
1594
1595 #ifdef CONFIG_ICONV
1596     subcp_close();
1597 #endif
1598
1599     ogg_sync_clear(&ogg_d->sync);
1600     if (ogg_d->subs) {
1601         for (i = 0; i < ogg_d->num_sub; i++) {
1602             os = &ogg_d->subs[i];
1603             ogg_stream_clear(&os->stream);
1604             if (os->vi_initialized)
1605                 vorbis_info_clear(&os->vi);
1606         }
1607         free(ogg_d->subs);
1608     }
1609     free(ogg_d->syncpoints);
1610     free(ogg_d->text_ids);
1611     if (ogg_d->text_langs) {
1612         for (i = 0; i < ogg_d->n_text; i++)
1613             free(ogg_d->text_langs[i]);
1614         free(ogg_d->text_langs);
1615     }
1616     free(ogg_d);
1617 }
1618
1619 static int demux_ogg_control(demuxer_t *demuxer, int cmd, void *arg)
1620 {
1621     ogg_demuxer_t *ogg_d = demuxer->priv;
1622     ogg_stream_t *os;
1623     double rate;
1624
1625     if (demuxer->video->id >= 0) {
1626         os = &ogg_d->subs[demuxer->video->id];
1627         rate = os->samplerate;
1628     } else {
1629         os = &ogg_d->subs[demuxer->audio->id];
1630         rate = os->vi.rate;
1631     }
1632
1633     switch(cmd) {
1634         case DEMUXER_CTRL_GET_TIME_LENGTH:
1635             if (ogg_d->duration <= 0)
1636                 return DEMUXER_CTRL_DONTKNOW;
1637             *(double *)arg = (double)(ogg_d->duration) / rate;
1638             return DEMUXER_CTRL_GUESS;
1639
1640         case DEMUXER_CTRL_GET_PERCENT_POS:
1641             if (ogg_d->duration <= 0)
1642                 return DEMUXER_CTRL_DONTKNOW;
1643             *(int *)arg = ((os->lastpos - ogg_d->initial_granulepos) * 100) / ogg_d->duration;
1644             return DEMUXER_CTRL_OK;
1645
1646         default:
1647             return DEMUXER_CTRL_NOTIMPL;
1648     }
1649 }
1650
1651 const demuxer_desc_t demuxer_desc_ogg = {
1652     "Ogg demuxer",
1653     "ogg",
1654     "Ogg",
1655     "?",
1656     "",
1657     DEMUXER_TYPE_OGG,
1658     1, // safe autodetect
1659     demux_ogg_open,
1660     demux_ogg_fill_buffer,
1661     NULL,
1662     demux_close_ogg,
1663     demux_ogg_seek,
1664     demux_ogg_control
1665 };