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