+ /* Check for Annodex header */
+ else if( oggpacket.bytes >= 7 &&
+ ! memcmp( oggpacket.packet, "AnxData", 7 ) )
+ {
+ Ogg_ReadAnnodexHeader( VLC_OBJECT(p_demux), p_stream,
+ &oggpacket );
+ }
+ /* Check for Kate header */
+ else if( oggpacket.bytes >= 8 &&
+ ! memcmp( &oggpacket.packet[1], "kate\0\0\0", 7 ) )
+ {
+ Ogg_ReadKateHeader( p_stream, &oggpacket );
+ msg_Dbg( p_demux, "found kate header" );
+ }
+ else if( oggpacket.bytes >= 142 &&
+ !memcmp( &oggpacket.packet[1],
+ "Direct Show Samples embedded in Ogg", 35 ))
+ {
+ /* Old header type */
+
+ /* Check for video header (old format) */
+ if( GetDWLE((oggpacket.packet+96)) == 0x05589f80 &&
+ oggpacket.bytes >= 184 )
+ {
+ p_stream->fmt.i_cat = VIDEO_ES;
+ p_stream->fmt.i_codec =
+ VLC_FOURCC( oggpacket.packet[68],
+ oggpacket.packet[69],
+ oggpacket.packet[70],
+ oggpacket.packet[71] );
+ msg_Dbg( p_demux, "found video header of type: %.4s",
+ (char *)&p_stream->fmt.i_codec );
+
+ p_stream->fmt.video.i_frame_rate = 10000000;
+ p_stream->fmt.video.i_frame_rate_base =
+ GetQWLE((oggpacket.packet+164));
+ p_stream->f_rate = 10000000.0 /
+ GetQWLE((oggpacket.packet+164));
+ p_stream->fmt.video.i_bits_per_pixel =
+ GetWLE((oggpacket.packet+182));
+ if( !p_stream->fmt.video.i_bits_per_pixel )
+ /* hack, FIXME */
+ p_stream->fmt.video.i_bits_per_pixel = 24;
+ p_stream->fmt.video.i_width =
+ GetDWLE((oggpacket.packet+176));
+ p_stream->fmt.video.i_height =
+ GetDWLE((oggpacket.packet+180));
+
+ msg_Dbg( p_demux,
+ "fps: %f, width:%i; height:%i, bitcount:%i",
+ p_stream->f_rate,
+ p_stream->fmt.video.i_width,
+ p_stream->fmt.video.i_height,
+ p_stream->fmt.video.i_bits_per_pixel);
+
+ }
+ /* Check for audio header (old format) */
+ else if( GetDWLE((oggpacket.packet+96)) == 0x05589F81 )
+ {
+ int i_extra_size;
+ unsigned int i_format_tag;
+
+ p_stream->fmt.i_cat = AUDIO_ES;
+
+ i_extra_size = GetWLE((oggpacket.packet+140));
+ if( i_extra_size > 0 && i_extra_size < oggpacket.bytes - 142 )
+ {
+ p_stream->fmt.i_extra = i_extra_size;
+ p_stream->fmt.p_extra = malloc( i_extra_size );
+ if( p_stream->fmt.p_extra )
+ memcpy( p_stream->fmt.p_extra,
+ oggpacket.packet + 142, i_extra_size );
+ else
+ p_stream->fmt.i_extra = 0;
+ }
+
+ i_format_tag = GetWLE((oggpacket.packet+124));
+ p_stream->fmt.audio.i_channels =
+ GetWLE((oggpacket.packet+126));
+ p_stream->f_rate = p_stream->fmt.audio.i_rate =
+ GetDWLE((oggpacket.packet+128));
+ p_stream->fmt.i_bitrate =
+ GetDWLE((oggpacket.packet+132)) * 8;
+ p_stream->fmt.audio.i_blockalign =
+ GetWLE((oggpacket.packet+136));
+ p_stream->fmt.audio.i_bitspersample =
+ GetWLE((oggpacket.packet+138));
+
+ wf_tag_to_fourcc( i_format_tag,
+ &p_stream->fmt.i_codec, 0 );
+
+ if( p_stream->fmt.i_codec ==
+ VLC_FOURCC('u','n','d','f') )
+ {
+ p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',
+ ( i_format_tag >> 8 ) & 0xff,
+ i_format_tag & 0xff );
+ }
+
+ msg_Dbg( p_demux, "found audio header of type: %.4s",
+ (char *)&p_stream->fmt.i_codec );
+ msg_Dbg( p_demux, "audio:0x%4.4x channels:%d %dHz "
+ "%dbits/sample %dkb/s",
+ i_format_tag,
+ p_stream->fmt.audio.i_channels,
+ p_stream->fmt.audio.i_rate,
+ p_stream->fmt.audio.i_bitspersample,
+ p_stream->fmt.i_bitrate / 1024 );
+
+ }
+ else
+ {
+ msg_Dbg( p_demux, "stream %d has an old header "
+ "but is of an unknown type", p_ogg->i_streams-1 );
+ free( p_stream );
+ p_ogg->i_streams--;
+ }
+ }
+ else if( (*oggpacket.packet & PACKET_TYPE_BITS ) == PACKET_TYPE_HEADER &&
+ oggpacket.bytes >= 56+1 )
+ {
+ stream_header_t tmp;
+ stream_header_t *st = &tmp;
+
+ memcpy( st->streamtype, &oggpacket.packet[1+0], 8 );
+ memcpy( st->subtype, &oggpacket.packet[1+8], 4 );
+ st->size = GetDWLE( &oggpacket.packet[1+12] );
+ st->time_unit = GetQWLE( &oggpacket.packet[1+16] );
+ st->samples_per_unit = GetQWLE( &oggpacket.packet[1+24] );
+ st->default_len = GetDWLE( &oggpacket.packet[1+32] );
+ st->buffersize = GetDWLE( &oggpacket.packet[1+36] );
+ st->bits_per_sample = GetWLE( &oggpacket.packet[1+40] ); // (padding 2)
+
+ /* Check for video header (new format) */
+ if( !strncmp( st->streamtype, "video", 5 ) )
+ {
+ st->sh.video.width = GetDWLE( &oggpacket.packet[1+44] );
+ st->sh.video.height = GetDWLE( &oggpacket.packet[1+48] );
+
+ p_stream->fmt.i_cat = VIDEO_ES;
+
+ /* We need to get rid of the header packet */
+ ogg_stream_packetout( &p_stream->os, &oggpacket );
+
+ p_stream->fmt.i_codec =
+ VLC_FOURCC( st->subtype[0], st->subtype[1],
+ st->subtype[2], st->subtype[3] );
+ msg_Dbg( p_demux, "found video header of type: %.4s",
+ (char *)&p_stream->fmt.i_codec );
+
+ p_stream->fmt.video.i_frame_rate = 10000000;
+ p_stream->fmt.video.i_frame_rate_base = st->time_unit;
+ if( st->time_unit <= 0 )
+ st->time_unit = 400000;
+ p_stream->f_rate = 10000000.0 / st->time_unit;
+ p_stream->fmt.video.i_bits_per_pixel = st->bits_per_sample;
+ p_stream->fmt.video.i_width = st->sh.video.width;
+ p_stream->fmt.video.i_height = st->sh.video.height;
+
+ msg_Dbg( p_demux,
+ "fps: %f, width:%i; height:%i, bitcount:%i",
+ p_stream->f_rate,
+ p_stream->fmt.video.i_width,
+ p_stream->fmt.video.i_height,
+ p_stream->fmt.video.i_bits_per_pixel );
+ }
+ /* Check for audio header (new format) */
+ else if( !strncmp( st->streamtype, "audio", 5 ) )
+ {
+ char p_buffer[5];
+ int i_extra_size;
+ int i_format_tag;
+
+ st->sh.audio.channels = GetWLE( &oggpacket.packet[1+44] );
+ st->sh.audio.blockalign = GetWLE( &oggpacket.packet[1+48] );
+ st->sh.audio.avgbytespersec = GetDWLE( &oggpacket.packet[1+52] );
+
+ p_stream->fmt.i_cat = AUDIO_ES;
+
+ /* We need to get rid of the header packet */
+ ogg_stream_packetout( &p_stream->os, &oggpacket );
+
+ i_extra_size = st->size - 56;
+
+ if( i_extra_size > 0 &&
+ i_extra_size < oggpacket.bytes - 1 - 56 )
+ {
+ p_stream->fmt.i_extra = i_extra_size;
+ p_stream->fmt.p_extra = malloc( p_stream->fmt.i_extra );
+ if( p_stream->fmt.p_extra )
+ memcpy( p_stream->fmt.p_extra, st + 1,
+ p_stream->fmt.i_extra );
+ else
+ p_stream->fmt.i_extra = 0;
+ }
+
+ memcpy( p_buffer, st->subtype, 4 );
+ p_buffer[4] = '\0';
+ i_format_tag = strtol(p_buffer,NULL,16);
+ p_stream->fmt.audio.i_channels = st->sh.audio.channels;
+ if( st->time_unit <= 0 )
+ st->time_unit = 10000000;
+ p_stream->f_rate = p_stream->fmt.audio.i_rate = st->samples_per_unit * 10000000 / st->time_unit;
+ p_stream->fmt.i_bitrate = st->sh.audio.avgbytespersec * 8;
+ p_stream->fmt.audio.i_blockalign = st->sh.audio.blockalign;
+ p_stream->fmt.audio.i_bitspersample = st->bits_per_sample;
+
+ wf_tag_to_fourcc( i_format_tag,
+ &p_stream->fmt.i_codec, 0 );
+
+ if( p_stream->fmt.i_codec ==
+ VLC_FOURCC('u','n','d','f') )
+ {
+ p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',
+ ( i_format_tag >> 8 ) & 0xff,
+ i_format_tag & 0xff );
+ }
+
+ msg_Dbg( p_demux, "found audio header of type: %.4s",
+ (char *)&p_stream->fmt.i_codec );
+ msg_Dbg( p_demux, "audio:0x%4.4x channels:%d %dHz "
+ "%dbits/sample %dkb/s",
+ i_format_tag,
+ p_stream->fmt.audio.i_channels,
+ p_stream->fmt.audio.i_rate,
+ p_stream->fmt.audio.i_bitspersample,
+ p_stream->fmt.i_bitrate / 1024 );
+ }
+ /* Check for text (subtitles) header */
+ else if( !strncmp(st->streamtype, "text", 4) )
+ {
+ /* We need to get rid of the header packet */
+ ogg_stream_packetout( &p_stream->os, &oggpacket );
+
+ msg_Dbg( p_demux, "found text subtitles header" );
+ p_stream->fmt.i_cat = SPU_ES;
+ p_stream->fmt.i_codec = VLC_CODEC_SUBT;
+ p_stream->f_rate = 1000; /* granulepos is in millisec */
+ }
+ else
+ {
+ msg_Dbg( p_demux, "stream %d has a header marker "
+ "but is of an unknown type", p_ogg->i_streams-1 );
+ free( p_stream );
+ p_ogg->i_streams--;
+ }
+ }
+ else if( oggpacket.bytes >= 7 &&
+ ! memcmp( oggpacket.packet, "fishead", 7 ) )