]> git.sesse.net Git - vlc/blobdiff - src/video_parser/vpar_headers.c
* Mandatory step for video output IV and the audio output quality
[vlc] / src / video_parser / vpar_headers.c
index 47e03ed58e9d1dabca8bf5bf257cfb4302337ffb..779cfa9eaaf48b13be02ffd6c5012345900585be 100644 (file)
@@ -2,7 +2,7 @@
  * vpar_headers.c : headers parsing
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: vpar_headers.c,v 1.73 2001/01/17 18:17:31 massiot Exp $
+ * $Id: vpar_headers.c,v 1.83 2001/05/01 04:18:18 sam Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *          Stéphane Borel <stef@via.ecp.fr>
 #include "defs.h"
 
 #include <stdlib.h>                                                /* free() */
+#include <string.h>                                    /* memcpy(), memset() */
 
 #include "config.h"
 #include "common.h"
 #include "threads.h"
 #include "mtime.h"
-#include "plugins.h"
 
 #include "intf_msg.h"
 
 #include "video_output.h"
 
 #include "video_decoder.h"
+#include "vdec_motion.h"
 #include "../video_decoder/vdec_idct.h"
-#include "../video_decoder/vdec_motion.h"
 
-#include "../video_decoder/vpar_blocks.h"
+#include "vpar_blocks.h"
 #include "../video_decoder/vpar_headers.h"
 #include "../video_decoder/vpar_synchro.h"
 #include "../video_decoder/video_parser.h"
 #include "../video_decoder/video_fifo.h"
 
+#include "main.h" /* XXX REMOVE THIS */
+
 /*
  * Local prototypes
  */
@@ -283,6 +285,7 @@ int vpar_ParseHeader( vpar_thread_t * p_vpar )
             break;
 
         default:
+            break;
         }
     }
 
@@ -343,7 +346,7 @@ static void SequenceHeader( vpar_thread_t * p_vpar )
                     p_vpar->pi_default_intra_quant );
     }
 
-    if( GetBits( &p_vpar->bit_stream, 1 ) ) /* load_non_intra_quantizer_matrix */
+    if( GetBits(&p_vpar->bit_stream, 1) ) /* load_non_intra_quantizer_matrix */
     {
         LoadMatrix( p_vpar, &p_vpar->sequence.nonintra_quant );
     }
@@ -380,7 +383,8 @@ static void SequenceHeader( vpar_thread_t * p_vpar )
         p_vpar->sequence.i_chroma_format = GetBits( &p_vpar->bit_stream, 2 );
         p_vpar->sequence.i_width |= GetBits( &p_vpar->bit_stream, 2 ) << 12;
         p_vpar->sequence.i_height |= GetBits( &p_vpar->bit_stream, 2 ) << 12;
-        /* bit_rate_extension, marker_bit, vbv_buffer_size_extension, low_delay */
+        /* bit_rate_extension, marker_bit, vbv_buffer_size_extension,
+         * low_delay */
         RemoveBits( &p_vpar->bit_stream, 22 );
         /* frame_rate_extension_n */
         i_dummy = GetBits( &p_vpar->bit_stream, 2 );
@@ -446,6 +450,13 @@ static void SequenceHeader( vpar_thread_t * p_vpar )
 
     /* Extension and User data */
     ExtensionAndUserData( p_vpar );
+
+    /* XXX: The vout request and fifo opening will eventually be here */
+    if( p_main->p_vout == NULL )
+    {
+       intf_Msg( "vpar: no vout present, spawning one" );
+        p_main->p_vout = p_vpar->p_vout = vout_CreateThread( NULL );
+    }
 }
 
 /*****************************************************************************
@@ -470,6 +481,28 @@ static void PictureHeader( vpar_thread_t * p_vpar )
     int                 i_mb;
 #endif
 
+    /* Recover in case of stream discontinuity. */
+    if( p_vpar->sequence.b_expect_discontinuity )
+    {
+        ReferenceUpdate( p_vpar, I_CODING_TYPE, NULL );
+        ReferenceUpdate( p_vpar, I_CODING_TYPE, NULL );
+        if( p_vpar->picture.p_picture != NULL )
+        {
+#ifdef VDEC_SMP
+            int     i_mb;
+
+            for( i_mb = 0; p_vpar->picture.pp_mb[i_mb] != NULL; i_mb++ )
+            {
+                vpar_DestroyMacroblock( &p_vpar->vfifo,
+                                        p_vpar->picture.pp_mb[i_mb] );
+            }
+#endif
+            vout_DestroyPicture( p_vpar->p_vout, p_vpar->picture.p_picture );
+        }
+        p_vpar->sequence.b_expect_discontinuity = 0;
+    }
+
+    /* Parse the picture header. */
     RemoveBits( &p_vpar->bit_stream, 10 ); /* temporal_reference */
     p_vpar->picture.i_coding_type = GetBits( &p_vpar->bit_stream, 3 );
     RemoveBits( &p_vpar->bit_stream, 16 ); /* vbv_delay */
@@ -540,8 +573,7 @@ static void PictureHeader( vpar_thread_t * p_vpar )
         p_vpar->picture.b_q_scale_type = 0;
         p_vpar->picture.b_intra_vlc_format = 0;
         p_vpar->picture.b_alternate_scan = 0; /* zigzag */
-        p_vpar->picture.b_repeat_first_field = 1; /* FIXME! this contradicts
-                                                   * ISO/IEC */
+        p_vpar->picture.b_repeat_first_field = 0;
         p_vpar->picture.b_progressive = 1;
     }
 
@@ -572,7 +604,7 @@ static void PictureHeader( vpar_thread_t * p_vpar )
 
         p_vpar->picture.i_current_structure = 0;
 
-        intf_DbgMsg("vpar debug: odd number of field picture.");
+        intf_WarnMsg( 2, "Odd number of field pictures." );
     }
 
     /* Do we have the reference pictures ? */
@@ -597,11 +629,11 @@ static void PictureHeader( vpar_thread_t * p_vpar )
         int     i_repeat_field;
 
         /* Compute the number of times the frame will be emitted by the
-         * decoder (number of periods). */
+         * decoder (number of half-periods). */
         if( p_vpar->sequence.b_progressive )
         {
-            i_repeat_field = 1 + p_vpar->picture.b_repeat_first_field
-                               + p_vpar->picture.b_top_field_first;
+            i_repeat_field = (1 + p_vpar->picture.b_repeat_first_field
+                                + p_vpar->picture.b_top_field_first) * 2;
         }
         else
         {
@@ -671,7 +703,7 @@ static void PictureHeader( vpar_thread_t * p_vpar )
     {
         /* This is a new frame. Get a structure from the video_output. */
         while( ( P_picture = vout_CreatePicture( p_vpar->p_vout,
-                                        99+p_vpar->sequence.i_chroma_format, /*XXX??*/
+                              /* XXX */ 99+p_vpar->sequence.i_chroma_format,
                                         p_vpar->sequence.i_width,
                                         p_vpar->sequence.i_height ) )
              == NULL )
@@ -705,7 +737,8 @@ static void PictureHeader( vpar_thread_t * p_vpar )
 
 #ifdef VDEC_SMP
         /* Link referenced pictures for the decoder
-         * They are unlinked in vpar_ReleaseMacroblock() & vpar_DestroyMacroblock() */
+         * They are unlinked in vpar_ReleaseMacroblock() &
+         * vpar_DestroyMacroblock() */
         if( p_vpar->picture.i_coding_type == P_CODING_TYPE ||
             p_vpar->picture.i_coding_type == B_CODING_TYPE )
         {
@@ -737,7 +770,68 @@ static void PictureHeader( vpar_thread_t * p_vpar )
     /* Extension and User data. */
     ExtensionAndUserData( p_vpar );
 
-    vpar_PictureData( p_vpar, i_mb_base );
+    /* This is an MP@ML decoder, please note that neither of the following
+     * assertions can be true :
+     *   p_vpar->sequence.i_chroma_format != CHROMA_420
+     *   p_vpar->sequence.i_height > 2800
+     *   p_vpar->sequence.i_scalable_mode == SC_DP
+     * Be cautious if you try to use the decoder for other profiles and
+     * levels.
+     */
+    if( p_vpar->sequence.b_mpeg2 )
+    {
+        static f_picture_data_t ppf_picture_data[4][4] =
+        {
+            {
+                NULL, NULL, NULL, NULL
+            },
+            {
+                /* TOP_FIELD */
+#if (VPAR_OPTIM_LEVEL > 1)
+                NULL, vpar_PictureData2IT, vpar_PictureData2PT,
+                vpar_PictureData2BT
+#else
+                NULL, vpar_PictureDataGENERIC, vpar_PictureDataGENERIC,
+                vpar_PictureDataGENERIC
+#endif
+            },
+            {
+                /* BOTTOM_FIELD */
+#if (VPAR_OPTIM_LEVEL > 1)
+                NULL, vpar_PictureData2IB, vpar_PictureData2PB,
+                vpar_PictureData2BB
+#else
+                NULL, vpar_PictureDataGENERIC, vpar_PictureDataGENERIC,
+                vpar_PictureDataGENERIC
+#endif
+            },
+            {
+                /* FRAME_PICTURE */
+#if (VPAR_OPTIM_LEVEL > 0)
+                NULL, vpar_PictureData2IF, vpar_PictureData2PF,
+                vpar_PictureData2BF
+#else
+                NULL, vpar_PictureDataGENERIC, vpar_PictureDataGENERIC,
+                vpar_PictureDataGENERIC
+#endif
+            }
+        };
+
+        ppf_picture_data[p_vpar->picture.i_structure]
+                        [p_vpar->picture.i_coding_type]( p_vpar, i_mb_base );
+    }
+    else
+    {
+#if (VPAR_OPTIM_LEVEL > 0)
+        static f_picture_data_t pf_picture_data[5] =
+        { NULL, vpar_PictureData1I, vpar_PictureData1P, vpar_PictureData1B,
+          vpar_PictureData1D };
+
+        pf_picture_data[p_vpar->picture.i_coding_type]( p_vpar, i_mb_base );
+#else
+        vpar_PictureDataGENERIC( p_vpar, i_mb_base );
+#endif
+    }
 
     if( p_vpar->p_fifo->b_die || p_vpar->p_fifo->b_error )
     {
@@ -829,6 +923,7 @@ static void ExtensionAndUserData( vpar_thread_t * p_vpar )
                 CopyrightExtension( p_vpar );
                 break;
             default:
+                break;
             }
             break;