[vlc-devel] commit: Fixed VC1 muxing in ASF. (Laurent Aimar )

git version control git at videolan.org
Thu Apr 30 22:19:23 CEST 2009


vlc | branch: master | Laurent Aimar <fenrir at videolan.org> | Thu Apr 30 20:42:35 2009 +0200| [59a904c1e2e2d5498c3fd7b07b7f5a84082c2bd4] | committer: Laurent Aimar 

Fixed VC1 muxing in ASF.

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=59a904c1e2e2d5498c3fd7b07b7f5a84082c2bd4
---

 modules/mux/asf.c |  135 +++++++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 111 insertions(+), 24 deletions(-)

diff --git a/modules/mux/asf.c b/modules/mux/asf.c
index 7f252fe..6c60bcc 100644
--- a/modules/mux/asf.c
+++ b/modules/mux/asf.c
@@ -121,6 +121,7 @@ typedef struct
 
     int          i_extra;
     uint8_t      *p_extra;
+    bool         b_extended;
 
     es_format_t  fmt;
 
@@ -361,6 +362,7 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
     tk->i_cat = p_input->p_fmt->i_cat;
     tk->i_sequence = 0;
     tk->b_audio_correction = 0;
+    tk->b_extended = false;
 
     switch( tk->i_cat )
     {
@@ -507,23 +509,10 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
         }
         case VIDEO_ES:
         {
-            tk->i_extra = 11 + sizeof( BITMAPINFOHEADER ) +
-                          p_input->p_fmt->i_extra;
-            tk->p_extra = malloc( tk->i_extra );
-            if( !tk->p_extra )
-                return VLC_ENOMEM;
-            bo_init( &bo, tk->p_extra, tk->i_extra );
-            bo_addle_u32( &bo, p_input->p_fmt->video.i_width );
-            bo_addle_u32( &bo, p_input->p_fmt->video.i_height );
-            bo_add_u8   ( &bo, 0x02 );  /* flags */
-            bo_addle_u16( &bo, sizeof( BITMAPINFOHEADER ) +
-                               p_input->p_fmt->i_extra );
-            bo_addle_u32( &bo, sizeof( BITMAPINFOHEADER ) +
-                               p_input->p_fmt->i_extra );
-            bo_addle_u32( &bo, p_input->p_fmt->video.i_width );
-            bo_addle_u32( &bo, p_input->p_fmt->video.i_height );
-            bo_addle_u16( &bo, 1 );
-            bo_addle_u16( &bo, 24 );
+            const es_format_t *p_fmt = p_input->p_fmt;
+            uint8_t *p_codec_extra = NULL;
+            int     i_codec_extra = 0;
+
             if( p_input->p_fmt->i_codec == VLC_FOURCC('m','p','4','v') )
             {
                 tk->psz_name = "MPEG-4 Video";
@@ -559,6 +548,23 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
                 tk->psz_name = "Windows Media Video 9";
                 tk->i_fourcc = VLC_FOURCC( 'W', 'M', 'V', '3' );
             }
+            else if( p_input->p_fmt->i_codec == VLC_FOURCC('W','V','C','1') )
+            {
+                tk->psz_name = "Windows Media Video 9 Advanced Profile";
+                tk->i_fourcc = VLC_FOURCC( 'W', 'V', 'C', '1' );
+                tk->b_extended = true;
+
+                if( p_fmt->i_extra > 0 )
+                {
+                    p_codec_extra = malloc( 1 + p_fmt->i_extra );
+                    if( p_codec_extra )
+                    {
+                        i_codec_extra = 1 + p_fmt->i_extra;
+                        p_codec_extra[0] = 0x01;
+                        memcpy( &p_codec_extra[1], p_fmt->p_extra, p_fmt->i_extra );
+                    }
+                }
+            }
             else if( p_input->p_fmt->i_codec == VLC_FOURCC('h','2','6','4') )
             {
                 tk->psz_name = "H.264/MPEG-4 AVC";
@@ -569,17 +575,38 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
                 tk->psz_name = _("Unknown Video");
                 tk->i_fourcc = p_input->p_fmt->i_codec;
             }
+            if( !i_codec_extra && p_fmt->i_extra > 0 )
+            {
+                p_codec_extra = malloc( p_fmt->i_extra );
+                if( p_codec_extra )
+                {
+                    i_codec_extra = p_fmt->i_extra;
+                    memcpy( p_codec_extra, p_fmt->p_extra, p_fmt->i_extra );
+                }
+            }
+
+            tk->i_extra = 11 + sizeof( BITMAPINFOHEADER ) + i_codec_extra;
+            tk->p_extra = malloc( tk->i_extra );
+            if( !tk->p_extra )
+                return VLC_ENOMEM;
+            bo_init( &bo, tk->p_extra, tk->i_extra );
+            bo_addle_u32( &bo, p_input->p_fmt->video.i_width );
+            bo_addle_u32( &bo, p_input->p_fmt->video.i_height );
+            bo_add_u8   ( &bo, 0x02 );  /* flags */
+            bo_addle_u16( &bo, sizeof( BITMAPINFOHEADER ) + i_codec_extra );
+            bo_addle_u32( &bo, sizeof( BITMAPINFOHEADER ) + i_codec_extra );
+            bo_addle_u32( &bo, p_input->p_fmt->video.i_width );
+            bo_addle_u32( &bo, p_input->p_fmt->video.i_height );
+            bo_addle_u16( &bo, 1 );
+            bo_addle_u16( &bo, 24 );
             bo_add_mem( &bo, (uint8_t*)&tk->i_fourcc, 4 );
             bo_addle_u32( &bo, 0 );
             bo_addle_u32( &bo, 0 );
             bo_addle_u32( &bo, 0 );
             bo_addle_u32( &bo, 0 );
             bo_addle_u32( &bo, 0 );
-            if( p_input->p_fmt->i_extra > 0 )
-            {
-                bo_add_mem  ( &bo, p_input->p_fmt->p_extra,
-                              p_input->p_fmt->i_extra );
-            }
+            if( i_codec_extra > 0 )
+                bo_add_mem( &bo, p_codec_extra, i_codec_extra );
 
             if( p_input->p_fmt->i_bitrate > 50000 )
             {
@@ -589,7 +616,7 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
             {
                 p_sys->i_bitrate += 512000;
             }
-            if (p_sys->i_bitrate_override)
+            if( p_sys->i_bitrate_override )
                 p_sys->i_bitrate = p_sys->i_bitrate_override;
             break;
         }
@@ -680,6 +707,24 @@ static int Mux( sout_mux_t *p_mux )
 
         data = block_FifoGet( p_input->p_fifo );
 
+        /* Convert VC1 to ASF special format */
+        if( tk->i_fourcc == VLC_FOURCC( 'W', 'V', 'C', '1' ) )
+        {
+            while( data->i_buffer >= 4 &&
+                   ( data->p_buffer[0] != 0x00 || data->p_buffer[1] != 0x00 ||
+                     data->p_buffer[2] != 0x01 ||
+                     ( data->p_buffer[3] != 0x0D && data->p_buffer[3] != 0x0C ) ) )
+            {
+                data->i_buffer--;
+                data->p_buffer++;
+            }
+            if( data->i_buffer >= 4 )
+            {
+                data->i_buffer -= 4;
+                data->p_buffer += 4;
+            }
+        }
+
         if( ( pk = asf_packet_create( p_mux, tk, data ) ) )
         {
             sout_AccessOutWrite( p_mux->p_access, pk );
@@ -842,6 +887,8 @@ static const guid_t asf_object_index_guid =
 {0x33000890, 0xE5B1, 0x11CF, {0x89, 0xF4, 0x00, 0xA0, 0xC9, 0x03, 0x49, 0xCB}};
 static const guid_t asf_object_metadata_guid =
 {0xC5F8CBEA, 0x5BAF, 0x4877, {0x84, 0x67, 0xAA, 0x8C, 0x44, 0xFA, 0x4C, 0xCA}};
+static const guid_t asf_object_extended_stream_properties_guid =
+{0x14E6A5CB, 0xC672, 0x4332, {0x83, 0x99, 0xA9, 0x69, 0x52, 0x06, 0x5B, 0x5A}};
 
 /****************************************************************************
  * Misc
@@ -899,6 +946,8 @@ static block_t *asf_header_create( sout_mux_t *p_mux, bool b_broadcast )
                              strlen( p_sys->psz_rating ) + 1 );
     }
 
+    i_header_ext_size = 46;
+
     /* size of the metadata object */
     for( i = 0; i < p_sys->i_track; i++ )
     {
@@ -908,9 +957,13 @@ static block_t *asf_header_create( sout_mux_t *p_mux, bool b_broadcast )
             i_cm_size = 26 + 2 * (16 + 2 * sizeof("AspectRatio?"));
             break;
         }
+        if( p_track->b_extended )
+            i_header_ext_size += 88;
+
     }
 
-    i_header_ext_size = i_cm_size ? i_cm_size + 46 : 46;
+    i_header_ext_size += i_cm_size;
+
     i_size += i_ci_size + i_cd_size + i_header_ext_size ;
 
     if( p_sys->b_asf_http )
@@ -958,6 +1011,40 @@ static block_t *asf_header_create( sout_mux_t *p_mux, bool b_broadcast )
     bo_addle_u16( &bo, 6 );
     bo_addle_u32( &bo, i_header_ext_size - 46 );
 
+    /* extended stream properties */
+    for( i = 0; i < p_sys->i_track; i++ )
+    {
+        const asf_track_t *p_track = &p_sys->track[i];
+        const es_format_t *p_fmt = &p_track->fmt;
+
+        if( !p_track->b_extended )
+            continue;
+
+        uint64_t i_avg_duration = 0;
+        if( p_fmt->i_cat == VIDEO_ES &&
+            p_fmt->video.i_frame_rate > 0 && p_fmt->video.i_frame_rate_base > 0 )
+            i_avg_duration = ( INT64_C(10000000) * p_fmt->video.i_frame_rate_base +
+                               p_fmt->video.i_frame_rate/2 ) / p_fmt->video.i_frame_rate;
+
+        bo_add_guid ( &bo, &asf_object_extended_stream_properties_guid );
+        bo_addle_u64( &bo, 88 );
+        bo_addle_u64( &bo, 0 );
+        bo_addle_u64( &bo, 0 );
+        bo_addle_u32( &bo, p_fmt->i_bitrate );  /* Bitrate */
+        bo_addle_u32( &bo, 0 );                 /* Buffer size */
+        bo_addle_u32( &bo, 0 );                 /* Initial buffer fullness */
+        bo_addle_u32( &bo, p_fmt->i_bitrate );  /* Alternate Bitrate */
+        bo_addle_u32( &bo, 0 );                 /* Alternate Buffer size */
+        bo_addle_u32( &bo, 0 );                 /* Alternate Initial buffer fullness */
+        bo_addle_u32( &bo, 0 );                 /* Maximum object size (0 = unkown) */
+        bo_addle_u32( &bo, 0x02 );              /* Flags (seekable) */
+        bo_addle_u16( &bo, i+1 ); /* Stream number */
+        bo_addle_u16( &bo, 0 ); /* Stream language index */
+        bo_addle_u64( &bo, i_avg_duration );    /* Average time per frame */
+        bo_addle_u16( &bo, 0 ); /* Stream name count */
+        bo_addle_u16( &bo, 0 ); /* Payload extension system count */
+    }
+
     /* metadata object (part of header extension) */
     if( i_cm_size )
     {




More information about the vlc-devel mailing list