13 #include "stream/stream.h"
16 #include "libavutil/intreadwrite.h"
18 #define FOURCC_VORBIS mmioFOURCC('v', 'r', 'b', 's')
19 #define FOURCC_SPEEX mmioFOURCC('s', 'p', 'x', ' ')
20 #define FOURCC_THEORA mmioFOURCC('t', 'h', 'e', 'o')
23 #include <tremor/ogg.h>
24 #include <tremor/ivorbiscodec.h>
27 #include <vorbis/codec.h>
30 #ifdef CONFIG_OGGTHEORA
31 #include <theora/theora.h>
32 int _ilog (unsigned int); /* defined in many places in theora/lib/ */
35 #define BLOCK_SIZE 4096
37 /* Theora decoder context : we won't be able to interpret granule positions
38 * without using theora_granule_time with the theora_state of the stream.
39 * This is duplicated in `vd_theora.c'; put this in a common header?
41 #ifdef CONFIG_OGGTHEORA
42 typedef struct theora_struct_st
{
50 // Header for the new header format
51 typedef struct stream_header_video
55 } stream_header_video
;
57 typedef struct stream_header_audio
60 ogg_int16_t blockalign
;
61 ogg_int32_t avgbytespersec
;
62 } stream_header_audio
;
64 typedef struct __attribute__((__packed__
)) stream_header
69 ogg_int32_t size
; // size of the structure
71 ogg_int64_t time_unit
; // in reference time
72 ogg_int64_t samples_per_unit
;
73 ogg_int32_t default_len
; // in media time
75 ogg_int32_t buffersize
;
76 ogg_int16_t bits_per_sample
;
83 stream_header_video video
;
85 stream_header_audio audio
;
91 typedef struct ogg_syncpoint
{
97 typedef struct ogg_stream
{
98 /// Timestamping stuff
99 float samplerate
; /// granulpos 2 time
102 int keyframe_frequency_force
;
104 // Logical stream state
105 ogg_stream_state stream
;
120 typedef struct ogg_demuxer
{
121 /// Physical stream state
128 ogg_syncpoint_t
* syncpoints
;
130 off_t pos
, last_size
;
131 int64_t final_granulepos
;
133 /* Used for subtitle switching. */
139 #define NUM_VORBIS_HDR_PACKETS 3
141 /// Some defines from OggDS
142 #define PACKET_TYPE_HEADER 0x01
143 #define PACKET_TYPE_BITS 0x07
144 #define PACKET_LEN_BITS01 0xc0
145 #define PACKET_LEN_BITS2 0x02
146 #define PACKET_IS_SYNCPOINT 0x08
148 extern char *dvdsub_lang
, *audio_lang
;
149 extern int dvdsub_id
;
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 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
))
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 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
) {
1220 ogg_demuxer_t
*ogg_d
;
1222 uint32_t hdrsizes
[3];
1224 sh_audio_t
*sh_audio
= demuxer
->audio
->sh
;
1226 uint8_t *extradata
= sh_audio
->wf
+ 1;
1228 unsigned char *p
= NULL
,*buf
;
1231 /// Check that the cbSize is big enough for the following reads
1232 if(sh_audio
->wf
->cbSize
< 22+3*4) {
1233 mp_msg(MSGT_DEMUX
,MSGL_ERR
,"AVI Ogg : Initial audio header is too small !!!!!\n");
1236 /// Get the size of the 3 header packet
1238 for (i
= 0; i
< 3; i
++) {
1239 hdrsizes
[i
] = AV_RL32(extradata
);
1242 // printf("\n!!!!!! hdr sizes: %d %d %d \n",hdrsizes[0],hdrsizes[1],hdrsizes[2]);
1245 if(sh_audio
->wf
->cbSize
< 22+3*4+hdrsizes
[0]+hdrsizes
[1] + hdrsizes
[2]) {
1246 mp_msg(MSGT_DEMUX
,MSGL_ERR
,"AVI Ogg : Audio header is too small !!!!!\n");
1250 // Build the ogg demuxer private datas
1251 ogg_d
= calloc(1,sizeof(ogg_demuxer_t
));
1253 ogg_d
->subs
= malloc(sizeof(ogg_stream_t
));
1254 ogg_d
->subs
[0].vorbis
= 1;
1256 // Init the ogg physical stream
1257 ogg_sync_init(&ogg_d
->sync
);
1259 // Get the first page of the stream : we assume there only 1 logical stream
1260 while((np
= ogg_sync_pageout(&ogg_d
->sync
,&ogg_d
->page
)) <= 0 ) {
1262 mp_msg(MSGT_DEMUX
,MSGL_ERR
,"AVI Ogg error : Can't init using first stream packets\n");
1267 plen
= ds_get_packet(demuxer
->audio
,&p
);
1268 buf
= ogg_sync_buffer(&ogg_d
->sync
,plen
);
1270 ogg_sync_wrote(&ogg_d
->sync
,plen
);
1272 // Init the logical stream
1273 mp_msg(MSGT_DEMUX
,MSGL_DBG2
,"AVI Ogg found page with serial %d\n",ogg_page_serialno(&ogg_d
->page
));
1274 ogg_stream_init(&ogg_d
->subs
[0].stream
,ogg_page_serialno(&ogg_d
->page
));
1276 ogg_stream_pagein(&ogg_d
->subs
[0].stream
,&ogg_d
->page
);
1278 // Create the ds_stream and the ogg demuxer
1279 s
= new_ds_stream(demuxer
->audio
);
1280 od
= new_demuxer(s
,DEMUXER_TYPE_OGG
,0,-2,-2,NULL
);
1282 /// Add the header packets in the ogg demuxer audio stream
1283 for (i
= 0; i
< 3; i
++) {
1284 dp
= new_demux_packet(hdrsizes
[i
]);
1285 memcpy(dp
->buffer
,extradata
,hdrsizes
[i
]);
1286 ds_add_packet(od
->audio
,dp
);
1287 extradata
+= hdrsizes
[i
];
1290 // Finish setting up the ogg demuxer
1292 sh_audio
= new_sh_audio(od
,0);
1295 od
->audio
->sh
= sh_audio
;
1296 sh_audio
->ds
= od
->audio
;
1297 sh_audio
->format
= FOURCC_VORBIS
;
1298 fixup_vorbis_wf(sh_audio
, ogg_d
);
1300 /// Return the joined demuxers
1301 return new_demuxers_demuxer(demuxer
,od
,demuxer
);
1304 demuxer
->audio
->id
= -2;
1309 static void demux_ogg_seek(demuxer_t
*demuxer
,float rel_seek_secs
,float audio_delay
,int flags
) {
1310 ogg_demuxer_t
* ogg_d
= demuxer
->priv
;
1311 ogg_sync_state
* sync
= &ogg_d
->sync
;
1312 ogg_page
* page
= &ogg_d
->page
;
1313 ogg_stream_state
* oss
;
1318 int i
,sp
,first
,precision
=1,do_seek
=1;
1319 vorbis_info
* vi
= NULL
;
1320 int64_t gp
= 0, old_gp
;
1327 ogg_int64_t granulepos_orig
;
1329 if(demuxer
->video
->id
>= 0) {
1330 ds
= demuxer
->video
;
1331 rate
= ogg_d
->subs
[ds
->id
].samplerate
;
1333 ds
= demuxer
->audio
;
1334 os
= &ogg_d
->subs
[ds
->id
];
1336 rate
= (float)vi
->rate
;
1337 samplesize
= ((sh_audio_t
*)ds
->sh
)->samplesize
;
1340 os
= &ogg_d
->subs
[ds
->id
];
1343 old_gp
= os
->lastpos
;
1344 old_pos
= ogg_d
->pos
;
1346 //calculate the granulepos to seek to
1347 gp
= flags
& SEEK_ABSOLUTE
? 0 : os
->lastpos
;
1348 if(flags
& SEEK_FACTOR
) {
1349 if (ogg_d
->final_granulepos
> 0)
1350 gp
+= ogg_d
->final_granulepos
* rel_seek_secs
;
1352 gp
+= rel_seek_secs
* (demuxer
->movi_end
- demuxer
->movi_start
) * os
->lastpos
/ ogg_d
->pos
;
1354 gp
+= rel_seek_secs
* rate
;
1357 //calculate the filepos to seek to
1358 if(ogg_d
->syncpoints
) {
1359 for(sp
= 0; sp
< ogg_d
->num_syncpoint
; sp
++) {
1360 if(ogg_d
->syncpoints
[sp
].granulepos
>= gp
) break;
1363 if(sp
>= ogg_d
->num_syncpoint
) return;
1364 if (sp
> 0 && ogg_d
->syncpoints
[sp
].granulepos
- gp
> gp
- ogg_d
->syncpoints
[sp
-1].granulepos
)
1366 if (ogg_d
->syncpoints
[sp
].granulepos
== os
->lastpos
) {
1367 if (sp
> 0 && gp
< os
->lastpos
) sp
--;
1368 if (sp
< ogg_d
->num_syncpoint
-1 && gp
> os
->lastpos
) sp
++;
1370 pos
= ogg_d
->syncpoints
[sp
].page_pos
;
1373 pos
= flags
& SEEK_ABSOLUTE
? 0 : ogg_d
->pos
;
1374 if(flags
& SEEK_FACTOR
)
1375 pos
+= (demuxer
->movi_end
- demuxer
->movi_start
) * rel_seek_secs
;
1377 if (ogg_d
->final_granulepos
> 0) {
1378 pos
+= rel_seek_secs
* (demuxer
->movi_end
- demuxer
->movi_start
) / (ogg_d
->final_granulepos
/ rate
);
1379 } else if (os
->lastpos
> 0) {
1380 pos
+= rel_seek_secs
* ogg_d
->pos
/ (os
->lastpos
/ rate
);
1383 if (pos
< 0) pos
= 0;
1384 if (pos
> (demuxer
->movi_end
- demuxer
->movi_start
))
1385 pos
= demuxer
->movi_end
- demuxer
->movi_start
;
1386 } // if(ogg_d->syncpoints)
1390 stream_seek(demuxer
->stream
,pos
+demuxer
->movi_start
);
1391 ogg_sync_reset(sync
);
1392 for(i
= 0 ; i
< ogg_d
->num_sub
; i
++) {
1393 ogg_stream_reset(&ogg_d
->subs
[i
].stream
);
1394 ogg_d
->subs
[i
].lastpos
= ogg_d
->subs
[i
].lastsize
= 0;
1397 ogg_d
->last_size
= 0;
1398 /* we just guess that we reached correct granulepos, in case a
1399 subsequent search occurs before we read a valid granulepos */
1401 first
= !(ogg_d
->syncpoints
);
1404 ogg_d
->pos
+= ogg_d
->last_size
;
1405 ogg_d
->last_size
= 0;
1406 np
= ogg_sync_pageseek(sync
,page
);
1410 if(np
<= 0) { // We need more data
1411 char* buf
= ogg_sync_buffer(sync
,BLOCK_SIZE
);
1412 int len
= stream_read(demuxer
->stream
,buf
,BLOCK_SIZE
);
1413 if(len
== 0 && demuxer
->stream
->eof
) {
1414 mp_msg(MSGT_DEMUX
,MSGL_V
,"EOF while trying to seek !!!!\n");
1417 ogg_sync_wrote(sync
,len
);
1420 ogg_d
->last_size
= np
;
1421 if(ogg_page_serialno(page
) != oss
->serialno
)
1424 if(ogg_stream_pagein(oss
,page
) != 0)
1428 np
= ogg_stream_packetout(oss
,&op
);
1433 if (first
) { /* Discard the first packet as it's probably broken,
1434 and we don't have any other means to decide whether it is
1439 is_gp_valid
= (op
.granulepos
>= 0);
1440 granulepos_orig
=op
.granulepos
;
1441 demux_ogg_read_packet(os
,&op
,&pts
,&is_keyframe
,samplesize
);
1442 if (precision
&& is_gp_valid
) {
1444 if (abs(gp
- op
.granulepos
) > rate
&& (op
.granulepos
!= old_gp
)) {
1445 //prepare another seek because we are off by more than 1s
1446 pos
+= (gp
- op
.granulepos
) * (pos
- old_pos
) / (op
.granulepos
- old_gp
);
1447 if (pos
< 0) pos
= 0;
1448 if (pos
< demuxer
->movi_end
- demuxer
->movi_start
) {
1454 if (is_gp_valid
&& pos
> 0 && old_gp
> gp
1455 && 2 * (old_gp
- op
.granulepos
) < old_gp
- gp
) {
1456 /* prepare another seek because looking for a syncpoint
1457 destroyed the backward search */
1458 pos
= old_pos
- 1.5 * (old_pos
- pos
);
1459 if (pos
< 0) pos
= 0;
1460 if (pos
< demuxer
->movi_end
- demuxer
->movi_start
) {
1465 if(!precision
&& (is_keyframe
|| os
->vorbis
|| os
->speex
) ) {
1466 if (sub_clear_text(&ogg_sub
, MP_NOPTS_VALUE
)) {
1468 vo_osd_changed(OSDTYPE_SUBTITLE
);
1470 op
.granulepos
=granulepos_orig
;
1471 demux_ogg_add_packet(ds
,os
,ds
->id
,&op
);
1477 mp_msg(MSGT_DEMUX
,MSGL_ERR
,"Can't find the good packet :(\n");
1481 static void demux_close_ogg(demuxer_t
* demuxer
) {
1482 ogg_demuxer_t
* ogg_d
= demuxer
->priv
;
1483 ogg_stream_t
* os
= NULL
;
1493 ogg_sync_clear(&ogg_d
->sync
);
1496 for (i
= 0; i
< ogg_d
->num_sub
; i
++)
1498 os
= &ogg_d
->subs
[i
];
1499 ogg_stream_clear(&os
->stream
);
1500 if(os
->vi_initialized
)
1501 vorbis_info_clear(&os
->vi
);
1505 if(ogg_d
->syncpoints
)
1506 free(ogg_d
->syncpoints
);
1507 if (ogg_d
->text_ids
)
1508 free(ogg_d
->text_ids
);
1509 if (ogg_d
->text_langs
) {
1510 for (i
= 0; i
< ogg_d
->n_text
; i
++)
1511 if (ogg_d
->text_langs
[i
]) free(ogg_d
->text_langs
[i
]);
1512 free(ogg_d
->text_langs
);
1517 static int demux_ogg_control(demuxer_t
*demuxer
,int cmd
, void *arg
){
1518 ogg_demuxer_t
* ogg_d
= demuxer
->priv
;
1522 if(demuxer
->video
->id
>= 0) {
1523 os
= &ogg_d
->subs
[demuxer
->video
->id
];
1524 rate
= os
->samplerate
;
1526 os
= &ogg_d
->subs
[demuxer
->audio
->id
];
1532 case DEMUXER_CTRL_GET_TIME_LENGTH
:
1533 if (ogg_d
->final_granulepos
<=0) return DEMUXER_CTRL_DONTKNOW
;
1534 *(double *)arg
=(double)ogg_d
->final_granulepos
/ rate
;
1535 return DEMUXER_CTRL_GUESS
;
1537 case DEMUXER_CTRL_GET_PERCENT_POS
:
1538 if (ogg_d
->final_granulepos
<=0) return DEMUXER_CTRL_DONTKNOW
;
1539 *(int *)arg
=(os
->lastpos
*100) / ogg_d
->final_granulepos
;
1540 return DEMUXER_CTRL_OK
;
1543 return DEMUXER_CTRL_NOTIMPL
;
1549 const demuxer_desc_t demuxer_desc_ogg
= {
1556 1, // safe autodetect
1558 demux_ogg_fill_buffer
,