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.
30 #include "stream/stream.h"
33 #include "ffmpeg_files/intreadwrite.h"
35 #include "demux_mov.h"
36 #include "demux_ogg.h"
38 #define FOURCC_VORBIS mmioFOURCC('v', 'r', 'b', 's')
39 #define FOURCC_SPEEX mmioFOURCC('s', 'p', 'x', ' ')
40 #define FOURCC_THEORA mmioFOURCC('t', 'h', 'e', 'o')
43 #include <tremor/ogg.h>
44 #include <tremor/ivorbiscodec.h>
47 #include <vorbis/codec.h>
50 #ifdef CONFIG_OGGTHEORA
51 #include <theora/theora.h>
52 int _ilog (unsigned int); /* defined in many places in theora/lib/ */
55 #define BLOCK_SIZE 4096
57 /* Theora decoder context : we won't be able to interpret granule positions
58 * without using theora_granule_time with the theora_state of the stream.
59 * This is duplicated in `vd_theora.c'; put this in a common header?
61 #ifdef CONFIG_OGGTHEORA
62 typedef struct theora_struct_st
{
70 // Header for the new header format
71 typedef struct stream_header_video
{
74 } stream_header_video
;
76 typedef struct stream_header_audio
{
78 ogg_int16_t blockalign
;
79 ogg_int32_t avgbytespersec
;
80 } stream_header_audio
;
82 typedef struct __attribute__((__packed__
)) stream_header
{
86 ogg_int32_t size
; // size of the structure
88 ogg_int64_t time_unit
; // in reference time
89 ogg_int64_t samples_per_unit
;
90 ogg_int32_t default_len
; // in media time
92 ogg_int32_t buffersize
;
93 ogg_int16_t bits_per_sample
;
99 stream_header_video video
;
101 stream_header_audio audio
;
105 /// Our private datas
107 typedef struct ogg_syncpoint
{
113 typedef struct ogg_stream
{
114 /// Timestamping stuff
115 float samplerate
; /// granulpos 2 time
118 int keyframe_frequency_force
;
120 // Logical stream state
121 ogg_stream_state stream
;
136 typedef struct ogg_demuxer
{
137 /// Physical stream state
144 ogg_syncpoint_t
*syncpoints
;
146 off_t pos
, last_size
;
147 int64_t initial_granulepos
;
148 int64_t final_granulepos
;
151 /* Used for subtitle switching. */
157 #define NUM_VORBIS_HDR_PACKETS 3
159 /// Some defines from OggDS
160 #define PACKET_TYPE_HEADER 0x01
161 #define PACKET_TYPE_BITS 0x07
162 #define PACKET_LEN_BITS01 0xc0
163 #define PACKET_LEN_BITS2 0x02
164 #define PACKET_IS_SYNCPOINT 0x08
166 extern char *dvdsub_lang
, *audio_lang
;
168 //-------- subtitle support - should be moved to decoder layer, and queue
169 // - subtitles up in demuxer buffer...
171 #include "subreader.h"
172 #include "libvo/sub.h"
173 #define OGG_SUB_MAX_LINE 128
175 static subtitle ogg_sub
;
178 static void demux_ogg_add_sub(ogg_stream_t
*os
, ogg_packet
*pack
)
181 char *packet
= pack
->packet
;
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],
191 if (((unsigned char)packet
[0]) == 0x88) { // some subtitle text
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;
199 if (pack
->bytes
< lcv
)
201 for (i
= hdrlen
; i
> 0; i
--) {
203 duration
|= (unsigned char)packet
[i
];
205 if (hdrlen
> 0 && duration
> 0) {
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]);
220 subcp_recode(&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
)
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
)
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
);
255 *os
= &ogg_d
->subs
[id
].stream
;
260 static unsigned char *demux_ogg_read_packet(ogg_stream_t
*os
, ogg_packet
*pack
,
261 float *pts
, int *flags
,
264 unsigned char *data
= pack
->packet
;
265 int size
= pack
->bytes
;
267 *pts
= MP_NOPTS_VALUE
;
271 if (*pack
->packet
& PACKET_TYPE_HEADER
) {
275 int32_t blocksize
= 0;
277 // When we dump the audio, there is no vi, but we don't care of timestamp in this case
278 vi
= os
->vi_initialized
? &os
->vi
: NULL
;
280 blocksize
= vorbis_packet_blocksize(vi
, pack
) / samplesize
;
281 // Calculate the timestamp if the packet don't have any
282 if (pack
->granulepos
== -1) {
283 pack
->granulepos
= os
->lastpos
;
284 if (os
->lastsize
> 0)
285 pack
->granulepos
+= os
->lastsize
;
289 *pts
= pack
->granulepos
/ (float)vi
->rate
;
290 os
->lastsize
= blocksize
;
291 os
->lastpos
= pack
->granulepos
;
293 } else if (os
->speex
) {
294 // whole packet (default)
295 # ifdef CONFIG_OGGTHEORA
296 } else if (os
->theora
) {
297 /* we pass complete packets to theora, mustn't strip the header! */
300 /* header packets begin on 1-bit: thus check (*data&0x80). We don't
301 have theora_state st, until all header packets were passed to the
303 if (!size
|| !(*data
&0x80)) {
304 int keyframe_granule_shift
= _ilog(os
->keyframe_frequency_force
- 1);
305 int64_t iframemask
= (1 << keyframe_granule_shift
) - 1;
307 if (pack
->granulepos
>= 0) {
308 os
->lastpos
= pack
->granulepos
>> keyframe_granule_shift
;
309 os
->lastpos
+= pack
->granulepos
& iframemask
;
310 *flags
= (pack
->granulepos
& iframemask
) == 0;
314 pack
->granulepos
= os
->lastpos
;
315 *pts
= (double)os
->lastpos
/ (double)os
->samplerate
;
317 #endif /* CONFIG_OGGTHEORA */
318 } else if (os
->flac
) {
319 /* we pass complete packets to flac, mustn't strip the header! */
320 if (os
->flac
== 2 && pack
->packet
[0] != 0xff)
323 if (*pack
->packet
& PACKET_TYPE_HEADER
) {
327 int16_t hdrlen
= (*pack
->packet
& PACKET_LEN_BITS01
) >> 6;
329 hdrlen
|= (*pack
->packet
& PACKET_LEN_BITS2
) << 1;
330 data
= pack
->packet
+ 1 + hdrlen
;
331 // Calculate the timestamp
332 if (pack
->granulepos
== -1)
333 pack
->granulepos
= os
->lastpos
+ (os
->lastsize
? os
->lastsize
: 1);
334 // If we already have a timestamp it can be a syncpoint
335 if (*pack
->packet
& PACKET_IS_SYNCPOINT
)
337 *pts
= pack
->granulepos
/ os
->samplerate
;
338 // Save the packet length and timestamp
342 os
->lastsize
|= pack
->packet
[hdrlen
];
345 os
->lastpos
= pack
->granulepos
;
351 // check if clang has substring from comma separated langlist
352 static int demux_ogg_check_lang(const char *clang
, const char *langlist
)
356 if (!langlist
|| !*langlist
)
358 while ((c
= strchr(langlist
, ','))) {
359 if (!strncasecmp(clang
, langlist
, c
- langlist
))
363 if (!strncasecmp(clang
, langlist
, strlen(langlist
)))
368 /** \brief Change the current subtitle stream and return its ID.
370 \param demuxer The demuxer whose subtitle stream will be changed.
371 \param new_num The number of the new subtitle track. The number must be
372 between 0 and ogg_d->n_text - 1.
374 \returns The Ogg stream number ( = page serial number) of the newly selected
377 static int demux_ogg_sub_id(demuxer_t
*demuxer
, int index
)
379 ogg_demuxer_t
*ogg_d
= demuxer
->priv
;
380 return (index
< 0) ? index
: (index
>= ogg_d
->n_text
) ? -1 : ogg_d
->text_ids
[index
];
383 /** \brief Translate the ogg track number into the subtitle number.
384 * \param demuxer The demuxer about whose subtitles we are inquiring.
385 * \param id The ogg track number of the subtitle track.
387 static int demux_ogg_sub_reverse_id(demuxer_t
*demuxer
, int id
)
389 ogg_demuxer_t
*ogg_d
= demuxer
->priv
;
392 for (i
= 0; i
< ogg_d
->n_text
; i
++)
393 if (ogg_d
->text_ids
[i
] == id
)
398 /// Try to print out comments and also check for LANGUAGE= tag
399 static void demux_ogg_check_comments(demuxer_t
*d
, ogg_stream_t
*os
,
400 int id
, vorbis_comment
*vc
)
402 const char *hdr
, *val
;
403 char **cmt
= vc
->user_comments
;
405 ogg_demuxer_t
*ogg_d
= d
->priv
;
406 static const struct table
{
410 { "ENCODED_USING", "Software" },
411 { "ENCODER_URL", "Encoder URL" },
412 { "TITLE", "Title" },
413 { "ARTIST", "Artist" },
414 { "COMMENT", "Comments" },
415 { "DATE", "Creation Date" },
416 { "GENRE", "Genre" },
417 { "ALBUM", "Album" },
418 { "TRACKNUMBER", "Track" },
424 if (!strncasecmp(*cmt
, "LANGUAGE=", 9)) {
426 if (ogg_d
->subs
[id
].text
)
427 mp_msg(MSGT_IDENTIFY
, MSGL_INFO
, "ID_SID_%d_LANG=%s\n",
428 ogg_d
->subs
[id
].id
, val
);
429 else if (id
!= d
->video
->id
)
430 mp_msg(MSGT_IDENTIFY
, MSGL_INFO
, "ID_AID_%d_LANG=%s\n",
431 ogg_d
->subs
[id
].id
, val
);
432 if (ogg_d
->subs
[id
].text
)
433 mp_msg(MSGT_DEMUX
, MSGL_INFO
,
434 "[Ogg] Language for -sid %d is '-slang \"%s\"'\n",
435 ogg_d
->subs
[id
].id
, val
);
436 // copy this language name into the array
437 index
= demux_ogg_sub_reverse_id(d
, id
);
441 // in case of malicious files with more than one lang per track:
442 if (ogg_d
->text_langs
[index
])
443 free(ogg_d
->text_langs
[index
]);
444 ogg_d
->text_langs
[index
] = strdup(val
);
445 sh
= d
->s_streams
[index
];
449 sh
->lang
= strdup(val
);
451 // check for -slang if subs are uninitialized yet
452 if (os
->text
&& d
->sub
->id
< 0 && demux_ogg_check_lang(val
, dvdsub_lang
)) {
454 d
->opts
->sub_id
= index
;
455 mp_msg(MSGT_DEMUX
, MSGL_V
,
456 "Ogg demuxer: Displaying subtitle stream id %d which matched -slang %s\n",
463 for (i
= 0; table
[i
].ogg
; i
++) {
464 if (!strncasecmp(*cmt
, table
[i
].ogg
, strlen(table
[i
].ogg
)) &&
465 (*cmt
)[strlen(table
[i
].ogg
)] == '=') {
467 val
= *cmt
+ strlen(table
[i
].ogg
) + 1;
472 demux_info_add(d
, hdr
, val
);
473 mp_dbg(MSGT_DEMUX
, MSGL_DBG2
, " %s: %s\n", hdr
, val
);
478 /// Calculate the timestamp and add the packet to the demux stream
479 // return 1 if the packet was added, 0 otherwise
480 static int demux_ogg_add_packet(demux_stream_t
*ds
, ogg_stream_t
*os
,
481 int id
, ogg_packet
*pack
)
483 demuxer_t
*d
= ds
->demuxer
;
490 // If packet is an comment header then we try to get comments at first
491 if (pack
->bytes
>= 7 && !memcmp(pack
->packet
, "\003vorbis", 7)) {
495 vorbis_info_init(&vi
);
496 vorbis_comment_init(&vc
);
497 vi
.rate
= 1L; // it's checked by vorbis_synthesis_headerin()
498 if (vorbis_synthesis_headerin(&vi
, &vc
, pack
) == 0) // if no errors
499 demux_ogg_check_comments(d
, os
, id
, &vc
);
500 vorbis_comment_clear(&vc
);
501 vorbis_info_clear(&vi
);
504 if (id
== demux_ogg_sub_id(d
, d
->sub
->id
)) // don't want to add subtitles to the demuxer for now
505 demux_ogg_add_sub(os
, pack
);
509 // discard first two packets, they contain the header and comment
510 if (os
->hdr_packets
< 2) {
515 // If packet is an header we jump it except for vorbis and theora
516 // (PACKET_TYPE_HEADER bit doesn't even exist for theora ?!)
517 // We jump nothing for FLAC. Ain't this great? Packet contents have to be
518 // handled differently for each and every stream type. The joy! The joy!
519 if (!os
->flac
&& (*pack
->packet
& PACKET_TYPE_HEADER
) &&
520 (ds
!= d
->audio
|| ((sh_audio_t
*)ds
->sh
)->format
!= FOURCC_VORBIS
|| os
->hdr_packets
>= NUM_VORBIS_HDR_PACKETS
) &&
521 (ds
!= d
->video
|| (((sh_video_t
*)ds
->sh
)->format
!= FOURCC_THEORA
)))
525 // For vorbis packet the packet is the data, for other codec we must jump
527 if (ds
== d
->audio
&& ((sh_audio_t
*)ds
->sh
)->format
== FOURCC_VORBIS
) {
528 samplesize
= ((sh_audio_t
*)ds
->sh
)->samplesize
;
530 data
= demux_ogg_read_packet(os
, pack
, &pts
, &flags
, samplesize
);
534 /// Clear subtitles if necessary (for broken files)
535 if (sub_clear_text(&ogg_sub
, pts
)) {
537 vo_osd_changed(OSDTYPE_SUBTITLE
);
540 dp
= new_demux_packet(pack
->bytes
- (data
- pack
->packet
));
541 memcpy(dp
->buffer
, data
, pack
->bytes
- (data
- pack
->packet
));
544 ds_add_packet(ds
, dp
);
545 mp_msg(MSGT_DEMUX
, MSGL_DBG2
,
546 "New dp: %p ds=%p pts=%5.3f len=%d flag=%d \n",
547 dp
, ds
, pts
, dp
->len
, flags
);
551 /// if -forceidx build a table of all syncpoints to make seeking easier
552 /// otherwise try to get at least the final_granulepos
553 static void demux_ogg_scan_stream(demuxer_t
*demuxer
)
555 ogg_demuxer_t
*ogg_d
= demuxer
->priv
;
556 stream_t
*s
= demuxer
->stream
;
557 ogg_sync_state
*sync
= &ogg_d
->sync
;
558 ogg_page
*page
= &ogg_d
->page
;
559 ogg_stream_state
*oss
;
562 int np
, sid
, p
, samplesize
= 1;
565 pos
= last_pos
= demuxer
->movi_start
;
568 stream_seek(s
, demuxer
->movi_start
);
569 ogg_sync_reset(sync
);
571 // Get the serial number of the stream we use
572 if (demuxer
->video
->id
>= 0) {
573 sid
= demuxer
->video
->id
;
574 } else if (demuxer
->audio
->id
>= 0) {
575 sid
= demuxer
->audio
->id
;
576 if (((sh_audio_t
*)demuxer
->audio
->sh
)->format
== FOURCC_VORBIS
)
577 samplesize
= ((sh_audio_t
*)demuxer
->audio
->sh
)->samplesize
;
580 os
= &ogg_d
->subs
[sid
];
584 np
= ogg_sync_pageseek(sync
, page
);
585 if (np
< 0) { // We had to skip some bytes
587 mp_msg(MSGT_DEMUX
, MSGL_ERR
,
588 "Bad page sync while building syncpoints table (%d)\n",
593 if (np
<= 0) { // We need more data
594 char *buf
= ogg_sync_buffer(sync
, BLOCK_SIZE
);
595 int len
= stream_read(s
, buf
, BLOCK_SIZE
);
597 if (len
== 0 && s
->eof
)
599 ogg_sync_wrote(sync
, len
);
603 //ogg_sync_pageout(sync, page);
604 if (ogg_page_serialno(page
) != os
->stream
.serialno
) { // It isn't a page from the stream we want
608 if (ogg_stream_pagein(oss
, page
) != 0) {
609 mp_msg(MSGT_DEMUX
, MSGL_ERR
, "Pagein error ????\n");
614 while (ogg_stream_packetout(oss
, &op
) == 1) {
618 demux_ogg_read_packet(os
, &op
, &pts
, &flags
, samplesize
);
619 if (op
.granulepos
>= 0) {
620 ogg_d
->final_granulepos
= op
.granulepos
;
621 if (ogg_d
->initial_granulepos
== MP_NOPTS_VALUE
&& (flags
& 1)) {
622 ogg_d
->initial_granulepos
= op
.granulepos
;
623 if (index_mode
!= 2 && ogg_d
->pos
< demuxer
->movi_end
- 2 * 270000) {
624 //the 270000 are just a wild guess
625 stream_seek(s
, FFMAX(ogg_d
->pos
, demuxer
->movi_end
- 270000));
626 ogg_sync_reset(sync
);
631 if (index_mode
== 2 && (flags
|| (os
->vorbis
&& op
.granulepos
>= 0))) {
632 if (ogg_d
->num_syncpoint
> SIZE_MAX
/ sizeof(ogg_syncpoint_t
) - 1)
634 ogg_d
->syncpoints
= realloc_struct(ogg_d
->syncpoints
, (ogg_d
->num_syncpoint
+ 1), sizeof(ogg_syncpoint_t
));
635 ogg_d
->syncpoints
[ogg_d
->num_syncpoint
].granulepos
= op
.granulepos
;
636 ogg_d
->syncpoints
[ogg_d
->num_syncpoint
].page_pos
= (ogg_page_continued(page
) && p
== 0) ? last_pos
: pos
;
637 ogg_d
->num_syncpoint
++;
641 if (p
> 1 || (p
== 1 && !ogg_page_continued(page
)))
645 mp_msg(MSGT_DEMUX
, MSGL_INFO
, "Building syncpoint table %d%%\r",
646 (int)(pos
* 100 / s
->end_pos
));
649 if (index_mode
== 2) {
650 mp_msg(MSGT_DEMUX
, MSGL_INFO
, "\n");
651 mp_msg(MSGT_DEMUX
, MSGL_V
,
652 "Ogg syncpoints table builed: %d syncpoints\n",
653 ogg_d
->num_syncpoint
);
656 mp_msg(MSGT_DEMUX
, MSGL_V
, "Ogg stream length (granulepos): %"PRId64
"\n",
657 ogg_d
->final_granulepos
);
660 stream_seek(s
, demuxer
->movi_start
);
661 ogg_sync_reset(sync
);
662 for (np
= 0; np
< ogg_d
->num_sub
; np
++) {
663 ogg_stream_reset(&ogg_d
->subs
[np
].stream
);
664 ogg_d
->subs
[np
].lastpos
= ogg_d
->subs
[np
].lastsize
= ogg_d
->subs
[np
].hdr_packets
= 0;
667 // Get the first page
669 np
= ogg_sync_pageout(sync
, page
);
670 if (np
<= 0) { // We need more data
671 char *buf
= ogg_sync_buffer(sync
, BLOCK_SIZE
);
672 int len
= stream_read(s
, buf
, BLOCK_SIZE
);
674 if (len
== 0 && s
->eof
) {
675 mp_msg(MSGT_DEMUX
, MSGL_ERR
, "EOF while trying to get the first page !!!!\n");
678 ogg_sync_wrote(sync
, len
);
681 demux_ogg_get_page_stream(ogg_d
, &oss
);
682 ogg_stream_pagein(oss
, page
);
687 static void fixup_vorbis_wf(sh_audio_t
*sh
, ogg_demuxer_t
*od
)
690 int ris
, init_error
= 0;
692 unsigned char *buf
[3];
695 ogg_stream_t
*os
= &od
->subs
[sh
->ds
->id
];
698 vorbis_info_init(&os
->vi
);
699 vorbis_comment_init(&vc
);
700 for (i
= 0; i
< 3; i
++) {
701 op
[i
].bytes
= ds_get_packet(sh
->ds
, &(op
[i
].packet
));
702 mp_msg(MSGT_DEMUX
, MSGL_V
, "fixup_vorbis_wf: i=%d, size=%ld\n", i
, op
[i
].bytes
);
703 if (op
[i
].bytes
< 0) {
704 mp_msg(MSGT_DEMUX
, MSGL_ERR
, "Ogg demuxer error!, fixup_vorbis_wf: bad packet n. %d\n", i
);
707 buf
[i
] = malloc(op
[i
].bytes
);
710 memcpy(buf
[i
], op
[i
].packet
, op
[i
].bytes
);
712 op
[i
].b_o_s
= (i
== 0);
713 ris
= vorbis_synthesis_headerin(&os
->vi
, &vc
, &op
[i
]);
716 mp_msg(MSGT_DECAUDIO
, MSGL_ERR
, "DEMUX_OGG: header n. %d broken! len=%ld, code: %d\n", i
, op
[i
].bytes
, ris
);
719 vorbis_comment_clear(&vc
);
721 os
->vi_initialized
= 1;
723 len
= op
[0].bytes
+ op
[1].bytes
+ op
[2].bytes
;
724 sh
->wf
= calloc(1, sizeof(WAVEFORMATEX
) + len
+ len
/ 255 + 64);
725 ptr
= (unsigned char*)(sh
->wf
+ 1);
729 offset
+= store_ughvlc(&ptr
[offset
], op
[0].bytes
);
730 mp_msg(MSGT_DEMUX
, MSGL_V
, "demux_ogg, offset after 1st len = %u\n", offset
);
731 offset
+= store_ughvlc(&ptr
[offset
], op
[1].bytes
);
732 mp_msg(MSGT_DEMUX
, MSGL_V
, "demux_ogg, offset after 2nd len = %u\n", offset
);
733 for (i
= 0; i
< 3; i
++) {
734 mp_msg(MSGT_DEMUX
, MSGL_V
, "demux_ogg, i=%d, bytes: %ld, offset: %u\n", i
, op
[i
].bytes
, offset
);
735 memcpy(&ptr
[offset
], buf
[i
], op
[i
].bytes
);
736 offset
+= op
[i
].bytes
;
738 sh
->wf
->cbSize
= offset
;
739 mp_msg(MSGT_DEMUX
, MSGL_V
, "demux_ogg, extradata size: %d\n", sh
->wf
->cbSize
);
740 sh
->wf
= realloc(sh
->wf
, sizeof(WAVEFORMATEX
) + sh
->wf
->cbSize
);
742 if (op
[0].bytes
>= 29) {
744 int nombr
, minbr
, maxbr
;
747 sh
->channels
= ptr
[11];
748 sh
->samplerate
= sh
->wf
->nSamplesPerSec
= AV_RL32(&ptr
[12]);
749 maxbr
= AV_RL32(&ptr
[16]); //max
750 nombr
= AV_RL32(&ptr
[20]); //nominal
751 minbr
= AV_RL32(&ptr
[24]); //minimum
765 sh
->wf
->nAvgBytesPerSec
= br
;
766 sh
->wf
->wBitsPerSample
= 16;
767 sh
->samplesize
= (sh
->wf
->wBitsPerSample
+ 7) / 8;
769 mp_msg(MSGT_DEMUX
, MSGL_V
,
770 "demux_ogg, vorbis stream features are: channels: %d, srate: %d, bitrate: %d, max: %u, nominal: %u, min: %u\n",
771 sh
->channels
, sh
->samplerate
, sh
->wf
->nAvgBytesPerSec
,
772 maxbr
, nombr
, minbr
);
779 /// Open an ogg physical stream
780 // Not static because it's used also in demuxer_avi.c
781 int demux_ogg_open(demuxer_t
*demuxer
)
783 ogg_demuxer_t
*ogg_d
;
786 int np
, s_no
, n_audio
= 0, n_video
= 0;
787 int audio_id
= -1, video_id
= -1, text_id
= -1;
788 ogg_sync_state
*sync
;
800 demuxer
->priv
= ogg_d
= calloc(1, sizeof(*ogg_d
));
807 /// Try to get a page
808 ogg_d
->pos
+= ogg_d
->last_size
;
809 np
= ogg_sync_pageseek(sync
, page
);
812 mp_msg(MSGT_DEMUX
, MSGL_DBG2
, "Ogg demuxer : Bad page sync\n");
815 /// Need some more data
819 buf
= ogg_sync_buffer(sync
, BLOCK_SIZE
);
820 len
= stream_read(s
, buf
, BLOCK_SIZE
);
821 if (len
== 0 && s
->eof
) {
824 ogg_sync_wrote(sync
, len
);
827 ogg_d
->last_size
= np
;
828 // We got one page now
830 if (!ogg_page_bos(page
)) { // It's not a beginning page
831 // Header parsing end here, we need to get the page otherwise it will be lost
832 int id
= demux_ogg_get_page_stream(ogg_d
, NULL
);
834 ogg_stream_pagein(&ogg_d
->subs
[id
].stream
, page
);
836 mp_msg(MSGT_DEMUX
, MSGL_ERR
,
837 "Ogg : Warning found none bos page from unknown stream %d\n",
838 ogg_page_serialno(page
));
842 /// Init the data structure needed for a logical stream
843 ogg_d
->subs
= realloc_struct(ogg_d
->subs
, ogg_d
->num_sub
+1,
844 sizeof(ogg_stream_t
));
845 memset(&ogg_d
->subs
[ogg_d
->num_sub
], 0, sizeof(ogg_stream_t
));
846 /// Get the stream serial number
847 s_no
= ogg_page_serialno(page
);
848 ogg_stream_init(&ogg_d
->subs
[ogg_d
->num_sub
].stream
, s_no
);
849 mp_msg(MSGT_DEMUX
, MSGL_DBG2
,
850 "Ogg : Found a stream with serial=%d\n", s_no
);
851 // Take the first page
852 ogg_stream_pagein(&ogg_d
->subs
[ogg_d
->num_sub
].stream
, page
);
853 // Get first packet of the page
854 ogg_stream_packetout(&ogg_d
->subs
[ogg_d
->num_sub
].stream
, &pack
);
860 ogg_d
->subs
[ogg_d
->num_sub
].ogg_d
= ogg_d
;
863 if (pack
.bytes
>= 7 && !strncmp(&pack
.packet
[1], "vorbis", 6)) {
864 sh_a
= new_sh_audio_aid(demuxer
, ogg_d
->num_sub
, n_audio
);
865 sh_a
->format
= FOURCC_VORBIS
;
866 ogg_d
->subs
[ogg_d
->num_sub
].vorbis
= 1;
867 ogg_d
->subs
[ogg_d
->num_sub
].id
= n_audio
;
869 mp_msg(MSGT_DEMUX
, MSGL_INFO
,
870 "[Ogg] stream %d: audio (Vorbis), -aid %d\n",
871 ogg_d
->num_sub
, n_audio
- 1);
872 } else if (pack
.bytes
>= 80 && !strncmp(pack
.packet
, "Speex", 5)) {
873 sh_a
= new_sh_audio_aid(demuxer
, ogg_d
->num_sub
, n_audio
);
874 sh_a
->wf
= calloc(1, sizeof(WAVEFORMATEX
) + pack
.bytes
);
875 sh_a
->format
= FOURCC_SPEEX
;
876 sh_a
->samplerate
= sh_a
->wf
->nSamplesPerSec
= AV_RL32(&pack
.packet
[36]);
877 sh_a
->channels
= sh_a
->wf
->nChannels
= AV_RL32(&pack
.packet
[48]);
878 sh_a
->wf
->wFormatTag
= sh_a
->format
;
879 sh_a
->wf
->nAvgBytesPerSec
= AV_RL32(&pack
.packet
[52]);
880 sh_a
->wf
->nBlockAlign
= 0;
881 sh_a
->wf
->wBitsPerSample
= 16;
882 sh_a
->samplesize
= 2;
883 sh_a
->wf
->cbSize
= pack
.bytes
;
884 memcpy(&sh_a
->wf
[1], pack
.packet
, pack
.bytes
);
886 ogg_d
->subs
[ogg_d
->num_sub
].samplerate
= sh_a
->samplerate
;
887 ogg_d
->subs
[ogg_d
->num_sub
].speex
= 1;
888 ogg_d
->subs
[ogg_d
->num_sub
].id
= n_audio
;
890 mp_msg(MSGT_DEMUX
, MSGL_INFO
,
891 "[Ogg] stream %d: audio (Speex), -aid %d\n",
892 ogg_d
->num_sub
, n_audio
- 1);
895 #ifdef CONFIG_OGGTHEORA
896 } else if (pack
.bytes
>= 7 && !strncmp (&pack
.packet
[1], "theora", 6)) {
901 theora_info_init (&inf
);
902 theora_comment_init (&cc
);
904 errorCode
= theora_decode_header (&inf
, &cc
, &pack
);
906 mp_msg(MSGT_DEMUX
, MSGL_ERR
,
907 "Theora header parsing failed: %i \n", errorCode
);
909 sh_v
= new_sh_video_vid(demuxer
, ogg_d
->num_sub
, n_video
);
911 sh_v
->bih
= calloc(1, sizeof(BITMAPINFOHEADER
));
912 sh_v
->bih
->biSize
= sizeof(BITMAPINFOHEADER
);
913 sh_v
->bih
->biCompression
= sh_v
->format
= FOURCC_THEORA
;
914 sh_v
->fps
= ((double)inf
.fps_numerator
) / (double)inf
.fps_denominator
;
915 sh_v
->frametime
= ((double)inf
.fps_denominator
) / (double)inf
.fps_numerator
;
916 sh_v
->disp_w
= sh_v
->bih
->biWidth
= inf
.frame_width
;
917 sh_v
->disp_h
= sh_v
->bih
->biHeight
= inf
.frame_height
;
918 sh_v
->bih
->biBitCount
= 24;
919 sh_v
->bih
->biPlanes
= 3;
920 sh_v
->bih
->biSizeImage
= ((sh_v
->bih
->biBitCount
/ 8) * sh_v
->bih
->biWidth
* sh_v
->bih
->biHeight
);
921 ogg_d
->subs
[ogg_d
->num_sub
].samplerate
= sh_v
->fps
;
922 ogg_d
->subs
[ogg_d
->num_sub
].theora
= 1;
923 ogg_d
->subs
[ogg_d
->num_sub
].keyframe_frequency_force
= inf
.keyframe_frequency_force
;
924 ogg_d
->subs
[ogg_d
->num_sub
].id
= n_video
;
926 mp_msg(MSGT_DEMUX
, MSGL_INFO
,
927 "[Ogg] stream %d: video (Theora v%d.%d.%d), -vid %d\n",
929 (int)inf
.version_major
,
930 (int)inf
.version_minor
,
931 (int)inf
.version_subminor
,
933 if (mp_msg_test(MSGT_HEADER
, MSGL_V
))
934 print_video_header(sh_v
->bih
, MSGL_V
);
936 theora_comment_clear(&cc
);
937 theora_info_clear(&inf
);
938 #endif /* CONFIG_OGGTHEORA */
939 } else if (pack
.bytes
>= 4 && !strncmp (&pack
.packet
[0], "fLaC", 4)) {
940 sh_a
= new_sh_audio_aid(demuxer
, ogg_d
->num_sub
, n_audio
);
941 sh_a
->format
= mmioFOURCC('f', 'L', 'a', 'C');
942 ogg_d
->subs
[ogg_d
->num_sub
].id
= n_audio
;
944 ogg_d
->subs
[ogg_d
->num_sub
].flac
= 1;
946 mp_msg(MSGT_DEMUX
, MSGL_INFO
,
947 "[Ogg] stream %d: audio (FLAC), -aid %d\n",
948 ogg_d
->num_sub
, n_audio
- 1);
949 } else if (pack
.bytes
>= 51 && !strncmp(&pack
.packet
[1], "FLAC", 4)) {
950 sh_a
= new_sh_audio_aid(demuxer
, ogg_d
->num_sub
, n_audio
);
951 sh_a
->format
= mmioFOURCC('f', 'L', 'a', 'C');
952 ogg_d
->subs
[ogg_d
->num_sub
].id
= n_audio
;
954 ogg_d
->subs
[ogg_d
->num_sub
].flac
= 2;
955 sh_a
->wf
= calloc(1, sizeof(WAVEFORMATEX
) + 34);
956 sh_a
->wf
->wFormatTag
= sh_a
->format
;
957 sh_a
->wf
->cbSize
= 34;
958 memcpy(&sh_a
->wf
[1], &pack
.packet
[17], 34);
959 mp_msg(MSGT_DEMUX
, MSGL_INFO
,
960 "[Ogg] stream %d: audio (FLAC, try 2), -aid %d\n",
961 ogg_d
->num_sub
, n_audio
- 1);
963 /// Check for old header
964 } else if (pack
.bytes
>= 142 &&
965 !strncmp(&pack
.packet
[1], "Direct Show Samples embedded in Ogg", 35)) {
968 if (AV_RL32(pack
.packet
+ 96) == 0x05589f80 && pack
.bytes
>= 184) {
969 sh_v
= new_sh_video_vid(demuxer
, ogg_d
->num_sub
, n_video
);
970 sh_v
->bih
= calloc(1, sizeof(BITMAPINFOHEADER
));
971 sh_v
->bih
->biSize
= sizeof(BITMAPINFOHEADER
);
972 sh_v
->bih
->biCompression
= sh_v
->format
= mmioFOURCC(pack
.packet
[68], pack
.packet
[69],
973 pack
.packet
[70], pack
.packet
[71]);
974 sh_v
->frametime
= AV_RL64(pack
.packet
+ 164) * 0.0000001;
975 sh_v
->fps
= 1 / sh_v
->frametime
;
976 sh_v
->disp_w
= sh_v
->bih
->biWidth
= AV_RL32(pack
.packet
+ 176);
977 sh_v
->disp_h
= sh_v
->bih
->biHeight
= AV_RL32(pack
.packet
+ 180);
978 sh_v
->bih
->biBitCount
= AV_RL16(pack
.packet
+ 182);
979 if (!sh_v
->bih
->biBitCount
)
980 sh_v
->bih
->biBitCount
= 24; // hack, FIXME
981 sh_v
->bih
->biPlanes
= 1;
982 sh_v
->bih
->biSizeImage
= (sh_v
->bih
->biBitCount
>> 3) * sh_v
->bih
->biWidth
* sh_v
->bih
->biHeight
;
984 ogg_d
->subs
[ogg_d
->num_sub
].samplerate
= sh_v
->fps
;
985 ogg_d
->subs
[ogg_d
->num_sub
].id
= n_video
;
987 mp_msg(MSGT_DEMUX
, MSGL_INFO
,
988 "[Ogg] stream %d: video (FOURCC %c%c%c%c), -vid %d\n",
989 ogg_d
->num_sub
, pack
.packet
[68], pack
.packet
[69],
990 pack
.packet
[70], pack
.packet
[71], n_video
- 1);
991 if (mp_msg_test(MSGT_HEADER
, MSGL_V
))
992 print_video_header(sh_v
->bih
, MSGL_V
);
994 } else if (AV_RL32(pack
.packet
+ 96) == 0x05589F81) {
995 unsigned int extra_size
;
997 sh_a
= new_sh_audio_aid(demuxer
, ogg_d
->num_sub
, n_audio
);
998 extra_size
= AV_RL16(pack
.packet
+ 140);
999 sh_a
->wf
= calloc(1, sizeof(WAVEFORMATEX
) + extra_size
);
1000 sh_a
->format
= sh_a
->wf
->wFormatTag
= AV_RL16(pack
.packet
+ 124);
1001 sh_a
->channels
= sh_a
->wf
->nChannels
= AV_RL16(pack
.packet
+ 126);
1002 sh_a
->samplerate
= sh_a
->wf
->nSamplesPerSec
= AV_RL32(pack
.packet
+ 128);
1003 sh_a
->wf
->nAvgBytesPerSec
= AV_RL32(pack
.packet
+ 132);
1004 sh_a
->wf
->nBlockAlign
= AV_RL16(pack
.packet
+ 136);
1005 sh_a
->wf
->wBitsPerSample
= AV_RL16(pack
.packet
+ 138);
1006 sh_a
->samplesize
= (sh_a
->wf
->wBitsPerSample
+ 7) / 8;
1007 sh_a
->wf
->cbSize
= extra_size
;
1009 memcpy(((char *)sh_a
->wf
) + sizeof(WAVEFORMATEX
),
1010 pack
.packet
+ 142, extra_size
);
1012 ogg_d
->subs
[ogg_d
->num_sub
].samplerate
= sh_a
->samplerate
; // * sh_a->channels;
1013 ogg_d
->subs
[ogg_d
->num_sub
].id
= n_audio
;
1015 mp_msg(MSGT_DEMUX
, MSGL_INFO
,
1016 "[Ogg] stream %d: audio (format 0x%04x), -aid %d\n",
1017 ogg_d
->num_sub
, sh_a
->format
, n_audio
- 1);
1018 if (mp_msg_test(MSGT_HEADER
, MSGL_V
))
1019 print_wave_header(sh_a
->wf
, MSGL_V
);
1021 mp_msg(MSGT_DEMUX
, MSGL_WARN
,
1022 "Ogg stream %d contains an old header but the header type is unknown\n",
1026 } else if ((*pack
.packet
& PACKET_TYPE_BITS
) == PACKET_TYPE_HEADER
&&
1027 pack
.bytes
>= (int)sizeof(stream_header
) + 1) {
1028 stream_header
*st
= (stream_header
*)(pack
.packet
+ 1);
1029 /// New video header
1030 if (strncmp(st
->streamtype
, "video", 5) == 0) {
1031 sh_v
= new_sh_video_vid(demuxer
, ogg_d
->num_sub
, n_video
);
1032 sh_v
->bih
= calloc(1, sizeof(BITMAPINFOHEADER
));
1033 sh_v
->bih
->biSize
= sizeof(BITMAPINFOHEADER
);
1034 sh_v
->bih
->biCompression
= sh_v
->format
= mmioFOURCC(st
->subtype
[0], st
->subtype
[1],
1035 st
->subtype
[2], st
->subtype
[3]);
1036 sh_v
->frametime
= AV_RL64(&st
->time_unit
) * 0.0000001;
1037 sh_v
->fps
= 1.0 / sh_v
->frametime
;
1038 sh_v
->bih
->biBitCount
= AV_RL16(&st
->bits_per_sample
);
1039 sh_v
->disp_w
= sh_v
->bih
->biWidth
= AV_RL32(&st
->sh
.video
.width
);
1040 sh_v
->disp_h
= sh_v
->bih
->biHeight
= AV_RL32(&st
->sh
.video
.height
);
1041 if (!sh_v
->bih
->biBitCount
)
1042 sh_v
->bih
->biBitCount
= 24; // hack, FIXME
1043 sh_v
->bih
->biPlanes
= 1;
1044 sh_v
->bih
->biSizeImage
= (sh_v
->bih
->biBitCount
>> 3) * sh_v
->bih
->biWidth
* sh_v
->bih
->biHeight
;
1046 ogg_d
->subs
[ogg_d
->num_sub
].samplerate
= sh_v
->fps
;
1047 ogg_d
->subs
[ogg_d
->num_sub
].id
= n_video
;
1049 mp_msg(MSGT_DEMUX
, MSGL_INFO
,
1050 "[Ogg] stream %d: video (FOURCC %c%c%c%c), -vid %d\n",
1051 ogg_d
->num_sub
, st
->subtype
[0], st
->subtype
[1],
1052 st
->subtype
[2], st
->subtype
[3], n_video
- 1);
1053 if (mp_msg_test(MSGT_HEADER
, MSGL_V
))
1054 print_video_header(sh_v
->bih
, MSGL_V
);
1055 /// New audio header
1056 } else if (strncmp(st
->streamtype
, "audio", 5) == 0) {
1058 unsigned int extra_size
= AV_RL32(&st
->size
) - sizeof(stream_header
);
1059 unsigned int extra_offset
= 0;
1061 memcpy(buffer
, st
->subtype
, 4);
1064 /* Nasty workaround. stream_header.size seems not to contain the real
1065 size in all cases. There are four extra bytes that are unaccounted
1066 for in front of the real codec initialization data _at least_ for
1067 AAC. So far I've only seen those bytes being all 0, so we can
1068 just skip them here. */
1069 if ((strtol(buffer
, NULL
, 16) == 0xff) && (extra_size
>= 4)) {
1074 sh_a
= new_sh_audio_aid(demuxer
, ogg_d
->num_sub
, n_audio
);
1075 sh_a
->wf
= calloc(1, sizeof(WAVEFORMATEX
) + extra_size
);
1076 sh_a
->format
= sh_a
->wf
->wFormatTag
= strtol(buffer
, NULL
, 16);
1077 sh_a
->channels
= sh_a
->wf
->nChannels
= AV_RL16(&st
->sh
.audio
.channels
);
1078 sh_a
->samplerate
= sh_a
->wf
->nSamplesPerSec
= AV_RL64(&st
->samples_per_unit
);
1079 sh_a
->wf
->nAvgBytesPerSec
= AV_RL32(&st
->sh
.audio
.avgbytespersec
);
1080 sh_a
->wf
->nBlockAlign
= AV_RL16(&st
->sh
.audio
.blockalign
);
1081 sh_a
->wf
->wBitsPerSample
= AV_RL16(&st
->bits_per_sample
);
1082 sh_a
->samplesize
= (sh_a
->wf
->wBitsPerSample
+ 7) / 8;
1083 sh_a
->wf
->cbSize
= extra_size
;
1085 memcpy(((char *)sh_a
->wf
)+sizeof(WAVEFORMATEX
),
1086 ((char *)(st
+1))+extra_offset
, extra_size
);
1088 ogg_d
->subs
[ogg_d
->num_sub
].samplerate
= sh_a
->samplerate
; // * sh_a->channels;
1089 ogg_d
->subs
[ogg_d
->num_sub
].id
= n_audio
;
1091 mp_msg(MSGT_DEMUX
, MSGL_INFO
,
1092 "[Ogg] stream %d: audio (format 0x%04x), -aid %d\n",
1093 ogg_d
->num_sub
, sh_a
->format
, n_audio
- 1);
1094 if (mp_msg_test(MSGT_HEADER
, MSGL_V
))
1095 print_wave_header(sh_a
->wf
, MSGL_V
);
1097 /// Check for text (subtitles) header
1098 } else if (strncmp(st
->streamtype
, "text", 4) == 0) {
1099 mp_msg(MSGT_DEMUX
, MSGL_INFO
,
1100 "[Ogg] stream %d: subtitles (SRT-like text subtitles), -sid %d\n",
1101 ogg_d
->num_sub
, ogg_d
->n_text
);
1102 ogg_d
->subs
[ogg_d
->num_sub
].samplerate
= AV_RL64(&st
->time_unit
) / 10;
1103 ogg_d
->subs
[ogg_d
->num_sub
].text
= 1;
1104 ogg_d
->subs
[ogg_d
->num_sub
].id
= ogg_d
->n_text
;
1105 if (demuxer
->sub
->id
== ogg_d
->n_text
)
1106 text_id
= ogg_d
->num_sub
;
1107 new_sh_sub(demuxer
, ogg_d
->n_text
);
1109 ogg_d
->text_ids
= realloc_struct(ogg_d
->text_ids
, ogg_d
->n_text
, sizeof(*ogg_d
->text_ids
));
1110 ogg_d
->text_ids
[ogg_d
->n_text
- 1] = ogg_d
->num_sub
;
1111 ogg_d
->text_langs
= realloc_struct(ogg_d
->text_langs
, ogg_d
->n_text
, sizeof(*ogg_d
->text_langs
));
1112 ogg_d
->text_langs
[ogg_d
->n_text
- 1] = NULL
;
1113 //// Unknown header type
1115 mp_msg(MSGT_DEMUX
, MSGL_ERR
,
1116 "Ogg stream %d has a header marker but is of an unknown type\n",
1118 /// Unknown (invalid ?) header
1120 mp_msg(MSGT_DEMUX
, MSGL_ERR
,
1121 "Ogg stream %d is of an unknown type\n",
1125 demux_stream_t
*ds
= NULL
;
1127 // If the audio stream is not defined we took the first one
1128 if (demuxer
->audio
->id
== -1) {
1129 demuxer
->audio
->id
= n_audio
- 1;
1130 //if (sh_a->wf) print_wave_header(sh_a->wf, MSGL_INFO);
1132 /// Is it the stream we want
1133 if (demuxer
->audio
->id
== n_audio
- 1) {
1134 demuxer
->audio
->sh
= sh_a
;
1135 sh_a
->ds
= demuxer
->audio
;
1136 ds
= demuxer
->audio
;
1137 audio_id
= ogg_d
->num_sub
;
1142 if (demuxer
->video
->id
== -1) {
1143 demuxer
->video
->id
= n_video
- 1;
1144 //if (sh_v->bih) print_video_header(sh_v->bih, MSGL_INFO);
1146 if (demuxer
->video
->id
== n_video
- 1) {
1147 demuxer
->video
->sh
= sh_v
;
1148 sh_v
->ds
= demuxer
->video
;
1149 ds
= demuxer
->video
;
1150 video_id
= ogg_d
->num_sub
;
1153 /// Add the header packets if the stream isn't seekable
1154 if (ds
&& !s
->end_pos
) {
1155 /// Finish the page, otherwise packets will be lost
1157 demux_ogg_add_packet(ds
, &ogg_d
->subs
[ogg_d
->num_sub
],
1158 ogg_d
->num_sub
, &pack
);
1159 } while (ogg_stream_packetout(&ogg_d
->subs
[ogg_d
->num_sub
].stream
, &pack
) == 1);
1165 if (!n_video
&& !n_audio
) {
1169 if (!n_video
|| video_id
< 0)
1170 demuxer
->video
->id
= -2;
1172 demuxer
->video
->id
= video_id
;
1173 if (!n_audio
|| audio_id
< 0)
1174 demuxer
->audio
->id
= -2;
1176 demuxer
->audio
->id
= audio_id
;
1177 /* Disable the subs only if there are no text streams at all.
1178 Otherwise the stream to display might be chosen later when the comment
1179 packet is encountered and the user used -slang instead of -sid. */
1181 demuxer
->sub
->id
= -2;
1182 else if (text_id
>= 0) {
1183 demuxer
->sub
->id
= text_id
;
1184 mp_msg(MSGT_DEMUX
, MSGL_V
,
1185 "Ogg demuxer: Displaying subtitle stream id %d\n", text_id
);
1188 ogg_d
->final_granulepos
= 0;
1189 ogg_d
->initial_granulepos
= MP_NOPTS_VALUE
;
1191 demuxer
->seekable
= 0;
1193 demuxer
->movi_start
= s
->start_pos
; // Needed for XCD (Ogg written in MODE2)
1194 demuxer
->movi_end
= s
->end_pos
;
1195 demuxer
->seekable
= 1;
1196 demux_ogg_scan_stream(demuxer
);
1198 if (ogg_d
->initial_granulepos
== MP_NOPTS_VALUE
)
1199 ogg_d
->initial_granulepos
= 0;
1200 ogg_d
->duration
= ogg_d
->final_granulepos
- ogg_d
->initial_granulepos
;
1202 mp_msg(MSGT_DEMUX
, MSGL_V
,
1203 "Ogg demuxer : found %d audio stream%s, %d video stream%s and %d text stream%s\n",
1204 n_audio
, n_audio
> 1 ? "s" : "",
1205 n_video
, n_video
> 1 ? "s" : "",
1206 ogg_d
->n_text
, ogg_d
->n_text
> 1 ? "s" : "");
1208 sh_a
= demuxer
->audio
->sh
;
1209 if (sh_a
&& sh_a
->format
== FOURCC_VORBIS
)
1210 fixup_vorbis_wf(sh_a
, ogg_d
);
1212 return DEMUXER_TYPE_OGG
;
1218 static int demux_ogg_fill_buffer(demuxer_t
*d
, demux_stream_t
*dsds
)
1220 ogg_demuxer_t
*ogg_d
;
1223 ogg_sync_state
*sync
;
1224 ogg_stream_state
*os
;
1231 sync
= &ogg_d
->sync
;
1232 page
= &ogg_d
->page
;
1234 /// Find the stream we are working on
1235 if ((id
= demux_ogg_get_page_stream(ogg_d
, &os
)) < 0) {
1236 mp_msg(MSGT_DEMUX
, MSGL_ERR
, "Ogg demuxer : can't get current stream\n");
1243 /// Try to get some packet from the current page
1244 while ((np
= ogg_stream_packetout(os
, &pack
)) != 1) {
1245 /// No packet we go the next page
1251 ogg_d
->pos
+= ogg_d
->last_size
;
1252 /// Get the next page from the physical stream
1253 while ((pa
= ogg_sync_pageseek(sync
, page
)) <= 0) {
1254 /// Error : we skip some bytes
1256 mp_msg(MSGT_DEMUX
, MSGL_WARN
,
1257 "Ogg : Page out not synced, we skip some bytes\n");
1261 /// We need more data
1262 buf
= ogg_sync_buffer(sync
, BLOCK_SIZE
);
1263 len
= stream_read(s
, buf
, BLOCK_SIZE
);
1264 if (len
== 0 && s
->eof
) {
1265 mp_msg(MSGT_DEMUX
, MSGL_DBG2
, "Ogg : Stream EOF !!!!\n");
1268 ogg_sync_wrote(sync
, len
);
1270 ogg_d
->last_size
= pa
;
1271 /// Find the page's logical stream
1272 if ((id
= demux_ogg_get_page_stream(ogg_d
, &os
)) < 0) {
1273 mp_msg(MSGT_DEMUX
, MSGL_ERR
,
1274 "Ogg demuxer error : we met an unknown stream\n");
1278 if (ogg_stream_pagein(os
, page
) == 0)
1280 /// Page was invalid => retry
1281 mp_msg(MSGT_DEMUX
, MSGL_WARN
,
1282 "Ogg demuxer : got invalid page !!!!!\n");
1283 ogg_d
->pos
+= ogg_d
->last_size
;
1285 } else /// Packet was corrupted
1286 mp_msg(MSGT_DEMUX
, MSGL_WARN
,
1287 "Ogg : bad packet in stream %d\n", id
);
1290 /// Is the actual logical stream in use ?
1291 if (id
== d
->audio
->id
)
1293 else if (id
== d
->video
->id
)
1295 else if (ogg_d
->subs
[id
].text
)
1299 if (!demux_ogg_add_packet(ds
, &ogg_d
->subs
[id
], id
, &pack
))
1300 continue; /// Unuseful packet, get another
1301 d
->filepos
= ogg_d
->pos
;
1307 /// For avi with Ogg audio stream we have to create an ogg demuxer for this
1308 // stream, then we join the avi and ogg demuxer with a demuxers demuxer
1309 demuxer_t
*init_avi_with_ogg(demuxer_t
*demuxer
)
1311 struct MPOpts
*opts
= demuxer
->opts
;
1313 ogg_demuxer_t
*ogg_d
;
1315 uint32_t hdrsizes
[3];
1317 sh_audio_t
*sh_audio
= demuxer
->audio
->sh
;
1319 uint8_t *extradata
= (uint8_t *)(sh_audio
->wf
+ 1);
1321 unsigned char *p
= NULL
, *buf
;
1324 /// Check that the cbSize is big enough for the following reads
1325 if (sh_audio
->wf
->cbSize
< 22 + 3 * 4) {
1326 mp_msg(MSGT_DEMUX
, MSGL_ERR
,
1327 "AVI Ogg : Initial audio header is too small !!!!!\n");
1330 /// Get the size of the 3 header packet
1332 for (i
= 0; i
< 3; i
++) {
1333 hdrsizes
[i
] = AV_RL32(extradata
);
1336 // printf("\n!!!!!! hdr sizes: %d %d %d \n", hdrsizes[0], hdrsizes[1], hdrsizes[2]);
1339 if (sh_audio
->wf
->cbSize
< 22 + 3 * 4 + hdrsizes
[0] + hdrsizes
[1] + hdrsizes
[2]) {
1340 mp_msg(MSGT_DEMUX
, MSGL_ERR
,
1341 "AVI Ogg : Audio header is too small !!!!!\n");
1345 // Build the ogg demuxer private datas
1346 ogg_d
= calloc(1, sizeof(*ogg_d
));
1348 ogg_d
->subs
= malloc(sizeof(*ogg_d
->subs
));
1349 ogg_d
->subs
[0].vorbis
= 1;
1351 // Init the ogg physical stream
1352 ogg_sync_init(&ogg_d
->sync
);
1354 // Get the first page of the stream : we assume there only 1 logical stream
1355 while ((np
= ogg_sync_pageout(&ogg_d
->sync
, &ogg_d
->page
)) <= 0 ) {
1357 mp_msg(MSGT_DEMUX
, MSGL_ERR
,
1358 "AVI Ogg error : Can't init using first stream packets\n");
1363 plen
= ds_get_packet(demuxer
->audio
, &p
);
1364 buf
= ogg_sync_buffer(&ogg_d
->sync
, plen
);
1365 memcpy(buf
, p
, plen
);
1366 ogg_sync_wrote(&ogg_d
->sync
, plen
);
1368 // Init the logical stream
1369 mp_msg(MSGT_DEMUX
, MSGL_DBG2
,
1370 "AVI Ogg found page with serial %d\n",
1371 ogg_page_serialno(&ogg_d
->page
));
1372 ogg_stream_init(&ogg_d
->subs
[0].stream
, ogg_page_serialno(&ogg_d
->page
));
1374 ogg_stream_pagein(&ogg_d
->subs
[0].stream
, &ogg_d
->page
);
1376 // Create the ds_stream and the ogg demuxer
1377 s
= new_ds_stream(demuxer
->audio
);
1378 od
= new_demuxer(opts
, s
, DEMUXER_TYPE_OGG
, 0, -2, -2, NULL
);
1380 /// Add the header packets in the ogg demuxer audio stream
1381 for (i
= 0; i
< 3; i
++) {
1382 dp
= new_demux_packet(hdrsizes
[i
]);
1383 memcpy(dp
->buffer
, extradata
, hdrsizes
[i
]);
1384 ds_add_packet(od
->audio
, dp
);
1385 extradata
+= hdrsizes
[i
];
1388 // Finish setting up the ogg demuxer
1390 sh_audio
= new_sh_audio(od
, 0);
1393 od
->audio
->sh
= sh_audio
;
1394 sh_audio
->ds
= od
->audio
;
1395 sh_audio
->format
= FOURCC_VORBIS
;
1396 fixup_vorbis_wf(sh_audio
, ogg_d
);
1398 /// Return the joined demuxers
1399 return new_demuxers_demuxer(demuxer
, od
, demuxer
);
1402 demuxer
->audio
->id
= -2;
1407 static void demux_ogg_seek(demuxer_t
*demuxer
, float rel_seek_secs
,
1408 float audio_delay
, int flags
)
1410 ogg_demuxer_t
*ogg_d
= demuxer
->priv
;
1411 ogg_sync_state
*sync
= &ogg_d
->sync
;
1412 ogg_page
* page
= &ogg_d
->page
;
1413 ogg_stream_state
*oss
;
1418 int i
, sp
, first
, precision
= 1, do_seek
= 1;
1419 vorbis_info
*vi
= NULL
;
1420 int64_t gp
= 0, old_gp
;
1427 ogg_int64_t granulepos_orig
;
1429 if (demuxer
->video
->id
>= 0) {
1430 ds
= demuxer
->video
;
1431 rate
= ogg_d
->subs
[ds
->id
].samplerate
;
1433 ds
= demuxer
->audio
;
1434 os
= &ogg_d
->subs
[ds
->id
];
1436 rate
= (float)vi
->rate
;
1437 samplesize
= ((sh_audio_t
*)ds
->sh
)->samplesize
;
1440 os
= &ogg_d
->subs
[ds
->id
];
1443 old_gp
= os
->lastpos
;
1444 old_pos
= ogg_d
->pos
;
1446 //calculate the granulepos to seek to
1447 gp
= flags
& SEEK_ABSOLUTE
? ogg_d
->initial_granulepos
: os
->lastpos
;
1448 if (flags
& SEEK_FACTOR
) {
1449 if (ogg_d
->duration
> 0)
1450 gp
+= ogg_d
->duration
* rel_seek_secs
;
1452 gp
+= rel_seek_secs
* (demuxer
->movi_end
- demuxer
->movi_start
) * os
->lastpos
/ ogg_d
->pos
;
1454 gp
+= rel_seek_secs
* rate
;
1458 //calculate the filepos to seek to
1459 if (ogg_d
->syncpoints
) {
1460 for (sp
= 0; sp
< ogg_d
->num_syncpoint
; sp
++)
1461 if (ogg_d
->syncpoints
[sp
].granulepos
>= gp
)
1464 if (sp
>= ogg_d
->num_syncpoint
)
1466 if (sp
> 0 && ogg_d
->syncpoints
[sp
].granulepos
- gp
> gp
- ogg_d
->syncpoints
[sp
- 1].granulepos
)
1468 if (ogg_d
->syncpoints
[sp
].granulepos
== os
->lastpos
) {
1469 if (sp
> 0 && gp
< os
->lastpos
)
1471 if (sp
< ogg_d
->num_syncpoint
- 1 && gp
> os
->lastpos
)
1474 pos
= ogg_d
->syncpoints
[sp
].page_pos
;
1477 pos
= flags
& SEEK_ABSOLUTE
? 0 : ogg_d
->pos
;
1478 if (flags
& SEEK_FACTOR
)
1479 pos
+= (demuxer
->movi_end
- demuxer
->movi_start
) * rel_seek_secs
;
1481 if (ogg_d
->duration
> 0) {
1482 pos
+= rel_seek_secs
* (demuxer
->movi_end
- demuxer
->movi_start
) / (ogg_d
->duration
/ rate
);
1483 } else if (os
->lastpos
> 0) {
1484 pos
+= rel_seek_secs
* ogg_d
->pos
/ (os
->lastpos
/ rate
);
1489 if (pos
> (demuxer
->movi_end
- demuxer
->movi_start
))
1490 pos
= demuxer
->movi_end
- demuxer
->movi_start
;
1491 } // if (ogg_d->syncpoints)
1495 stream_seek(demuxer
->stream
, pos
+demuxer
->movi_start
);
1496 ogg_sync_reset(sync
);
1497 for (i
= 0; i
< ogg_d
->num_sub
; i
++) {
1498 ogg_stream_reset(&ogg_d
->subs
[i
].stream
);
1499 ogg_d
->subs
[i
].lastpos
= ogg_d
->subs
[i
].lastsize
= 0;
1502 ogg_d
->last_size
= 0;
1503 /* we just guess that we reached correct granulepos, in case a
1504 subsequent search occurs before we read a valid granulepos */
1506 first
= !(ogg_d
->syncpoints
);
1509 ogg_d
->pos
+= ogg_d
->last_size
;
1510 ogg_d
->last_size
= 0;
1511 np
= ogg_sync_pageseek(sync
, page
);
1515 if (np
<= 0) { // We need more data
1516 char *buf
= ogg_sync_buffer(sync
, BLOCK_SIZE
);
1517 int len
= stream_read(demuxer
->stream
, buf
, BLOCK_SIZE
);
1519 if (len
== 0 && demuxer
->stream
->eof
) {
1520 mp_msg(MSGT_DEMUX
, MSGL_V
, "EOF while trying to seek !!!!\n");
1523 ogg_sync_wrote(sync
, len
);
1526 ogg_d
->last_size
= np
;
1527 if (ogg_page_serialno(page
) != oss
->serialno
)
1530 if (ogg_stream_pagein(oss
, page
) != 0)
1534 np
= ogg_stream_packetout(oss
, &op
);
1539 if (first
) { /* Discard the first packet as it's probably broken,
1540 and we don't have any other means to decide whether it is
1545 is_gp_valid
= (op
.granulepos
>= 0);
1546 granulepos_orig
=op
.granulepos
;
1547 demux_ogg_read_packet(os
, &op
, &pts
, &is_keyframe
, samplesize
);
1548 if (precision
&& is_gp_valid
) {
1550 if (abs(gp
- op
.granulepos
) > rate
&& (op
.granulepos
!= old_gp
)) {
1551 //prepare another seek because we are off by more than 1s
1552 pos
+= (gp
- op
.granulepos
) * (pos
- old_pos
) / (op
.granulepos
- old_gp
);
1555 if (pos
< demuxer
->movi_end
- demuxer
->movi_start
) {
1561 if (is_gp_valid
&& pos
> 0 && old_gp
> gp
1562 && 2 * (old_gp
- op
.granulepos
) < old_gp
- gp
) {
1563 /* prepare another seek because looking for a syncpoint
1564 destroyed the backward search */
1565 pos
= old_pos
- 1.5 * (old_pos
- pos
);
1568 if (pos
< demuxer
->movi_end
- demuxer
->movi_start
) {
1573 if (!precision
&& (is_keyframe
|| os
->vorbis
|| os
->speex
)) {
1574 if (sub_clear_text(&ogg_sub
, MP_NOPTS_VALUE
)) {
1576 vo_osd_changed(OSDTYPE_SUBTITLE
);
1578 op
.granulepos
=granulepos_orig
;
1579 demux_ogg_add_packet(ds
, os
, ds
->id
, &op
);
1585 mp_msg(MSGT_DEMUX
, MSGL_ERR
, "Can't find the good packet :(\n");
1588 static void demux_close_ogg(demuxer_t
*demuxer
)
1590 ogg_demuxer_t
*ogg_d
= demuxer
->priv
;
1591 ogg_stream_t
*os
= NULL
;
1601 ogg_sync_clear(&ogg_d
->sync
);
1603 for (i
= 0; i
< ogg_d
->num_sub
; i
++) {
1604 os
= &ogg_d
->subs
[i
];
1605 ogg_stream_clear(&os
->stream
);
1606 if (os
->vi_initialized
)
1607 vorbis_info_clear(&os
->vi
);
1611 if (ogg_d
->syncpoints
)
1612 free(ogg_d
->syncpoints
);
1613 if (ogg_d
->text_ids
)
1614 free(ogg_d
->text_ids
);
1615 if (ogg_d
->text_langs
) {
1616 for (i
= 0; i
< ogg_d
->n_text
; i
++)
1617 if (ogg_d
->text_langs
[i
]) free(ogg_d
->text_langs
[i
]);
1618 free(ogg_d
->text_langs
);
1623 static int demux_ogg_control(demuxer_t
*demuxer
, int cmd
, void *arg
)
1625 ogg_demuxer_t
*ogg_d
= demuxer
->priv
;
1629 if (demuxer
->video
->id
>= 0) {
1630 os
= &ogg_d
->subs
[demuxer
->video
->id
];
1631 rate
= os
->samplerate
;
1633 os
= &ogg_d
->subs
[demuxer
->audio
->id
];
1638 case DEMUXER_CTRL_GET_TIME_LENGTH
:
1639 if (ogg_d
->duration
<= 0)
1640 return DEMUXER_CTRL_DONTKNOW
;
1641 *(double *)arg
= (double)(ogg_d
->duration
) / rate
;
1642 return DEMUXER_CTRL_GUESS
;
1644 case DEMUXER_CTRL_GET_PERCENT_POS
:
1645 if (ogg_d
->duration
<= 0)
1646 return DEMUXER_CTRL_DONTKNOW
;
1647 *(int *)arg
= ((os
->lastpos
- ogg_d
->initial_granulepos
) * 100) / ogg_d
->duration
;
1648 return DEMUXER_CTRL_OK
;
1651 return DEMUXER_CTRL_NOTIMPL
;
1655 const demuxer_desc_t demuxer_desc_ogg
= {
1662 1, // safe autodetect
1664 demux_ogg_fill_buffer
,