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 "libavutil/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
;
167 extern int dvdsub_id
;
169 //-------- subtitle support - should be moved to decoder layer, and queue
170 // - subtitles up in demuxer buffer...
172 #include "subreader.h"
173 #include "libvo/sub.h"
174 #define OGG_SUB_MAX_LINE 128
176 static subtitle ogg_sub
;
179 static void demux_ogg_add_sub(ogg_stream_t
*os
, ogg_packet
*pack
)
182 char *packet
= pack
->packet
;
186 mp_msg(MSGT_DEMUX
, MSGL_DBG2
, "\ndemux_ogg_add_sub %02X %02X %02X '%s'\n",
187 (unsigned char)packet
[0],
188 (unsigned char)packet
[1],
189 (unsigned char)packet
[2],
192 if (((unsigned char)packet
[0]) == 0x88) { // some subtitle text
194 double endpts
= MP_NOPTS_VALUE
;
195 int32_t duration
= 0;
196 int16_t hdrlen
= (*packet
& PACKET_LEN_BITS01
) >> 6, i
;
198 hdrlen
|= (*packet
& PACKET_LEN_BITS2
) << 1;
200 if (pack
->bytes
< lcv
)
202 for (i
= hdrlen
; i
> 0; i
--) {
204 duration
|= (unsigned char)packet
[i
];
206 if (hdrlen
> 0 && duration
> 0) {
209 if (pack
->granulepos
== -1)
210 pack
->granulepos
= os
->lastpos
+ os
->lastsize
;
211 pts
= (float)pack
->granulepos
/ (float)os
->samplerate
;
212 endpts
= 1.0 + pts
+ (float)duration
/ 1000.0;
214 sub_clear_text(&ogg_sub
, MP_NOPTS_VALUE
);
215 sub_add_text(&ogg_sub
, &packet
[lcv
], pack
->bytes
- lcv
, endpts
);
218 mp_msg(MSGT_DEMUX
, MSGL_DBG2
, "Ogg sub lines: %d first: '%s'\n",
219 ogg_sub
.lines
, ogg_sub
.text
[0]);
221 subcp_recode(&ogg_sub
);
224 vo_osd_changed(OSDTYPE_SUBTITLE
);
228 // get the logical stream of the current page
229 // fill os if non NULL and return the stream id
230 static int demux_ogg_get_page_stream(ogg_demuxer_t
*ogg_d
,
231 ogg_stream_state
**os
)
234 ogg_page
*page
= &ogg_d
->page
;
236 s_no
= ogg_page_serialno(page
);
238 for (id
= 0; id
< ogg_d
->num_sub
; id
++)
239 if (s_no
== ogg_d
->subs
[id
].stream
.serialno
)
242 if (id
== ogg_d
->num_sub
) {
243 // If we have only one vorbis stream allow the stream id to change
244 // it's normal on radio stream (each song have an different id).
245 // But we (or the codec?) should check that the samplerate, etc
246 // doesn't change (for radio stream it's ok)
247 if (ogg_d
->num_sub
== 1 && ogg_d
->subs
[0].vorbis
) {
248 ogg_stream_reset(&ogg_d
->subs
[0].stream
);
249 ogg_stream_init(&ogg_d
->subs
[0].stream
, s_no
);
256 *os
= &ogg_d
->subs
[id
].stream
;
261 static unsigned char *demux_ogg_read_packet(ogg_stream_t
*os
, ogg_packet
*pack
,
262 float *pts
, int *flags
,
265 unsigned char *data
= pack
->packet
;
266 int size
= pack
->bytes
;
268 *pts
= MP_NOPTS_VALUE
;
272 if (*pack
->packet
& PACKET_TYPE_HEADER
) {
276 int32_t blocksize
= 0;
278 // When we dump the audio, there is no vi, but we don't care of timestamp in this case
279 vi
= os
->vi_initialized
? &os
->vi
: NULL
;
281 blocksize
= vorbis_packet_blocksize(vi
, pack
) / samplesize
;
282 // Calculate the timestamp if the packet don't have any
283 if (pack
->granulepos
== -1) {
284 pack
->granulepos
= os
->lastpos
;
285 if (os
->lastsize
> 0)
286 pack
->granulepos
+= os
->lastsize
;
290 *pts
= pack
->granulepos
/ (float)vi
->rate
;
291 os
->lastsize
= blocksize
;
292 os
->lastpos
= pack
->granulepos
;
294 } else if (os
->speex
) {
295 // whole packet (default)
296 # ifdef CONFIG_OGGTHEORA
297 } else if (os
->theora
) {
298 /* we pass complete packets to theora, mustn't strip the header! */
301 /* header packets begin on 1-bit: thus check (*data&0x80). We don't
302 have theora_state st, until all header packets were passed to the
304 if (!size
|| !(*data
&0x80)) {
305 int keyframe_granule_shift
= _ilog(os
->keyframe_frequency_force
- 1);
306 int64_t iframemask
= (1 << keyframe_granule_shift
) - 1;
308 if (pack
->granulepos
>= 0) {
309 os
->lastpos
= pack
->granulepos
>> keyframe_granule_shift
;
310 os
->lastpos
+= pack
->granulepos
& iframemask
;
311 *flags
= (pack
->granulepos
& iframemask
) == 0;
315 pack
->granulepos
= os
->lastpos
;
316 *pts
= (double)os
->lastpos
/ (double)os
->samplerate
;
318 #endif /* CONFIG_OGGTHEORA */
319 } else if (os
->flac
) {
320 /* we pass complete packets to flac, mustn't strip the header! */
321 if (os
->flac
== 2 && pack
->packet
[0] != 0xff)
324 if (*pack
->packet
& PACKET_TYPE_HEADER
) {
328 int16_t hdrlen
= (*pack
->packet
& PACKET_LEN_BITS01
) >> 6;
330 hdrlen
|= (*pack
->packet
& PACKET_LEN_BITS2
) << 1;
331 data
= pack
->packet
+ 1 + hdrlen
;
332 // Calculate the timestamp
333 if (pack
->granulepos
== -1)
334 pack
->granulepos
= os
->lastpos
+ (os
->lastsize
? os
->lastsize
: 1);
335 // If we already have a timestamp it can be a syncpoint
336 if (*pack
->packet
& PACKET_IS_SYNCPOINT
)
338 *pts
= pack
->granulepos
/ os
->samplerate
;
339 // Save the packet length and timestamp
343 os
->lastsize
|= pack
->packet
[hdrlen
];
346 os
->lastpos
= pack
->granulepos
;
352 // check if clang has substring from comma separated langlist
353 static int demux_ogg_check_lang(const char *clang
, const char *langlist
)
357 if (!langlist
|| !*langlist
)
359 while ((c
= strchr(langlist
, ','))) {
360 if (!strncasecmp(clang
, langlist
, c
- langlist
))
364 if (!strncasecmp(clang
, langlist
, strlen(langlist
)))
369 /** \brief Change the current subtitle stream and return its ID.
371 \param demuxer The demuxer whose subtitle stream will be changed.
372 \param new_num The number of the new subtitle track. The number must be
373 between 0 and ogg_d->n_text - 1.
375 \returns The Ogg stream number ( = page serial number) of the newly selected
378 static int demux_ogg_sub_id(demuxer_t
*demuxer
, int index
)
380 ogg_demuxer_t
*ogg_d
= demuxer
->priv
;
381 return (index
< 0) ? index
: (index
>= ogg_d
->n_text
) ? -1 : ogg_d
->text_ids
[index
];
384 /** \brief Translate the ogg track number into the subtitle number.
385 * \param demuxer The demuxer about whose subtitles we are inquiring.
386 * \param id The ogg track number of the subtitle track.
388 static int demux_ogg_sub_reverse_id(demuxer_t
*demuxer
, int id
)
390 ogg_demuxer_t
*ogg_d
= demuxer
->priv
;
393 for (i
= 0; i
< ogg_d
->n_text
; i
++)
394 if (ogg_d
->text_ids
[i
] == id
)
399 /// Try to print out comments and also check for LANGUAGE= tag
400 static void demux_ogg_check_comments(demuxer_t
*d
, ogg_stream_t
*os
,
401 int id
, vorbis_comment
*vc
)
403 const char *hdr
, *val
;
404 char **cmt
= vc
->user_comments
;
406 ogg_demuxer_t
*ogg_d
= d
->priv
;
407 static const struct table
{
411 { "ENCODED_USING", "Software" },
412 { "ENCODER_URL", "Encoder URL" },
413 { "TITLE", "Title" },
414 { "ARTIST", "Artist" },
415 { "COMMENT", "Comments" },
416 { "DATE", "Creation Date" },
417 { "GENRE", "Genre" },
418 { "ALBUM", "Album" },
419 { "TRACKNUMBER", "Track" },
425 if (!strncasecmp(*cmt
, "LANGUAGE=", 9)) {
427 if (ogg_d
->subs
[id
].text
)
428 mp_msg(MSGT_IDENTIFY
, MSGL_INFO
, "ID_SID_%d_LANG=%s\n",
429 ogg_d
->subs
[id
].id
, val
);
430 else if (id
!= d
->video
->id
)
431 mp_msg(MSGT_IDENTIFY
, MSGL_INFO
, "ID_AID_%d_LANG=%s\n",
432 ogg_d
->subs
[id
].id
, val
);
433 if (ogg_d
->subs
[id
].text
)
434 mp_msg(MSGT_DEMUX
, MSGL_INFO
,
435 "[Ogg] Language for -sid %d is '-slang \"%s\"'\n",
436 ogg_d
->subs
[id
].id
, val
);
437 // copy this language name into the array
438 index
= demux_ogg_sub_reverse_id(d
, id
);
442 // in case of malicious files with more than one lang per track:
443 if (ogg_d
->text_langs
[index
])
444 free(ogg_d
->text_langs
[index
]);
445 ogg_d
->text_langs
[index
] = strdup(val
);
446 sh
= d
->s_streams
[index
];
450 sh
->lang
= strdup(val
);
452 // check for -slang if subs are uninitialized yet
453 if (os
->text
&& d
->sub
->id
< 0 && demux_ogg_check_lang(val
, dvdsub_lang
)) {
456 mp_msg(MSGT_DEMUX
, MSGL_V
,
457 "Ogg demuxer: Displaying subtitle stream id %d which matched -slang %s\n",
464 for (i
= 0; table
[i
].ogg
; i
++) {
465 if (!strncasecmp(*cmt
, table
[i
].ogg
, strlen(table
[i
].ogg
)) &&
466 (*cmt
)[strlen(table
[i
].ogg
)] == '=') {
468 val
= *cmt
+ strlen(table
[i
].ogg
) + 1;
473 demux_info_add(d
, hdr
, val
);
474 mp_dbg(MSGT_DEMUX
, MSGL_DBG2
, " %s: %s\n", hdr
, val
);
479 /// Calculate the timestamp and add the packet to the demux stream
480 // return 1 if the packet was added, 0 otherwise
481 static int demux_ogg_add_packet(demux_stream_t
*ds
, ogg_stream_t
*os
,
482 int id
, ogg_packet
*pack
)
484 demuxer_t
*d
= ds
->demuxer
;
491 // If packet is an comment header then we try to get comments at first
492 if (pack
->bytes
>= 7 && !memcmp(pack
->packet
, "\003vorbis", 7)) {
496 vorbis_info_init(&vi
);
497 vorbis_comment_init(&vc
);
498 vi
.rate
= 1L; // it's checked by vorbis_synthesis_headerin()
499 if (vorbis_synthesis_headerin(&vi
, &vc
, pack
) == 0) // if no errors
500 demux_ogg_check_comments(d
, os
, id
, &vc
);
501 vorbis_comment_clear(&vc
);
502 vorbis_info_clear(&vi
);
505 if (id
== demux_ogg_sub_id(d
, d
->sub
->id
)) // don't want to add subtitles to the demuxer for now
506 demux_ogg_add_sub(os
, pack
);
510 // discard first two packets, they contain the header and comment
511 if (os
->hdr_packets
< 2) {
516 // If packet is an header we jump it except for vorbis and theora
517 // (PACKET_TYPE_HEADER bit doesn't even exist for theora ?!)
518 // We jump nothing for FLAC. Ain't this great? Packet contents have to be
519 // handled differently for each and every stream type. The joy! The joy!
520 if (!os
->flac
&& (*pack
->packet
& PACKET_TYPE_HEADER
) &&
521 (ds
!= d
->audio
|| ((sh_audio_t
*)ds
->sh
)->format
!= FOURCC_VORBIS
|| os
->hdr_packets
>= NUM_VORBIS_HDR_PACKETS
) &&
522 (ds
!= d
->video
|| (((sh_video_t
*)ds
->sh
)->format
!= FOURCC_THEORA
)))
526 // For vorbis packet the packet is the data, for other codec we must jump
528 if (ds
== d
->audio
&& ((sh_audio_t
*)ds
->sh
)->format
== FOURCC_VORBIS
) {
529 samplesize
= ((sh_audio_t
*)ds
->sh
)->samplesize
;
531 data
= demux_ogg_read_packet(os
, pack
, &pts
, &flags
, samplesize
);
535 /// Clear subtitles if necessary (for broken files)
536 if (sub_clear_text(&ogg_sub
, pts
)) {
538 vo_osd_changed(OSDTYPE_SUBTITLE
);
541 dp
= new_demux_packet(pack
->bytes
- (data
- pack
->packet
));
542 memcpy(dp
->buffer
, data
, pack
->bytes
- (data
- pack
->packet
));
545 ds_add_packet(ds
, dp
);
546 mp_msg(MSGT_DEMUX
, MSGL_DBG2
,
547 "New dp: %p ds=%p pts=%5.3f len=%d flag=%d \n",
548 dp
, ds
, pts
, dp
->len
, flags
);
552 /// if -forceidx build a table of all syncpoints to make seeking easier
553 /// otherwise try to get at least the final_granulepos
554 static void demux_ogg_scan_stream(demuxer_t
*demuxer
)
556 ogg_demuxer_t
*ogg_d
= demuxer
->priv
;
557 stream_t
*s
= demuxer
->stream
;
558 ogg_sync_state
*sync
= &ogg_d
->sync
;
559 ogg_page
*page
= &ogg_d
->page
;
560 ogg_stream_state
*oss
;
563 int np
, sid
, p
, samplesize
= 1;
566 pos
= last_pos
= demuxer
->movi_start
;
569 stream_seek(s
, demuxer
->movi_start
);
570 ogg_sync_reset(sync
);
572 // Get the serial number of the stream we use
573 if (demuxer
->video
->id
>= 0) {
574 sid
= demuxer
->video
->id
;
575 } else if (demuxer
->audio
->id
>= 0) {
576 sid
= demuxer
->audio
->id
;
577 if (((sh_audio_t
*)demuxer
->audio
->sh
)->format
== FOURCC_VORBIS
)
578 samplesize
= ((sh_audio_t
*)demuxer
->audio
->sh
)->samplesize
;
581 os
= &ogg_d
->subs
[sid
];
585 np
= ogg_sync_pageseek(sync
, page
);
586 if (np
< 0) { // We had to skip some bytes
588 mp_msg(MSGT_DEMUX
, MSGL_ERR
,
589 "Bad page sync while building syncpoints table (%d)\n",
594 if (np
<= 0) { // We need more data
595 char *buf
= ogg_sync_buffer(sync
, BLOCK_SIZE
);
596 int len
= stream_read(s
, buf
, BLOCK_SIZE
);
598 if (len
== 0 && s
->eof
)
600 ogg_sync_wrote(sync
, len
);
604 //ogg_sync_pageout(sync, page);
605 if (ogg_page_serialno(page
) != os
->stream
.serialno
) { // It isn't a page from the stream we want
609 if (ogg_stream_pagein(oss
, page
) != 0) {
610 mp_msg(MSGT_DEMUX
, MSGL_ERR
, "Pagein error ????\n");
615 while (ogg_stream_packetout(oss
, &op
) == 1) {
619 demux_ogg_read_packet(os
, &op
, &pts
, &flags
, samplesize
);
620 if (op
.granulepos
>= 0) {
621 ogg_d
->final_granulepos
= op
.granulepos
;
622 if (ogg_d
->initial_granulepos
== MP_NOPTS_VALUE
&& (flags
& 1)) {
623 ogg_d
->initial_granulepos
= op
.granulepos
;
624 if (index_mode
!= 2 && ogg_d
->pos
< demuxer
->movi_end
- 2 * 270000) {
625 //the 270000 are just a wild guess
626 stream_seek(s
, FFMAX(ogg_d
->pos
, demuxer
->movi_end
- 270000));
627 ogg_sync_reset(sync
);
632 if (index_mode
== 2 && (flags
|| (os
->vorbis
&& op
.granulepos
>= 0))) {
633 if (ogg_d
->num_syncpoint
> SIZE_MAX
/ sizeof(ogg_syncpoint_t
) - 1)
635 ogg_d
->syncpoints
= realloc_struct(ogg_d
->syncpoints
, (ogg_d
->num_syncpoint
+ 1), sizeof(ogg_syncpoint_t
));
636 ogg_d
->syncpoints
[ogg_d
->num_syncpoint
].granulepos
= op
.granulepos
;
637 ogg_d
->syncpoints
[ogg_d
->num_syncpoint
].page_pos
= (ogg_page_continued(page
) && p
== 0) ? last_pos
: pos
;
638 ogg_d
->num_syncpoint
++;
642 if (p
> 1 || (p
== 1 && !ogg_page_continued(page
)))
646 mp_msg(MSGT_DEMUX
, MSGL_INFO
, "Building syncpoint table %d%%\r",
647 (int)(pos
* 100 / s
->end_pos
));
650 if (index_mode
== 2) {
651 mp_msg(MSGT_DEMUX
, MSGL_INFO
, "\n");
652 mp_msg(MSGT_DEMUX
, MSGL_V
,
653 "Ogg syncpoints table builed: %d syncpoints\n",
654 ogg_d
->num_syncpoint
);
657 mp_msg(MSGT_DEMUX
, MSGL_V
, "Ogg stream length (granulepos): %"PRId64
"\n",
658 ogg_d
->final_granulepos
);
661 stream_seek(s
, demuxer
->movi_start
);
662 ogg_sync_reset(sync
);
663 for (np
= 0; np
< ogg_d
->num_sub
; np
++) {
664 ogg_stream_reset(&ogg_d
->subs
[np
].stream
);
665 ogg_d
->subs
[np
].lastpos
= ogg_d
->subs
[np
].lastsize
= ogg_d
->subs
[np
].hdr_packets
= 0;
668 // Get the first page
670 np
= ogg_sync_pageout(sync
, page
);
671 if (np
<= 0) { // We need more data
672 char *buf
= ogg_sync_buffer(sync
, BLOCK_SIZE
);
673 int len
= stream_read(s
, buf
, BLOCK_SIZE
);
675 if (len
== 0 && s
->eof
) {
676 mp_msg(MSGT_DEMUX
, MSGL_ERR
, "EOF while trying to get the first page !!!!\n");
679 ogg_sync_wrote(sync
, len
);
682 demux_ogg_get_page_stream(ogg_d
, &oss
);
683 ogg_stream_pagein(oss
, page
);
688 static void fixup_vorbis_wf(sh_audio_t
*sh
, ogg_demuxer_t
*od
)
691 int ris
, init_error
= 0;
693 unsigned char *buf
[3];
696 ogg_stream_t
*os
= &od
->subs
[sh
->ds
->id
];
699 vorbis_info_init(&os
->vi
);
700 vorbis_comment_init(&vc
);
701 for (i
= 0; i
< 3; i
++) {
702 op
[i
].bytes
= ds_get_packet(sh
->ds
, &(op
[i
].packet
));
703 mp_msg(MSGT_DEMUX
, MSGL_V
, "fixup_vorbis_wf: i=%d, size=%ld\n", i
, op
[i
].bytes
);
704 if (op
[i
].bytes
< 0) {
705 mp_msg(MSGT_DEMUX
, MSGL_ERR
, "Ogg demuxer error!, fixup_vorbis_wf: bad packet n. %d\n", i
);
708 buf
[i
] = malloc(op
[i
].bytes
);
711 memcpy(buf
[i
], op
[i
].packet
, op
[i
].bytes
);
713 op
[i
].b_o_s
= (i
== 0);
714 ris
= vorbis_synthesis_headerin(&os
->vi
, &vc
, &op
[i
]);
717 mp_msg(MSGT_DECAUDIO
, MSGL_ERR
, "DEMUX_OGG: header n. %d broken! len=%ld, code: %d\n", i
, op
[i
].bytes
, ris
);
720 vorbis_comment_clear(&vc
);
722 os
->vi_initialized
= 1;
724 len
= op
[0].bytes
+ op
[1].bytes
+ op
[2].bytes
;
725 sh
->wf
= calloc(1, sizeof(WAVEFORMATEX
) + len
+ len
/ 255 + 64);
726 ptr
= (unsigned char*)(sh
->wf
+ 1);
730 offset
+= store_ughvlc(&ptr
[offset
], op
[0].bytes
);
731 mp_msg(MSGT_DEMUX
, MSGL_V
, "demux_ogg, offset after 1st len = %u\n", offset
);
732 offset
+= store_ughvlc(&ptr
[offset
], op
[1].bytes
);
733 mp_msg(MSGT_DEMUX
, MSGL_V
, "demux_ogg, offset after 2nd len = %u\n", offset
);
734 for (i
= 0; i
< 3; i
++) {
735 mp_msg(MSGT_DEMUX
, MSGL_V
, "demux_ogg, i=%d, bytes: %ld, offset: %u\n", i
, op
[i
].bytes
, offset
);
736 memcpy(&ptr
[offset
], buf
[i
], op
[i
].bytes
);
737 offset
+= op
[i
].bytes
;
739 sh
->wf
->cbSize
= offset
;
740 mp_msg(MSGT_DEMUX
, MSGL_V
, "demux_ogg, extradata size: %d\n", sh
->wf
->cbSize
);
741 sh
->wf
= realloc(sh
->wf
, sizeof(WAVEFORMATEX
) + sh
->wf
->cbSize
);
743 if (op
[0].bytes
>= 29) {
745 int nombr
, minbr
, maxbr
;
748 sh
->channels
= ptr
[11];
749 sh
->samplerate
= sh
->wf
->nSamplesPerSec
= AV_RL32(&ptr
[12]);
750 maxbr
= AV_RL32(&ptr
[16]); //max
751 nombr
= AV_RL32(&ptr
[20]); //nominal
752 minbr
= AV_RL32(&ptr
[24]); //minimum
766 sh
->wf
->nAvgBytesPerSec
= br
;
767 sh
->wf
->wBitsPerSample
= 16;
768 sh
->samplesize
= (sh
->wf
->wBitsPerSample
+ 7) / 8;
770 mp_msg(MSGT_DEMUX
, MSGL_V
,
771 "demux_ogg, vorbis stream features are: channels: %d, srate: %d, bitrate: %d, max: %u, nominal: %u, min: %u\n",
772 sh
->channels
, sh
->samplerate
, sh
->wf
->nAvgBytesPerSec
,
773 maxbr
, nombr
, minbr
);
780 /// Open an ogg physical stream
781 // Not static because it's used also in demuxer_avi.c
782 int demux_ogg_open(demuxer_t
*demuxer
)
784 ogg_demuxer_t
*ogg_d
;
787 int np
, s_no
, n_audio
= 0, n_video
= 0;
788 int audio_id
= -1, video_id
= -1, text_id
= -1;
789 ogg_sync_state
*sync
;
801 demuxer
->priv
= ogg_d
= calloc(1, sizeof(*ogg_d
));
808 /// Try to get a page
809 ogg_d
->pos
+= ogg_d
->last_size
;
810 np
= ogg_sync_pageseek(sync
, page
);
813 mp_msg(MSGT_DEMUX
, MSGL_DBG2
, "Ogg demuxer : Bad page sync\n");
816 /// Need some more data
820 buf
= ogg_sync_buffer(sync
, BLOCK_SIZE
);
821 len
= stream_read(s
, buf
, BLOCK_SIZE
);
822 if (len
== 0 && s
->eof
) {
825 ogg_sync_wrote(sync
, len
);
828 ogg_d
->last_size
= np
;
829 // We got one page now
831 if (!ogg_page_bos(page
)) { // It's not a beginning page
832 // Header parsing end here, we need to get the page otherwise it will be lost
833 int id
= demux_ogg_get_page_stream(ogg_d
, NULL
);
835 ogg_stream_pagein(&ogg_d
->subs
[id
].stream
, page
);
837 mp_msg(MSGT_DEMUX
, MSGL_ERR
,
838 "Ogg : Warning found none bos page from unknown stream %d\n",
839 ogg_page_serialno(page
));
843 /// Init the data structure needed for a logical stream
844 ogg_d
->subs
= realloc_struct(ogg_d
->subs
, ogg_d
->num_sub
+1,
845 sizeof(ogg_stream_t
));
846 memset(&ogg_d
->subs
[ogg_d
->num_sub
], 0, sizeof(ogg_stream_t
));
847 /// Get the stream serial number
848 s_no
= ogg_page_serialno(page
);
849 ogg_stream_init(&ogg_d
->subs
[ogg_d
->num_sub
].stream
, s_no
);
850 mp_msg(MSGT_DEMUX
, MSGL_DBG2
,
851 "Ogg : Found a stream with serial=%d\n", s_no
);
852 // Take the first page
853 ogg_stream_pagein(&ogg_d
->subs
[ogg_d
->num_sub
].stream
, page
);
854 // Get first packet of the page
855 ogg_stream_packetout(&ogg_d
->subs
[ogg_d
->num_sub
].stream
, &pack
);
861 ogg_d
->subs
[ogg_d
->num_sub
].ogg_d
= ogg_d
;
864 if (pack
.bytes
>= 7 && !strncmp(&pack
.packet
[1], "vorbis", 6)) {
865 sh_a
= new_sh_audio_aid(demuxer
, ogg_d
->num_sub
, n_audio
);
866 sh_a
->format
= FOURCC_VORBIS
;
867 ogg_d
->subs
[ogg_d
->num_sub
].vorbis
= 1;
868 ogg_d
->subs
[ogg_d
->num_sub
].id
= n_audio
;
870 mp_msg(MSGT_DEMUX
, MSGL_INFO
,
871 "[Ogg] stream %d: audio (Vorbis), -aid %d\n",
872 ogg_d
->num_sub
, n_audio
- 1);
873 } else if (pack
.bytes
>= 80 && !strncmp(pack
.packet
, "Speex", 5)) {
874 sh_a
= new_sh_audio_aid(demuxer
, ogg_d
->num_sub
, n_audio
);
875 sh_a
->wf
= calloc(1, sizeof(WAVEFORMATEX
) + pack
.bytes
);
876 sh_a
->format
= FOURCC_SPEEX
;
877 sh_a
->samplerate
= sh_a
->wf
->nSamplesPerSec
= AV_RL32(&pack
.packet
[36]);
878 sh_a
->channels
= sh_a
->wf
->nChannels
= AV_RL32(&pack
.packet
[48]);
879 sh_a
->wf
->wFormatTag
= sh_a
->format
;
880 sh_a
->wf
->nAvgBytesPerSec
= AV_RL32(&pack
.packet
[52]);
881 sh_a
->wf
->nBlockAlign
= 0;
882 sh_a
->wf
->wBitsPerSample
= 16;
883 sh_a
->samplesize
= 2;
884 sh_a
->wf
->cbSize
= pack
.bytes
;
885 memcpy(&sh_a
->wf
[1], pack
.packet
, pack
.bytes
);
887 ogg_d
->subs
[ogg_d
->num_sub
].samplerate
= sh_a
->samplerate
;
888 ogg_d
->subs
[ogg_d
->num_sub
].speex
= 1;
889 ogg_d
->subs
[ogg_d
->num_sub
].id
= n_audio
;
891 mp_msg(MSGT_DEMUX
, MSGL_INFO
,
892 "[Ogg] stream %d: audio (Speex), -aid %d\n",
893 ogg_d
->num_sub
, n_audio
- 1);
896 #ifdef CONFIG_OGGTHEORA
897 } else if (pack
.bytes
>= 7 && !strncmp (&pack
.packet
[1], "theora", 6)) {
902 theora_info_init (&inf
);
903 theora_comment_init (&cc
);
905 errorCode
= theora_decode_header (&inf
, &cc
, &pack
);
907 mp_msg(MSGT_DEMUX
, MSGL_ERR
,
908 "Theora header parsing failed: %i \n", errorCode
);
910 sh_v
= new_sh_video_vid(demuxer
, ogg_d
->num_sub
, n_video
);
912 sh_v
->bih
= calloc(1, sizeof(BITMAPINFOHEADER
));
913 sh_v
->bih
->biSize
= sizeof(BITMAPINFOHEADER
);
914 sh_v
->bih
->biCompression
= sh_v
->format
= FOURCC_THEORA
;
915 sh_v
->fps
= ((double)inf
.fps_numerator
) / (double)inf
.fps_denominator
;
916 sh_v
->frametime
= ((double)inf
.fps_denominator
) / (double)inf
.fps_numerator
;
917 sh_v
->disp_w
= sh_v
->bih
->biWidth
= inf
.frame_width
;
918 sh_v
->disp_h
= sh_v
->bih
->biHeight
= inf
.frame_height
;
919 sh_v
->bih
->biBitCount
= 24;
920 sh_v
->bih
->biPlanes
= 3;
921 sh_v
->bih
->biSizeImage
= ((sh_v
->bih
->biBitCount
/ 8) * sh_v
->bih
->biWidth
* sh_v
->bih
->biHeight
);
922 ogg_d
->subs
[ogg_d
->num_sub
].samplerate
= sh_v
->fps
;
923 ogg_d
->subs
[ogg_d
->num_sub
].theora
= 1;
924 ogg_d
->subs
[ogg_d
->num_sub
].keyframe_frequency_force
= inf
.keyframe_frequency_force
;
925 ogg_d
->subs
[ogg_d
->num_sub
].id
= n_video
;
927 mp_msg(MSGT_DEMUX
, MSGL_INFO
,
928 "[Ogg] stream %d: video (Theora v%d.%d.%d), -vid %d\n",
930 (int)inf
.version_major
,
931 (int)inf
.version_minor
,
932 (int)inf
.version_subminor
,
934 if (mp_msg_test(MSGT_HEADER
, MSGL_V
))
935 print_video_header(sh_v
->bih
, MSGL_V
);
937 theora_comment_clear(&cc
);
938 theora_info_clear(&inf
);
939 #endif /* CONFIG_OGGTHEORA */
940 } else if (pack
.bytes
>= 4 && !strncmp (&pack
.packet
[0], "fLaC", 4)) {
941 sh_a
= new_sh_audio_aid(demuxer
, ogg_d
->num_sub
, n_audio
);
942 sh_a
->format
= mmioFOURCC('f', 'L', 'a', 'C');
943 ogg_d
->subs
[ogg_d
->num_sub
].id
= n_audio
;
945 ogg_d
->subs
[ogg_d
->num_sub
].flac
= 1;
947 mp_msg(MSGT_DEMUX
, MSGL_INFO
,
948 "[Ogg] stream %d: audio (FLAC), -aid %d\n",
949 ogg_d
->num_sub
, n_audio
- 1);
950 } else if (pack
.bytes
>= 51 && !strncmp(&pack
.packet
[1], "FLAC", 4)) {
951 sh_a
= new_sh_audio_aid(demuxer
, ogg_d
->num_sub
, n_audio
);
952 sh_a
->format
= mmioFOURCC('f', 'L', 'a', 'C');
953 ogg_d
->subs
[ogg_d
->num_sub
].id
= n_audio
;
955 ogg_d
->subs
[ogg_d
->num_sub
].flac
= 2;
956 sh_a
->wf
= calloc(1, sizeof(WAVEFORMATEX
) + 34);
957 sh_a
->wf
->wFormatTag
= sh_a
->format
;
958 sh_a
->wf
->cbSize
= 34;
959 memcpy(&sh_a
->wf
[1], &pack
.packet
[17], 34);
960 mp_msg(MSGT_DEMUX
, MSGL_INFO
,
961 "[Ogg] stream %d: audio (FLAC, try 2), -aid %d\n",
962 ogg_d
->num_sub
, n_audio
- 1);
964 /// Check for old header
965 } else if (pack
.bytes
>= 142 &&
966 !strncmp(&pack
.packet
[1], "Direct Show Samples embedded in Ogg", 35)) {
969 if (AV_RL32(pack
.packet
+ 96) == 0x05589f80 && pack
.bytes
>= 184) {
970 sh_v
= new_sh_video_vid(demuxer
, ogg_d
->num_sub
, n_video
);
971 sh_v
->bih
= calloc(1, sizeof(BITMAPINFOHEADER
));
972 sh_v
->bih
->biSize
= sizeof(BITMAPINFOHEADER
);
973 sh_v
->bih
->biCompression
= sh_v
->format
= mmioFOURCC(pack
.packet
[68], pack
.packet
[69],
974 pack
.packet
[70], pack
.packet
[71]);
975 sh_v
->frametime
= AV_RL64(pack
.packet
+ 164) * 0.0000001;
976 sh_v
->fps
= 1 / sh_v
->frametime
;
977 sh_v
->disp_w
= sh_v
->bih
->biWidth
= AV_RL32(pack
.packet
+ 176);
978 sh_v
->disp_h
= sh_v
->bih
->biHeight
= AV_RL32(pack
.packet
+ 180);
979 sh_v
->bih
->biBitCount
= AV_RL16(pack
.packet
+ 182);
980 if (!sh_v
->bih
->biBitCount
)
981 sh_v
->bih
->biBitCount
= 24; // hack, FIXME
982 sh_v
->bih
->biPlanes
= 1;
983 sh_v
->bih
->biSizeImage
= (sh_v
->bih
->biBitCount
>> 3) * sh_v
->bih
->biWidth
* sh_v
->bih
->biHeight
;
985 ogg_d
->subs
[ogg_d
->num_sub
].samplerate
= sh_v
->fps
;
986 ogg_d
->subs
[ogg_d
->num_sub
].id
= n_video
;
988 mp_msg(MSGT_DEMUX
, MSGL_INFO
,
989 "[Ogg] stream %d: video (FOURCC %c%c%c%c), -vid %d\n",
990 ogg_d
->num_sub
, pack
.packet
[68], pack
.packet
[69],
991 pack
.packet
[70], pack
.packet
[71], n_video
- 1);
992 if (mp_msg_test(MSGT_HEADER
, MSGL_V
))
993 print_video_header(sh_v
->bih
, MSGL_V
);
995 } else if (AV_RL32(pack
.packet
+ 96) == 0x05589F81) {
996 unsigned int extra_size
;
998 sh_a
= new_sh_audio_aid(demuxer
, ogg_d
->num_sub
, n_audio
);
999 extra_size
= AV_RL16(pack
.packet
+ 140);
1000 sh_a
->wf
= calloc(1, sizeof(WAVEFORMATEX
) + extra_size
);
1001 sh_a
->format
= sh_a
->wf
->wFormatTag
= AV_RL16(pack
.packet
+ 124);
1002 sh_a
->channels
= sh_a
->wf
->nChannels
= AV_RL16(pack
.packet
+ 126);
1003 sh_a
->samplerate
= sh_a
->wf
->nSamplesPerSec
= AV_RL32(pack
.packet
+ 128);
1004 sh_a
->wf
->nAvgBytesPerSec
= AV_RL32(pack
.packet
+ 132);
1005 sh_a
->wf
->nBlockAlign
= AV_RL16(pack
.packet
+ 136);
1006 sh_a
->wf
->wBitsPerSample
= AV_RL16(pack
.packet
+ 138);
1007 sh_a
->samplesize
= (sh_a
->wf
->wBitsPerSample
+ 7) / 8;
1008 sh_a
->wf
->cbSize
= extra_size
;
1010 memcpy(((char *)sh_a
->wf
) + sizeof(WAVEFORMATEX
),
1011 pack
.packet
+ 142, extra_size
);
1013 ogg_d
->subs
[ogg_d
->num_sub
].samplerate
= sh_a
->samplerate
; // * sh_a->channels;
1014 ogg_d
->subs
[ogg_d
->num_sub
].id
= n_audio
;
1016 mp_msg(MSGT_DEMUX
, MSGL_INFO
,
1017 "[Ogg] stream %d: audio (format 0x%04x), -aid %d\n",
1018 ogg_d
->num_sub
, sh_a
->format
, n_audio
- 1);
1019 if (mp_msg_test(MSGT_HEADER
, MSGL_V
))
1020 print_wave_header(sh_a
->wf
, MSGL_V
);
1022 mp_msg(MSGT_DEMUX
, MSGL_WARN
,
1023 "Ogg stream %d contains an old header but the header type is unknown\n",
1027 } else if ((*pack
.packet
& PACKET_TYPE_BITS
) == PACKET_TYPE_HEADER
&&
1028 pack
.bytes
>= (int)sizeof(stream_header
) + 1) {
1029 stream_header
*st
= (stream_header
*)(pack
.packet
+ 1);
1030 /// New video header
1031 if (strncmp(st
->streamtype
, "video", 5) == 0) {
1032 sh_v
= new_sh_video_vid(demuxer
, ogg_d
->num_sub
, n_video
);
1033 sh_v
->bih
= calloc(1, sizeof(BITMAPINFOHEADER
));
1034 sh_v
->bih
->biSize
= sizeof(BITMAPINFOHEADER
);
1035 sh_v
->bih
->biCompression
= sh_v
->format
= mmioFOURCC(st
->subtype
[0], st
->subtype
[1],
1036 st
->subtype
[2], st
->subtype
[3]);
1037 sh_v
->frametime
= AV_RL64(&st
->time_unit
) * 0.0000001;
1038 sh_v
->fps
= 1.0 / sh_v
->frametime
;
1039 sh_v
->bih
->biBitCount
= AV_RL16(&st
->bits_per_sample
);
1040 sh_v
->disp_w
= sh_v
->bih
->biWidth
= AV_RL32(&st
->sh
.video
.width
);
1041 sh_v
->disp_h
= sh_v
->bih
->biHeight
= AV_RL32(&st
->sh
.video
.height
);
1042 if (!sh_v
->bih
->biBitCount
)
1043 sh_v
->bih
->biBitCount
= 24; // hack, FIXME
1044 sh_v
->bih
->biPlanes
= 1;
1045 sh_v
->bih
->biSizeImage
= (sh_v
->bih
->biBitCount
>> 3) * sh_v
->bih
->biWidth
* sh_v
->bih
->biHeight
;
1047 ogg_d
->subs
[ogg_d
->num_sub
].samplerate
= sh_v
->fps
;
1048 ogg_d
->subs
[ogg_d
->num_sub
].id
= n_video
;
1050 mp_msg(MSGT_DEMUX
, MSGL_INFO
,
1051 "[Ogg] stream %d: video (FOURCC %c%c%c%c), -vid %d\n",
1052 ogg_d
->num_sub
, st
->subtype
[0], st
->subtype
[1],
1053 st
->subtype
[2], st
->subtype
[3], n_video
- 1);
1054 if (mp_msg_test(MSGT_HEADER
, MSGL_V
))
1055 print_video_header(sh_v
->bih
, MSGL_V
);
1056 /// New audio header
1057 } else if (strncmp(st
->streamtype
, "audio", 5) == 0) {
1059 unsigned int extra_size
= AV_RL32(&st
->size
) - sizeof(stream_header
);
1060 unsigned int extra_offset
= 0;
1062 memcpy(buffer
, st
->subtype
, 4);
1065 /* Nasty workaround. stream_header.size seems not to contain the real
1066 size in all cases. There are four extra bytes that are unaccounted
1067 for in front of the real codec initialization data _at least_ for
1068 AAC. So far I've only seen those bytes being all 0, so we can
1069 just skip them here. */
1070 if ((strtol(buffer
, NULL
, 16) == 0xff) && (extra_size
>= 4)) {
1075 sh_a
= new_sh_audio_aid(demuxer
, ogg_d
->num_sub
, n_audio
);
1076 sh_a
->wf
= calloc(1, sizeof(WAVEFORMATEX
) + extra_size
);
1077 sh_a
->format
= sh_a
->wf
->wFormatTag
= strtol(buffer
, NULL
, 16);
1078 sh_a
->channels
= sh_a
->wf
->nChannels
= AV_RL16(&st
->sh
.audio
.channels
);
1079 sh_a
->samplerate
= sh_a
->wf
->nSamplesPerSec
= AV_RL64(&st
->samples_per_unit
);
1080 sh_a
->wf
->nAvgBytesPerSec
= AV_RL32(&st
->sh
.audio
.avgbytespersec
);
1081 sh_a
->wf
->nBlockAlign
= AV_RL16(&st
->sh
.audio
.blockalign
);
1082 sh_a
->wf
->wBitsPerSample
= AV_RL16(&st
->bits_per_sample
);
1083 sh_a
->samplesize
= (sh_a
->wf
->wBitsPerSample
+ 7) / 8;
1084 sh_a
->wf
->cbSize
= extra_size
;
1086 memcpy(((char *)sh_a
->wf
)+sizeof(WAVEFORMATEX
),
1087 ((char *)(st
+1))+extra_offset
, extra_size
);
1089 ogg_d
->subs
[ogg_d
->num_sub
].samplerate
= sh_a
->samplerate
; // * sh_a->channels;
1090 ogg_d
->subs
[ogg_d
->num_sub
].id
= n_audio
;
1092 mp_msg(MSGT_DEMUX
, MSGL_INFO
,
1093 "[Ogg] stream %d: audio (format 0x%04x), -aid %d\n",
1094 ogg_d
->num_sub
, sh_a
->format
, n_audio
- 1);
1095 if (mp_msg_test(MSGT_HEADER
, MSGL_V
))
1096 print_wave_header(sh_a
->wf
, MSGL_V
);
1098 /// Check for text (subtitles) header
1099 } else if (strncmp(st
->streamtype
, "text", 4) == 0) {
1100 mp_msg(MSGT_DEMUX
, MSGL_INFO
,
1101 "[Ogg] stream %d: subtitles (SRT-like text subtitles), -sid %d\n",
1102 ogg_d
->num_sub
, ogg_d
->n_text
);
1103 ogg_d
->subs
[ogg_d
->num_sub
].samplerate
= AV_RL64(&st
->time_unit
) / 10;
1104 ogg_d
->subs
[ogg_d
->num_sub
].text
= 1;
1105 ogg_d
->subs
[ogg_d
->num_sub
].id
= ogg_d
->n_text
;
1106 if (demuxer
->sub
->id
== ogg_d
->n_text
)
1107 text_id
= ogg_d
->num_sub
;
1108 new_sh_sub(demuxer
, ogg_d
->n_text
);
1110 ogg_d
->text_ids
= realloc_struct(ogg_d
->text_ids
, ogg_d
->n_text
, sizeof(*ogg_d
->text_ids
));
1111 ogg_d
->text_ids
[ogg_d
->n_text
- 1] = ogg_d
->num_sub
;
1112 ogg_d
->text_langs
= realloc_struct(ogg_d
->text_langs
, ogg_d
->n_text
, sizeof(*ogg_d
->text_langs
));
1113 ogg_d
->text_langs
[ogg_d
->n_text
- 1] = NULL
;
1114 //// Unknown header type
1116 mp_msg(MSGT_DEMUX
, MSGL_ERR
,
1117 "Ogg stream %d has a header marker but is of an unknown type\n",
1119 /// Unknown (invalid ?) header
1121 mp_msg(MSGT_DEMUX
, MSGL_ERR
,
1122 "Ogg stream %d is of an unknown type\n",
1126 demux_stream_t
*ds
= NULL
;
1128 // If the audio stream is not defined we took the first one
1129 if (demuxer
->audio
->id
== -1) {
1130 demuxer
->audio
->id
= n_audio
- 1;
1131 //if (sh_a->wf) print_wave_header(sh_a->wf, MSGL_INFO);
1133 /// Is it the stream we want
1134 if (demuxer
->audio
->id
== n_audio
- 1) {
1135 demuxer
->audio
->sh
= sh_a
;
1136 sh_a
->ds
= demuxer
->audio
;
1137 ds
= demuxer
->audio
;
1138 audio_id
= ogg_d
->num_sub
;
1143 if (demuxer
->video
->id
== -1) {
1144 demuxer
->video
->id
= n_video
- 1;
1145 //if (sh_v->bih) print_video_header(sh_v->bih, MSGL_INFO);
1147 if (demuxer
->video
->id
== n_video
- 1) {
1148 demuxer
->video
->sh
= sh_v
;
1149 sh_v
->ds
= demuxer
->video
;
1150 ds
= demuxer
->video
;
1151 video_id
= ogg_d
->num_sub
;
1154 /// Add the header packets if the stream isn't seekable
1155 if (ds
&& !s
->end_pos
) {
1156 /// Finish the page, otherwise packets will be lost
1158 demux_ogg_add_packet(ds
, &ogg_d
->subs
[ogg_d
->num_sub
],
1159 ogg_d
->num_sub
, &pack
);
1160 } while (ogg_stream_packetout(&ogg_d
->subs
[ogg_d
->num_sub
].stream
, &pack
) == 1);
1166 if (!n_video
&& !n_audio
) {
1170 if (!n_video
|| video_id
< 0)
1171 demuxer
->video
->id
= -2;
1173 demuxer
->video
->id
= video_id
;
1174 if (!n_audio
|| audio_id
< 0)
1175 demuxer
->audio
->id
= -2;
1177 demuxer
->audio
->id
= audio_id
;
1178 /* Disable the subs only if there are no text streams at all.
1179 Otherwise the stream to display might be chosen later when the comment
1180 packet is encountered and the user used -slang instead of -sid. */
1182 demuxer
->sub
->id
= -2;
1183 else if (text_id
>= 0) {
1184 demuxer
->sub
->id
= text_id
;
1185 mp_msg(MSGT_DEMUX
, MSGL_V
,
1186 "Ogg demuxer: Displaying subtitle stream id %d\n", text_id
);
1189 ogg_d
->final_granulepos
= 0;
1190 ogg_d
->initial_granulepos
= MP_NOPTS_VALUE
;
1192 demuxer
->seekable
= 0;
1194 demuxer
->movi_start
= s
->start_pos
; // Needed for XCD (Ogg written in MODE2)
1195 demuxer
->movi_end
= s
->end_pos
;
1196 demuxer
->seekable
= 1;
1197 demux_ogg_scan_stream(demuxer
);
1199 if (ogg_d
->initial_granulepos
== MP_NOPTS_VALUE
)
1200 ogg_d
->initial_granulepos
= 0;
1201 ogg_d
->duration
= ogg_d
->final_granulepos
- ogg_d
->initial_granulepos
;
1203 mp_msg(MSGT_DEMUX
, MSGL_V
,
1204 "Ogg demuxer : found %d audio stream%s, %d video stream%s and %d text stream%s\n",
1205 n_audio
, n_audio
> 1 ? "s" : "",
1206 n_video
, n_video
> 1 ? "s" : "",
1207 ogg_d
->n_text
, ogg_d
->n_text
> 1 ? "s" : "");
1209 sh_a
= demuxer
->audio
->sh
;
1210 if (sh_a
&& sh_a
->format
== FOURCC_VORBIS
)
1211 fixup_vorbis_wf(sh_a
, ogg_d
);
1213 return DEMUXER_TYPE_OGG
;
1219 static int demux_ogg_fill_buffer(demuxer_t
*d
, demux_stream_t
*dsds
)
1221 ogg_demuxer_t
*ogg_d
;
1224 ogg_sync_state
*sync
;
1225 ogg_stream_state
*os
;
1232 sync
= &ogg_d
->sync
;
1233 page
= &ogg_d
->page
;
1235 /// Find the stream we are working on
1236 if ((id
= demux_ogg_get_page_stream(ogg_d
, &os
)) < 0) {
1237 mp_msg(MSGT_DEMUX
, MSGL_ERR
, "Ogg demuxer : can't get current stream\n");
1244 /// Try to get some packet from the current page
1245 while ((np
= ogg_stream_packetout(os
, &pack
)) != 1) {
1246 /// No packet we go the next page
1252 ogg_d
->pos
+= ogg_d
->last_size
;
1253 /// Get the next page from the physical stream
1254 while ((pa
= ogg_sync_pageseek(sync
, page
)) <= 0) {
1255 /// Error : we skip some bytes
1257 mp_msg(MSGT_DEMUX
, MSGL_WARN
,
1258 "Ogg : Page out not synced, we skip some bytes\n");
1262 /// We need more data
1263 buf
= ogg_sync_buffer(sync
, BLOCK_SIZE
);
1264 len
= stream_read(s
, buf
, BLOCK_SIZE
);
1265 if (len
== 0 && s
->eof
) {
1266 mp_msg(MSGT_DEMUX
, MSGL_DBG2
, "Ogg : Stream EOF !!!!\n");
1269 ogg_sync_wrote(sync
, len
);
1271 ogg_d
->last_size
= pa
;
1272 /// Find the page's logical stream
1273 if ((id
= demux_ogg_get_page_stream(ogg_d
, &os
)) < 0) {
1274 mp_msg(MSGT_DEMUX
, MSGL_ERR
,
1275 "Ogg demuxer error : we met an unknown stream\n");
1279 if (ogg_stream_pagein(os
, page
) == 0)
1281 /// Page was invalid => retry
1282 mp_msg(MSGT_DEMUX
, MSGL_WARN
,
1283 "Ogg demuxer : got invalid page !!!!!\n");
1284 ogg_d
->pos
+= ogg_d
->last_size
;
1286 } else /// Packet was corrupted
1287 mp_msg(MSGT_DEMUX
, MSGL_WARN
,
1288 "Ogg : bad packet in stream %d\n", id
);
1291 /// Is the actual logical stream in use ?
1292 if (id
== d
->audio
->id
)
1294 else if (id
== d
->video
->id
)
1296 else if (ogg_d
->subs
[id
].text
)
1300 if (!demux_ogg_add_packet(ds
, &ogg_d
->subs
[id
], id
, &pack
))
1301 continue; /// Unuseful packet, get another
1302 d
->filepos
= ogg_d
->pos
;
1308 /// For avi with Ogg audio stream we have to create an ogg demuxer for this
1309 // stream, then we join the avi and ogg demuxer with a demuxers demuxer
1310 demuxer_t
*init_avi_with_ogg(demuxer_t
*demuxer
)
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(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
,