00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <vlc/vlc.h>
00029 #include <vlc/input.h>
00030
00031 #include <ogg/ogg.h>
00032
00033 #include "codecs.h"
00034 #include "vlc_bits.h"
00035
00036
00037
00038
00039 static int Open ( vlc_object_t * );
00040 static void Close( vlc_object_t * );
00041
00042 vlc_module_begin();
00043 set_description( _("Ogg stream demuxer" ) );
00044 set_category( CAT_INPUT );
00045 set_subcategory( SUBCAT_INPUT_DEMUX );
00046 set_capability( "demux2", 50 );
00047 set_callbacks( Open, Close );
00048 add_shortcut( "ogg" );
00049 vlc_module_end();
00050
00051
00052
00053
00054
00055 typedef struct logical_stream_s
00056 {
00057 ogg_stream_state os;
00058
00059 es_format_t fmt;
00060 es_out_id_t *p_es;
00061 double f_rate;
00062
00063 int i_serial_no;
00064
00065
00066
00067
00068 int b_force_backup;
00069 int i_packets_backup;
00070 uint8_t *p_headers;
00071 int i_headers;
00072
00073
00074
00075 mtime_t i_pcr;
00076 mtime_t i_interpolated_pcr;
00077 mtime_t i_previous_pcr;
00078
00079
00080 int b_reinit;
00081 int i_theora_keyframe_granule_shift;
00082
00083
00084 int secondary_header_packets;
00085
00086 } logical_stream_t;
00087
00088 struct demux_sys_t
00089 {
00090 ogg_sync_state oy;
00091
00092 int i_streams;
00093 logical_stream_t **pp_stream;
00094
00095
00096
00097 mtime_t i_pcr;
00098
00099
00100 int i_eos;
00101
00102
00103 int i_bitrate;
00104 };
00105
00106
00107 typedef struct stream_header_video
00108 {
00109 ogg_int32_t width;
00110 ogg_int32_t height;
00111 } stream_header_video;
00112
00113 typedef struct stream_header_audio
00114 {
00115 ogg_int16_t channels;
00116 ogg_int16_t blockalign;
00117 ogg_int32_t avgbytespersec;
00118 } stream_header_audio;
00119
00120 typedef struct stream_header
00121 {
00122 char streamtype[8];
00123 char subtype[4];
00124
00125 ogg_int32_t size;
00126
00127 ogg_int64_t time_unit;
00128 ogg_int64_t samples_per_unit;
00129 ogg_int32_t default_len;
00130
00131 ogg_int32_t buffersize;
00132 ogg_int16_t bits_per_sample;
00133
00134 union
00135 {
00136
00137 stream_header_video video;
00138
00139 stream_header_audio audio;
00140 } sh;
00141 } stream_header;
00142
00143 #define OGG_BLOCK_SIZE 4096
00144
00145
00146 #define PACKET_TYPE_HEADER 0x01
00147 #define PACKET_TYPE_BITS 0x07
00148 #define PACKET_LEN_BITS01 0xc0
00149 #define PACKET_LEN_BITS2 0x02
00150 #define PACKET_IS_SYNCPOINT 0x08
00151
00152
00153
00154
00155 static int Demux ( demux_t * );
00156 static int Control( demux_t *, int, va_list );
00157
00158
00159 static int Ogg_ReadPage ( demux_t *, ogg_page * );
00160 static void Ogg_UpdatePCR ( logical_stream_t *, ogg_packet * );
00161 static void Ogg_DecodePacket ( demux_t *, logical_stream_t *, ogg_packet * );
00162
00163 static int Ogg_BeginningOfStream( demux_t *p_demux );
00164 static int Ogg_FindLogicalStreams( demux_t *p_demux );
00165 static void Ogg_EndOfStream( demux_t *p_demux );
00166
00167
00168 static void Ogg_ReadTheoraHeader( logical_stream_t *, ogg_packet * );
00169 static void Ogg_ReadVorbisHeader( logical_stream_t *, ogg_packet * );
00170 static void Ogg_ReadSpeexHeader( logical_stream_t *, ogg_packet * );
00171 static void Ogg_ReadFlacHeader( demux_t *, logical_stream_t *, ogg_packet * );
00172 static void Ogg_ReadAnnodexHeader( vlc_object_t *, logical_stream_t *, ogg_packet * );
00173
00174
00175
00176
00177 static int Open( vlc_object_t * p_this )
00178 {
00179 demux_t *p_demux = (demux_t *)p_this;
00180 demux_sys_t *p_sys;
00181 uint8_t *p_peek;
00182
00183
00184
00185 if( stream_Peek( p_demux->s, &p_peek, 4 ) < 4 ) return VLC_EGENERIC;
00186 if( strcmp( p_demux->psz_demux, "ogg" ) && memcmp( p_peek, "OggS", 4 ) )
00187 {
00188 return VLC_EGENERIC;
00189 }
00190
00191
00192 p_demux->pf_demux = Demux;
00193 p_demux->pf_control = Control;
00194 p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) );
00195
00196 memset( p_sys, 0, sizeof( demux_sys_t ) );
00197 p_sys->i_bitrate = 0;
00198 p_sys->pp_stream = NULL;
00199
00200
00201 p_sys->i_eos = 0;
00202
00203
00204 ogg_sync_init( &p_sys->oy );
00205
00206 return VLC_SUCCESS;
00207 }
00208
00209
00210
00211
00212 static void Close( vlc_object_t *p_this )
00213 {
00214 demux_t *p_demux = (demux_t *)p_this;
00215 demux_sys_t *p_sys = p_demux->p_sys ;
00216
00217
00218 ogg_sync_clear( &p_sys->oy );
00219
00220 Ogg_EndOfStream( p_demux );
00221
00222 free( p_sys );
00223 }
00224
00225
00226
00227
00228
00229
00230 static int Demux( demux_t * p_demux )
00231 {
00232 demux_sys_t *p_sys = p_demux->p_sys;
00233 ogg_page oggpage;
00234 ogg_packet oggpacket;
00235 int i_stream;
00236
00237
00238 if( p_sys->i_eos == p_sys->i_streams )
00239 {
00240 if( p_sys->i_eos )
00241 {
00242 msg_Dbg( p_demux, "end of a group of logical streams" );
00243 Ogg_EndOfStream( p_demux );
00244 }
00245
00246 p_sys->i_eos = 0;
00247 if( Ogg_BeginningOfStream( p_demux ) != VLC_SUCCESS ) return 0;
00248
00249 msg_Dbg( p_demux, "beginning of a group of logical streams" );
00250 es_out_Control( p_demux->out, ES_OUT_RESET_PCR );
00251 }
00252
00253
00254
00255
00256 if( Ogg_ReadPage( p_demux, &oggpage ) != VLC_SUCCESS )
00257 {
00258 return 0;
00259 }
00260
00261
00262 if( ogg_page_eos( &oggpage ) ) p_sys->i_eos++;
00263
00264
00265 for( i_stream = 0; i_stream < p_sys->i_streams; i_stream++ )
00266 {
00267 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
00268
00269 if( ogg_stream_pagein( &p_stream->os, &oggpage ) != 0 )
00270 continue;
00271
00272 while( ogg_stream_packetout( &p_stream->os, &oggpacket ) > 0 )
00273 {
00274
00275 if( p_stream->secondary_header_packets > 0 )
00276 {
00277 if( p_stream->fmt.i_codec == VLC_FOURCC('t','h','e','o') &&
00278 oggpacket.bytes >= 7 &&
00279 ! memcmp( &oggpacket.packet[1], "theora", 6 ) )
00280 {
00281 Ogg_ReadTheoraHeader( p_stream, &oggpacket );
00282 p_stream->secondary_header_packets = 0;
00283 }
00284 else if( p_stream->fmt.i_codec == VLC_FOURCC('v','o','r','b') &&
00285 oggpacket.bytes >= 7 &&
00286 ! memcmp( &oggpacket.packet[1], "vorbis", 6 ) )
00287 {
00288 Ogg_ReadVorbisHeader( p_stream, &oggpacket );
00289 p_stream->secondary_header_packets = 0;
00290 }
00291 else if ( p_stream->fmt.i_codec == VLC_FOURCC('c','m','m','l') )
00292 {
00293 p_stream->secondary_header_packets = 0;
00294 }
00295 }
00296
00297 if( p_stream->b_reinit )
00298 {
00299
00300
00301 Ogg_UpdatePCR( p_stream, &oggpacket );
00302
00303 if( p_stream->i_pcr >= 0 )
00304 {
00305 p_stream->b_reinit = 0;
00306 }
00307 else
00308 {
00309 p_stream->i_interpolated_pcr = -1;
00310 continue;
00311 }
00312
00313
00314 if( p_stream->fmt.i_codec == VLC_FOURCC( 'v','o','r','b' ) ||
00315 p_stream->fmt.i_codec == VLC_FOURCC( 's','p','x',' ' ) ||
00316 p_stream->fmt.i_codec == VLC_FOURCC( 'f','l','a','c' ) )
00317 {
00318 if( ogg_stream_packetout( &p_stream->os, &oggpacket ) > 0 )
00319 {
00320 Ogg_DecodePacket( p_demux, p_stream, &oggpacket );
00321 }
00322 else
00323 {
00324 es_out_Control( p_demux->out, ES_OUT_SET_PCR,
00325 p_stream->i_pcr );
00326 }
00327 continue;
00328 }
00329 }
00330
00331 Ogg_DecodePacket( p_demux, p_stream, &oggpacket );
00332 }
00333 break;
00334 }
00335
00336 i_stream = 0; p_sys->i_pcr = -1;
00337 for( ; i_stream < p_sys->i_streams; i_stream++ )
00338 {
00339 logical_stream_t *p_stream = p_sys->pp_stream[i_stream];
00340
00341 if( p_stream->fmt.i_cat == SPU_ES )
00342 continue;
00343 if( p_stream->i_interpolated_pcr < 0 )
00344 continue;
00345
00346 if( p_sys->i_pcr < 0 || p_stream->i_interpolated_pcr < p_sys->i_pcr )
00347 p_sys->i_pcr = p_stream->i_interpolated_pcr;
00348 }
00349
00350 if( p_sys->i_pcr >= 0 )
00351 {
00352 es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_sys->i_pcr );
00353 }
00354
00355
00356 return 1;
00357 }
00358
00359
00360
00361
00362 static int Control( demux_t *p_demux, int i_query, va_list args )
00363 {
00364 demux_sys_t *p_sys = p_demux->p_sys;
00365 int64_t *pi64;
00366 int i;
00367
00368 switch( i_query )
00369 {
00370 case DEMUX_GET_TIME:
00371 pi64 = (int64_t*)va_arg( args, int64_t * );
00372 *pi64 = p_sys->i_pcr;
00373 return VLC_SUCCESS;
00374
00375 case DEMUX_SET_TIME:
00376 return VLC_EGENERIC;
00377
00378 case DEMUX_SET_POSITION:
00379 for( i = 0; i < p_sys->i_streams; i++ )
00380 {
00381 logical_stream_t *p_stream = p_sys->pp_stream[i];
00382
00383
00384 p_stream->b_reinit = 1;
00385 p_stream->i_pcr = -1;
00386 p_stream->i_interpolated_pcr = -1;
00387 ogg_stream_reset( &p_stream->os );
00388 }
00389 ogg_sync_reset( &p_sys->oy );
00390
00391 default:
00392 return demux2_vaControlHelper( p_demux->s, 0, -1, p_sys->i_bitrate,
00393 1, i_query, args );
00394 }
00395 }
00396
00397
00398
00399
00400
00401
00402
00403 static int Ogg_ReadPage( demux_t *p_demux, ogg_page *p_oggpage )
00404 {
00405 demux_sys_t *p_ogg = p_demux->p_sys ;
00406 int i_read = 0;
00407 char *p_buffer;
00408
00409 while( ogg_sync_pageout( &p_ogg->oy, p_oggpage ) != 1 )
00410 {
00411 p_buffer = ogg_sync_buffer( &p_ogg->oy, OGG_BLOCK_SIZE );
00412
00413 i_read = stream_Read( p_demux->s, p_buffer, OGG_BLOCK_SIZE );
00414 if( i_read <= 0 )
00415 return VLC_EGENERIC;
00416
00417 ogg_sync_wrote( &p_ogg->oy, i_read );
00418 }
00419
00420 return VLC_SUCCESS;
00421 }
00422
00423
00424
00425
00426
00427 static void Ogg_UpdatePCR( logical_stream_t *p_stream,
00428 ogg_packet *p_oggpacket )
00429 {
00430
00431 if( p_oggpacket->granulepos >= 0 )
00432 {
00433 if( p_stream->fmt.i_codec != VLC_FOURCC( 't','h','e','o' ) )
00434 {
00435 p_stream->i_pcr = p_oggpacket->granulepos * I64C(1000000)
00436 / p_stream->f_rate;
00437 }
00438 else
00439 {
00440 ogg_int64_t iframe = p_oggpacket->granulepos >>
00441 p_stream->i_theora_keyframe_granule_shift;
00442 ogg_int64_t pframe = p_oggpacket->granulepos -
00443 ( iframe << p_stream->i_theora_keyframe_granule_shift );
00444
00445 p_stream->i_pcr = ( iframe + pframe ) * I64C(1000000)
00446 / p_stream->f_rate;
00447 }
00448
00449 p_stream->i_interpolated_pcr = p_stream->i_pcr;
00450 }
00451 else
00452 {
00453 p_stream->i_pcr = -1;
00454
00455
00456
00457 if( p_stream->fmt.i_cat == VIDEO_ES )
00458
00459 p_stream->i_interpolated_pcr += (I64C(1000000) / p_stream->f_rate);
00460 else if( p_stream->fmt.i_bitrate )
00461 p_stream->i_interpolated_pcr +=
00462 ( p_oggpacket->bytes * I64C(1000000) /
00463 p_stream->fmt.i_bitrate / 8 );
00464 }
00465 }
00466
00467
00468
00469
00470 static void Ogg_DecodePacket( demux_t *p_demux,
00471 logical_stream_t *p_stream,
00472 ogg_packet *p_oggpacket )
00473 {
00474 block_t *p_block;
00475 vlc_bool_t b_selected;
00476 int i_header_len = 0;
00477 mtime_t i_pts = -1, i_interpolated_pts;
00478
00479
00480 if( !p_oggpacket->bytes )
00481 {
00482 msg_Dbg( p_demux, "discarding 0 sized packet" );
00483 return;
00484 }
00485
00486 if( p_oggpacket->bytes >= 7 &&
00487 ! memcmp ( &p_oggpacket->packet[0], "Annodex", 7 ) )
00488 {
00489
00490 return;
00491 }
00492 else if( p_oggpacket->bytes >= 7 &&
00493 ! memcmp ( &p_oggpacket->packet[0], "AnxData", 7 ) )
00494 {
00495
00496 return;
00497 }
00498
00499 if( p_stream->fmt.i_codec == VLC_FOURCC( 's','u','b','t' ) &&
00500 p_oggpacket->packet[0] & PACKET_TYPE_BITS ) return;
00501
00502
00503 es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE,
00504 p_stream->p_es, &b_selected );
00505
00506 if( p_stream->b_force_backup )
00507 {
00508 uint8_t *p_extra;
00509 vlc_bool_t b_store_size = VLC_TRUE;
00510
00511 p_stream->i_packets_backup++;
00512 switch( p_stream->fmt.i_codec )
00513 {
00514 case VLC_FOURCC( 'v','o','r','b' ):
00515 case VLC_FOURCC( 's','p','x',' ' ):
00516 case VLC_FOURCC( 't','h','e','o' ):
00517 if( p_stream->i_packets_backup == 3 ) p_stream->b_force_backup = 0;
00518 break;
00519
00520 case VLC_FOURCC( 'f','l','a','c' ):
00521 if( !p_stream->fmt.audio.i_rate && p_stream->i_packets_backup == 2 )
00522 {
00523 Ogg_ReadFlacHeader( p_demux, p_stream, p_oggpacket );
00524 p_stream->b_force_backup = 0;
00525 }
00526 else if( p_stream->fmt.audio.i_rate )
00527 {
00528 p_stream->b_force_backup = 0;
00529 if( p_oggpacket->bytes >= 9 )
00530 {
00531 p_oggpacket->packet += 9;
00532 p_oggpacket->bytes -= 9;
00533 }
00534 }
00535 b_store_size = VLC_FALSE;
00536 break;
00537
00538 default:
00539 p_stream->b_force_backup = 0;
00540 break;
00541 }
00542
00543
00544 p_stream->p_headers =
00545 realloc( p_stream->p_headers, p_stream->i_headers +
00546 p_oggpacket->bytes + (b_store_size ? 2 : 0) );
00547 p_extra = p_stream->p_headers + p_stream->i_headers;
00548 if( b_store_size )
00549 {
00550 *(p_extra++) = p_oggpacket->bytes >> 8;
00551 *(p_extra++) = p_oggpacket->bytes & 0xFF;
00552 }
00553 memcpy( p_extra, p_oggpacket->packet, p_oggpacket->bytes );
00554 p_stream->i_headers += p_oggpacket->bytes + (b_store_size ? 2 : 0);
00555
00556 if( !p_stream->b_force_backup )
00557 {
00558
00559 p_stream->fmt.i_extra = p_stream->i_headers;
00560 p_stream->fmt.p_extra =
00561 realloc( p_stream->fmt.p_extra, p_stream->i_headers );
00562 memcpy( p_stream->fmt.p_extra, p_stream->p_headers,
00563 p_stream->i_headers );
00564 es_out_Control( p_demux->out, ES_OUT_SET_FMT,
00565 p_stream->p_es, &p_stream->fmt );
00566 }
00567
00568 b_selected = VLC_FALSE;
00569 }
00570
00571
00572 if( p_stream->fmt.i_codec == VLC_FOURCC( 'v','o','r','b' ) ||
00573 p_stream->fmt.i_codec == VLC_FOURCC( 's','p','x',' ' ) ||
00574 p_stream->fmt.i_codec == VLC_FOURCC( 'f','l','a','c' ) )
00575 {
00576 if( p_stream->i_pcr >= 0 )
00577 {
00578
00579
00580 if( p_stream->i_previous_pcr == 0 &&
00581 p_stream->i_pcr > 3 * DEFAULT_PTS_DELAY )
00582 {
00583 es_out_Control( p_demux->out, ES_OUT_RESET_PCR );
00584
00585
00586 es_out_Control( p_demux->out, ES_OUT_SET_PCR,
00587 p_stream->i_pcr );
00588 }
00589
00590 p_stream->i_previous_pcr = p_stream->i_pcr;
00591
00592
00593 i_pts = p_stream->i_pcr;
00594 }
00595 }
00596
00597
00598 i_interpolated_pts = p_stream->i_interpolated_pcr;
00599 Ogg_UpdatePCR( p_stream, p_oggpacket );
00600
00601 if( p_stream->i_pcr >= 0 )
00602 {
00603
00604
00605 if( p_stream->i_previous_pcr == 0 &&
00606 p_stream->i_pcr > 3 * DEFAULT_PTS_DELAY )
00607 {
00608 es_out_Control( p_demux->out, ES_OUT_RESET_PCR );
00609
00610
00611 es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_stream->i_pcr );
00612 }
00613 }
00614
00615 if( p_stream->fmt.i_codec != VLC_FOURCC( 'v','o','r','b' ) &&
00616 p_stream->fmt.i_codec != VLC_FOURCC( 's','p','x',' ' ) &&
00617 p_stream->fmt.i_codec != VLC_FOURCC( 'f','l','a','c' ) &&
00618 p_stream->i_pcr >= 0 )
00619 {
00620 p_stream->i_previous_pcr = p_stream->i_pcr;
00621
00622
00623 i_pts = p_stream->i_pcr;
00624 }
00625
00626 if( !b_selected )
00627 {
00628
00629
00630 return;
00631 }
00632
00633 if( p_oggpacket->bytes <= 0 )
00634 return;
00635
00636 if( !( p_block = block_New( p_demux, p_oggpacket->bytes ) ) ) return;
00637
00638
00639 if( i_pts == 0 ) i_pts = 1;
00640 else if( i_pts == -1 && i_interpolated_pts == 0 ) i_pts = 1;
00641 else if( i_pts == -1 ) i_pts = 0;
00642
00643 if( p_stream->fmt.i_cat == AUDIO_ES )
00644 p_block->i_dts = p_block->i_pts = i_pts;
00645 else if( p_stream->fmt.i_cat == SPU_ES )
00646 {
00647 p_block->i_dts = p_block->i_pts = i_pts;
00648 p_block->i_length = 0;
00649 }
00650 else if( p_stream->fmt.i_codec == VLC_FOURCC( 't','h','e','o' ) )
00651 p_block->i_dts = p_block->i_pts = i_pts;
00652 else
00653 {
00654 p_block->i_dts = i_pts;
00655 p_block->i_pts = 0;
00656 }
00657
00658 if( p_stream->fmt.i_codec != VLC_FOURCC( 'v','o','r','b' ) &&
00659 p_stream->fmt.i_codec != VLC_FOURCC( 's','p','x',' ' ) &&
00660 p_stream->fmt.i_codec != VLC_FOURCC( 'f','l','a','c' ) &&
00661 p_stream->fmt.i_codec != VLC_FOURCC( 't','a','r','k' ) &&
00662 p_stream->fmt.i_codec != VLC_FOURCC( 't','h','e','o' ) &&
00663 p_stream->fmt.i_codec != VLC_FOURCC( 'c','m','m','l' ) )
00664 {
00665
00666 i_header_len = (*p_oggpacket->packet & PACKET_LEN_BITS01) >> 6;
00667 i_header_len |= (*p_oggpacket->packet & PACKET_LEN_BITS2) << 1;
00668
00669 if( p_stream->fmt.i_codec == VLC_FOURCC( 's','u','b','t' ))
00670 {
00671
00672 int i, lenbytes = 0;
00673
00674 if( i_header_len > 0 && p_oggpacket->bytes >= i_header_len + 1 )
00675 {
00676 for( i = 0, lenbytes = 0; i < i_header_len; i++ )
00677 {
00678 lenbytes = lenbytes << 8;
00679 lenbytes += *(p_oggpacket->packet + i_header_len - i);
00680 }
00681 }
00682 if( p_oggpacket->bytes - 1 - i_header_len > 2 ||
00683 ( p_oggpacket->packet[i_header_len + 1] != ' ' &&
00684 p_oggpacket->packet[i_header_len + 1] != 0 &&
00685 p_oggpacket->packet[i_header_len + 1] != '\n' &&
00686 p_oggpacket->packet[i_header_len + 1] != '\r' ) )
00687 {
00688 p_block->i_length = (mtime_t)lenbytes * 1000;
00689 }
00690 }
00691
00692 i_header_len++;
00693 if( p_block->i_buffer >= i_header_len )
00694 p_block->i_buffer -= i_header_len;
00695 else
00696 p_block->i_buffer = 0;
00697 }
00698
00699 if( p_stream->fmt.i_codec == VLC_FOURCC( 't','a','r','k' ) )
00700 {
00701
00702 msg_Warn( p_demux, "tarkin pts: "I64Fd", granule: "I64Fd,
00703 p_block->i_pts, p_block->i_dts );
00704 msleep(10000);
00705 }
00706
00707 memcpy( p_block->p_buffer, p_oggpacket->packet + i_header_len,
00708 p_oggpacket->bytes - i_header_len );
00709
00710 es_out_Send( p_demux->out, p_stream->p_es, p_block );
00711 }
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723 static int Ogg_FindLogicalStreams( demux_t *p_demux )
00724 {
00725 demux_sys_t *p_ogg = p_demux->p_sys ;
00726 ogg_packet oggpacket;
00727 ogg_page oggpage;
00728 int i_stream;
00729
00730 #define p_stream p_ogg->pp_stream[p_ogg->i_streams - 1]
00731
00732 while( Ogg_ReadPage( p_demux, &oggpage ) == VLC_SUCCESS )
00733 {
00734 if( ogg_page_bos( &oggpage ) )
00735 {
00736
00737
00738
00739 while( ogg_page_bos( &oggpage ) )
00740 {
00741 p_ogg->i_streams++;
00742 p_ogg->pp_stream =
00743 realloc( p_ogg->pp_stream, p_ogg->i_streams *
00744 sizeof(logical_stream_t *) );
00745
00746 p_stream = malloc( sizeof(logical_stream_t) );
00747 memset( p_stream, 0, sizeof(logical_stream_t) );
00748 p_stream->p_headers = 0;
00749 p_stream->secondary_header_packets = 0;
00750
00751 es_format_Init( &p_stream->fmt, 0, 0 );
00752
00753
00754 p_stream->i_serial_no = ogg_page_serialno( &oggpage );
00755 ogg_stream_init( &p_stream->os, p_stream->i_serial_no );
00756
00757
00758
00759 if( ogg_stream_pagein( &p_stream->os, &oggpage ) < 0 )
00760 {
00761
00762 msg_Err( p_demux, "error reading first page of "
00763 "Ogg bitstream data" );
00764 return VLC_EGENERIC;
00765 }
00766
00767
00768 ogg_stream_packetpeek( &p_stream->os, &oggpacket );
00769
00770
00771 if( oggpacket.bytes >= 7 &&
00772 ! memcmp( &oggpacket.packet[1], "vorbis", 6 ) )
00773 {
00774 Ogg_ReadVorbisHeader( p_stream, &oggpacket );
00775 msg_Dbg( p_demux, "found vorbis header" );
00776 }
00777
00778 else if( oggpacket.bytes >= 7 &&
00779 ! memcmp( &oggpacket.packet[0], "Speex", 5 ) )
00780 {
00781 Ogg_ReadSpeexHeader( p_stream, &oggpacket );
00782 msg_Dbg( p_demux, "found speex header, channels: %i, "
00783 "rate: %i, bitrate: %i",
00784 p_stream->fmt.audio.i_channels,
00785 (int)p_stream->f_rate, p_stream->fmt.i_bitrate );
00786 }
00787
00788 else if( oggpacket.bytes >= 4 &&
00789 ! memcmp( &oggpacket.packet[0], "fLaC", 4 ) )
00790 {
00791 msg_Dbg( p_demux, "found FLAC header" );
00792
00793
00794
00795
00796 p_stream->b_force_backup = 1;
00797
00798 p_stream->fmt.i_cat = AUDIO_ES;
00799 p_stream->fmt.i_codec = VLC_FOURCC( 'f','l','a','c' );
00800 }
00801
00802 else if( oggpacket.bytes >= 13 && oggpacket.packet[0] ==0x7F &&
00803 ! memcmp( &oggpacket.packet[1], "FLAC", 4 ) &&
00804 ! memcmp( &oggpacket.packet[9], "fLaC", 4 ) )
00805 {
00806 int i_packets = ((int)oggpacket.packet[7]) << 8 |
00807 oggpacket.packet[8];
00808 msg_Dbg( p_demux, "found FLAC header version %i.%i "
00809 "(%i header packets)",
00810 oggpacket.packet[5], oggpacket.packet[6],
00811 i_packets );
00812
00813 p_stream->b_force_backup = 1;
00814
00815 p_stream->fmt.i_cat = AUDIO_ES;
00816 p_stream->fmt.i_codec = VLC_FOURCC( 'f','l','a','c' );
00817 oggpacket.packet += 13; oggpacket.bytes -= 13;
00818 Ogg_ReadFlacHeader( p_demux, p_stream, &oggpacket );
00819 }
00820
00821 else if( oggpacket.bytes >= 7 &&
00822 ! memcmp( &oggpacket.packet[1], "theora", 6 ) )
00823 {
00824 Ogg_ReadTheoraHeader( p_stream, &oggpacket );
00825
00826 msg_Dbg( p_demux,
00827 "found theora header, bitrate: %i, rate: %f",
00828 p_stream->fmt.i_bitrate, p_stream->f_rate );
00829 }
00830
00831 else if( oggpacket.bytes >= 7 &&
00832 ! memcmp( &oggpacket.packet[1], "tarkin", 6 ) )
00833 {
00834 oggpack_buffer opb;
00835
00836 msg_Dbg( p_demux, "found tarkin header" );
00837 p_stream->fmt.i_cat = VIDEO_ES;
00838 p_stream->fmt.i_codec = VLC_FOURCC( 't','a','r','k' );
00839
00840
00841 oggpack_readinit( &opb, oggpacket.packet, oggpacket.bytes);
00842 oggpack_adv( &opb, 88 );
00843 oggpack_adv( &opb, 104 );
00844 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
00845 p_stream->f_rate = 2;
00846 msg_Dbg( p_demux,
00847 "found tarkin header, bitrate: %i, rate: %f",
00848 p_stream->fmt.i_bitrate, p_stream->f_rate );
00849 }
00850
00851 else if( oggpacket.bytes >= 7 &&
00852 ! memcmp( &oggpacket.packet[0], "Annodex", 7 ) )
00853 {
00854 Ogg_ReadAnnodexHeader( VLC_OBJECT(p_demux), p_stream,
00855 &oggpacket );
00856
00857 free( p_stream );
00858 p_ogg->i_streams--;
00859 }
00860
00861 else if( oggpacket.bytes >= 7 &&
00862 ! memcmp( &oggpacket.packet[0], "AnxData", 7 ) )
00863 {
00864 Ogg_ReadAnnodexHeader( VLC_OBJECT(p_demux), p_stream,
00865 &oggpacket );
00866 }
00867 else if( oggpacket.bytes >= 142 &&
00868 !memcmp( &oggpacket.packet[1],
00869 "Direct Show Samples embedded in Ogg", 35 ))
00870 {
00871
00872
00873
00874 if( GetDWLE((oggpacket.packet+96)) == 0x05589f80 &&
00875 oggpacket.bytes >= 184 )
00876 {
00877 p_stream->fmt.i_cat = VIDEO_ES;
00878 p_stream->fmt.i_codec =
00879 VLC_FOURCC( oggpacket.packet[68],
00880 oggpacket.packet[69],
00881 oggpacket.packet[70],
00882 oggpacket.packet[71] );
00883 msg_Dbg( p_demux, "found video header of type: %.4s",
00884 (char *)&p_stream->fmt.i_codec );
00885
00886 p_stream->fmt.video.i_frame_rate = 10000000;
00887 p_stream->fmt.video.i_frame_rate_base =
00888 GetQWLE((oggpacket.packet+164));
00889 p_stream->f_rate = 10000000.0 /
00890 GetQWLE((oggpacket.packet+164));
00891 p_stream->fmt.video.i_bits_per_pixel =
00892 GetWLE((oggpacket.packet+182));
00893 if( !p_stream->fmt.video.i_bits_per_pixel )
00894
00895 p_stream->fmt.video.i_bits_per_pixel = 24;
00896 p_stream->fmt.video.i_width =
00897 GetDWLE((oggpacket.packet+176));
00898 p_stream->fmt.video.i_height =
00899 GetDWLE((oggpacket.packet+180));
00900
00901 msg_Dbg( p_demux,
00902 "fps: %f, width:%i; height:%i, bitcount:%i",
00903 p_stream->f_rate,
00904 p_stream->fmt.video.i_width,
00905 p_stream->fmt.video.i_height,
00906 p_stream->fmt.video.i_bits_per_pixel);
00907
00908 }
00909
00910 else if( GetDWLE((oggpacket.packet+96)) == 0x05589F81 )
00911 {
00912 unsigned int i_extra_size;
00913 unsigned int i_format_tag;
00914
00915 p_stream->fmt.i_cat = AUDIO_ES;
00916
00917 i_extra_size = GetWLE((oggpacket.packet+140));
00918 if( i_extra_size )
00919 {
00920 p_stream->fmt.i_extra = i_extra_size;
00921 p_stream->fmt.p_extra = malloc( i_extra_size );
00922 memcpy( p_stream->fmt.p_extra,
00923 oggpacket.packet + 142, i_extra_size );
00924 }
00925
00926 i_format_tag = GetWLE((oggpacket.packet+124));
00927 p_stream->fmt.audio.i_channels =
00928 GetWLE((oggpacket.packet+126));
00929 p_stream->f_rate = p_stream->fmt.audio.i_rate =
00930 GetDWLE((oggpacket.packet+128));
00931 p_stream->fmt.i_bitrate =
00932 GetDWLE((oggpacket.packet+132)) * 8;
00933 p_stream->fmt.audio.i_blockalign =
00934 GetWLE((oggpacket.packet+136));
00935 p_stream->fmt.audio.i_bitspersample =
00936 GetWLE((oggpacket.packet+138));
00937
00938 wf_tag_to_fourcc( i_format_tag,
00939 &p_stream->fmt.i_codec, 0 );
00940
00941 if( p_stream->fmt.i_codec ==
00942 VLC_FOURCC('u','n','d','f') )
00943 {
00944 p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',
00945 ( i_format_tag >> 8 ) & 0xff,
00946 i_format_tag & 0xff );
00947 }
00948
00949 msg_Dbg( p_demux, "found audio header of type: %.4s",
00950 (char *)&p_stream->fmt.i_codec );
00951 msg_Dbg( p_demux, "audio:0x%4.4x channels:%d %dHz "
00952 "%dbits/sample %dkb/s",
00953 i_format_tag,
00954 p_stream->fmt.audio.i_channels,
00955 p_stream->fmt.audio.i_rate,
00956 p_stream->fmt.audio.i_bitspersample,
00957 p_stream->fmt.i_bitrate / 1024 );
00958
00959 }
00960 else
00961 {
00962 msg_Dbg( p_demux, "stream %d has an old header "
00963 "but is of an unknown type", p_ogg->i_streams-1 );
00964 free( p_stream );
00965 p_ogg->i_streams--;
00966 }
00967 }
00968 else if( (*oggpacket.packet & PACKET_TYPE_BITS )
00969 == PACKET_TYPE_HEADER &&
00970 oggpacket.bytes >= (int)sizeof(stream_header)+1 )
00971 {
00972 stream_header *st = (stream_header *)(oggpacket.packet+1);
00973
00974
00975 if( !strncmp( st->streamtype, "video", 5 ) )
00976 {
00977 p_stream->fmt.i_cat = VIDEO_ES;
00978
00979
00980 ogg_stream_packetout( &p_stream->os, &oggpacket );
00981
00982 p_stream->fmt.i_codec =
00983 VLC_FOURCC( st->subtype[0], st->subtype[1],
00984 st->subtype[2], st->subtype[3] );
00985 msg_Dbg( p_demux, "found video header of type: %.4s",
00986 (char *)&p_stream->fmt.i_codec );
00987
00988 p_stream->fmt.video.i_frame_rate = 10000000;
00989 p_stream->fmt.video.i_frame_rate_base =
00990 GetQWLE(&st->time_unit);
00991 p_stream->f_rate = 10000000.0 /
00992 GetQWLE(&st->time_unit);
00993 p_stream->fmt.video.i_bits_per_pixel =
00994 GetWLE(&st->bits_per_sample);
00995 p_stream->fmt.video.i_width =
00996 GetDWLE(&st->sh.video.width);
00997 p_stream->fmt.video.i_height =
00998 GetDWLE(&st->sh.video.height);
00999
01000 msg_Dbg( p_demux,
01001 "fps: %f, width:%i; height:%i, bitcount:%i",
01002 p_stream->f_rate,
01003 p_stream->fmt.video.i_width,
01004 p_stream->fmt.video.i_height,
01005 p_stream->fmt.video.i_bits_per_pixel );
01006 }
01007
01008 else if( !strncmp( st->streamtype, "audio", 5 ) )
01009 {
01010 char p_buffer[5];
01011 int i_format_tag;
01012
01013 p_stream->fmt.i_cat = AUDIO_ES;
01014
01015
01016 ogg_stream_packetout( &p_stream->os, &oggpacket );
01017
01018 p_stream->fmt.i_extra = GetQWLE(&st->size) -
01019 sizeof(stream_header);
01020 if( p_stream->fmt.i_extra )
01021 {
01022 p_stream->fmt.p_extra =
01023 malloc( p_stream->fmt.i_extra );
01024 memcpy( p_stream->fmt.p_extra, st + 1,
01025 p_stream->fmt.i_extra );
01026 }
01027
01028 memcpy( p_buffer, st->subtype, 4 );
01029 p_buffer[4] = '\0';
01030 i_format_tag = strtol(p_buffer,NULL,16);
01031 p_stream->fmt.audio.i_channels =
01032 GetWLE(&st->sh.audio.channels);
01033 p_stream->f_rate = p_stream->fmt.audio.i_rate =
01034 GetQWLE(&st->samples_per_unit);
01035 p_stream->fmt.i_bitrate =
01036 GetDWLE(&st->sh.audio.avgbytespersec) * 8;
01037 p_stream->fmt.audio.i_blockalign =
01038 GetWLE(&st->sh.audio.blockalign);
01039 p_stream->fmt.audio.i_bitspersample =
01040 GetWLE(&st->bits_per_sample);
01041
01042 wf_tag_to_fourcc( i_format_tag,
01043 &p_stream->fmt.i_codec, 0 );
01044
01045 if( p_stream->fmt.i_codec ==
01046 VLC_FOURCC('u','n','d','f') )
01047 {
01048 p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',
01049 ( i_format_tag >> 8 ) & 0xff,
01050 i_format_tag & 0xff );
01051 }
01052
01053 msg_Dbg( p_demux, "found audio header of type: %.4s",
01054 (char *)&p_stream->fmt.i_codec );
01055 msg_Dbg( p_demux, "audio:0x%4.4x channels:%d %dHz "
01056 "%dbits/sample %dkb/s",
01057 i_format_tag,
01058 p_stream->fmt.audio.i_channels,
01059 p_stream->fmt.audio.i_rate,
01060 p_stream->fmt.audio.i_bitspersample,
01061 p_stream->fmt.i_bitrate / 1024 );
01062 }
01063
01064 else if( !strncmp(st->streamtype, "text", 4) )
01065 {
01066
01067 ogg_stream_packetout( &p_stream->os, &oggpacket );
01068
01069 msg_Dbg( p_demux, "found text subtitles header" );
01070 p_stream->fmt.i_cat = SPU_ES;
01071 p_stream->fmt.i_codec = VLC_FOURCC('s','u','b','t');
01072 p_stream->f_rate = 1000;
01073 }
01074 else
01075 {
01076 msg_Dbg( p_demux, "stream %d has a header marker "
01077 "but is of an unknown type", p_ogg->i_streams-1 );
01078 free( p_stream );
01079 p_ogg->i_streams--;
01080 }
01081 }
01082 else
01083 {
01084 msg_Dbg( p_demux, "stream %d is of unknown type",
01085 p_ogg->i_streams-1 );
01086 free( p_stream );
01087 p_ogg->i_streams--;
01088 }
01089
01090 if( Ogg_ReadPage( p_demux, &oggpage ) != VLC_SUCCESS )
01091 return VLC_EGENERIC;
01092 }
01093
01094
01095
01096
01097 for( i_stream = 0; i_stream < p_ogg->i_streams; i_stream++ )
01098 {
01099 if( ogg_stream_pagein( &p_ogg->pp_stream[i_stream]->os,
01100 &oggpage ) == 0 )
01101 {
01102 break;
01103 }
01104 }
01105
01106 return VLC_SUCCESS;
01107 }
01108 }
01109 #undef p_stream
01110
01111 return VLC_EGENERIC;
01112 }
01113
01114
01115
01116
01117
01118 static int Ogg_BeginningOfStream( demux_t *p_demux )
01119 {
01120 demux_sys_t *p_ogg = p_demux->p_sys ;
01121 int i_stream;
01122
01123
01124
01125 if( Ogg_FindLogicalStreams( p_demux ) != VLC_SUCCESS )
01126 {
01127 msg_Warn( p_demux, "couldn't find any ogg logical stream" );
01128 return VLC_EGENERIC;
01129 }
01130
01131 p_ogg->i_bitrate = 0;
01132
01133 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
01134 {
01135 #define p_stream p_ogg->pp_stream[i_stream]
01136 p_stream->p_es = es_out_Add( p_demux->out, &p_stream->fmt );
01137
01138 if( p_stream->fmt.i_codec == VLC_FOURCC('c','m','m','l') )
01139 {
01140
01141 es_out_Control( p_demux->out, ES_OUT_SET_ES, p_stream->p_es );
01142 }
01143
01144 p_ogg->i_bitrate += p_stream->fmt.i_bitrate;
01145
01146 p_stream->i_pcr = p_stream->i_previous_pcr =
01147 p_stream->i_interpolated_pcr = -1;
01148 p_stream->b_reinit = 0;
01149 #undef p_stream
01150 }
01151
01152 return VLC_SUCCESS;
01153 }
01154
01155
01156
01157
01158 static void Ogg_EndOfStream( demux_t *p_demux )
01159 {
01160 demux_sys_t *p_ogg = p_demux->p_sys ;
01161 int i_stream;
01162
01163 #define p_stream p_ogg->pp_stream[i_stream]
01164 for( i_stream = 0 ; i_stream < p_ogg->i_streams; i_stream++ )
01165 {
01166 if( p_stream->p_es )
01167 es_out_Del( p_demux->out, p_stream->p_es );
01168
01169 p_ogg->i_bitrate -= p_stream->fmt.i_bitrate;
01170
01171 ogg_stream_clear( &p_ogg->pp_stream[i_stream]->os );
01172 if( p_ogg->pp_stream[i_stream]->p_headers)
01173 free( p_ogg->pp_stream[i_stream]->p_headers );
01174
01175 es_format_Clean( &p_stream->fmt );
01176
01177 free( p_ogg->pp_stream[i_stream] );
01178 }
01179 #undef p_stream
01180
01181
01182 if( p_ogg->pp_stream ) free( p_ogg->pp_stream );
01183 p_ogg->pp_stream = NULL;
01184 p_ogg->i_streams = 0;
01185 }
01186
01187 static void Ogg_ReadTheoraHeader( logical_stream_t *p_stream,
01188 ogg_packet *p_oggpacket )
01189 {
01190 bs_t bitstream;
01191 int i_fps_numerator;
01192 int i_fps_denominator;
01193 int i_keyframe_frequency_force;
01194
01195 p_stream->fmt.i_cat = VIDEO_ES;
01196 p_stream->fmt.i_codec = VLC_FOURCC( 't','h','e','o' );
01197
01198
01199
01200
01201 p_stream->b_force_backup = 1;
01202
01203
01204 bs_init( &bitstream, p_oggpacket->packet, p_oggpacket->bytes );
01205 bs_skip( &bitstream, 56 );
01206 bs_read( &bitstream, 8 );
01207 bs_read( &bitstream, 8 );
01208 bs_read( &bitstream, 8 );
01209 bs_read( &bitstream, 16 ) ;
01210 bs_read( &bitstream, 16 ) ;
01211 bs_read( &bitstream, 24 );
01212 bs_read( &bitstream, 24 );
01213 bs_read( &bitstream, 8 );
01214 bs_read( &bitstream, 8 );
01215
01216 i_fps_numerator = bs_read( &bitstream, 32 );
01217 i_fps_denominator = bs_read( &bitstream, 32 );
01218 bs_read( &bitstream, 24 );
01219 bs_read( &bitstream, 24 );
01220
01221 p_stream->fmt.video.i_frame_rate = i_fps_numerator;
01222 p_stream->fmt.video.i_frame_rate_base = i_fps_denominator;
01223
01224 bs_read( &bitstream, 8 );
01225 p_stream->fmt.i_bitrate = bs_read( &bitstream, 24 );
01226 bs_read( &bitstream, 6 );
01227
01228 i_keyframe_frequency_force = 1 << bs_read( &bitstream, 5 );
01229
01230
01231 p_stream->i_theora_keyframe_granule_shift = 0;
01232 i_keyframe_frequency_force--;
01233 while( i_keyframe_frequency_force )
01234 {
01235 p_stream->i_theora_keyframe_granule_shift++;
01236 i_keyframe_frequency_force >>= 1;
01237 }
01238
01239 p_stream->f_rate = ((float)i_fps_numerator) / i_fps_denominator;
01240 }
01241
01242 static void Ogg_ReadVorbisHeader( logical_stream_t *p_stream,
01243 ogg_packet *p_oggpacket )
01244 {
01245 oggpack_buffer opb;
01246
01247 p_stream->fmt.i_cat = AUDIO_ES;
01248 p_stream->fmt.i_codec = VLC_FOURCC( 'v','o','r','b' );
01249
01250
01251
01252
01253 p_stream->b_force_backup = 1;
01254
01255
01256 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
01257 oggpack_adv( &opb, 88 );
01258 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 8 );
01259 p_stream->f_rate = p_stream->fmt.audio.i_rate =
01260 oggpack_read( &opb, 32 );
01261 oggpack_adv( &opb, 32 );
01262 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
01263 }
01264
01265 static void Ogg_ReadSpeexHeader( logical_stream_t *p_stream,
01266 ogg_packet *p_oggpacket )
01267 {
01268 oggpack_buffer opb;
01269
01270 p_stream->fmt.i_cat = AUDIO_ES;
01271 p_stream->fmt.i_codec = VLC_FOURCC( 's','p','x',' ' );
01272
01273
01274
01275
01276 p_stream->b_force_backup = 1;
01277
01278
01279 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
01280 oggpack_adv( &opb, 224 );
01281 oggpack_adv( &opb, 32 );
01282 oggpack_adv( &opb, 32 );
01283 p_stream->f_rate = p_stream->fmt.audio.i_rate = oggpack_read( &opb, 32 );
01284 oggpack_adv( &opb, 32 );
01285 oggpack_adv( &opb, 32 );
01286 p_stream->fmt.audio.i_channels = oggpack_read( &opb, 32 );
01287 p_stream->fmt.i_bitrate = oggpack_read( &opb, 32 );
01288 }
01289
01290 static void Ogg_ReadFlacHeader( demux_t *p_demux, logical_stream_t *p_stream,
01291 ogg_packet *p_oggpacket )
01292 {
01293
01294 bs_t s;
01295
01296 bs_init( &s, p_oggpacket->packet, p_oggpacket->bytes );
01297
01298 bs_read( &s, 1 );
01299 if( bs_read( &s, 7 ) == 0 )
01300 {
01301 if( bs_read( &s, 24 ) >= 34 )
01302 {
01303 bs_skip( &s, 80 );
01304 p_stream->f_rate = p_stream->fmt.audio.i_rate = bs_read( &s, 20 );
01305 p_stream->fmt.audio.i_channels = bs_read( &s, 3 ) + 1;
01306
01307 msg_Dbg( p_demux, "FLAC header, channels: %i, rate: %i",
01308 p_stream->fmt.audio.i_channels, (int)p_stream->f_rate );
01309 }
01310 else msg_Dbg( p_demux, "FLAC STREAMINFO metadata too short" );
01311
01312
01313 *((uint8_t*)p_oggpacket->packet) |= 0x80;
01314 }
01315 else
01316 {
01317
01318 msg_Dbg( p_demux, "Invalid FLAC STREAMINFO metadata" );
01319 }
01320 }
01321
01322 static void Ogg_ReadAnnodexHeader( vlc_object_t *p_this,
01323 logical_stream_t *p_stream,
01324 ogg_packet *p_oggpacket )
01325 {
01326 if( p_oggpacket->bytes >= 28 &&
01327 !memcmp( &p_oggpacket->packet[0], "Annodex", 7 ) )
01328 {
01329 oggpack_buffer opb;
01330
01331 uint16_t major_version;
01332 uint16_t minor_version;
01333 uint64_t timebase_numerator;
01334 uint64_t timebase_denominator;
01335
01336 Ogg_ReadTheoraHeader( p_stream, p_oggpacket );
01337
01338 oggpack_readinit( &opb, p_oggpacket->packet, p_oggpacket->bytes);
01339 oggpack_adv( &opb, 8*8 );
01340 major_version = oggpack_read( &opb, 2*8 );
01341 minor_version = oggpack_read( &opb, 2*8 );
01342 timebase_numerator = GetQWLE( &p_oggpacket->packet[16] );
01343 timebase_denominator = GetQWLE( &p_oggpacket->packet[24] );
01344 }
01345 else if( p_oggpacket->bytes >= 42 &&
01346 !memcmp( &p_oggpacket->packet[0], "AnxData", 7 ) )
01347 {
01348 uint64_t granule_rate_numerator;
01349 uint64_t granule_rate_denominator;
01350 char content_type_string[1024];
01351
01352
01353
01354 granule_rate_numerator = GetQWLE( &p_oggpacket->packet[8] );
01355 granule_rate_denominator = GetQWLE( &p_oggpacket->packet[16] );
01356 p_stream->secondary_header_packets =
01357 GetDWLE( &p_oggpacket->packet[24] );
01358
01359
01360
01361 content_type_string[0] = '\0';
01362 if( !strncasecmp( &p_oggpacket->packet[28], "Content-Type: ", 14 ) )
01363 {
01364 uint8_t *p = memchr( &p_oggpacket->packet[42], '\r',
01365 p_oggpacket->bytes - 1 );
01366 if( p && p[0] == '\r' && p[1] == '\n' )
01367 sscanf( &p_oggpacket->packet[42], "%1024s\r\n",
01368 content_type_string );
01369 }
01370
01371 msg_Dbg( p_this, "AnxData packet info: "I64Fd" / "I64Fd", %d, ``%s''",
01372 granule_rate_numerator, granule_rate_denominator,
01373 p_stream->secondary_header_packets, content_type_string );
01374
01375 p_stream->f_rate = (float) granule_rate_numerator /
01376 (float) granule_rate_denominator;
01377
01378
01379
01380
01381 if( !strncmp(content_type_string, "audio/x-wav", 11) )
01382 {
01383
01384 p_stream->fmt.i_cat = UNKNOWN_ES;
01385 }
01386 else if( !strncmp(content_type_string, "audio/x-vorbis", 14) )
01387 {
01388 p_stream->fmt.i_cat = AUDIO_ES;
01389 p_stream->fmt.i_codec = VLC_FOURCC( 'v','o','r','b' );
01390
01391 p_stream->b_force_backup = 1;
01392 }
01393 else if( !strncmp(content_type_string, "audio/x-speex", 14) )
01394 {
01395 p_stream->fmt.i_cat = AUDIO_ES;
01396 p_stream->fmt.i_codec = VLC_FOURCC( 's','p','x',' ' );
01397
01398 p_stream->b_force_backup = 1;
01399 }
01400 else if( !strncmp(content_type_string, "video/x-theora", 14) )
01401 {
01402 p_stream->fmt.i_cat = VIDEO_ES;
01403 p_stream->fmt.i_codec = VLC_FOURCC( 't','h','e','o' );
01404
01405 p_stream->b_force_backup = 1;
01406 }
01407 else if( !strncmp(content_type_string, "video/x-xvid", 14) )
01408 {
01409 p_stream->fmt.i_cat = VIDEO_ES;
01410 p_stream->fmt.i_codec = VLC_FOURCC( 'x','v','i','d' );
01411
01412 p_stream->b_force_backup = 1;
01413 }
01414 else if( !strncmp(content_type_string, "video/mpeg", 14) )
01415 {
01416
01417 p_stream->fmt.i_cat = VIDEO_ES;
01418 p_stream->fmt.i_codec = VLC_FOURCC( 'm','p','g','v' );
01419 }
01420 else if( !strncmp(content_type_string, "text/x-cmml", 11) )
01421 {
01422 ogg_stream_packetout( &p_stream->os, p_oggpacket );
01423 p_stream->fmt.i_cat = SPU_ES;
01424 p_stream->fmt.i_codec = VLC_FOURCC( 'c','m','m','l' );
01425 }
01426 }
01427 }