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 //-------- subtitle support - should be moved to decoder layer, and queue
167 // - subtitles up in demuxer buffer...
169 #include "subreader.h"
170 #include "libvo/sub.h"
171 #define OGG_SUB_MAX_LINE 128
173 static subtitle ogg_sub
;
176 static void demux_ogg_add_sub(ogg_stream_t
*os
, ogg_packet
*pack
)
179 char *packet
= pack
->packet
;
183 mp_msg(MSGT_DEMUX
, MSGL_DBG2
, "\ndemux_ogg_add_sub %02X %02X %02X '%s'\n",
184 (unsigned char)packet
[0],
185 (unsigned char)packet
[1],
186 (unsigned char)packet
[2],
189 if (((unsigned char)packet
[0]) == 0x88) { // some subtitle text
191 double endpts
= MP_NOPTS_VALUE
;
192 int32_t duration
= 0;
193 int16_t hdrlen
= (*packet
& PACKET_LEN_BITS01
) >> 6, i
;
195 hdrlen
|= (*packet
& PACKET_LEN_BITS2
) << 1;
197 if (pack
->bytes
< lcv
)
199 for (i
= hdrlen
; i
> 0; i
--) {
201 duration
|= (unsigned char)packet
[i
];
203 if (hdrlen
> 0 && duration
> 0) {
206 if (pack
->granulepos
== -1)
207 pack
->granulepos
= os
->lastpos
+ os
->lastsize
;
208 pts
= (float)pack
->granulepos
/ (float)os
->samplerate
;
209 endpts
= 1.0 + pts
+ (float)duration
/ 1000.0;
211 sub_clear_text(&ogg_sub
, MP_NOPTS_VALUE
);
212 sub_add_text(&ogg_sub
, &packet
[lcv
], pack
->bytes
- lcv
, endpts
);
215 mp_msg(MSGT_DEMUX
, MSGL_DBG2
, "Ogg sub lines: %d first: '%s'\n",
216 ogg_sub
.lines
, ogg_sub
.text
[0]);
218 subcp_recode(&ogg_sub
);
221 vo_osd_changed(OSDTYPE_SUBTITLE
);
225 // get the logical stream of the current page
226 // fill os if non NULL and return the stream id
227 static int demux_ogg_get_page_stream(ogg_demuxer_t
*ogg_d
,
228 ogg_stream_state
**os
)
231 ogg_page
*page
= &ogg_d
->page
;
233 s_no
= ogg_page_serialno(page
);
235 for (id
= 0; id
< ogg_d
->num_sub
; id
++)
236 if (s_no
== ogg_d
->subs
[id
].stream
.serialno
)
239 if (id
== ogg_d
->num_sub
) {
240 // If we have only one vorbis stream allow the stream id to change
241 // it's normal on radio stream (each song have an different id).
242 // But we (or the codec?) should check that the samplerate, etc
243 // doesn't change (for radio stream it's ok)
244 if (ogg_d
->num_sub
== 1 && ogg_d
->subs
[0].vorbis
) {
245 ogg_stream_reset(&ogg_d
->subs
[0].stream
);
246 ogg_stream_init(&ogg_d
->subs
[0].stream
, s_no
);
253 *os
= &ogg_d
->subs
[id
].stream
;
258 static unsigned char *demux_ogg_read_packet(ogg_stream_t
*os
, ogg_packet
*pack
,
259 float *pts
, int *flags
,
262 unsigned char *data
= pack
->packet
;
264 *pts
= MP_NOPTS_VALUE
;
268 if (*pack
->packet
& PACKET_TYPE_HEADER
) {
272 int32_t blocksize
= 0;
274 // When we dump the audio, there is no vi, but we don't care of timestamp in this case
275 vi
= os
->vi_initialized
? &os
->vi
: NULL
;
277 blocksize
= vorbis_packet_blocksize(vi
, pack
) / samplesize
;
278 // Calculate the timestamp if the packet don't have any
279 if (pack
->granulepos
== -1) {
280 pack
->granulepos
= os
->lastpos
;
281 if (os
->lastsize
> 0)
282 pack
->granulepos
+= os
->lastsize
;
286 *pts
= pack
->granulepos
/ (float)vi
->rate
;
287 os
->lastsize
= blocksize
;
288 os
->lastpos
= pack
->granulepos
;
290 } else if (os
->speex
) {
291 // whole packet (default)
292 # ifdef CONFIG_OGGTHEORA
293 } else if (os
->theora
) {
294 /* we pass complete packets to theora, mustn't strip the header! */
297 /* header packets begin on 1-bit: thus check (*data&0x80). We don't
298 have theora_state st, until all header packets were passed to the
300 if (!pack
->bytes
|| !(*data
&0x80)) {
301 int keyframe_granule_shift
= _ilog(os
->keyframe_frequency_force
- 1);
302 int64_t iframemask
= (1 << keyframe_granule_shift
) - 1;
304 if (pack
->granulepos
>= 0) {
305 os
->lastpos
= pack
->granulepos
>> keyframe_granule_shift
;
306 os
->lastpos
+= pack
->granulepos
& iframemask
;
307 *flags
= (pack
->granulepos
& iframemask
) == 0;
311 pack
->granulepos
= os
->lastpos
;
312 *pts
= (double)os
->lastpos
/ (double)os
->samplerate
;
314 #endif /* CONFIG_OGGTHEORA */
315 } else if (os
->flac
) {
316 /* we pass complete packets to flac, mustn't strip the header! */
317 if (os
->flac
== 2 && pack
->packet
[0] != 0xff)
320 if (*pack
->packet
& PACKET_TYPE_HEADER
) {
324 int16_t hdrlen
= (*pack
->packet
& PACKET_LEN_BITS01
) >> 6;
326 hdrlen
|= (*pack
->packet
& PACKET_LEN_BITS2
) << 1;
327 data
= pack
->packet
+ 1 + hdrlen
;
328 // Calculate the timestamp
329 if (pack
->granulepos
== -1)
330 pack
->granulepos
= os
->lastpos
+ (os
->lastsize
? os
->lastsize
: 1);
331 // If we already have a timestamp it can be a syncpoint
332 if (*pack
->packet
& PACKET_IS_SYNCPOINT
)
334 *pts
= pack
->granulepos
/ os
->samplerate
;
335 // Save the packet length and timestamp
339 os
->lastsize
|= pack
->packet
[hdrlen
];
342 os
->lastpos
= pack
->granulepos
;
348 // check if clang has substring from comma separated langlist
349 static int demux_ogg_check_lang(const char *clang
, const char *langlist
)
353 if (!langlist
|| !*langlist
)
355 while ((c
= strchr(langlist
, ','))) {
356 if (!strncasecmp(clang
, langlist
, c
- langlist
))
360 if (!strncasecmp(clang
, langlist
, strlen(langlist
)))
365 /** \brief Change the current subtitle stream and return its ID.
367 \param demuxer The demuxer whose subtitle stream will be changed.
368 \param new_num The number of the new subtitle track. The number must be
369 between 0 and ogg_d->n_text - 1.
371 \returns The Ogg stream number ( = page serial number) of the newly selected
374 static int demux_ogg_sub_id(demuxer_t
*demuxer
, int index
)
376 ogg_demuxer_t
*ogg_d
= demuxer
->priv
;
377 return (index
< 0) ? index
: (index
>= ogg_d
->n_text
) ? -1 : ogg_d
->text_ids
[index
];
380 /** \brief Translate the ogg track number into the subtitle number.
381 * \param demuxer The demuxer about whose subtitles we are inquiring.
382 * \param id The ogg track number of the subtitle track.
384 static int demux_ogg_sub_reverse_id(demuxer_t
*demuxer
, int id
)
386 ogg_demuxer_t
*ogg_d
= demuxer
->priv
;
389 for (i
= 0; i
< ogg_d
->n_text
; i
++)
390 if (ogg_d
->text_ids
[i
] == id
)
395 /// Try to print out comments and also check for LANGUAGE= tag
396 static void demux_ogg_check_comments(demuxer_t
*d
, ogg_stream_t
*os
,
397 int id
, vorbis_comment
*vc
)
399 const char *hdr
, *val
;
400 char **cmt
= vc
->user_comments
;
402 ogg_demuxer_t
*ogg_d
= d
->priv
;
403 static const struct table
{
407 { "ENCODED_USING", "Software" },
408 { "ENCODER_URL", "Encoder URL" },
409 { "TITLE", "Title" },
410 { "ARTIST", "Artist" },
411 { "COMMENT", "Comments" },
412 { "DATE", "Creation Date" },
413 { "GENRE", "Genre" },
414 { "ALBUM", "Album" },
415 { "TRACKNUMBER", "Track" },
421 if (!strncasecmp(*cmt
, "LANGUAGE=", 9)) {
423 if (ogg_d
->subs
[id
].text
)
424 mp_msg(MSGT_IDENTIFY
, MSGL_INFO
, "ID_SID_%d_LANG=%s\n",
425 ogg_d
->subs
[id
].id
, val
);
426 else if (id
!= d
->video
->id
)
427 mp_msg(MSGT_IDENTIFY
, MSGL_INFO
, "ID_AID_%d_LANG=%s\n",
428 ogg_d
->subs
[id
].id
, val
);
429 if (ogg_d
->subs
[id
].text
)
430 mp_msg(MSGT_DEMUX
, MSGL_INFO
,
431 "[Ogg] Language for -sid %d is '-slang \"%s\"'\n",
432 ogg_d
->subs
[id
].id
, val
);
433 // copy this language name into the array
434 index
= demux_ogg_sub_reverse_id(d
, id
);
438 // in case of malicious files with more than one lang per track:
439 if (ogg_d
->text_langs
[index
])
440 free(ogg_d
->text_langs
[index
]);
441 ogg_d
->text_langs
[index
] = strdup(val
);
442 sh
= d
->s_streams
[index
];
446 sh
->lang
= strdup(val
);
448 // check for -slang if subs are uninitialized yet
449 if (os
->text
&& d
->sub
->id
< 0
450 && demux_ogg_check_lang(val
, d
->opts
->sub_lang
)) {
452 d
->opts
->sub_id
= index
;
453 mp_msg(MSGT_DEMUX
, MSGL_V
,
454 "Ogg demuxer: Displaying subtitle stream id %d which matched -slang %s\n",
461 for (i
= 0; table
[i
].ogg
; i
++) {
462 if (!strncasecmp(*cmt
, table
[i
].ogg
, strlen(table
[i
].ogg
)) &&
463 (*cmt
)[strlen(table
[i
].ogg
)] == '=') {
465 val
= *cmt
+ strlen(table
[i
].ogg
) + 1;
470 demux_info_add(d
, hdr
, val
);
471 mp_dbg(MSGT_DEMUX
, MSGL_DBG2
, " %s: %s\n", hdr
, val
);
476 /// Calculate the timestamp and add the packet to the demux stream
477 // return 1 if the packet was added, 0 otherwise
478 static int demux_ogg_add_packet(demux_stream_t
*ds
, ogg_stream_t
*os
,
479 int id
, ogg_packet
*pack
)
481 demuxer_t
*d
= ds
->demuxer
;
488 // If packet is an comment header then we try to get comments at first
489 if (pack
->bytes
>= 7 && !memcmp(pack
->packet
, "\003vorbis", 7)) {
493 vorbis_info_init(&vi
);
494 vorbis_comment_init(&vc
);
495 vi
.rate
= 1L; // it's checked by vorbis_synthesis_headerin()
496 if (vorbis_synthesis_headerin(&vi
, &vc
, pack
) == 0) // if no errors
497 demux_ogg_check_comments(d
, os
, id
, &vc
);
498 vorbis_comment_clear(&vc
);
499 vorbis_info_clear(&vi
);
502 if (id
== demux_ogg_sub_id(d
, d
->sub
->id
)) // don't want to add subtitles to the demuxer for now
503 demux_ogg_add_sub(os
, pack
);
507 // discard first two packets, they contain the header and comment
508 if (os
->hdr_packets
< 2) {
513 // If packet is an header we jump it except for vorbis and theora
514 // (PACKET_TYPE_HEADER bit doesn't even exist for theora ?!)
515 // We jump nothing for FLAC. Ain't this great? Packet contents have to be
516 // handled differently for each and every stream type. The joy! The joy!
517 if (!os
->flac
&& (*pack
->packet
& PACKET_TYPE_HEADER
) &&
518 (ds
!= d
->audio
|| ((sh_audio_t
*)ds
->sh
)->format
!= FOURCC_VORBIS
|| os
->hdr_packets
>= NUM_VORBIS_HDR_PACKETS
) &&
519 (ds
!= d
->video
|| (((sh_video_t
*)ds
->sh
)->format
!= FOURCC_THEORA
)))
523 // For vorbis packet the packet is the data, for other codec we must jump
525 if (ds
== d
->audio
&& ((sh_audio_t
*)ds
->sh
)->format
== FOURCC_VORBIS
) {
526 samplesize
= ((sh_audio_t
*)ds
->sh
)->samplesize
;
528 data
= demux_ogg_read_packet(os
, pack
, &pts
, &flags
, samplesize
);
532 /// Clear subtitles if necessary (for broken files)
533 if (sub_clear_text(&ogg_sub
, pts
)) {
535 vo_osd_changed(OSDTYPE_SUBTITLE
);
538 dp
= new_demux_packet(pack
->bytes
- (data
- pack
->packet
));
539 memcpy(dp
->buffer
, data
, pack
->bytes
- (data
- pack
->packet
));
542 ds_add_packet(ds
, dp
);
543 mp_msg(MSGT_DEMUX
, MSGL_DBG2
,
544 "New dp: %p ds=%p pts=%5.3f len=%d flag=%d \n",
545 dp
, ds
, pts
, dp
->len
, flags
);
549 /// if -forceidx build a table of all syncpoints to make seeking easier
550 /// otherwise try to get at least the final_granulepos
551 static void demux_ogg_scan_stream(demuxer_t
*demuxer
)
553 ogg_demuxer_t
*ogg_d
= demuxer
->priv
;
554 stream_t
*s
= demuxer
->stream
;
555 ogg_sync_state
*sync
= &ogg_d
->sync
;
556 ogg_page
*page
= &ogg_d
->page
;
557 ogg_stream_state
*oss
;
560 int np
, sid
, p
, samplesize
= 1;
563 pos
= last_pos
= demuxer
->movi_start
;
566 stream_seek(s
, demuxer
->movi_start
);
567 ogg_sync_reset(sync
);
569 // Get the serial number of the stream we use
570 if (demuxer
->video
->id
>= 0) {
571 sid
= demuxer
->video
->id
;
572 } else if (demuxer
->audio
->id
>= 0) {
573 sid
= demuxer
->audio
->id
;
574 if (((sh_audio_t
*)demuxer
->audio
->sh
)->format
== FOURCC_VORBIS
)
575 samplesize
= ((sh_audio_t
*)demuxer
->audio
->sh
)->samplesize
;
578 os
= &ogg_d
->subs
[sid
];
582 np
= ogg_sync_pageseek(sync
, page
);
583 if (np
< 0) { // We had to skip some bytes
585 mp_msg(MSGT_DEMUX
, MSGL_ERR
,
586 "Bad page sync while building syncpoints table (%d)\n",
591 if (np
<= 0) { // We need more data
592 char *buf
= ogg_sync_buffer(sync
, BLOCK_SIZE
);
593 int len
= stream_read(s
, buf
, BLOCK_SIZE
);
595 if (len
== 0 && s
->eof
)
597 ogg_sync_wrote(sync
, len
);
601 //ogg_sync_pageout(sync, page);
602 if (ogg_page_serialno(page
) != os
->stream
.serialno
) { // It isn't a page from the stream we want
606 if (ogg_stream_pagein(oss
, page
) != 0) {
607 mp_msg(MSGT_DEMUX
, MSGL_ERR
, "Pagein error ????\n");
612 while (ogg_stream_packetout(oss
, &op
) == 1) {
616 demux_ogg_read_packet(os
, &op
, &pts
, &flags
, samplesize
);
617 if (op
.granulepos
>= 0) {
618 ogg_d
->final_granulepos
= op
.granulepos
;
619 if (ogg_d
->initial_granulepos
== MP_NOPTS_VALUE
&& (flags
& 1)) {
620 ogg_d
->initial_granulepos
= op
.granulepos
;
621 if (index_mode
!= 2 && ogg_d
->pos
< demuxer
->movi_end
- 2 * 270000) {
622 //the 270000 are just a wild guess
623 stream_seek(s
, FFMAX(ogg_d
->pos
, demuxer
->movi_end
- 270000));
624 ogg_sync_reset(sync
);
629 if (index_mode
== 2 && (flags
|| (os
->vorbis
&& op
.granulepos
>= 0))) {
630 if (ogg_d
->num_syncpoint
> SIZE_MAX
/ sizeof(ogg_syncpoint_t
) - 1)
632 ogg_d
->syncpoints
= realloc_struct(ogg_d
->syncpoints
, (ogg_d
->num_syncpoint
+ 1), sizeof(ogg_syncpoint_t
));
633 ogg_d
->syncpoints
[ogg_d
->num_syncpoint
].granulepos
= op
.granulepos
;
634 ogg_d
->syncpoints
[ogg_d
->num_syncpoint
].page_pos
= (ogg_page_continued(page
) && p
== 0) ? last_pos
: pos
;
635 ogg_d
->num_syncpoint
++;
639 if (p
> 1 || (p
== 1 && !ogg_page_continued(page
)))
643 mp_msg(MSGT_DEMUX
, MSGL_INFO
, "Building syncpoint table %d%%\r",
644 (int)(pos
* 100 / s
->end_pos
));
647 if (index_mode
== 2) {
648 mp_msg(MSGT_DEMUX
, MSGL_INFO
, "\n");
649 mp_msg(MSGT_DEMUX
, MSGL_V
,
650 "Ogg syncpoints table builed: %d syncpoints\n",
651 ogg_d
->num_syncpoint
);
654 mp_msg(MSGT_DEMUX
, MSGL_V
, "Ogg stream length (granulepos): %"PRId64
"\n",
655 ogg_d
->final_granulepos
);
658 stream_seek(s
, demuxer
->movi_start
);
659 ogg_sync_reset(sync
);
660 for (np
= 0; np
< ogg_d
->num_sub
; np
++) {
661 ogg_stream_reset(&ogg_d
->subs
[np
].stream
);
662 ogg_d
->subs
[np
].lastpos
= ogg_d
->subs
[np
].lastsize
= ogg_d
->subs
[np
].hdr_packets
= 0;
665 // Get the first page
667 np
= ogg_sync_pageout(sync
, page
);
668 if (np
<= 0) { // We need more data
669 char *buf
= ogg_sync_buffer(sync
, BLOCK_SIZE
);
670 int len
= stream_read(s
, buf
, BLOCK_SIZE
);
672 if (len
== 0 && s
->eof
) {
673 mp_msg(MSGT_DEMUX
, MSGL_ERR
, "EOF while trying to get the first page !!!!\n");
676 ogg_sync_wrote(sync
, len
);
679 demux_ogg_get_page_stream(ogg_d
, &oss
);
680 ogg_stream_pagein(oss
, page
);
685 static void fixup_vorbis_wf(sh_audio_t
*sh
, ogg_demuxer_t
*od
)
688 int ris
, init_error
= 0;
690 unsigned char *buf
[3];
693 ogg_stream_t
*os
= &od
->subs
[sh
->ds
->id
];
696 vorbis_info_init(&os
->vi
);
697 vorbis_comment_init(&vc
);
698 for (i
= 0; i
< 3; i
++) {
699 op
[i
].bytes
= ds_get_packet(sh
->ds
, &(op
[i
].packet
));
700 mp_msg(MSGT_DEMUX
, MSGL_V
, "fixup_vorbis_wf: i=%d, size=%ld\n", i
, op
[i
].bytes
);
701 if (op
[i
].bytes
< 0) {
702 mp_msg(MSGT_DEMUX
, MSGL_ERR
, "Ogg demuxer error!, fixup_vorbis_wf: bad packet n. %d\n", i
);
705 buf
[i
] = malloc(op
[i
].bytes
);
708 memcpy(buf
[i
], op
[i
].packet
, op
[i
].bytes
);
710 op
[i
].b_o_s
= (i
== 0);
711 ris
= vorbis_synthesis_headerin(&os
->vi
, &vc
, &op
[i
]);
714 mp_msg(MSGT_DECAUDIO
, MSGL_ERR
, "DEMUX_OGG: header n. %d broken! len=%ld, code: %d\n", i
, op
[i
].bytes
, ris
);
717 vorbis_comment_clear(&vc
);
719 os
->vi_initialized
= 1;
721 len
= op
[0].bytes
+ op
[1].bytes
+ op
[2].bytes
;
722 sh
->wf
= calloc(1, sizeof(*sh
->wf
) + len
+ len
/ 255 + 64);
723 ptr
= (unsigned char*)(sh
->wf
+ 1);
727 offset
+= store_ughvlc(&ptr
[offset
], op
[0].bytes
);
728 mp_msg(MSGT_DEMUX
, MSGL_V
, "demux_ogg, offset after 1st len = %u\n", offset
);
729 offset
+= store_ughvlc(&ptr
[offset
], op
[1].bytes
);
730 mp_msg(MSGT_DEMUX
, MSGL_V
, "demux_ogg, offset after 2nd len = %u\n", offset
);
731 for (i
= 0; i
< 3; i
++) {
732 mp_msg(MSGT_DEMUX
, MSGL_V
, "demux_ogg, i=%d, bytes: %ld, offset: %u\n", i
, op
[i
].bytes
, offset
);
733 memcpy(&ptr
[offset
], buf
[i
], op
[i
].bytes
);
734 offset
+= op
[i
].bytes
;
736 sh
->wf
->cbSize
= offset
;
737 mp_msg(MSGT_DEMUX
, MSGL_V
, "demux_ogg, extradata size: %d\n", sh
->wf
->cbSize
);
738 sh
->wf
= realloc(sh
->wf
, sizeof(*sh
->wf
) + sh
->wf
->cbSize
);
740 if (op
[0].bytes
>= 29) {
742 int nombr
, minbr
, maxbr
;
745 sh
->channels
= ptr
[11];
746 sh
->samplerate
= sh
->wf
->nSamplesPerSec
= AV_RL32(&ptr
[12]);
747 maxbr
= AV_RL32(&ptr
[16]); //max
748 nombr
= AV_RL32(&ptr
[20]); //nominal
749 minbr
= AV_RL32(&ptr
[24]); //minimum
763 sh
->wf
->nAvgBytesPerSec
= br
;
764 sh
->wf
->wBitsPerSample
= 16;
765 sh
->samplesize
= (sh
->wf
->wBitsPerSample
+ 7) / 8;
767 mp_msg(MSGT_DEMUX
, MSGL_V
,
768 "demux_ogg, vorbis stream features are: channels: %d, srate: %d, bitrate: %d, max: %u, nominal: %u, min: %u\n",
769 sh
->channels
, sh
->samplerate
, sh
->wf
->nAvgBytesPerSec
,
770 maxbr
, nombr
, minbr
);
777 /// Open an ogg physical stream
778 // Not static because it's used also in demuxer_avi.c
779 int demux_ogg_open(demuxer_t
*demuxer
)
781 ogg_demuxer_t
*ogg_d
;
784 int np
, s_no
, n_audio
= 0, n_video
= 0;
785 int audio_id
= -1, video_id
= -1, text_id
= -1;
786 ogg_sync_state
*sync
;
798 demuxer
->priv
= ogg_d
= calloc(1, sizeof(*ogg_d
));
805 /// Try to get a page
806 ogg_d
->pos
+= ogg_d
->last_size
;
807 np
= ogg_sync_pageseek(sync
, page
);
810 mp_msg(MSGT_DEMUX
, MSGL_DBG2
, "Ogg demuxer : Bad page sync\n");
813 /// Need some more data
817 buf
= ogg_sync_buffer(sync
, BLOCK_SIZE
);
818 len
= stream_read(s
, buf
, BLOCK_SIZE
);
819 if (len
== 0 && s
->eof
) {
822 ogg_sync_wrote(sync
, len
);
825 ogg_d
->last_size
= np
;
826 // We got one page now
828 if (!ogg_page_bos(page
)) { // It's not a beginning page
829 // Header parsing end here, we need to get the page otherwise it will be lost
830 int id
= demux_ogg_get_page_stream(ogg_d
, NULL
);
832 ogg_stream_pagein(&ogg_d
->subs
[id
].stream
, page
);
834 mp_msg(MSGT_DEMUX
, MSGL_ERR
,
835 "Ogg : Warning found none bos page from unknown stream %d\n",
836 ogg_page_serialno(page
));
840 /// Init the data structure needed for a logical stream
841 ogg_d
->subs
= realloc_struct(ogg_d
->subs
, ogg_d
->num_sub
+1,
842 sizeof(ogg_stream_t
));
843 memset(&ogg_d
->subs
[ogg_d
->num_sub
], 0, sizeof(ogg_stream_t
));
844 /// Get the stream serial number
845 s_no
= ogg_page_serialno(page
);
846 ogg_stream_init(&ogg_d
->subs
[ogg_d
->num_sub
].stream
, s_no
);
847 mp_msg(MSGT_DEMUX
, MSGL_DBG2
,
848 "Ogg : Found a stream with serial=%d\n", s_no
);
849 // Take the first page
850 ogg_stream_pagein(&ogg_d
->subs
[ogg_d
->num_sub
].stream
, page
);
851 // Get first packet of the page
852 ogg_stream_packetout(&ogg_d
->subs
[ogg_d
->num_sub
].stream
, &pack
);
858 ogg_d
->subs
[ogg_d
->num_sub
].ogg_d
= ogg_d
;
861 if (pack
.bytes
>= 7 && !strncmp(&pack
.packet
[1], "vorbis", 6)) {
862 sh_a
= new_sh_audio_aid(demuxer
, ogg_d
->num_sub
, n_audio
);
863 sh_a
->format
= FOURCC_VORBIS
;
864 ogg_d
->subs
[ogg_d
->num_sub
].vorbis
= 1;
865 ogg_d
->subs
[ogg_d
->num_sub
].id
= n_audio
;
867 mp_msg(MSGT_DEMUX
, MSGL_INFO
,
868 "[Ogg] stream %d: audio (Vorbis), -aid %d\n",
869 ogg_d
->num_sub
, n_audio
- 1);
870 } else if (pack
.bytes
>= 80 && !strncmp(pack
.packet
, "Speex", 5)) {
871 sh_a
= new_sh_audio_aid(demuxer
, ogg_d
->num_sub
, n_audio
);
872 sh_a
->wf
= calloc(1, sizeof(*sh_a
->wf
) + pack
.bytes
);
873 sh_a
->format
= FOURCC_SPEEX
;
874 sh_a
->samplerate
= sh_a
->wf
->nSamplesPerSec
= AV_RL32(&pack
.packet
[36]);
875 sh_a
->channels
= sh_a
->wf
->nChannels
= AV_RL32(&pack
.packet
[48]);
876 sh_a
->wf
->wFormatTag
= sh_a
->format
;
877 sh_a
->wf
->nAvgBytesPerSec
= AV_RL32(&pack
.packet
[52]);
878 sh_a
->wf
->nBlockAlign
= 0;
879 sh_a
->wf
->wBitsPerSample
= 16;
880 sh_a
->samplesize
= 2;
881 sh_a
->wf
->cbSize
= pack
.bytes
;
882 memcpy(&sh_a
->wf
[1], pack
.packet
, pack
.bytes
);
884 ogg_d
->subs
[ogg_d
->num_sub
].samplerate
= sh_a
->samplerate
;
885 ogg_d
->subs
[ogg_d
->num_sub
].speex
= 1;
886 ogg_d
->subs
[ogg_d
->num_sub
].id
= n_audio
;
888 mp_msg(MSGT_DEMUX
, MSGL_INFO
,
889 "[Ogg] stream %d: audio (Speex), -aid %d\n",
890 ogg_d
->num_sub
, n_audio
- 1);
893 #ifdef CONFIG_OGGTHEORA
894 } else if (pack
.bytes
>= 7 && !strncmp (&pack
.packet
[1], "theora", 6)) {
899 theora_info_init (&inf
);
900 theora_comment_init (&cc
);
902 errorCode
= theora_decode_header (&inf
, &cc
, &pack
);
904 mp_msg(MSGT_DEMUX
, MSGL_ERR
,
905 "Theora header parsing failed: %i \n", errorCode
);
907 sh_v
= new_sh_video_vid(demuxer
, ogg_d
->num_sub
, n_video
);
909 sh_v
->bih
= calloc(1, sizeof(*sh_v
->bih
));
910 sh_v
->bih
->biSize
= sizeof(*sh_v
->bih
);
911 sh_v
->bih
->biCompression
= sh_v
->format
= FOURCC_THEORA
;
912 sh_v
->fps
= ((double)inf
.fps_numerator
) / (double)inf
.fps_denominator
;
913 sh_v
->frametime
= ((double)inf
.fps_denominator
) / (double)inf
.fps_numerator
;
914 sh_v
->disp_w
= sh_v
->bih
->biWidth
= inf
.frame_width
;
915 sh_v
->disp_h
= sh_v
->bih
->biHeight
= inf
.frame_height
;
916 sh_v
->bih
->biBitCount
= 24;
917 sh_v
->bih
->biPlanes
= 3;
918 sh_v
->bih
->biSizeImage
= ((sh_v
->bih
->biBitCount
/ 8) * sh_v
->bih
->biWidth
* sh_v
->bih
->biHeight
);
919 ogg_d
->subs
[ogg_d
->num_sub
].samplerate
= sh_v
->fps
;
920 ogg_d
->subs
[ogg_d
->num_sub
].theora
= 1;
921 ogg_d
->subs
[ogg_d
->num_sub
].keyframe_frequency_force
= inf
.keyframe_frequency_force
;
922 ogg_d
->subs
[ogg_d
->num_sub
].id
= n_video
;
924 mp_msg(MSGT_DEMUX
, MSGL_INFO
,
925 "[Ogg] stream %d: video (Theora v%d.%d.%d), -vid %d\n",
927 (int)inf
.version_major
,
928 (int)inf
.version_minor
,
929 (int)inf
.version_subminor
,
931 if (mp_msg_test(MSGT_HEADER
, MSGL_V
))
932 print_video_header(sh_v
->bih
, MSGL_V
);
934 theora_comment_clear(&cc
);
935 theora_info_clear(&inf
);
936 #endif /* CONFIG_OGGTHEORA */
937 } else if (pack
.bytes
>= 4 && !strncmp (&pack
.packet
[0], "fLaC", 4)) {
938 sh_a
= new_sh_audio_aid(demuxer
, ogg_d
->num_sub
, n_audio
);
939 sh_a
->format
= mmioFOURCC('f', 'L', 'a', 'C');
940 ogg_d
->subs
[ogg_d
->num_sub
].id
= n_audio
;
942 ogg_d
->subs
[ogg_d
->num_sub
].flac
= 1;
944 mp_msg(MSGT_DEMUX
, MSGL_INFO
,
945 "[Ogg] stream %d: audio (FLAC), -aid %d\n",
946 ogg_d
->num_sub
, n_audio
- 1);
947 } else if (pack
.bytes
>= 51 && !strncmp(&pack
.packet
[1], "FLAC", 4)) {
948 sh_a
= new_sh_audio_aid(demuxer
, ogg_d
->num_sub
, n_audio
);
949 sh_a
->format
= mmioFOURCC('f', 'L', 'a', 'C');
950 ogg_d
->subs
[ogg_d
->num_sub
].id
= n_audio
;
952 ogg_d
->subs
[ogg_d
->num_sub
].flac
= 2;
953 sh_a
->wf
= calloc(1, sizeof(*sh_a
->wf
) + 34);
954 sh_a
->wf
->wFormatTag
= sh_a
->format
;
955 sh_a
->wf
->cbSize
= 34;
956 memcpy(&sh_a
->wf
[1], &pack
.packet
[17], 34);
957 mp_msg(MSGT_DEMUX
, MSGL_INFO
,
958 "[Ogg] stream %d: audio (FLAC, try 2), -aid %d\n",
959 ogg_d
->num_sub
, n_audio
- 1);
961 /// Check for old header
962 } else if (pack
.bytes
>= 142 &&
963 !strncmp(&pack
.packet
[1], "Direct Show Samples embedded in Ogg", 35)) {
966 if (AV_RL32(pack
.packet
+ 96) == 0x05589f80 && pack
.bytes
>= 184) {
967 sh_v
= new_sh_video_vid(demuxer
, ogg_d
->num_sub
, n_video
);
968 sh_v
->bih
= calloc(1, sizeof(*sh_v
->bih
));
969 sh_v
->bih
->biSize
= sizeof(*sh_v
->bih
);
970 sh_v
->bih
->biCompression
= sh_v
->format
= mmioFOURCC(pack
.packet
[68], pack
.packet
[69],
971 pack
.packet
[70], pack
.packet
[71]);
972 sh_v
->frametime
= AV_RL64(pack
.packet
+ 164) * 0.0000001;
973 sh_v
->fps
= 1 / sh_v
->frametime
;
974 sh_v
->disp_w
= sh_v
->bih
->biWidth
= AV_RL32(pack
.packet
+ 176);
975 sh_v
->disp_h
= sh_v
->bih
->biHeight
= AV_RL32(pack
.packet
+ 180);
976 sh_v
->bih
->biBitCount
= AV_RL16(pack
.packet
+ 182);
977 if (!sh_v
->bih
->biBitCount
)
978 sh_v
->bih
->biBitCount
= 24; // hack, FIXME
979 sh_v
->bih
->biPlanes
= 1;
980 sh_v
->bih
->biSizeImage
= (sh_v
->bih
->biBitCount
>> 3) * sh_v
->bih
->biWidth
* sh_v
->bih
->biHeight
;
982 ogg_d
->subs
[ogg_d
->num_sub
].samplerate
= sh_v
->fps
;
983 ogg_d
->subs
[ogg_d
->num_sub
].id
= n_video
;
985 mp_msg(MSGT_DEMUX
, MSGL_INFO
,
986 "[Ogg] stream %d: video (FOURCC %c%c%c%c), -vid %d\n",
987 ogg_d
->num_sub
, pack
.packet
[68], pack
.packet
[69],
988 pack
.packet
[70], pack
.packet
[71], n_video
- 1);
989 if (mp_msg_test(MSGT_HEADER
, MSGL_V
))
990 print_video_header(sh_v
->bih
, MSGL_V
);
992 } else if (AV_RL32(pack
.packet
+ 96) == 0x05589F81) {
993 unsigned int extra_size
;
995 sh_a
= new_sh_audio_aid(demuxer
, ogg_d
->num_sub
, n_audio
);
996 extra_size
= AV_RL16(pack
.packet
+ 140);
997 sh_a
->wf
= calloc(1, sizeof(*sh_a
->wf
) + extra_size
);
998 sh_a
->format
= sh_a
->wf
->wFormatTag
= AV_RL16(pack
.packet
+ 124);
999 sh_a
->channels
= sh_a
->wf
->nChannels
= AV_RL16(pack
.packet
+ 126);
1000 sh_a
->samplerate
= sh_a
->wf
->nSamplesPerSec
= AV_RL32(pack
.packet
+ 128);
1001 sh_a
->wf
->nAvgBytesPerSec
= AV_RL32(pack
.packet
+ 132);
1002 sh_a
->wf
->nBlockAlign
= AV_RL16(pack
.packet
+ 136);
1003 sh_a
->wf
->wBitsPerSample
= AV_RL16(pack
.packet
+ 138);
1004 sh_a
->samplesize
= (sh_a
->wf
->wBitsPerSample
+ 7) / 8;
1005 sh_a
->wf
->cbSize
= extra_size
;
1007 memcpy(sh_a
->wf
+ 1,
1008 pack
.packet
+ 142, extra_size
);
1010 ogg_d
->subs
[ogg_d
->num_sub
].samplerate
= sh_a
->samplerate
; // * sh_a->channels;
1011 ogg_d
->subs
[ogg_d
->num_sub
].id
= n_audio
;
1013 mp_msg(MSGT_DEMUX
, MSGL_INFO
,
1014 "[Ogg] stream %d: audio (format 0x%04x), -aid %d\n",
1015 ogg_d
->num_sub
, sh_a
->format
, n_audio
- 1);
1016 if (mp_msg_test(MSGT_HEADER
, MSGL_V
))
1017 print_wave_header(sh_a
->wf
, MSGL_V
);
1019 mp_msg(MSGT_DEMUX
, MSGL_WARN
,
1020 "Ogg stream %d contains an old header but the header type is unknown\n",
1024 } else if ((*pack
.packet
& PACKET_TYPE_BITS
) == PACKET_TYPE_HEADER
&&
1025 pack
.bytes
>= (int)sizeof(stream_header
) + 1) {
1026 stream_header
*st
= (stream_header
*)(pack
.packet
+ 1);
1027 /// New video header
1028 if (strncmp(st
->streamtype
, "video", 5) == 0) {
1029 sh_v
= new_sh_video_vid(demuxer
, ogg_d
->num_sub
, n_video
);
1030 sh_v
->bih
= calloc(1, sizeof(*sh_v
->bih
));
1031 sh_v
->bih
->biSize
= sizeof(*sh_v
->bih
);
1032 sh_v
->bih
->biCompression
= sh_v
->format
= mmioFOURCC(st
->subtype
[0], st
->subtype
[1],
1033 st
->subtype
[2], st
->subtype
[3]);
1034 sh_v
->frametime
= AV_RL64(&st
->time_unit
) * 0.0000001;
1035 sh_v
->fps
= 1.0 / sh_v
->frametime
;
1036 sh_v
->bih
->biBitCount
= AV_RL16(&st
->bits_per_sample
);
1037 sh_v
->disp_w
= sh_v
->bih
->biWidth
= AV_RL32(&st
->sh
.video
.width
);
1038 sh_v
->disp_h
= sh_v
->bih
->biHeight
= AV_RL32(&st
->sh
.video
.height
);
1039 if (!sh_v
->bih
->biBitCount
)
1040 sh_v
->bih
->biBitCount
= 24; // hack, FIXME
1041 sh_v
->bih
->biPlanes
= 1;
1042 sh_v
->bih
->biSizeImage
= (sh_v
->bih
->biBitCount
>> 3) * sh_v
->bih
->biWidth
* sh_v
->bih
->biHeight
;
1044 ogg_d
->subs
[ogg_d
->num_sub
].samplerate
= sh_v
->fps
;
1045 ogg_d
->subs
[ogg_d
->num_sub
].id
= n_video
;
1047 mp_msg(MSGT_DEMUX
, MSGL_INFO
,
1048 "[Ogg] stream %d: video (FOURCC %c%c%c%c), -vid %d\n",
1049 ogg_d
->num_sub
, st
->subtype
[0], st
->subtype
[1],
1050 st
->subtype
[2], st
->subtype
[3], n_video
- 1);
1051 if (mp_msg_test(MSGT_HEADER
, MSGL_V
))
1052 print_video_header(sh_v
->bih
, MSGL_V
);
1053 /// New audio header
1054 } else if (strncmp(st
->streamtype
, "audio", 5) == 0) {
1056 unsigned int extra_size
= AV_RL32(&st
->size
) - sizeof(stream_header
);
1057 unsigned int extra_offset
= 0;
1059 memcpy(buffer
, st
->subtype
, 4);
1062 /* Nasty workaround. stream_header.size seems not to contain the real
1063 size in all cases. There are four extra bytes that are unaccounted
1064 for in front of the real codec initialization data _at least_ for
1065 AAC. So far I've only seen those bytes being all 0, so we can
1066 just skip them here. */
1067 if ((strtol(buffer
, NULL
, 16) == 0xff) && (extra_size
>= 4)) {
1072 sh_a
= new_sh_audio_aid(demuxer
, ogg_d
->num_sub
, n_audio
);
1073 sh_a
->wf
= calloc(1, sizeof(*sh_a
->wf
) + extra_size
);
1074 sh_a
->format
= sh_a
->wf
->wFormatTag
= strtol(buffer
, NULL
, 16);
1075 sh_a
->channels
= sh_a
->wf
->nChannels
= AV_RL16(&st
->sh
.audio
.channels
);
1076 sh_a
->samplerate
= sh_a
->wf
->nSamplesPerSec
= AV_RL64(&st
->samples_per_unit
);
1077 sh_a
->wf
->nAvgBytesPerSec
= AV_RL32(&st
->sh
.audio
.avgbytespersec
);
1078 sh_a
->wf
->nBlockAlign
= AV_RL16(&st
->sh
.audio
.blockalign
);
1079 sh_a
->wf
->wBitsPerSample
= AV_RL16(&st
->bits_per_sample
);
1080 sh_a
->samplesize
= (sh_a
->wf
->wBitsPerSample
+ 7) / 8;
1081 sh_a
->wf
->cbSize
= extra_size
;
1084 ((char *)(st
+1))+extra_offset
, extra_size
);
1086 ogg_d
->subs
[ogg_d
->num_sub
].samplerate
= sh_a
->samplerate
; // * sh_a->channels;
1087 ogg_d
->subs
[ogg_d
->num_sub
].id
= n_audio
;
1089 mp_msg(MSGT_DEMUX
, MSGL_INFO
,
1090 "[Ogg] stream %d: audio (format 0x%04x), -aid %d\n",
1091 ogg_d
->num_sub
, sh_a
->format
, n_audio
- 1);
1092 if (mp_msg_test(MSGT_HEADER
, MSGL_V
))
1093 print_wave_header(sh_a
->wf
, MSGL_V
);
1095 /// Check for text (subtitles) header
1096 } else if (strncmp(st
->streamtype
, "text", 4) == 0) {
1097 mp_msg(MSGT_DEMUX
, MSGL_INFO
,
1098 "[Ogg] stream %d: subtitles (SRT-like text subtitles), -sid %d\n",
1099 ogg_d
->num_sub
, ogg_d
->n_text
);
1100 ogg_d
->subs
[ogg_d
->num_sub
].samplerate
= AV_RL64(&st
->time_unit
) / 10;
1101 ogg_d
->subs
[ogg_d
->num_sub
].text
= 1;
1102 ogg_d
->subs
[ogg_d
->num_sub
].id
= ogg_d
->n_text
;
1103 if (demuxer
->sub
->id
== ogg_d
->n_text
)
1104 text_id
= ogg_d
->num_sub
;
1105 new_sh_sub(demuxer
, ogg_d
->n_text
);
1107 ogg_d
->text_ids
= realloc_struct(ogg_d
->text_ids
, ogg_d
->n_text
, sizeof(*ogg_d
->text_ids
));
1108 ogg_d
->text_ids
[ogg_d
->n_text
- 1] = ogg_d
->num_sub
;
1109 ogg_d
->text_langs
= realloc_struct(ogg_d
->text_langs
, ogg_d
->n_text
, sizeof(*ogg_d
->text_langs
));
1110 ogg_d
->text_langs
[ogg_d
->n_text
- 1] = NULL
;
1111 //// Unknown header type
1113 mp_msg(MSGT_DEMUX
, MSGL_ERR
,
1114 "Ogg stream %d has a header marker but is of an unknown type\n",
1116 /// Unknown (invalid ?) header
1118 mp_msg(MSGT_DEMUX
, MSGL_ERR
,
1119 "Ogg stream %d is of an unknown type\n",
1123 demux_stream_t
*ds
= NULL
;
1125 // If the audio stream is not defined we took the first one
1126 if (demuxer
->audio
->id
== -1) {
1127 demuxer
->audio
->id
= n_audio
- 1;
1128 //if (sh_a->wf) print_wave_header(sh_a->wf, MSGL_INFO);
1130 /// Is it the stream we want
1131 if (demuxer
->audio
->id
== n_audio
- 1) {
1132 demuxer
->audio
->sh
= sh_a
;
1133 sh_a
->ds
= demuxer
->audio
;
1134 ds
= demuxer
->audio
;
1135 audio_id
= ogg_d
->num_sub
;
1140 if (demuxer
->video
->id
== -1) {
1141 demuxer
->video
->id
= n_video
- 1;
1142 //if (sh_v->bih) print_video_header(sh_v->bih, MSGL_INFO);
1144 if (demuxer
->video
->id
== n_video
- 1) {
1145 demuxer
->video
->sh
= sh_v
;
1146 sh_v
->ds
= demuxer
->video
;
1147 ds
= demuxer
->video
;
1148 video_id
= ogg_d
->num_sub
;
1151 /// Add the header packets if the stream isn't seekable
1152 if (ds
&& !s
->end_pos
) {
1153 /// Finish the page, otherwise packets will be lost
1155 demux_ogg_add_packet(ds
, &ogg_d
->subs
[ogg_d
->num_sub
],
1156 ogg_d
->num_sub
, &pack
);
1157 } while (ogg_stream_packetout(&ogg_d
->subs
[ogg_d
->num_sub
].stream
, &pack
) == 1);
1163 if (!n_video
&& !n_audio
) {
1167 if (!n_video
|| video_id
< 0)
1168 demuxer
->video
->id
= -2;
1170 demuxer
->video
->id
= video_id
;
1171 if (!n_audio
|| audio_id
< 0)
1172 demuxer
->audio
->id
= -2;
1174 demuxer
->audio
->id
= audio_id
;
1175 /* Disable the subs only if there are no text streams at all.
1176 Otherwise the stream to display might be chosen later when the comment
1177 packet is encountered and the user used -slang instead of -sid. */
1179 demuxer
->sub
->id
= -2;
1180 else if (text_id
>= 0) {
1181 demuxer
->sub
->id
= text_id
;
1182 mp_msg(MSGT_DEMUX
, MSGL_V
,
1183 "Ogg demuxer: Displaying subtitle stream id %d\n", text_id
);
1186 ogg_d
->final_granulepos
= 0;
1187 ogg_d
->initial_granulepos
= MP_NOPTS_VALUE
;
1189 demuxer
->seekable
= 0;
1191 demuxer
->movi_start
= s
->start_pos
; // Needed for XCD (Ogg written in MODE2)
1192 demuxer
->movi_end
= s
->end_pos
;
1193 demuxer
->seekable
= 1;
1194 demux_ogg_scan_stream(demuxer
);
1196 if (ogg_d
->initial_granulepos
== MP_NOPTS_VALUE
)
1197 ogg_d
->initial_granulepos
= 0;
1198 ogg_d
->duration
= ogg_d
->final_granulepos
- ogg_d
->initial_granulepos
;
1200 mp_msg(MSGT_DEMUX
, MSGL_V
,
1201 "Ogg demuxer : found %d audio stream%s, %d video stream%s and %d text stream%s\n",
1202 n_audio
, n_audio
> 1 ? "s" : "",
1203 n_video
, n_video
> 1 ? "s" : "",
1204 ogg_d
->n_text
, ogg_d
->n_text
> 1 ? "s" : "");
1206 sh_a
= demuxer
->audio
->sh
;
1207 if (sh_a
&& sh_a
->format
== FOURCC_VORBIS
)
1208 fixup_vorbis_wf(sh_a
, ogg_d
);
1210 return DEMUXER_TYPE_OGG
;
1216 static int demux_ogg_fill_buffer(demuxer_t
*d
, demux_stream_t
*dsds
)
1218 ogg_demuxer_t
*ogg_d
;
1221 ogg_sync_state
*sync
;
1222 ogg_stream_state
*os
;
1229 sync
= &ogg_d
->sync
;
1230 page
= &ogg_d
->page
;
1232 /// Find the stream we are working on
1233 if ((id
= demux_ogg_get_page_stream(ogg_d
, &os
)) < 0) {
1234 mp_msg(MSGT_DEMUX
, MSGL_ERR
, "Ogg demuxer : can't get current stream\n");
1241 /// Try to get some packet from the current page
1242 while ((np
= ogg_stream_packetout(os
, &pack
)) != 1) {
1243 /// No packet we go the next page
1249 ogg_d
->pos
+= ogg_d
->last_size
;
1250 /// Get the next page from the physical stream
1251 while ((pa
= ogg_sync_pageseek(sync
, page
)) <= 0) {
1252 /// Error : we skip some bytes
1254 mp_msg(MSGT_DEMUX
, MSGL_WARN
,
1255 "Ogg : Page out not synced, we skip some bytes\n");
1259 /// We need more data
1260 buf
= ogg_sync_buffer(sync
, BLOCK_SIZE
);
1261 len
= stream_read(s
, buf
, BLOCK_SIZE
);
1262 if (len
== 0 && s
->eof
) {
1263 mp_msg(MSGT_DEMUX
, MSGL_DBG2
, "Ogg : Stream EOF !!!!\n");
1266 ogg_sync_wrote(sync
, len
);
1268 ogg_d
->last_size
= pa
;
1269 /// Find the page's logical stream
1270 if ((id
= demux_ogg_get_page_stream(ogg_d
, &os
)) < 0) {
1271 mp_msg(MSGT_DEMUX
, MSGL_ERR
,
1272 "Ogg demuxer error : we met an unknown stream\n");
1276 if (ogg_stream_pagein(os
, page
) == 0)
1278 /// Page was invalid => retry
1279 mp_msg(MSGT_DEMUX
, MSGL_WARN
,
1280 "Ogg demuxer : got invalid page !!!!!\n");
1281 ogg_d
->pos
+= ogg_d
->last_size
;
1283 } else /// Packet was corrupted
1284 mp_msg(MSGT_DEMUX
, MSGL_WARN
,
1285 "Ogg : bad packet in stream %d\n", id
);
1288 /// Is the actual logical stream in use ?
1289 if (id
== d
->audio
->id
)
1291 else if (id
== d
->video
->id
)
1293 else if (ogg_d
->subs
[id
].text
)
1297 if (!demux_ogg_add_packet(ds
, &ogg_d
->subs
[id
], id
, &pack
))
1298 continue; /// Unuseful packet, get another
1299 d
->filepos
= ogg_d
->pos
;
1305 /// For avi with Ogg audio stream we have to create an ogg demuxer for this
1306 // stream, then we join the avi and ogg demuxer with a demuxers demuxer
1307 demuxer_t
*init_avi_with_ogg(demuxer_t
*demuxer
)
1309 struct MPOpts
*opts
= demuxer
->opts
;
1311 ogg_demuxer_t
*ogg_d
;
1313 uint32_t hdrsizes
[3];
1315 sh_audio_t
*sh_audio
= demuxer
->audio
->sh
;
1317 uint8_t *extradata
= (uint8_t *)(sh_audio
->wf
+ 1);
1319 unsigned char *p
= NULL
, *buf
;
1322 /// Check that the cbSize is big enough for the following reads
1323 if (sh_audio
->wf
->cbSize
< 22 + 3 * 4) {
1324 mp_msg(MSGT_DEMUX
, MSGL_ERR
,
1325 "AVI Ogg : Initial audio header is too small !!!!!\n");
1328 /// Get the size of the 3 header packet
1330 for (i
= 0; i
< 3; i
++) {
1331 hdrsizes
[i
] = AV_RL32(extradata
);
1334 // printf("\n!!!!!! hdr sizes: %d %d %d \n", hdrsizes[0], hdrsizes[1], hdrsizes[2]);
1337 if (sh_audio
->wf
->cbSize
< 22 + 3 * 4 + hdrsizes
[0] + hdrsizes
[1] + hdrsizes
[2]) {
1338 mp_msg(MSGT_DEMUX
, MSGL_ERR
,
1339 "AVI Ogg : Audio header is too small !!!!!\n");
1343 // Build the ogg demuxer private datas
1344 ogg_d
= calloc(1, sizeof(*ogg_d
));
1346 ogg_d
->subs
= malloc(sizeof(*ogg_d
->subs
));
1347 ogg_d
->subs
[0].vorbis
= 1;
1349 // Init the ogg physical stream
1350 ogg_sync_init(&ogg_d
->sync
);
1352 // Get the first page of the stream : we assume there only 1 logical stream
1353 while ((np
= ogg_sync_pageout(&ogg_d
->sync
, &ogg_d
->page
)) <= 0 ) {
1355 mp_msg(MSGT_DEMUX
, MSGL_ERR
,
1356 "AVI Ogg error : Can't init using first stream packets\n");
1361 plen
= ds_get_packet(demuxer
->audio
, &p
);
1362 buf
= ogg_sync_buffer(&ogg_d
->sync
, plen
);
1363 memcpy(buf
, p
, plen
);
1364 ogg_sync_wrote(&ogg_d
->sync
, plen
);
1366 // Init the logical stream
1367 mp_msg(MSGT_DEMUX
, MSGL_DBG2
,
1368 "AVI Ogg found page with serial %d\n",
1369 ogg_page_serialno(&ogg_d
->page
));
1370 ogg_stream_init(&ogg_d
->subs
[0].stream
, ogg_page_serialno(&ogg_d
->page
));
1372 ogg_stream_pagein(&ogg_d
->subs
[0].stream
, &ogg_d
->page
);
1374 // Create the ds_stream and the ogg demuxer
1375 s
= new_ds_stream(demuxer
->audio
);
1376 od
= new_demuxer(opts
, s
, DEMUXER_TYPE_OGG
, 0, -2, -2, NULL
);
1378 /// Add the header packets in the ogg demuxer audio stream
1379 for (i
= 0; i
< 3; i
++) {
1380 dp
= new_demux_packet(hdrsizes
[i
]);
1381 memcpy(dp
->buffer
, extradata
, hdrsizes
[i
]);
1382 ds_add_packet(od
->audio
, dp
);
1383 extradata
+= hdrsizes
[i
];
1386 // Finish setting up the ogg demuxer
1388 sh_audio
= new_sh_audio(od
, 0);
1391 od
->audio
->sh
= sh_audio
;
1392 sh_audio
->ds
= od
->audio
;
1393 sh_audio
->format
= FOURCC_VORBIS
;
1394 fixup_vorbis_wf(sh_audio
, ogg_d
);
1396 /// Return the joined demuxers
1397 return new_demuxers_demuxer(demuxer
, od
, demuxer
);
1400 demuxer
->audio
->id
= -2;
1405 static void demux_ogg_seek(demuxer_t
*demuxer
, float rel_seek_secs
,
1406 float audio_delay
, int flags
)
1408 ogg_demuxer_t
*ogg_d
= demuxer
->priv
;
1409 ogg_sync_state
*sync
= &ogg_d
->sync
;
1410 ogg_page
* page
= &ogg_d
->page
;
1411 ogg_stream_state
*oss
;
1416 int i
, sp
, first
, precision
= 1, do_seek
= 1;
1417 vorbis_info
*vi
= NULL
;
1418 int64_t gp
= 0, old_gp
;
1425 ogg_int64_t granulepos_orig
;
1427 if (demuxer
->video
->id
>= 0) {
1428 ds
= demuxer
->video
;
1429 rate
= ogg_d
->subs
[ds
->id
].samplerate
;
1431 ds
= demuxer
->audio
;
1432 os
= &ogg_d
->subs
[ds
->id
];
1434 rate
= (float)vi
->rate
;
1435 samplesize
= ((sh_audio_t
*)ds
->sh
)->samplesize
;
1438 os
= &ogg_d
->subs
[ds
->id
];
1441 old_gp
= os
->lastpos
;
1442 old_pos
= ogg_d
->pos
;
1444 //calculate the granulepos to seek to
1445 gp
= flags
& SEEK_ABSOLUTE
? ogg_d
->initial_granulepos
: os
->lastpos
;
1446 if (flags
& SEEK_FACTOR
) {
1447 if (ogg_d
->duration
> 0)
1448 gp
+= ogg_d
->duration
* rel_seek_secs
;
1450 gp
+= rel_seek_secs
* (demuxer
->movi_end
- demuxer
->movi_start
) * os
->lastpos
/ ogg_d
->pos
;
1452 gp
+= rel_seek_secs
* rate
;
1456 //calculate the filepos to seek to
1457 if (ogg_d
->syncpoints
) {
1458 for (sp
= 0; sp
< ogg_d
->num_syncpoint
; sp
++)
1459 if (ogg_d
->syncpoints
[sp
].granulepos
>= gp
)
1462 if (sp
>= ogg_d
->num_syncpoint
)
1464 if (sp
> 0 && ogg_d
->syncpoints
[sp
].granulepos
- gp
> gp
- ogg_d
->syncpoints
[sp
- 1].granulepos
)
1466 if (ogg_d
->syncpoints
[sp
].granulepos
== os
->lastpos
) {
1467 if (sp
> 0 && gp
< os
->lastpos
)
1469 if (sp
< ogg_d
->num_syncpoint
- 1 && gp
> os
->lastpos
)
1472 pos
= ogg_d
->syncpoints
[sp
].page_pos
;
1475 pos
= flags
& SEEK_ABSOLUTE
? 0 : ogg_d
->pos
;
1476 if (flags
& SEEK_FACTOR
)
1477 pos
+= (demuxer
->movi_end
- demuxer
->movi_start
) * rel_seek_secs
;
1479 if (ogg_d
->duration
> 0) {
1480 pos
+= rel_seek_secs
* (demuxer
->movi_end
- demuxer
->movi_start
) / (ogg_d
->duration
/ rate
);
1481 } else if (os
->lastpos
> 0) {
1482 pos
+= rel_seek_secs
* ogg_d
->pos
/ (os
->lastpos
/ rate
);
1487 if (pos
> (demuxer
->movi_end
- demuxer
->movi_start
))
1488 pos
= demuxer
->movi_end
- demuxer
->movi_start
;
1489 } // if (ogg_d->syncpoints)
1493 stream_seek(demuxer
->stream
, pos
+demuxer
->movi_start
);
1494 ogg_sync_reset(sync
);
1495 for (i
= 0; i
< ogg_d
->num_sub
; i
++) {
1496 ogg_stream_reset(&ogg_d
->subs
[i
].stream
);
1497 ogg_d
->subs
[i
].lastpos
= ogg_d
->subs
[i
].lastsize
= 0;
1500 ogg_d
->last_size
= 0;
1501 /* we just guess that we reached correct granulepos, in case a
1502 subsequent search occurs before we read a valid granulepos */
1504 first
= !(ogg_d
->syncpoints
);
1507 ogg_d
->pos
+= ogg_d
->last_size
;
1508 ogg_d
->last_size
= 0;
1509 np
= ogg_sync_pageseek(sync
, page
);
1513 if (np
<= 0) { // We need more data
1514 char *buf
= ogg_sync_buffer(sync
, BLOCK_SIZE
);
1515 int len
= stream_read(demuxer
->stream
, buf
, BLOCK_SIZE
);
1517 if (len
== 0 && demuxer
->stream
->eof
) {
1518 mp_msg(MSGT_DEMUX
, MSGL_V
, "EOF while trying to seek !!!!\n");
1521 ogg_sync_wrote(sync
, len
);
1524 ogg_d
->last_size
= np
;
1525 if (ogg_page_serialno(page
) != oss
->serialno
)
1528 if (ogg_stream_pagein(oss
, page
) != 0)
1532 np
= ogg_stream_packetout(oss
, &op
);
1537 if (first
) { /* Discard the first packet as it's probably broken,
1538 and we don't have any other means to decide whether it is
1543 is_gp_valid
= (op
.granulepos
>= 0);
1544 granulepos_orig
=op
.granulepos
;
1545 demux_ogg_read_packet(os
, &op
, &pts
, &is_keyframe
, samplesize
);
1546 if (precision
&& is_gp_valid
) {
1548 if (abs(gp
- op
.granulepos
) > rate
&& (op
.granulepos
!= old_gp
)) {
1549 //prepare another seek because we are off by more than 1s
1550 pos
+= (gp
- op
.granulepos
) * (pos
- old_pos
) / (op
.granulepos
- old_gp
);
1553 if (pos
< demuxer
->movi_end
- demuxer
->movi_start
) {
1559 if (is_gp_valid
&& pos
> 0 && old_gp
> gp
1560 && 2 * (old_gp
- op
.granulepos
) < old_gp
- gp
) {
1561 /* prepare another seek because looking for a syncpoint
1562 destroyed the backward search */
1563 pos
= old_pos
- 1.5 * (old_pos
- pos
);
1566 if (pos
< demuxer
->movi_end
- demuxer
->movi_start
) {
1571 if (!precision
&& (is_keyframe
|| os
->vorbis
|| os
->speex
)) {
1572 if (sub_clear_text(&ogg_sub
, MP_NOPTS_VALUE
)) {
1574 vo_osd_changed(OSDTYPE_SUBTITLE
);
1576 op
.granulepos
=granulepos_orig
;
1577 demux_ogg_add_packet(ds
, os
, ds
->id
, &op
);
1583 mp_msg(MSGT_DEMUX
, MSGL_ERR
, "Can't find the good packet :(\n");
1586 static void demux_close_ogg(demuxer_t
*demuxer
)
1588 ogg_demuxer_t
*ogg_d
= demuxer
->priv
;
1589 ogg_stream_t
*os
= NULL
;
1599 ogg_sync_clear(&ogg_d
->sync
);
1601 for (i
= 0; i
< ogg_d
->num_sub
; i
++) {
1602 os
= &ogg_d
->subs
[i
];
1603 ogg_stream_clear(&os
->stream
);
1604 if (os
->vi_initialized
)
1605 vorbis_info_clear(&os
->vi
);
1609 if (ogg_d
->syncpoints
)
1610 free(ogg_d
->syncpoints
);
1611 if (ogg_d
->text_ids
)
1612 free(ogg_d
->text_ids
);
1613 if (ogg_d
->text_langs
) {
1614 for (i
= 0; i
< ogg_d
->n_text
; i
++)
1615 if (ogg_d
->text_langs
[i
]) free(ogg_d
->text_langs
[i
]);
1616 free(ogg_d
->text_langs
);
1621 static int demux_ogg_control(demuxer_t
*demuxer
, int cmd
, void *arg
)
1623 ogg_demuxer_t
*ogg_d
= demuxer
->priv
;
1627 if (demuxer
->video
->id
>= 0) {
1628 os
= &ogg_d
->subs
[demuxer
->video
->id
];
1629 rate
= os
->samplerate
;
1631 os
= &ogg_d
->subs
[demuxer
->audio
->id
];
1636 case DEMUXER_CTRL_GET_TIME_LENGTH
:
1637 if (ogg_d
->duration
<= 0)
1638 return DEMUXER_CTRL_DONTKNOW
;
1639 *(double *)arg
= (double)(ogg_d
->duration
) / rate
;
1640 return DEMUXER_CTRL_GUESS
;
1642 case DEMUXER_CTRL_GET_PERCENT_POS
:
1643 if (ogg_d
->duration
<= 0)
1644 return DEMUXER_CTRL_DONTKNOW
;
1645 *(int *)arg
= ((os
->lastpos
- ogg_d
->initial_granulepos
) * 100) / ogg_d
->duration
;
1646 return DEMUXER_CTRL_OK
;
1649 return DEMUXER_CTRL_NOTIMPL
;
1653 const demuxer_desc_t demuxer_desc_ogg
= {
1660 1, // safe autodetect
1662 demux_ogg_fill_buffer
,