14 #include "stream/stream.h"
17 #include "libavutil/intreadwrite.h"
19 #define FOURCC_VORBIS mmioFOURCC('v', 'r', 'b', 's')
20 #define FOURCC_SPEEX mmioFOURCC('s', 'p', 'x', ' ')
21 #define FOURCC_THEORA mmioFOURCC('t', 'h', 'e', 'o')
24 #include <tremor/ogg.h>
25 #include <tremor/ivorbiscodec.h>
28 #include <vorbis/codec.h>
31 #ifdef CONFIG_OGGTHEORA
32 #include <theora/theora.h>
33 int _ilog (unsigned int); /* defined in many places in theora/lib/ */
36 #define BLOCK_SIZE 4096
38 /* Theora decoder context : we won't be able to interpret granule positions
39 * without using theora_granule_time with the theora_state of the stream.
40 * This is duplicated in `vd_theora.c'; put this in a common header?
42 #ifdef CONFIG_OGGTHEORA
43 typedef struct theora_struct_st
{
51 // Header for the new header format
52 typedef struct stream_header_video
56 } stream_header_video
;
58 typedef struct stream_header_audio
61 ogg_int16_t blockalign
;
62 ogg_int32_t avgbytespersec
;
63 } stream_header_audio
;
65 typedef struct __attribute__((__packed__
)) stream_header
70 ogg_int32_t size
; // size of the structure
72 ogg_int64_t time_unit
; // in reference time
73 ogg_int64_t samples_per_unit
;
74 ogg_int32_t default_len
; // in media time
76 ogg_int32_t buffersize
;
77 ogg_int16_t bits_per_sample
;
84 stream_header_video video
;
86 stream_header_audio audio
;
92 typedef struct ogg_syncpoint
{
98 typedef struct ogg_stream
{
99 /// Timestamping stuff
100 float samplerate
; /// granulpos 2 time
103 int keyframe_frequency_force
;
105 // Logical stream state
106 ogg_stream_state stream
;
121 typedef struct ogg_demuxer
{
122 /// Physical stream state
129 ogg_syncpoint_t
* syncpoints
;
131 off_t pos
, last_size
;
132 int64_t final_granulepos
;
134 /* Used for subtitle switching. */
140 #define NUM_VORBIS_HDR_PACKETS 3
142 /// Some defines from OggDS
143 #define PACKET_TYPE_HEADER 0x01
144 #define PACKET_TYPE_BITS 0x07
145 #define PACKET_LEN_BITS01 0xc0
146 #define PACKET_LEN_BITS2 0x02
147 #define PACKET_IS_SYNCPOINT 0x08
149 extern char *dvdsub_lang
, *audio_lang
;
151 //-------- subtitle support - should be moved to decoder layer, and queue
152 // - subtitles up in demuxer buffer...
154 #include "subreader.h"
155 #include "libvo/sub.h"
156 #define OGG_SUB_MAX_LINE 128
158 static subtitle ogg_sub
;
161 static void demux_ogg_add_sub (ogg_stream_t
* os
,ogg_packet
* pack
) {
163 char *packet
= pack
->packet
;
167 mp_msg(MSGT_DEMUX
,MSGL_DBG2
,"\ndemux_ogg_add_sub %02X %02X %02X '%s'\n",
168 (unsigned char)packet
[0],
169 (unsigned char)packet
[1],
170 (unsigned char)packet
[2],
173 if (((unsigned char)packet
[0]) == 0x88) { // some subtitle text
175 double endpts
= MP_NOPTS_VALUE
;
176 int32_t duration
= 0;
177 int16_t hdrlen
= (*packet
& PACKET_LEN_BITS01
)>>6, i
;
178 hdrlen
|= (*packet
& PACKET_LEN_BITS2
) <<1;
180 if (pack
->bytes
< lcv
)
182 for (i
= hdrlen
; i
> 0; i
--) {
184 duration
|= (unsigned char)packet
[i
];
186 if (hdrlen
> 0 && duration
> 0) {
188 if(pack
->granulepos
== -1)
189 pack
->granulepos
= os
->lastpos
+ os
->lastsize
;
190 pts
= (float)pack
->granulepos
/(float)os
->samplerate
;
191 endpts
= 1.0 + pts
+ (float)duration
/1000.0;
193 sub_clear_text(&ogg_sub
, MP_NOPTS_VALUE
);
194 sub_add_text(&ogg_sub
, &packet
[lcv
], pack
->bytes
- lcv
, endpts
);
197 mp_msg(MSGT_DEMUX
,MSGL_DBG2
,"Ogg sub lines: %d first: '%s'\n",
198 ogg_sub
.lines
, ogg_sub
.text
[0]);
200 subcp_recode(&ogg_sub
);
203 vo_osd_changed(OSDTYPE_SUBTITLE
);
207 // get the logical stream of the current page
208 // fill os if non NULL and return the stream id
209 static int demux_ogg_get_page_stream(ogg_demuxer_t
* ogg_d
,ogg_stream_state
** os
) {
211 ogg_page
* page
= &ogg_d
->page
;
213 s_no
= ogg_page_serialno(page
);
215 for(id
= 0; id
< ogg_d
->num_sub
; id
++) {
216 if(s_no
== ogg_d
->subs
[id
].stream
.serialno
)
220 if(id
== ogg_d
->num_sub
) {
221 // If we have only one vorbis stream allow the stream id to change
222 // it's normal on radio stream (each song have an different id).
223 // But we (or the codec?) should check that the samplerate, etc
224 // doesn't change (for radio stream it's ok)
225 if(ogg_d
->num_sub
== 1 && ogg_d
->subs
[0].vorbis
) {
226 ogg_stream_reset(&ogg_d
->subs
[0].stream
);
227 ogg_stream_init(&ogg_d
->subs
[0].stream
,s_no
);
234 *os
= &ogg_d
->subs
[id
].stream
;
240 static unsigned char* demux_ogg_read_packet(ogg_stream_t
* os
,ogg_packet
* pack
,float* pts
,int* flags
, int samplesize
) {
241 unsigned char* data
= pack
->packet
;
247 if(*pack
->packet
& PACKET_TYPE_HEADER
)
249 else if (os
->vi_initialized
)
254 // When we dump the audio, there is no vi, but we don't care of timestamp in this case
256 blocksize
= vorbis_packet_blocksize(vi
,pack
) / samplesize
;
257 // Calculate the timestamp if the packet don't have any
258 if(pack
->granulepos
== -1) {
259 pack
->granulepos
= os
->lastpos
;
261 pack
->granulepos
+= os
->lastsize
;
263 *pts
= pack
->granulepos
/ (float)vi
->rate
;
264 os
->lastsize
= blocksize
;
265 os
->lastpos
= pack
->granulepos
;
267 } else if (os
->speex
) {
268 // whole packet (default)
269 # ifdef CONFIG_OGGTHEORA
270 } else if (os
->theora
) {
271 /* we pass complete packets to theora, mustn't strip the header! */
274 /* header packets begin on 1-bit: thus check (*data&0x80). We don't
275 have theora_state st, until all header packets were passed to the
279 int keyframe_granule_shift
=_ilog(os
->keyframe_frequency_force
-1);
280 int64_t iframemask
= (1 << keyframe_granule_shift
) - 1;
282 if (pack
->granulepos
>= 0)
284 os
->lastpos
= pack
->granulepos
>> keyframe_granule_shift
;
285 os
->lastpos
+= pack
->granulepos
& iframemask
;
286 *flags
= (pack
->granulepos
& iframemask
) == 0;
292 pack
->granulepos
= os
->lastpos
;
293 *pts
= (double)os
->lastpos
/ (double)os
->samplerate
;
295 #endif /* CONFIG_OGGTHEORA */
296 } else if (os
->flac
) {
297 /* we pass complete packets to flac, mustn't strip the header! */
298 if (os
->flac
== 2 && pack
->packet
[0] != 0xff)
301 if(*pack
->packet
& PACKET_TYPE_HEADER
)
305 int16_t hdrlen
= (*pack
->packet
& PACKET_LEN_BITS01
)>>6;
306 hdrlen
|= (*pack
->packet
& PACKET_LEN_BITS2
) <<1;
307 data
= pack
->packet
+ 1 + hdrlen
;
308 // Calculate the timestamp
309 if(pack
->granulepos
== -1)
310 pack
->granulepos
= os
->lastpos
+ (os
->lastsize
? os
->lastsize
: 1);
311 // If we already have a timestamp it can be a syncpoint
312 if(*pack
->packet
& PACKET_IS_SYNCPOINT
)
314 *pts
= pack
->granulepos
/os
->samplerate
;
315 // Save the packet length and timestamp
319 os
->lastsize
|= pack
->packet
[hdrlen
];
322 os
->lastpos
= pack
->granulepos
;
328 // check if clang has substring from comma separated langlist
329 static int demux_ogg_check_lang(const char *clang
, const char *langlist
)
333 if (!langlist
|| !*langlist
)
335 while ((c
= strchr(langlist
, ',')))
337 if (!strncasecmp(clang
, langlist
, c
- langlist
))
341 if (!strncasecmp(clang
, langlist
, strlen(langlist
)))
346 static int demux_ogg_sub_reverse_id(demuxer_t
*demuxer
, int id
);
348 /// Try to print out comments and also check for LANGUAGE= tag
349 static void demux_ogg_check_comments(demuxer_t
*d
, ogg_stream_t
*os
, int id
, vorbis_comment
*vc
)
351 const char *hdr
, *val
;
352 char **cmt
= vc
->user_comments
;
354 ogg_demuxer_t
*ogg_d
= d
->priv
;
355 static const struct table
{
359 { "ENCODED_USING", "Software" },
360 { "ENCODER_URL", "Encoder URL" },
362 { "ARTIST", "Artist" },
363 { "COMMENT", "Comments" },
364 { "DATE", "Creation Date" },
365 { "GENRE", "Genre" },
366 { "ALBUM", "Album" },
367 { "TRACKNUMBER", "Track" },
374 if (!strncasecmp(*cmt
, "LANGUAGE=", 9))
377 if (ogg_d
->subs
[id
].text
)
378 mp_msg(MSGT_IDENTIFY
, MSGL_INFO
, "ID_SID_%d_LANG=%s\n", ogg_d
->subs
[id
].id
, val
);
379 else if (id
!= d
->video
->id
)
380 mp_msg(MSGT_IDENTIFY
, MSGL_INFO
, "ID_AID_%d_LANG=%s\n", ogg_d
->subs
[id
].id
, val
);
381 if (ogg_d
->subs
[id
].text
)
382 mp_msg(MSGT_DEMUX
, MSGL_INFO
, "[Ogg] Language for -sid %d is '-slang \"%s\"'\n", ogg_d
->subs
[id
].id
, val
);
383 // copy this language name into the array
384 index
= demux_ogg_sub_reverse_id(d
, id
);
387 // in case of malicious files with more than one lang per track:
388 if (ogg_d
->text_langs
[index
]) free(ogg_d
->text_langs
[index
]);
389 ogg_d
->text_langs
[index
] = strdup(val
);
390 sh
= d
->s_streams
[index
];
391 if (sh
&& sh
->lang
) free(sh
->lang
);
392 if (sh
) sh
->lang
= strdup(val
);
394 // check for -slang if subs are uninitialized yet
395 if (os
->text
&& d
->sub
->id
< 0 && demux_ogg_check_lang(val
, dvdsub_lang
))
398 d
->opts
->sub_id
= index
;
399 mp_msg(MSGT_DEMUX
, MSGL_V
, "Ogg demuxer: Displaying subtitle stream id %d which matched -slang %s\n", id
, val
);
405 for (i
= 0; table
[i
].ogg
; i
++)
407 if (!strncasecmp(*cmt
, table
[i
].ogg
, strlen(table
[i
].ogg
)) &&
408 (*cmt
)[strlen(table
[i
].ogg
)] == '=')
411 val
= *cmt
+ strlen(table
[i
].ogg
) + 1;
416 demux_info_add(d
, hdr
, val
);
417 mp_dbg(MSGT_DEMUX
, MSGL_DBG2
, " %s: %s\n", hdr
, val
);
422 /// Calculate the timestamp and add the packet to the demux stream
423 // return 1 if the packet was added, 0 otherwise
424 static int demux_ogg_add_packet(demux_stream_t
* ds
,ogg_stream_t
* os
,int id
,ogg_packet
* pack
) {
425 demuxer_t
* d
= ds
->demuxer
;
432 // If packet is an comment header then we try to get comments at first
433 if (pack
->bytes
>= 7 && !memcmp(pack
->packet
, "\003vorbis", 7))
438 vorbis_info_init(&vi
);
439 vorbis_comment_init(&vc
);
440 vi
.rate
= 1L; // it's checked by vorbis_synthesis_headerin()
441 if(vorbis_synthesis_headerin(&vi
, &vc
, pack
) == 0) // if no errors
442 demux_ogg_check_comments(d
, os
, id
, &vc
);
443 vorbis_comment_clear(&vc
);
444 vorbis_info_clear(&vi
);
447 if (id
== demux_ogg_sub_id(d
, d
->sub
->id
)) // don't want to add subtitles to the demuxer for now
448 demux_ogg_add_sub(os
,pack
);
452 // discard first two packets, they contain the header and comment
453 if (os
->hdr_packets
< 2) {
458 // If packet is an header we jump it except for vorbis and theora
459 // (PACKET_TYPE_HEADER bit doesn't even exist for theora ?!)
460 // We jump nothing for FLAC. Ain't this great? Packet contents have to be
461 // handled differently for each and every stream type. The joy! The joy!
462 if(!os
->flac
&& (*pack
->packet
& PACKET_TYPE_HEADER
) &&
463 (ds
!= d
->audio
|| ((sh_audio_t
*)ds
->sh
)->format
!= FOURCC_VORBIS
|| os
->hdr_packets
>= NUM_VORBIS_HDR_PACKETS
) &&
464 (ds
!= d
->video
|| (((sh_video_t
*)ds
->sh
)->format
!= FOURCC_THEORA
)))
467 // For vorbis packet the packet is the data, for other codec we must jump
469 if(ds
== d
->audio
&& ((sh_audio_t
*)ds
->sh
)->format
== FOURCC_VORBIS
) {
470 samplesize
= ((sh_audio_t
*)ds
->sh
)->samplesize
;
472 data
= demux_ogg_read_packet(os
,pack
,&pts
,&flags
,samplesize
);
476 /// Clear subtitles if necessary (for broken files)
477 if (sub_clear_text(&ogg_sub
, pts
)) {
479 vo_osd_changed(OSDTYPE_SUBTITLE
);
482 dp
= new_demux_packet(pack
->bytes
-(data
-pack
->packet
));
483 memcpy(dp
->buffer
,data
,pack
->bytes
-(data
-pack
->packet
));
486 ds_add_packet(ds
,dp
);
487 mp_msg(MSGT_DEMUX
,MSGL_DBG2
,"New dp: %p ds=%p pts=%5.3f len=%d flag=%d \n",
488 dp
, ds
, pts
, dp
->len
, flags
);
492 /// if -forceidx build a table of all syncpoints to make seeking easier
493 /// otherwise try to get at least the final_granulepos
494 static void demux_ogg_scan_stream(demuxer_t
* demuxer
) {
495 ogg_demuxer_t
* ogg_d
= demuxer
->priv
;
496 stream_t
*s
= demuxer
->stream
;
497 ogg_sync_state
* sync
= &ogg_d
->sync
;
498 ogg_page
* page
= &ogg_d
->page
;
499 ogg_stream_state
* oss
;
502 int np
,sid
,p
,samplesize
=1;
504 pos
= last_pos
= demuxer
->movi_start
;
507 if(index_mode
== 2) {
508 stream_seek(s
,demuxer
->movi_start
);
510 //the 270000 are just a wild guess
511 stream_seek(s
,FFMAX(ogg_d
->pos
,demuxer
->movi_end
-270000));
513 ogg_sync_reset(sync
);
515 // Get the serial number of the stream we use
516 if(demuxer
->video
->id
>= 0) {
517 sid
= demuxer
->video
->id
;
519 else if(demuxer
->audio
->id
>= 0) {
520 sid
= demuxer
->audio
->id
;
521 if(((sh_audio_t
*)demuxer
->audio
->sh
)->format
== FOURCC_VORBIS
) {
522 samplesize
= ((sh_audio_t
*)demuxer
->audio
->sh
)->samplesize
;
526 os
= &ogg_d
->subs
[sid
];
530 np
= ogg_sync_pageseek(sync
,page
);
531 if(np
< 0) { // We had to skip some bytes
532 if(index_mode
== 2) mp_msg(MSGT_DEMUX
,MSGL_ERR
,"Bad page sync while building syncpoints table (%d)\n",-np
);
536 if(np
<= 0) { // We need more data
537 char* buf
= ogg_sync_buffer(sync
,BLOCK_SIZE
);
538 int len
= stream_read(s
,buf
,BLOCK_SIZE
);
539 if(len
== 0 && s
->eof
)
541 ogg_sync_wrote(sync
,len
);
545 //ogg_sync_pageout(sync,page);
546 if(ogg_page_serialno(page
) != os
->stream
.serialno
) { // It isn't a page from the stream we want
550 if(ogg_stream_pagein(oss
,page
) != 0) {
551 mp_msg(MSGT_DEMUX
,MSGL_ERR
,"Pagein error ????\n");
556 while(ogg_stream_packetout(oss
,&op
) == 1) {
559 demux_ogg_read_packet(os
,&op
,&pts
,&flags
,samplesize
);
560 if(op
.granulepos
>= 0) ogg_d
->final_granulepos
= op
.granulepos
;
561 if(index_mode
== 2 && (flags
|| (os
->vorbis
&& op
.granulepos
>= 0))) {
562 if (ogg_d
->num_syncpoint
> SIZE_MAX
/ sizeof(ogg_syncpoint_t
) - 1) break;
563 ogg_d
->syncpoints
= realloc_struct(ogg_d
->syncpoints
,(ogg_d
->num_syncpoint
+1), sizeof(ogg_syncpoint_t
));
564 ogg_d
->syncpoints
[ogg_d
->num_syncpoint
].granulepos
= op
.granulepos
;
565 ogg_d
->syncpoints
[ogg_d
->num_syncpoint
].page_pos
= (ogg_page_continued(page
) && p
== 0) ? last_pos
: pos
;
566 ogg_d
->num_syncpoint
++;
570 if(p
> 1 || (p
== 1 && ! ogg_page_continued(page
)))
573 if(index_mode
== 2) mp_msg(MSGT_DEMUX
,MSGL_INFO
,"Building syncpoint table %d%%\r",(int)(pos
*100/s
->end_pos
));
575 if(index_mode
== 2) mp_msg(MSGT_DEMUX
,MSGL_INFO
,"\n");
577 if(index_mode
== 2) mp_msg(MSGT_DEMUX
,MSGL_V
,"Ogg syncpoints table builed: %d syncpoints\n",ogg_d
->num_syncpoint
);
578 mp_msg(MSGT_DEMUX
,MSGL_V
,"Ogg stream length (granulepos): %"PRId64
"\n",ogg_d
->final_granulepos
);
581 stream_seek(s
,demuxer
->movi_start
);
582 ogg_sync_reset(sync
);
583 for(np
= 0 ; np
< ogg_d
->num_sub
; np
++) {
584 ogg_stream_reset(&ogg_d
->subs
[np
].stream
);
585 ogg_d
->subs
[np
].lastpos
= ogg_d
->subs
[np
].lastsize
= ogg_d
->subs
[np
].hdr_packets
= 0;
589 // Get the first page
591 np
= ogg_sync_pageout(sync
,page
);
592 if(np
<= 0) { // We need more data
593 char* buf
= ogg_sync_buffer(sync
,BLOCK_SIZE
);
594 int len
= stream_read(s
,buf
,BLOCK_SIZE
);
595 if(len
== 0 && s
->eof
) {
596 mp_msg(MSGT_DEMUX
,MSGL_ERR
,"EOF while trying to get the first page !!!!\n");
600 ogg_sync_wrote(sync
,len
);
603 demux_ogg_get_page_stream(ogg_d
,&oss
);
604 ogg_stream_pagein(oss
,page
);
610 void print_wave_header(WAVEFORMATEX
*h
, int verbose_level
);
611 void print_video_header(BITMAPINFOHEADER
*h
, int verbose_level
);
613 /* defined in demux_mov.c */
614 unsigned int store_ughvlc(unsigned char *s
, unsigned int v
);
616 /** \brief Change the current subtitle stream and return its ID.
618 \param demuxer The demuxer whose subtitle stream will be changed.
619 \param new_num The number of the new subtitle track. The number must be
620 between 0 and ogg_d->n_text - 1.
622 \returns The Ogg stream number ( = page serial number) of the newly selected
625 int demux_ogg_sub_id(demuxer_t
*demuxer
, int index
) {
626 ogg_demuxer_t
*ogg_d
= demuxer
->priv
;
627 return (index
< 0) ? index
: (index
>= ogg_d
->n_text
) ? -1 : ogg_d
->text_ids
[index
];
630 /** \brief Translate the ogg track number into the subtitle number.
631 * \param demuxer The demuxer about whose subtitles we are inquiring.
632 * \param id The ogg track number of the subtitle track.
634 static int demux_ogg_sub_reverse_id(demuxer_t
*demuxer
, int id
) {
635 ogg_demuxer_t
*ogg_d
= demuxer
->priv
;
637 for (i
= 0; i
< ogg_d
->n_text
; i
++)
638 if (ogg_d
->text_ids
[i
] == id
) return i
;
642 static void demux_close_ogg(demuxer_t
* demuxer
);
644 static void fixup_vorbis_wf(sh_audio_t
*sh
, ogg_demuxer_t
*od
)
647 int ris
, init_error
= 0;
649 unsigned char *buf
[3];
652 ogg_stream_t
*os
= &od
->subs
[sh
->ds
->id
];
655 vorbis_info_init(&os
->vi
);
656 vorbis_comment_init(&vc
);
657 for(i
= 0; i
< 3; i
++) {
658 op
[i
].bytes
= ds_get_packet(sh
->ds
, &(op
[i
].packet
));
659 mp_msg(MSGT_DEMUX
,MSGL_V
, "fixup_vorbis_wf: i=%d, size=%ld\n", i
, op
[i
].bytes
);
660 if(op
[i
].bytes
< 0) {
661 mp_msg(MSGT_DEMUX
,MSGL_ERR
,"Ogg demuxer error!, fixup_vorbis_wf: bad packet n. %d\n", i
);
664 buf
[i
] = malloc(op
[i
].bytes
);
667 memcpy(buf
[i
], op
[i
].packet
, op
[i
].bytes
);
669 op
[i
].b_o_s
= (i
==0);
670 ris
= vorbis_synthesis_headerin(&os
->vi
,&vc
,&op
[i
]);
673 mp_msg(MSGT_DECAUDIO
,MSGL_ERR
,"DEMUX_OGG: header n. %d broken! len=%ld, code: %d\n", i
, op
[i
].bytes
, ris
);
676 vorbis_comment_clear(&vc
);
678 os
->vi_initialized
= 1;
680 len
= op
[0].bytes
+ op
[1].bytes
+ op
[2].bytes
;
681 sh
->wf
= calloc(1, sizeof(WAVEFORMATEX
) + len
+ len
/255 + 64);
682 ptr
= (unsigned char*) (sh
->wf
+1);
686 offset
+= store_ughvlc(&ptr
[offset
], op
[0].bytes
);
687 mp_msg(MSGT_DEMUX
,MSGL_V
,"demux_ogg, offset after 1st len = %u\n", offset
);
688 offset
+= store_ughvlc(&ptr
[offset
], op
[1].bytes
);
689 mp_msg(MSGT_DEMUX
,MSGL_V
,"demux_ogg, offset after 2nd len = %u\n", offset
);
690 for(i
= 0; i
< 3; i
++) {
691 mp_msg(MSGT_DEMUX
,MSGL_V
,"demux_ogg, i=%d, bytes: %ld, offset: %u\n", i
, op
[i
].bytes
, offset
);
692 memcpy(&ptr
[offset
], buf
[i
], op
[i
].bytes
);
693 offset
+= op
[i
].bytes
;
695 sh
->wf
->cbSize
= offset
;
696 mp_msg(MSGT_DEMUX
,MSGL_V
, "demux_ogg, extradata size: %d\n", sh
->wf
->cbSize
);
697 sh
->wf
= realloc(sh
->wf
, sizeof(WAVEFORMATEX
) + sh
->wf
->cbSize
);
699 if(op
[0].bytes
>= 29) {
701 int nombr
, minbr
, maxbr
;
703 sh
->channels
= ptr
[11];
704 sh
->samplerate
= sh
->wf
->nSamplesPerSec
= AV_RL32(&ptr
[12]);
705 maxbr
= AV_RL32(&ptr
[16]); //max
706 nombr
= AV_RL32(&ptr
[20]); //nominal
707 minbr
= AV_RL32(&ptr
[24]); //minimum
721 sh
->wf
->nAvgBytesPerSec
= br
;
722 sh
->wf
->wBitsPerSample
= 16;
723 sh
->samplesize
= (sh
->wf
->wBitsPerSample
+7)/8;
725 mp_msg(MSGT_DEMUX
,MSGL_V
,"demux_ogg, vorbis stream features are: channels: %d, srate: %d, bitrate: %d, max: %u, nominal: %u, min: %u\n",
726 sh
->channels
, sh
->samplerate
, sh
->wf
->nAvgBytesPerSec
, maxbr
, nombr
, minbr
);
734 /// Open an ogg physical stream
735 // Not static because it's used also in demuxer_avi.c
736 int demux_ogg_open(demuxer_t
* demuxer
) {
737 ogg_demuxer_t
* ogg_d
;
740 int np
,s_no
, n_audio
= 0, n_video
= 0;
741 int audio_id
= -1, video_id
= -1, text_id
= -1;
742 ogg_sync_state
* sync
;
755 ogg_d
= calloc(1,sizeof(ogg_demuxer_t
));
762 /// Try to get a page
763 ogg_d
->pos
+= ogg_d
->last_size
;
764 np
= ogg_sync_pageseek(sync
,page
);
767 mp_msg(MSGT_DEMUX
,MSGL_DBG2
,"Ogg demuxer : Bad page sync\n");
770 /// Need some more data
773 buf
= ogg_sync_buffer(sync
,BLOCK_SIZE
);
774 len
= stream_read(s
,buf
,BLOCK_SIZE
);
775 if(len
== 0 && s
->eof
) {
778 ogg_sync_wrote(sync
,len
);
781 ogg_d
->last_size
= np
;
782 // We got one page now
784 if( ! ogg_page_bos(page
) ) { // It's not a beginning page
785 // Header parsing end here, we need to get the page otherwise it will be lost
786 int id
= demux_ogg_get_page_stream(ogg_d
,NULL
);
788 ogg_stream_pagein(&ogg_d
->subs
[id
].stream
,page
);
790 mp_msg(MSGT_DEMUX
,MSGL_ERR
,"Ogg : Warning found none bos page from unknown stream %d\n",ogg_page_serialno(page
));
794 /// Init the data structure needed for a logical stream
795 ogg_d
->subs
= realloc_struct(ogg_d
->subs
,ogg_d
->num_sub
+1,sizeof(ogg_stream_t
));
796 memset(&ogg_d
->subs
[ogg_d
->num_sub
],0,sizeof(ogg_stream_t
));
797 /// Get the stream serial number
798 s_no
= ogg_page_serialno(page
);
799 ogg_stream_init(&ogg_d
->subs
[ogg_d
->num_sub
].stream
,s_no
);
800 mp_msg(MSGT_DEMUX
,MSGL_DBG2
,"Ogg : Found a stream with serial=%d\n",s_no
);
801 // Take the first page
802 ogg_stream_pagein(&ogg_d
->subs
[ogg_d
->num_sub
].stream
,page
);
803 // Get first packet of the page
804 ogg_stream_packetout(&ogg_d
->subs
[ogg_d
->num_sub
].stream
,&pack
);
810 ogg_d
->subs
[ogg_d
->num_sub
].ogg_d
= ogg_d
;
813 if(pack
.bytes
>= 7 && ! strncmp(&pack
.packet
[1],"vorbis", 6) ) {
814 sh_a
= new_sh_audio_aid(demuxer
,ogg_d
->num_sub
, n_audio
);
815 sh_a
->format
= FOURCC_VORBIS
;
816 ogg_d
->subs
[ogg_d
->num_sub
].vorbis
= 1;
817 ogg_d
->subs
[ogg_d
->num_sub
].id
= n_audio
;
819 mp_msg(MSGT_DEMUX
,MSGL_INFO
,"[Ogg] stream %d: audio (Vorbis), -aid %d\n",ogg_d
->num_sub
,n_audio
-1);
820 } else if (pack
.bytes
>= 80 && !strncmp(pack
.packet
,"Speex", 5)) {
821 sh_a
= new_sh_audio_aid(demuxer
, ogg_d
->num_sub
, n_audio
);
822 sh_a
->wf
= calloc(1, sizeof(WAVEFORMATEX
) + pack
.bytes
);
823 sh_a
->format
= FOURCC_SPEEX
;
824 sh_a
->samplerate
= sh_a
->wf
->nSamplesPerSec
= AV_RL32(&pack
.packet
[36]);
825 sh_a
->channels
= sh_a
->wf
->nChannels
= AV_RL32(&pack
.packet
[48]);
826 sh_a
->wf
->wFormatTag
= sh_a
->format
;
827 sh_a
->wf
->nAvgBytesPerSec
= AV_RL32(&pack
.packet
[52]);
828 sh_a
->wf
->nBlockAlign
= 0;
829 sh_a
->wf
->wBitsPerSample
= 16;
830 sh_a
->samplesize
= 2;
831 sh_a
->wf
->cbSize
= pack
.bytes
;
832 memcpy(&sh_a
->wf
[1], pack
.packet
, pack
.bytes
);
834 ogg_d
->subs
[ogg_d
->num_sub
].samplerate
= sh_a
->samplerate
;
835 ogg_d
->subs
[ogg_d
->num_sub
].speex
= 1;
836 ogg_d
->subs
[ogg_d
->num_sub
].id
= n_audio
;
838 mp_msg(MSGT_DEMUX
,MSGL_INFO
,"[Ogg] stream %d: audio (Speex), -aid %d\n",ogg_d
->num_sub
,n_audio
-1);
841 # ifdef CONFIG_OGGTHEORA
842 } else if (pack
.bytes
>= 7 && !strncmp (&pack
.packet
[1], "theora", 6)) {
847 theora_info_init (&inf
);
848 theora_comment_init (&cc
);
850 errorCode
= theora_decode_header (&inf
, &cc
, &pack
);
852 mp_msg(MSGT_DEMUX
,MSGL_ERR
,"Theora header parsing failed: %i \n",
856 sh_v
= new_sh_video_vid(demuxer
,ogg_d
->num_sub
, n_video
);
858 sh_v
->bih
= calloc(1,sizeof(BITMAPINFOHEADER
));
859 sh_v
->bih
->biSize
=sizeof(BITMAPINFOHEADER
);
860 sh_v
->bih
->biCompression
= sh_v
->format
= FOURCC_THEORA
;
861 sh_v
->fps
= ((double)inf
.fps_numerator
)/
862 (double)inf
.fps_denominator
;
863 sh_v
->frametime
= ((double)inf
.fps_denominator
)/
864 (double)inf
.fps_numerator
;
865 sh_v
->disp_w
= sh_v
->bih
->biWidth
= inf
.frame_width
;
866 sh_v
->disp_h
= sh_v
->bih
->biHeight
= inf
.frame_height
;
867 sh_v
->bih
->biBitCount
= 24;
868 sh_v
->bih
->biPlanes
= 3;
869 sh_v
->bih
->biSizeImage
= ((sh_v
->bih
->biBitCount
/8) *
870 sh_v
->bih
->biWidth
*sh_v
->bih
->biHeight
);
871 ogg_d
->subs
[ogg_d
->num_sub
].samplerate
= sh_v
->fps
;
872 ogg_d
->subs
[ogg_d
->num_sub
].theora
= 1;
873 ogg_d
->subs
[ogg_d
->num_sub
].keyframe_frequency_force
= inf
.keyframe_frequency_force
;
874 ogg_d
->subs
[ogg_d
->num_sub
].id
= n_video
;
876 mp_msg(MSGT_DEMUX
,MSGL_INFO
,
877 "[Ogg] stream %d: video (Theora v%d.%d.%d), -vid %d\n",
879 (int)inf
.version_major
,
880 (int)inf
.version_minor
,
881 (int)inf
.version_subminor
,
883 if( mp_msg_test(MSGT_HEADER
,MSGL_V
) ) print_video_header(sh_v
->bih
,MSGL_V
);
885 theora_comment_clear(&cc
);
886 theora_info_clear(&inf
);
887 # endif /* CONFIG_OGGTHEORA */
888 } else if (pack
.bytes
>= 4 && !strncmp (&pack
.packet
[0], "fLaC", 4)) {
889 sh_a
= new_sh_audio_aid(demuxer
,ogg_d
->num_sub
, n_audio
);
890 sh_a
->format
= mmioFOURCC('f', 'L', 'a', 'C');
891 ogg_d
->subs
[ogg_d
->num_sub
].id
= n_audio
;
893 ogg_d
->subs
[ogg_d
->num_sub
].flac
= 1;
895 mp_msg(MSGT_DEMUX
,MSGL_INFO
,"[Ogg] stream %d: audio (FLAC), -aid %d\n",ogg_d
->num_sub
,n_audio
-1);
896 } else if (pack
.bytes
>= 51 && !strncmp(&pack
.packet
[1], "FLAC", 4)) {
897 sh_a
= new_sh_audio_aid(demuxer
,ogg_d
->num_sub
, n_audio
);
898 sh_a
->format
= mmioFOURCC('f', 'L', 'a', 'C');
899 ogg_d
->subs
[ogg_d
->num_sub
].id
= n_audio
;
901 ogg_d
->subs
[ogg_d
->num_sub
].flac
= 2;
902 sh_a
->wf
= calloc(1, sizeof(WAVEFORMATEX
) + 34);
903 sh_a
->wf
->wFormatTag
= sh_a
->format
;
904 sh_a
->wf
->cbSize
= 34;
905 memcpy(&sh_a
->wf
[1], &pack
.packet
[17], 34);
906 mp_msg(MSGT_DEMUX
,MSGL_INFO
,"[Ogg] stream %d: audio (FLAC, try 2), -aid %d\n",ogg_d
->num_sub
,n_audio
-1);
908 /// Check for old header
909 } else if(pack
.bytes
>= 142 && ! strncmp(&pack
.packet
[1],"Direct Show Samples embedded in Ogg",35) ) {
912 if(AV_RL32(pack
.packet
+96) == 0x05589f80 && pack
.bytes
>= 184) {
913 sh_v
= new_sh_video_vid(demuxer
,ogg_d
->num_sub
, n_video
);
914 sh_v
->bih
= calloc(1,sizeof(BITMAPINFOHEADER
));
915 sh_v
->bih
->biSize
=sizeof(BITMAPINFOHEADER
);
916 sh_v
->bih
->biCompression
=
917 sh_v
->format
= mmioFOURCC(pack
.packet
[68],pack
.packet
[69],
918 pack
.packet
[70],pack
.packet
[71]);
919 sh_v
->frametime
= AV_RL64(pack
.packet
+164)*0.0000001;
920 sh_v
->fps
= 1/sh_v
->frametime
;
921 sh_v
->disp_w
= sh_v
->bih
->biWidth
= AV_RL32(pack
.packet
+176);
922 sh_v
->disp_h
= sh_v
->bih
->biHeight
= AV_RL32(pack
.packet
+180);
923 sh_v
->bih
->biBitCount
= AV_RL16(pack
.packet
+182);
924 if(!sh_v
->bih
->biBitCount
) sh_v
->bih
->biBitCount
=24; // hack, FIXME
925 sh_v
->bih
->biPlanes
=1;
926 sh_v
->bih
->biSizeImage
=(sh_v
->bih
->biBitCount
>>3)*sh_v
->bih
->biWidth
*sh_v
->bih
->biHeight
;
928 ogg_d
->subs
[ogg_d
->num_sub
].samplerate
= sh_v
->fps
;
929 ogg_d
->subs
[ogg_d
->num_sub
].id
= n_video
;
931 mp_msg(MSGT_DEMUX
,MSGL_INFO
,"[Ogg] stream %d: video (FOURCC %c%c%c%c), -vid %d\n",
932 ogg_d
->num_sub
,pack
.packet
[68],pack
.packet
[69],pack
.packet
[70],pack
.packet
[71],n_video
-1);
933 if( mp_msg_test(MSGT_HEADER
,MSGL_V
) ) print_video_header(sh_v
->bih
,MSGL_V
);
935 } else if(AV_RL32(pack
.packet
+96) == 0x05589F81) {
936 unsigned int extra_size
;
937 sh_a
= new_sh_audio_aid(demuxer
,ogg_d
->num_sub
, n_audio
);
938 extra_size
= AV_RL16(pack
.packet
+140);
939 sh_a
->wf
= calloc(1,sizeof(WAVEFORMATEX
)+extra_size
);
940 sh_a
->format
= sh_a
->wf
->wFormatTag
= AV_RL16(pack
.packet
+124);
941 sh_a
->channels
= sh_a
->wf
->nChannels
= AV_RL16(pack
.packet
+126);
942 sh_a
->samplerate
= sh_a
->wf
->nSamplesPerSec
= AV_RL32(pack
.packet
+128);
943 sh_a
->wf
->nAvgBytesPerSec
= AV_RL32(pack
.packet
+132);
944 sh_a
->wf
->nBlockAlign
= AV_RL16(pack
.packet
+136);
945 sh_a
->wf
->wBitsPerSample
= AV_RL16(pack
.packet
+138);
946 sh_a
->samplesize
= (sh_a
->wf
->wBitsPerSample
+7)/8;
947 sh_a
->wf
->cbSize
= extra_size
;
949 memcpy(((char *)sh_a
->wf
)+sizeof(WAVEFORMATEX
),pack
.packet
+142,extra_size
);
951 ogg_d
->subs
[ogg_d
->num_sub
].samplerate
= sh_a
->samplerate
; // * sh_a->channels;
952 ogg_d
->subs
[ogg_d
->num_sub
].id
= n_audio
;
954 mp_msg(MSGT_DEMUX
,MSGL_INFO
,"[Ogg] stream %d: audio (format 0x%04x), -aid %d\n",ogg_d
->num_sub
,sh_a
->format
,n_audio
-1);
955 if( mp_msg_test(MSGT_HEADER
,MSGL_V
) ) print_wave_header(sh_a
->wf
,MSGL_V
);
957 mp_msg(MSGT_DEMUX
,MSGL_WARN
,"Ogg stream %d contains an old header but the header type is unknown\n",ogg_d
->num_sub
);
960 } else if ( (*pack
.packet
& PACKET_TYPE_BITS
) == PACKET_TYPE_HEADER
&&
961 pack
.bytes
>= (int)sizeof(stream_header
)+1) {
962 stream_header
*st
= (stream_header
*)(pack
.packet
+1);
964 if(strncmp(st
->streamtype
,"video",5) == 0) {
965 sh_v
= new_sh_video_vid(demuxer
,ogg_d
->num_sub
, n_video
);
966 sh_v
->bih
= calloc(1,sizeof(BITMAPINFOHEADER
));
967 sh_v
->bih
->biSize
=sizeof(BITMAPINFOHEADER
);
968 sh_v
->bih
->biCompression
=
969 sh_v
->format
= mmioFOURCC(st
->subtype
[0],st
->subtype
[1],
970 st
->subtype
[2],st
->subtype
[3]);
971 sh_v
->frametime
= AV_RL64(&st
->time_unit
)*0.0000001;
972 sh_v
->fps
= 1.0/sh_v
->frametime
;
973 sh_v
->bih
->biBitCount
= AV_RL16(&st
->bits_per_sample
);
974 sh_v
->disp_w
= sh_v
->bih
->biWidth
= AV_RL32(&st
->sh
.video
.width
);
975 sh_v
->disp_h
= sh_v
->bih
->biHeight
= AV_RL32(&st
->sh
.video
.height
);
976 if(!sh_v
->bih
->biBitCount
) sh_v
->bih
->biBitCount
=24; // hack, FIXME
977 sh_v
->bih
->biPlanes
=1;
978 sh_v
->bih
->biSizeImage
=(sh_v
->bih
->biBitCount
>>3)*sh_v
->bih
->biWidth
*sh_v
->bih
->biHeight
;
980 ogg_d
->subs
[ogg_d
->num_sub
].samplerate
= sh_v
->fps
;
981 ogg_d
->subs
[ogg_d
->num_sub
].id
= n_video
;
983 mp_msg(MSGT_DEMUX
,MSGL_INFO
,"[Ogg] stream %d: video (FOURCC %c%c%c%c), -vid %d\n",
984 ogg_d
->num_sub
,st
->subtype
[0],st
->subtype
[1],st
->subtype
[2],st
->subtype
[3],n_video
-1);
985 if( mp_msg_test(MSGT_HEADER
,MSGL_V
) ) print_video_header(sh_v
->bih
,MSGL_V
);
987 } else if(strncmp(st
->streamtype
,"audio",5) == 0) {
989 unsigned int extra_size
= AV_RL32(&st
->size
) - sizeof(stream_header
);
990 unsigned int extra_offset
= 0;
992 memcpy(buffer
,st
->subtype
,4);
995 /* Nasty workaround. stream_header.size seems not to contain the real
996 size in all cases. There are four extra bytes that are unaccounted
997 for in front of the real codec initialization data _at least_ for
998 AAC. So far I've only seen those bytes being all 0, so we can
999 just skip them here. */
1000 if ((strtol(buffer
, NULL
, 16) == 0xff) && (extra_size
>= 4)) {
1005 sh_a
= new_sh_audio_aid(demuxer
,ogg_d
->num_sub
, n_audio
);
1006 sh_a
->wf
= calloc(1,sizeof(WAVEFORMATEX
)+extra_size
);
1007 sh_a
->format
= sh_a
->wf
->wFormatTag
= strtol(buffer
, NULL
, 16);
1008 sh_a
->channels
= sh_a
->wf
->nChannels
= AV_RL16(&st
->sh
.audio
.channels
);
1009 sh_a
->samplerate
= sh_a
->wf
->nSamplesPerSec
= AV_RL64(&st
->samples_per_unit
);
1010 sh_a
->wf
->nAvgBytesPerSec
= AV_RL32(&st
->sh
.audio
.avgbytespersec
);
1011 sh_a
->wf
->nBlockAlign
= AV_RL16(&st
->sh
.audio
.blockalign
);
1012 sh_a
->wf
->wBitsPerSample
= AV_RL16(&st
->bits_per_sample
);
1013 sh_a
->samplesize
= (sh_a
->wf
->wBitsPerSample
+7)/8;
1014 sh_a
->wf
->cbSize
= extra_size
;
1016 memcpy(((char *)sh_a
->wf
)+sizeof(WAVEFORMATEX
),((char *)(st
+1))+extra_offset
,extra_size
);
1018 ogg_d
->subs
[ogg_d
->num_sub
].samplerate
= sh_a
->samplerate
; // * sh_a->channels;
1019 ogg_d
->subs
[ogg_d
->num_sub
].id
= n_audio
;
1021 mp_msg(MSGT_DEMUX
,MSGL_INFO
,"[Ogg] stream %d: audio (format 0x%04x), -aid %d\n",ogg_d
->num_sub
,sh_a
->format
,n_audio
-1);
1022 if( mp_msg_test(MSGT_HEADER
,MSGL_V
) ) print_wave_header(sh_a
->wf
,MSGL_V
);
1024 /// Check for text (subtitles) header
1025 } else if (strncmp(st
->streamtype
, "text", 4) == 0) {
1026 mp_msg(MSGT_DEMUX
, MSGL_INFO
, "[Ogg] stream %d: subtitles (SRT-like text subtitles), -sid %d\n", ogg_d
->num_sub
, ogg_d
->n_text
);
1027 ogg_d
->subs
[ogg_d
->num_sub
].samplerate
= AV_RL64(&st
->time_unit
)/10;
1028 ogg_d
->subs
[ogg_d
->num_sub
].text
= 1;
1029 ogg_d
->subs
[ogg_d
->num_sub
].id
= ogg_d
->n_text
;
1030 if (demuxer
->sub
->id
== ogg_d
->n_text
)
1031 text_id
= ogg_d
->num_sub
;
1032 new_sh_sub(demuxer
, ogg_d
->n_text
);
1034 ogg_d
->text_ids
= realloc_struct(ogg_d
->text_ids
, ogg_d
->n_text
, sizeof(int));
1035 ogg_d
->text_ids
[ogg_d
->n_text
- 1] = ogg_d
->num_sub
;
1036 ogg_d
->text_langs
= realloc_struct(ogg_d
->text_langs
, ogg_d
->n_text
, sizeof(char *));
1037 ogg_d
->text_langs
[ogg_d
->n_text
- 1] = NULL
;
1038 //// Unknown header type
1040 mp_msg(MSGT_DEMUX
,MSGL_ERR
,"Ogg stream %d has a header marker but is of an unknown type\n",ogg_d
->num_sub
);
1041 /// Unknown (invalid ?) header
1043 mp_msg(MSGT_DEMUX
,MSGL_ERR
,"Ogg stream %d is of an unknown type\n",ogg_d
->num_sub
);
1046 demux_stream_t
* ds
= NULL
;
1048 // If the audio stream is not defined we took the first one
1049 if(demuxer
->audio
->id
== -1) {
1050 demuxer
->audio
->id
= n_audio
- 1;
1051 // if(sh_a->wf) print_wave_header(sh_a->wf,MSGL_INFO);
1053 /// Is it the stream we want
1054 if(demuxer
->audio
->id
== n_audio
- 1) {
1055 demuxer
->audio
->sh
= sh_a
;
1056 sh_a
->ds
= demuxer
->audio
;
1057 ds
= demuxer
->audio
;
1058 audio_id
= ogg_d
->num_sub
;
1063 if(demuxer
->video
->id
== -1) {
1064 demuxer
->video
->id
= n_video
- 1;
1065 // if(sh_v->bih) print_video_header(sh_v->bih,MSGL_INFO);
1067 if(demuxer
->video
->id
== n_video
- 1) {
1068 demuxer
->video
->sh
= sh_v
;
1069 sh_v
->ds
= demuxer
->video
;
1070 ds
= demuxer
->video
;
1071 video_id
= ogg_d
->num_sub
;
1074 /// Add the header packets if the stream isn't seekable
1075 if(ds
&& !s
->end_pos
) {
1076 /// Finish the page, otherwise packets will be lost
1078 demux_ogg_add_packet(ds
,&ogg_d
->subs
[ogg_d
->num_sub
],ogg_d
->num_sub
,&pack
);
1079 } while(ogg_stream_packetout(&ogg_d
->subs
[ogg_d
->num_sub
].stream
,&pack
) == 1);
1085 if(!n_video
&& !n_audio
) {
1089 if(!n_video
|| video_id
< 0)
1090 demuxer
->video
->id
= -2;
1092 demuxer
->video
->id
= video_id
;
1093 if(!n_audio
|| audio_id
< 0)
1094 demuxer
->audio
->id
= -2;
1096 demuxer
->audio
->id
= audio_id
;
1097 /* Disable the subs only if there are no text streams at all.
1098 Otherwise the stream to display might be chosen later when the comment
1099 packet is encountered and the user used -slang instead of -sid. */
1101 demuxer
->sub
->id
= -2;
1102 else if (text_id
>= 0) {
1103 demuxer
->sub
->id
= text_id
;
1104 mp_msg(MSGT_DEMUX
, MSGL_V
, "Ogg demuxer: Displaying subtitle stream id %d\n", text_id
);
1107 ogg_d
->final_granulepos
=0;
1109 demuxer
->seekable
= 0;
1111 demuxer
->movi_start
= s
->start_pos
; // Needed for XCD (Ogg written in MODE2)
1112 demuxer
->movi_end
= s
->end_pos
;
1113 demuxer
->seekable
= 1;
1114 demux_ogg_scan_stream(demuxer
);
1117 mp_msg(MSGT_DEMUX
,MSGL_V
,"Ogg demuxer : found %d audio stream%s, %d video stream%s and %d text stream%s\n",n_audio
,n_audio
>1?"s":"",n_video
,n_video
>1?"s":"",ogg_d
->n_text
,ogg_d
->n_text
>1?"s":"");
1119 sh_a
= demuxer
->audio
->sh
;
1121 if(sh_a
->format
== FOURCC_VORBIS
)
1122 fixup_vorbis_wf(sh_a
, ogg_d
);
1124 return DEMUXER_TYPE_OGG
;
1131 static int demux_ogg_fill_buffer(demuxer_t
*d
, demux_stream_t
*dsds
) {
1132 ogg_demuxer_t
* ogg_d
;
1135 ogg_sync_state
* sync
;
1136 ogg_stream_state
* os
;
1143 sync
= &ogg_d
->sync
;
1144 page
= &ogg_d
->page
;
1146 /// Find the stream we are working on
1147 if ( (id
= demux_ogg_get_page_stream(ogg_d
,&os
)) < 0) {
1148 mp_msg(MSGT_DEMUX
,MSGL_ERR
,"Ogg demuxer : can't get current stream\n");
1155 /// Try to get some packet from the current page
1156 while( (np
= ogg_stream_packetout(os
,&pack
)) != 1) {
1157 /// No packet we go the next page
1162 ogg_d
->pos
+= ogg_d
->last_size
;
1163 /// Get the next page from the physical stream
1164 while( (pa
= ogg_sync_pageseek(sync
,page
)) <= 0) {
1165 /// Error : we skip some bytes
1167 mp_msg(MSGT_DEMUX
,MSGL_WARN
,"Ogg : Page out not synced, we skip some bytes\n");
1171 /// We need more data
1172 buf
= ogg_sync_buffer(sync
,BLOCK_SIZE
);
1173 len
= stream_read(s
,buf
,BLOCK_SIZE
);
1174 if(len
== 0 && s
->eof
) {
1175 mp_msg(MSGT_DEMUX
,MSGL_DBG2
,"Ogg : Stream EOF !!!!\n");
1178 ogg_sync_wrote(sync
,len
);
1180 ogg_d
->last_size
= pa
;
1181 /// Find the page's logical stream
1182 if( (id
= demux_ogg_get_page_stream(ogg_d
,&os
)) < 0) {
1183 mp_msg(MSGT_DEMUX
,MSGL_ERR
,"Ogg demuxer error : we met an unknown stream\n");
1187 if(ogg_stream_pagein(os
,page
) == 0)
1189 /// Page was invalid => retry
1190 mp_msg(MSGT_DEMUX
,MSGL_WARN
,"Ogg demuxer : got invalid page !!!!!\n");
1191 ogg_d
->pos
+= ogg_d
->last_size
;
1193 } else /// Packet was corrupted
1194 mp_msg(MSGT_DEMUX
,MSGL_WARN
,"Ogg : bad packet in stream %d\n",id
);
1197 /// Is the actual logical stream in use ?
1198 if(id
== d
->audio
->id
)
1200 else if(id
== d
->video
->id
)
1202 else if (ogg_d
->subs
[id
].text
)
1206 if(!demux_ogg_add_packet(ds
,&ogg_d
->subs
[id
],id
,&pack
))
1207 continue; /// Unuseful packet, get another
1208 d
->filepos
= ogg_d
->pos
;
1216 /// For avi with Ogg audio stream we have to create an ogg demuxer for this
1217 // stream, then we join the avi and ogg demuxer with a demuxers demuxer
1218 demuxer_t
* init_avi_with_ogg(demuxer_t
* demuxer
) {
1219 struct MPOpts
*opts
= demuxer
->opts
;
1221 ogg_demuxer_t
*ogg_d
;
1223 uint32_t hdrsizes
[3];
1225 sh_audio_t
*sh_audio
= demuxer
->audio
->sh
;
1227 uint8_t *extradata
= sh_audio
->wf
+ 1;
1229 unsigned char *p
= NULL
,*buf
;
1232 /// Check that the cbSize is big enough for the following reads
1233 if(sh_audio
->wf
->cbSize
< 22+3*4) {
1234 mp_msg(MSGT_DEMUX
,MSGL_ERR
,"AVI Ogg : Initial audio header is too small !!!!!\n");
1237 /// Get the size of the 3 header packet
1239 for (i
= 0; i
< 3; i
++) {
1240 hdrsizes
[i
] = AV_RL32(extradata
);
1243 // printf("\n!!!!!! hdr sizes: %d %d %d \n",hdrsizes[0],hdrsizes[1],hdrsizes[2]);
1246 if(sh_audio
->wf
->cbSize
< 22+3*4+hdrsizes
[0]+hdrsizes
[1] + hdrsizes
[2]) {
1247 mp_msg(MSGT_DEMUX
,MSGL_ERR
,"AVI Ogg : Audio header is too small !!!!!\n");
1251 // Build the ogg demuxer private datas
1252 ogg_d
= calloc(1,sizeof(ogg_demuxer_t
));
1254 ogg_d
->subs
= malloc(sizeof(ogg_stream_t
));
1255 ogg_d
->subs
[0].vorbis
= 1;
1257 // Init the ogg physical stream
1258 ogg_sync_init(&ogg_d
->sync
);
1260 // Get the first page of the stream : we assume there only 1 logical stream
1261 while((np
= ogg_sync_pageout(&ogg_d
->sync
,&ogg_d
->page
)) <= 0 ) {
1263 mp_msg(MSGT_DEMUX
,MSGL_ERR
,"AVI Ogg error : Can't init using first stream packets\n");
1268 plen
= ds_get_packet(demuxer
->audio
,&p
);
1269 buf
= ogg_sync_buffer(&ogg_d
->sync
,plen
);
1271 ogg_sync_wrote(&ogg_d
->sync
,plen
);
1273 // Init the logical stream
1274 mp_msg(MSGT_DEMUX
,MSGL_DBG2
,"AVI Ogg found page with serial %d\n",ogg_page_serialno(&ogg_d
->page
));
1275 ogg_stream_init(&ogg_d
->subs
[0].stream
,ogg_page_serialno(&ogg_d
->page
));
1277 ogg_stream_pagein(&ogg_d
->subs
[0].stream
,&ogg_d
->page
);
1279 // Create the ds_stream and the ogg demuxer
1280 s
= new_ds_stream(demuxer
->audio
);
1281 od
= new_demuxer(opts
, s
,DEMUXER_TYPE_OGG
,0,-2,-2,NULL
);
1283 /// Add the header packets in the ogg demuxer audio stream
1284 for (i
= 0; i
< 3; i
++) {
1285 dp
= new_demux_packet(hdrsizes
[i
]);
1286 memcpy(dp
->buffer
,extradata
,hdrsizes
[i
]);
1287 ds_add_packet(od
->audio
,dp
);
1288 extradata
+= hdrsizes
[i
];
1291 // Finish setting up the ogg demuxer
1293 sh_audio
= new_sh_audio(od
,0);
1296 od
->audio
->sh
= sh_audio
;
1297 sh_audio
->ds
= od
->audio
;
1298 sh_audio
->format
= FOURCC_VORBIS
;
1299 fixup_vorbis_wf(sh_audio
, ogg_d
);
1301 /// Return the joined demuxers
1302 return new_demuxers_demuxer(demuxer
,od
,demuxer
);
1305 demuxer
->audio
->id
= -2;
1310 static void demux_ogg_seek(demuxer_t
*demuxer
,float rel_seek_secs
,float audio_delay
,int flags
) {
1311 ogg_demuxer_t
* ogg_d
= demuxer
->priv
;
1312 ogg_sync_state
* sync
= &ogg_d
->sync
;
1313 ogg_page
* page
= &ogg_d
->page
;
1314 ogg_stream_state
* oss
;
1319 int i
,sp
,first
,precision
=1,do_seek
=1;
1320 vorbis_info
* vi
= NULL
;
1321 int64_t gp
= 0, old_gp
;
1328 ogg_int64_t granulepos_orig
;
1330 if(demuxer
->video
->id
>= 0) {
1331 ds
= demuxer
->video
;
1332 rate
= ogg_d
->subs
[ds
->id
].samplerate
;
1334 ds
= demuxer
->audio
;
1335 os
= &ogg_d
->subs
[ds
->id
];
1337 rate
= (float)vi
->rate
;
1338 samplesize
= ((sh_audio_t
*)ds
->sh
)->samplesize
;
1341 os
= &ogg_d
->subs
[ds
->id
];
1344 old_gp
= os
->lastpos
;
1345 old_pos
= ogg_d
->pos
;
1347 //calculate the granulepos to seek to
1348 gp
= flags
& SEEK_ABSOLUTE
? 0 : os
->lastpos
;
1349 if(flags
& SEEK_FACTOR
) {
1350 if (ogg_d
->final_granulepos
> 0)
1351 gp
+= ogg_d
->final_granulepos
* rel_seek_secs
;
1353 gp
+= rel_seek_secs
* (demuxer
->movi_end
- demuxer
->movi_start
) * os
->lastpos
/ ogg_d
->pos
;
1355 gp
+= rel_seek_secs
* rate
;
1358 //calculate the filepos to seek to
1359 if(ogg_d
->syncpoints
) {
1360 for(sp
= 0; sp
< ogg_d
->num_syncpoint
; sp
++) {
1361 if(ogg_d
->syncpoints
[sp
].granulepos
>= gp
) break;
1364 if(sp
>= ogg_d
->num_syncpoint
) return;
1365 if (sp
> 0 && ogg_d
->syncpoints
[sp
].granulepos
- gp
> gp
- ogg_d
->syncpoints
[sp
-1].granulepos
)
1367 if (ogg_d
->syncpoints
[sp
].granulepos
== os
->lastpos
) {
1368 if (sp
> 0 && gp
< os
->lastpos
) sp
--;
1369 if (sp
< ogg_d
->num_syncpoint
-1 && gp
> os
->lastpos
) sp
++;
1371 pos
= ogg_d
->syncpoints
[sp
].page_pos
;
1374 pos
= flags
& SEEK_ABSOLUTE
? 0 : ogg_d
->pos
;
1375 if(flags
& SEEK_FACTOR
)
1376 pos
+= (demuxer
->movi_end
- demuxer
->movi_start
) * rel_seek_secs
;
1378 if (ogg_d
->final_granulepos
> 0) {
1379 pos
+= rel_seek_secs
* (demuxer
->movi_end
- demuxer
->movi_start
) / (ogg_d
->final_granulepos
/ rate
);
1380 } else if (os
->lastpos
> 0) {
1381 pos
+= rel_seek_secs
* ogg_d
->pos
/ (os
->lastpos
/ rate
);
1384 if (pos
< 0) pos
= 0;
1385 if (pos
> (demuxer
->movi_end
- demuxer
->movi_start
))
1386 pos
= demuxer
->movi_end
- demuxer
->movi_start
;
1387 } // if(ogg_d->syncpoints)
1391 stream_seek(demuxer
->stream
,pos
+demuxer
->movi_start
);
1392 ogg_sync_reset(sync
);
1393 for(i
= 0 ; i
< ogg_d
->num_sub
; i
++) {
1394 ogg_stream_reset(&ogg_d
->subs
[i
].stream
);
1395 ogg_d
->subs
[i
].lastpos
= ogg_d
->subs
[i
].lastsize
= 0;
1398 ogg_d
->last_size
= 0;
1399 /* we just guess that we reached correct granulepos, in case a
1400 subsequent search occurs before we read a valid granulepos */
1402 first
= !(ogg_d
->syncpoints
);
1405 ogg_d
->pos
+= ogg_d
->last_size
;
1406 ogg_d
->last_size
= 0;
1407 np
= ogg_sync_pageseek(sync
,page
);
1411 if(np
<= 0) { // We need more data
1412 char* buf
= ogg_sync_buffer(sync
,BLOCK_SIZE
);
1413 int len
= stream_read(demuxer
->stream
,buf
,BLOCK_SIZE
);
1414 if(len
== 0 && demuxer
->stream
->eof
) {
1415 mp_msg(MSGT_DEMUX
,MSGL_V
,"EOF while trying to seek !!!!\n");
1418 ogg_sync_wrote(sync
,len
);
1421 ogg_d
->last_size
= np
;
1422 if(ogg_page_serialno(page
) != oss
->serialno
)
1425 if(ogg_stream_pagein(oss
,page
) != 0)
1429 np
= ogg_stream_packetout(oss
,&op
);
1434 if (first
) { /* Discard the first packet as it's probably broken,
1435 and we don't have any other means to decide whether it is
1440 is_gp_valid
= (op
.granulepos
>= 0);
1441 granulepos_orig
=op
.granulepos
;
1442 demux_ogg_read_packet(os
,&op
,&pts
,&is_keyframe
,samplesize
);
1443 if (precision
&& is_gp_valid
) {
1445 if (abs(gp
- op
.granulepos
) > rate
&& (op
.granulepos
!= old_gp
)) {
1446 //prepare another seek because we are off by more than 1s
1447 pos
+= (gp
- op
.granulepos
) * (pos
- old_pos
) / (op
.granulepos
- old_gp
);
1448 if (pos
< 0) pos
= 0;
1449 if (pos
< demuxer
->movi_end
- demuxer
->movi_start
) {
1455 if (is_gp_valid
&& pos
> 0 && old_gp
> gp
1456 && 2 * (old_gp
- op
.granulepos
) < old_gp
- gp
) {
1457 /* prepare another seek because looking for a syncpoint
1458 destroyed the backward search */
1459 pos
= old_pos
- 1.5 * (old_pos
- pos
);
1460 if (pos
< 0) pos
= 0;
1461 if (pos
< demuxer
->movi_end
- demuxer
->movi_start
) {
1466 if(!precision
&& (is_keyframe
|| os
->vorbis
|| os
->speex
) ) {
1467 if (sub_clear_text(&ogg_sub
, MP_NOPTS_VALUE
)) {
1469 vo_osd_changed(OSDTYPE_SUBTITLE
);
1471 op
.granulepos
=granulepos_orig
;
1472 demux_ogg_add_packet(ds
,os
,ds
->id
,&op
);
1478 mp_msg(MSGT_DEMUX
,MSGL_ERR
,"Can't find the good packet :(\n");
1482 static void demux_close_ogg(demuxer_t
* demuxer
) {
1483 ogg_demuxer_t
* ogg_d
= demuxer
->priv
;
1484 ogg_stream_t
* os
= NULL
;
1494 ogg_sync_clear(&ogg_d
->sync
);
1497 for (i
= 0; i
< ogg_d
->num_sub
; i
++)
1499 os
= &ogg_d
->subs
[i
];
1500 ogg_stream_clear(&os
->stream
);
1501 if(os
->vi_initialized
)
1502 vorbis_info_clear(&os
->vi
);
1506 if(ogg_d
->syncpoints
)
1507 free(ogg_d
->syncpoints
);
1508 if (ogg_d
->text_ids
)
1509 free(ogg_d
->text_ids
);
1510 if (ogg_d
->text_langs
) {
1511 for (i
= 0; i
< ogg_d
->n_text
; i
++)
1512 if (ogg_d
->text_langs
[i
]) free(ogg_d
->text_langs
[i
]);
1513 free(ogg_d
->text_langs
);
1518 static int demux_ogg_control(demuxer_t
*demuxer
,int cmd
, void *arg
){
1519 ogg_demuxer_t
* ogg_d
= demuxer
->priv
;
1523 if(demuxer
->video
->id
>= 0) {
1524 os
= &ogg_d
->subs
[demuxer
->video
->id
];
1525 rate
= os
->samplerate
;
1527 os
= &ogg_d
->subs
[demuxer
->audio
->id
];
1533 case DEMUXER_CTRL_GET_TIME_LENGTH
:
1534 if (ogg_d
->final_granulepos
<=0) return DEMUXER_CTRL_DONTKNOW
;
1535 *(double *)arg
=(double)ogg_d
->final_granulepos
/ rate
;
1536 return DEMUXER_CTRL_GUESS
;
1538 case DEMUXER_CTRL_GET_PERCENT_POS
:
1539 if (ogg_d
->final_granulepos
<=0) return DEMUXER_CTRL_DONTKNOW
;
1540 *(int *)arg
=(os
->lastpos
*100) / ogg_d
->final_granulepos
;
1541 return DEMUXER_CTRL_OK
;
1544 return DEMUXER_CTRL_NOTIMPL
;
1550 const demuxer_desc_t demuxer_desc_ogg
= {
1557 1, // safe autodetect
1559 demux_ogg_fill_buffer
,