]> git.sesse.net Git - vlc/commitdiff
* modules/demux/ogg.c: fixed reading extra data for oggds audio header (needed for...
authorGildas Bazin <gbazin@videolan.org>
Wed, 11 Aug 2004 11:12:59 +0000 (11:12 +0000)
committerGildas Bazin <gbazin@videolan.org>
Wed, 11 Aug 2004 11:12:59 +0000 (11:12 +0000)
* modules/mux/ogg.c: generate proper oggds audio header.

modules/demux/ogg.c
modules/mux/ogg.c

index ff686553e0946762987e3e653c25b64977f1dc12..bb7a1837458bd3ed9f2a2de86fd272fbd83cd6c6 100644 (file)
@@ -278,21 +278,21 @@ static int Demux( demux_t * p_demux )
             /* Read info from any secondary header packets, if there are any */
             if( p_stream->secondary_header_packets > 0 )
             {
-                if( p_stream->fmt.i_codec == VLC_FOURCC( 't','h','e','o' ) &&
+                if( p_stream->fmt.i_codec == VLC_FOURCC('t','h','e','o') &&
                         oggpacket.bytes >= 7 &&
                         ! strncmp( &oggpacket.packet[1], "theora", 6 ) )
                 {
                     Ogg_ReadTheoraHeader( p_stream, &oggpacket );
                     p_stream->secondary_header_packets = 0;
                 }
-                else if( p_stream->fmt.i_codec == VLC_FOURCC( 'v','o','r','b' ) &&
+                else if( p_stream->fmt.i_codec == VLC_FOURCC('v','o','r','b') &&
                         oggpacket.bytes >= 7 &&
                         ! strncmp( &oggpacket.packet[1], "vorbis", 6 ) )
                 {
                     Ogg_ReadVorbisHeader( p_stream, &oggpacket );
                     p_stream->secondary_header_packets = 0;
                 }
-                else if ( p_stream->fmt.i_codec == VLC_FOURCC( 'c','m','m','l' ) )
+                else if ( p_stream->fmt.i_codec == VLC_FOURCC('c','m','m','l') )
                 {
                     p_stream->secondary_header_packets = 0;
                 }
@@ -979,30 +979,12 @@ static int Ogg_FindLogicalStreams( demux_t *p_demux )
                         p_stream->fmt.audio.i_bitspersample =
                             GetWLE((oggpacket.packet+138));
 
-                        switch( i_format_tag )
+                        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') )
                         {
-                        case WAVE_FORMAT_PCM:
-                            p_stream->fmt.i_codec =
-                                VLC_FOURCC( 'a', 'r', 'a', 'w' );
-                            break;
-                        case WAVE_FORMAT_MPEG:
-                        case WAVE_FORMAT_MPEGLAYER3:
-                            p_stream->fmt.i_codec =
-                                VLC_FOURCC( 'm', 'p', 'g', 'a' );
-                            break;
-                        case WAVE_FORMAT_A52:
-                            p_stream->fmt.i_codec =
-                                VLC_FOURCC( 'a', '5', '2', ' ' );
-                            break;
-                        case WAVE_FORMAT_WMA1:
-                            p_stream->fmt.i_codec =
-                                VLC_FOURCC( 'w', 'm', 'a', '1' );
-                            break;
-                        case WAVE_FORMAT_WMA2:
-                            p_stream->fmt.i_codec =
-                                VLC_FOURCC( 'w', 'm', 'a', '2' );
-                            break;
-                        default:
                             p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',
                                 ( i_format_tag >> 8 ) & 0xff,
                                 i_format_tag & 0xff );
@@ -1074,6 +1056,16 @@ static int Ogg_FindLogicalStreams( demux_t *p_demux )
                         /* We need to get rid of the header packet */
                         ogg_stream_packetout( &p_stream->os, &oggpacket );
 
+                        p_stream->fmt.i_extra = GetQWLE(&st->size) -
+                            sizeof(stream_header);
+                        if( p_stream->fmt.i_extra )
+                        {
+                            p_stream->fmt.p_extra =
+                                malloc( p_stream->fmt.i_extra );
+                            memcpy( p_stream->fmt.p_extra, st + 1,
+                                    p_stream->fmt.i_extra );
+                        }
+
                         memcpy( p_buffer, st->subtype, 4 );
                         p_buffer[4] = '\0';
                         i_format_tag = strtol(p_buffer,NULL,16);
@@ -1088,30 +1080,12 @@ static int Ogg_FindLogicalStreams( demux_t *p_demux )
                         p_stream->fmt.audio.i_bitspersample =
                             GetWLE(&st->bits_per_sample);
 
-                        switch( i_format_tag )
+                        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') )
                         {
-                        case WAVE_FORMAT_PCM:
-                            p_stream->fmt.i_codec =
-                                VLC_FOURCC( 'a', 'r', 'a', 'w' );
-                            break;
-                        case WAVE_FORMAT_MPEG:
-                        case WAVE_FORMAT_MPEGLAYER3:
-                            p_stream->fmt.i_codec =
-                                VLC_FOURCC( 'm', 'p', 'g', 'a' );
-                            break;
-                        case WAVE_FORMAT_A52:
-                            p_stream->fmt.i_codec =
-                                VLC_FOURCC( 'a', '5', '2', ' ' );
-                            break;
-                        case WAVE_FORMAT_WMA1:
-                            p_stream->fmt.i_codec =
-                                VLC_FOURCC( 'w', 'm', 'a', '1' );
-                            break;
-                        case WAVE_FORMAT_WMA2:
-                            p_stream->fmt.i_codec =
-                                VLC_FOURCC( 'w', 'm', 'a', '2' );
-                            break;
-                        default:
                             p_stream->fmt.i_codec = VLC_FOURCC( 'm', 's',
                                 ( i_format_tag >> 8 ) & 0xff,
                                 i_format_tag & 0xff );
index e479dba420a996b218c70f431944335ab5f53244..7fc3ae0260602989597e4bd49e6028463eee7bc1 100644 (file)
@@ -194,7 +194,7 @@ typedef struct
     int     i_keyframe_granule_shift; /* Theora only */
     ogg_stream_state os;
 
-    oggds_header_t oggds_header;
+    oggds_header_t *p_oggds_header;
 
     block_t *pp_sout_headers[3];
     int           i_sout_headers;
@@ -275,6 +275,7 @@ static void Close( vlc_object_t * p_this )
         {
             i_dts = p_sys->pp_del_streams[i]->i_dts;
             ogg_stream_clear( &p_sys->pp_del_streams[i]->os );
+            FREE( p_sys->pp_del_streams[i]->p_oggds_header );
             FREE( p_sys->pp_del_streams[i] );
         }
         FREE( p_sys->pp_del_streams );
@@ -324,6 +325,7 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
 {
     sout_mux_sys_t *p_sys = p_mux->p_sys;
     ogg_stream_t   *p_stream;
+    uint16_t i_tag;
 
     msg_Dbg( p_mux, "adding input" );
 
@@ -335,9 +337,8 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
     p_stream->i_packet_no = 0;
 
     p_stream->i_sout_headers = 0;
+    p_stream->p_oggds_header = 0;
 
-    memset( &p_stream->oggds_header, 0, sizeof(p_stream->oggds_header) );
-    p_stream->oggds_header.i_packet_type = PACKET_TYPE_HEADER;
     switch( p_input->p_fmt->i_cat )
     {
     case VIDEO_ES:
@@ -358,31 +359,36 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
         case VLC_FOURCC( 'W', 'M', 'V', '1' ):
         case VLC_FOURCC( 'W', 'M', 'V', '2' ):
         case VLC_FOURCC( 'W', 'M', 'V', '3' ):
-            memcpy( p_stream->oggds_header.stream_type, "video", 5 );
+            p_stream->p_oggds_header = malloc( sizeof(oggds_header_t) );
+            memset( p_stream->p_oggds_header, 0, sizeof(oggds_header_t) );
+            p_stream->p_oggds_header->i_packet_type = PACKET_TYPE_HEADER;
+
+            memcpy( p_stream->p_oggds_header->stream_type, "video", 5 );
             if( p_stream->i_fourcc == VLC_FOURCC( 'm', 'p', '4', 'v' ) )
             {
-                memcpy( p_stream->oggds_header.sub_type, "XVID", 4 );
+                memcpy( p_stream->p_oggds_header->sub_type, "XVID", 4 );
             }
             else if( p_stream->i_fourcc == VLC_FOURCC( 'D', 'I', 'V', '3' ) )
             {
-                memcpy( p_stream->oggds_header.sub_type, "DIV3", 4 );
+                memcpy( p_stream->p_oggds_header->sub_type, "DIV3", 4 );
             }
             else
             {
-                memcpy(p_stream->oggds_header.sub_type,&p_stream->i_fourcc,4);
+                memcpy( p_stream->p_oggds_header->sub_type,
+                        &p_stream->i_fourcc, 4 );
             }
-            SetDWLE( &p_stream->oggds_header.i_size,
-                     sizeof( oggds_header_t ) - 1);
-            SetQWLE( &p_stream->oggds_header.i_time_unit,
+            SetDWLE( &p_stream->p_oggds_header->i_size,
+                     sizeof( oggds_header_t ) - 1 );
+            SetQWLE( &p_stream->p_oggds_header->i_time_unit,
                      I64C(10000000) * p_input->p_fmt->video.i_frame_rate_base /
                      (int64_t)p_input->p_fmt->video.i_frame_rate );
-            SetQWLE( &p_stream->oggds_header.i_samples_per_unit, 1 );
-            SetDWLE( &p_stream->oggds_header.i_default_len, 1 ); /* ??? */
-            SetDWLE( &p_stream->oggds_header.i_buffer_size, 1024*1024 );
-            SetWLE( &p_stream->oggds_header.i_bits_per_sample, 0 );
-            SetDWLE( &p_stream->oggds_header.header.video.i_width,
+            SetQWLE( &p_stream->p_oggds_header->i_samples_per_unit, 1 );
+            SetDWLE( &p_stream->p_oggds_header->i_default_len, 1 ); /* ??? */
+            SetDWLE( &p_stream->p_oggds_header->i_buffer_size, 1024*1024 );
+            SetWLE( &p_stream->p_oggds_header->i_bits_per_sample, 0 );
+            SetDWLE( &p_stream->p_oggds_header->header.video.i_width,
                      p_input->p_fmt->video.i_width );
-            SetDWLE( &p_stream->oggds_header.header.video.i_height,
+            SetDWLE( &p_stream->p_oggds_header->header.video.i_height,
                      p_input->p_fmt->video.i_height );
             msg_Dbg( p_mux, "%4.4s stream", (char *)&p_stream->i_fourcc );
             break;
@@ -400,33 +406,6 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
     case AUDIO_ES:
         switch( p_stream->i_fourcc )
         {
-        case VLC_FOURCC( 'm', 'p', 'g', 'a' ):
-        case VLC_FOURCC( 'a', '5', '2', ' ' ):
-            memcpy( p_stream->oggds_header.stream_type, "audio", 5 );
-            if( p_stream->i_fourcc == VLC_FOURCC( 'm', 'p', 'g', 'a' ) )
-            {
-                memcpy( p_stream->oggds_header.sub_type, "55  ", 4 );
-            }
-            else if( p_stream->i_fourcc == VLC_FOURCC( 'a', '5', '2', ' ' ) )
-            {
-                memcpy( p_stream->oggds_header.sub_type, "2000", 4 );
-            }
-            SetDWLE( &p_stream->oggds_header.i_size,
-                     sizeof( oggds_header_t ) - 1);
-            SetQWLE( &p_stream->oggds_header.i_time_unit, 0 /* not used */ );
-            SetDWLE( &p_stream->oggds_header.i_default_len, 1 );
-            SetDWLE( &p_stream->oggds_header.i_buffer_size, 30*1024 );
-            SetQWLE( &p_stream->oggds_header.i_samples_per_unit,
-                     p_input->p_fmt->audio.i_rate );
-            SetWLE( &p_stream->oggds_header.i_bits_per_sample, 0 );
-            SetDWLE( &p_stream->oggds_header.header.audio.i_channels,
-                     p_input->p_fmt->audio.i_channels );
-            SetDWLE( &p_stream->oggds_header.header.audio.i_block_align,
-                     p_input->p_fmt->audio.i_blockalign );
-            SetDWLE( &p_stream->oggds_header.header.audio.i_avgbytespersec, 0);
-            msg_Dbg( p_mux, "mpga/a52 stream" );
-            break;
-
         case VLC_FOURCC( 'v', 'o', 'r', 'b' ):
             msg_Dbg( p_mux, "vorbis stream" );
             break;
@@ -440,8 +419,47 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
             break;
 
         default:
-            FREE( p_input->p_sys );
-            return VLC_EGENERIC;
+            fourcc_to_wf_tag( p_stream->i_fourcc, &i_tag );
+            if( i_tag == WAVE_FORMAT_UNKNOWN )
+            {
+                FREE( p_input->p_sys );
+                return VLC_EGENERIC;
+            }
+
+            p_stream->p_oggds_header =
+                malloc( sizeof(oggds_header_t) + p_input->p_fmt->i_extra );
+            memset( p_stream->p_oggds_header, 0, sizeof(oggds_header_t) );
+            p_stream->p_oggds_header->i_packet_type = PACKET_TYPE_HEADER;
+
+            SetDWLE( &p_stream->p_oggds_header->i_size,
+                     sizeof( oggds_header_t ) - 1 + p_input->p_fmt->i_extra );
+
+            if( p_input->p_fmt->i_extra )
+            {
+                memcpy( &p_stream->p_oggds_header[1],
+                       p_input->p_fmt->p_extra, p_input->p_fmt->i_extra );
+            }
+
+            memcpy( p_stream->p_oggds_header->stream_type, "audio", 5 );
+
+            memset( p_stream->p_oggds_header->sub_type, 0, 4 );
+            sprintf( p_stream->p_oggds_header->sub_type, "%-x", i_tag );
+
+            SetQWLE( &p_stream->p_oggds_header->i_time_unit, I64C(10000000) );
+            SetDWLE( &p_stream->p_oggds_header->i_default_len, 1 );
+            SetDWLE( &p_stream->p_oggds_header->i_buffer_size, 30*1024 );
+            SetQWLE( &p_stream->p_oggds_header->i_samples_per_unit,
+                     p_input->p_fmt->audio.i_rate );
+            SetWLE( &p_stream->p_oggds_header->i_bits_per_sample,
+                    p_input->p_fmt->audio.i_bitspersample );
+            SetDWLE( &p_stream->p_oggds_header->header.audio.i_channels,
+                     p_input->p_fmt->audio.i_channels );
+            SetDWLE( &p_stream->p_oggds_header->header.audio.i_block_align,
+                     p_input->p_fmt->audio.i_blockalign );
+            SetDWLE( &p_stream->p_oggds_header->header.audio.i_avgbytespersec,
+                     p_input->p_fmt->i_bitrate / 8);
+            msg_Dbg( p_mux, "%4.4s stream", (char *)&p_stream->i_fourcc );
+            break;
         }
         break;
 
@@ -449,7 +467,11 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
         switch( p_stream->i_fourcc )
         {
         case VLC_FOURCC( 's', 'u','b', 't' ):
-            memcpy( p_stream->oggds_header.stream_type, "text", 4 );
+            p_stream->p_oggds_header = malloc( sizeof(oggds_header_t) );
+            memset( p_stream->p_oggds_header, 0, sizeof(oggds_header_t) );
+            p_stream->p_oggds_header->i_packet_type = PACKET_TYPE_HEADER;
+
+            memcpy( p_stream->p_oggds_header->stream_type, "text", 4 );
             msg_Dbg( p_mux, "subtitles stream" );
             break;
 
@@ -510,6 +532,7 @@ static int DelStream( sout_mux_t *p_mux, sout_input_t *p_input )
         else
         {
             /* Wasn't already added so get rid of it */
+            FREE( p_stream->p_oggds_header );
             FREE( p_stream );
             p_sys->i_add_streams--;
         }
@@ -576,8 +599,8 @@ static block_t *OggStreamPageOut( sout_mux_t *p_mux,
 static block_t *OggCreateHeader( sout_mux_t *p_mux, mtime_t i_dts )
 {
     block_t *p_hdr = NULL;
-    block_t *p_og;
-    ogg_packet    op;
+    block_t *p_og = NULL;
+    ogg_packet op;
     int i;
 
     /* Write header for each stream. All b_o_s (beginning of stream) packets
@@ -645,11 +668,11 @@ static block_t *OggCreateHeader( sout_mux_t *p_mux, mtime_t i_dts )
             ogg_stream_packetin( &p_stream->os, &op );
             p_og = OggStreamFlush( p_mux, &p_stream->os, 0 );
         }
-        else
+        else if( p_stream->p_oggds_header )
         {
             /* ds header */
-            op.packet = (uint8_t*)&p_stream->oggds_header;
-            op.bytes  = sizeof( oggds_header_t );
+            op.packet = (uint8_t*)p_stream->p_oggds_header;
+            op.bytes  = p_stream->p_oggds_header->i_size + 1;
             op.b_o_s  = 1;
             op.e_o_s  = 0;
             op.granulepos = 0;
@@ -861,6 +884,7 @@ static int Mux( sout_mux_t *p_mux )
             /* Remove deleted logical streams */
             for( i = 0; i < p_sys->i_del_streams; i++ )
             {
+                FREE( p_sys->pp_del_streams[i]->p_oggds_header );
                 FREE( p_sys->pp_del_streams[i] );
             }
             FREE( p_sys->pp_del_streams );
@@ -922,11 +946,12 @@ static int Mux( sout_mux_t *p_mux )
                     ( i_dts - p_sys->i_start_dts + p_data->i_length ) *
                     (mtime_t)p_input->p_fmt->audio.i_rate / I64C(1000000);
             }
-            else
+            else if( p_stream->p_oggds_header )
             {
                 /* number of sample from begining */
                 op.granulepos = ( i_dts - p_sys->i_start_dts ) *
-                    p_stream->oggds_header.i_samples_per_unit / I64C(1000000);
+                    p_stream->p_oggds_header->i_samples_per_unit /
+                    I64C(1000000);
             }
         }
         else if( p_stream->i_cat == VIDEO_ES )
@@ -939,9 +964,9 @@ static int Mux( sout_mux_t *p_mux )
                     p_input->p_fmt->video.i_frame_rate_base /
                     I64C(1000000) ) << p_stream->i_keyframe_granule_shift;
             }
-            else
+            else if( p_stream->p_oggds_header )
                 op.granulepos = ( i_dts - p_sys->i_start_dts ) * I64C(10) /
-                    p_stream->oggds_header.i_time_unit;
+                    p_stream->p_oggds_header->i_time_unit;
         }
         else if( p_stream->i_cat == SPU_ES )
         {