]> git.sesse.net Git - vlc/blobdiff - modules/packetizer/mpeg4video.c
Work on getting slider seeking working better.
[vlc] / modules / packetizer / mpeg4video.c
index 27a04e409fd9f8e47174e881f3c69c5c5b656492..3488aafbda4b40512a0289c1496eb929c1dd4e49 100644 (file)
@@ -2,7 +2,7 @@
  * mpeg4video.c: mpeg 4 video packetizer
  *****************************************************************************
  * Copyright (C) 2001, 2002 VideoLAN
- * $Id: mpeg4video.c,v 1.17 2003/11/26 08:18:09 gbazin Exp $
+ * $Id$
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *          Eric Petit <titer@videolan.org>
@@ -41,7 +41,9 @@ static int  Open ( vlc_object_t * );
 static void Close( vlc_object_t * );
 
 vlc_module_begin();
-    set_description( _("MPEG4 Video packetizer") );
+    set_category( CAT_SOUT );
+    set_subcategory( SUBCAT_SOUT_PACKETIZER );
+    set_description( _("MPEG4 video packetizer") );
     set_capability( "packetizer", 50 );
     set_callbacks( Open, Close );
 vlc_module_end();
@@ -65,6 +67,9 @@ struct decoder_sys_t
     int         i_buffer;
     int         i_buffer_size;
     uint8_t     *p_buffer;
+    unsigned int i_flags;
+
+    vlc_bool_t  b_frame;
 };
 
 static int m4v_FindStartCode( uint8_t **pp_start, uint8_t *p_end );
@@ -111,8 +116,11 @@ static int Open( vlc_object_t *p_this )
         case VLC_FOURCC( 'X', 'v', 'i', 'D'):
         case VLC_FOURCC( 'x', 'v', 'i', 'd'):
         case VLC_FOURCC( 'D', 'X', '5', '0'):
+        case VLC_FOURCC( 'd', 'x', '5', '0'):
         case VLC_FOURCC( 0x04, 0,   0,   0):
         case VLC_FOURCC( '3', 'I', 'V', '2'):
+        case VLC_FOURCC( 'm', '4', 'c', 'c'):
+        case VLC_FOURCC( 'M', '4', 'C', 'C'):
             break;
 
         default:
@@ -126,13 +134,16 @@ static int Open( vlc_object_t *p_this )
         return VLC_EGENERIC;
     }
     p_sys->i_pts = 0;
+    p_sys->i_dts = 0;
     p_sys->b_vop = VLC_FALSE;
     p_sys->i_buffer = 0;
     p_sys->i_buffer_size = 0;
     p_sys->p_buffer = 0;
+    p_sys->i_flags = 0;
+    p_sys->b_frame = VLC_FALSE;
 
     /* Setup properties */
-    p_dec->fmt_out = p_dec->fmt_in;
+    es_format_Copy( &p_dec->fmt_out, &p_dec->fmt_in );
     p_dec->fmt_out.i_codec = VLC_FOURCC( 'm', 'p', '4', 'v' );
 
     if( p_dec->fmt_in.i_extra )
@@ -223,7 +234,8 @@ static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
         {
             /* Copy the complete VOL */
             p_dec->fmt_out.i_extra = p_start - p_vol;
-            p_dec->fmt_out.p_extra = malloc( p_dec->fmt_out.i_extra );
+            p_dec->fmt_out.p_extra =
+                realloc( p_dec->fmt_out.p_extra, p_dec->fmt_out.i_extra );
             memcpy( p_dec->fmt_out.p_extra, p_vol, p_dec->fmt_out.i_extra );
             m4v_VOLParse( &p_dec->fmt_out,
                           p_dec->fmt_out.p_extra, p_dec->fmt_out.i_extra );
@@ -246,6 +258,8 @@ static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
             p_sys->i_buffer -= i_out;
             p_start -= i_out;
 
+            p_out->i_flags = p_sys->i_flags;
+
             /* FIXME do proper dts/pts */
             p_out->i_pts = p_sys->i_pts;
             p_out->i_dts = p_sys->i_dts;
@@ -281,8 +295,46 @@ static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
         else if( p_start[3] == 0xb6 )
         {
             p_sys->b_vop = VLC_TRUE;
-            p_sys->i_pts = p_block->i_pts;
-            p_sys->i_dts = p_block->i_dts;
+            switch( p_start[4] >> 6 )
+            {
+                case 0:
+                    p_sys->i_flags = BLOCK_FLAG_TYPE_I;
+                    break;
+                case 1:
+                    p_sys->i_flags = BLOCK_FLAG_TYPE_P;
+                    break;
+                case 2:
+                    p_sys->i_flags = BLOCK_FLAG_TYPE_B;
+                    p_sys->b_frame = VLC_TRUE;
+                    break;
+                case 3: /* gni ? */
+                    p_sys->i_flags = BLOCK_FLAG_TYPE_PB;
+                    break;
+            }
+
+            /* The pts information is not available in all the containers.
+             * FIXME: calculate the pts correctly */
+            if( p_block->i_pts > 0 )
+            {
+                p_sys->i_pts = p_block->i_pts;
+            }
+            else if( (p_sys->i_flags&BLOCK_FLAG_TYPE_B) || !p_sys->b_frame )
+            {
+                p_sys->i_pts = p_block->i_dts;
+            }
+            else
+            {
+                p_sys->i_pts = 0;
+            }
+            if( p_block->i_dts > 0 )
+            {
+                p_sys->i_dts = p_block->i_dts;
+            }
+            else if( p_sys->i_dts > 0 )
+            {
+                /* XXX KLUDGE immonde, else transcode won't work */
+                p_sys->i_dts += 1000;
+            }
         }
         p_start += 4; /* Next */
     }
@@ -295,7 +347,8 @@ static int m4v_FindStartCode( uint8_t **pp_start, uint8_t *p_end )
 {
     uint8_t *p = *pp_start;
 
-    for( p = *pp_start; p < p_end - 4; p++ )
+    /* We wait for 4+1 bytes */
+    for( p = *pp_start; p < p_end - 5; p++ )
     {
         if( p[0] == 0 && p[1] == 0 && p[2] == 1 )
         {
@@ -384,14 +437,19 @@ static int m4v_VOLParse( es_format_t *fmt, uint8_t *p_vol, int i_vol )
     i_ar = bs_read( &s, 4 );
     if( i_ar == 0xf )
     {
-        int i_ar_width = bs_read( &s, 8 );
-        int i_ar_height= bs_read( &s, 8 );
+        int i_ar_width, i_ar_height;
+
+        i_ar_width = bs_read( &s, 8 );
+        i_ar_height= bs_read( &s, 8 );
     }
     if( bs_read1( &s ) )
     {
+        int i_chroma_format;
+        int i_low_delay;
+
         /* vol control parameter */
-        int i_chroma_format = bs_read( &s, 2 );
-        int i_low_delay = bs_read1( &s );
+        i_chroma_format = bs_read( &s, 2 );
+        i_low_delay = bs_read1( &s );
 
         if( bs_read1( &s ) )
         {
@@ -442,6 +500,3 @@ static int m4v_VOLParse( es_format_t *fmt, uint8_t *p_vol, int i_vol )
     }
     return VLC_SUCCESS;
 }
-
-
-