]> git.sesse.net Git - vlc/commitdiff
* Finally fixed repeat_first_field and co. (pas encore tout compris...)
authorChristophe Massiot <massiot@videolan.org>
Mon, 15 Jan 2001 18:02:49 +0000 (18:02 +0000)
committerChristophe Massiot <massiot@videolan.org>
Mon, 15 Jan 2001 18:02:49 +0000 (18:02 +0000)
src/video_decoder/vpar_headers.h
src/video_decoder/vpar_synchro.h
src/video_parser/vpar_headers.c
src/video_parser/vpar_synchro.c

index 71057b3c59ce49217b06c9e4aed6c3a7bd737ad3..2b08a7eb7ca4686f88d5099242001778ba0bcb19 100644 (file)
@@ -2,7 +2,7 @@
  * vpar_headers.h : video parser : headers parsing
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: vpar_headers.h,v 1.2 2001/01/15 13:25:09 massiot Exp $
+ * $Id: vpar_headers.h,v 1.3 2001/01/15 18:02:48 massiot Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *          Stéphane Borel <stef@via.ecp.fr>
@@ -110,7 +110,7 @@ typedef struct picture_parsing_s
     int                 i_intra_dc_precision;
     boolean_t           b_frame_pred_frame_dct, b_q_scale_type;
     boolean_t           b_intra_vlc_format;
-    boolean_t           b_alternate_scan, b_progressive_frame;
+    boolean_t           b_alternate_scan, b_progressive;
     boolean_t           b_top_field_first, b_concealment_mv;
     boolean_t           b_repeat_first_field;
     /* Relative to the current field */
index f4d0580a451b5a9949d260620111294941f7b0df..d430cd524d912df989601dcce404fb0827db2961 100644 (file)
@@ -2,7 +2,7 @@
  * vpar_synchro.h : video parser blocks management
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: vpar_synchro.h,v 1.4 2000/12/29 12:49:29 massiot Exp $
+ * $Id: vpar_synchro.h,v 1.5 2001/01/15 18:02:49 massiot Exp $
  *
  * Author: Christophe Massiot <massiot@via.ecp.fr>
  *
@@ -64,6 +64,7 @@ typedef struct video_synchro_s
     unsigned int    i_eta_p, i_eta_b;
     boolean_t       b_dropped_last;            /* for special synchros below */
     mtime_t         backward_pts, current_pts;
+    mtime_t         next_period;        /* period to add to the next picture */
 
 #ifdef STATS
     unsigned int    i_trashed_pic, i_not_chosen_pic, i_pic;
index 0467fafb385a9f378cafc6c587f34bd35720bb28..db28bbe2ea0662a38b78ec7f29f805d16aafe234 100644 (file)
@@ -2,7 +2,7 @@
  * vpar_headers.c : headers parsing
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: vpar_headers.c,v 1.68 2001/01/13 12:57:21 sam Exp $
+ * $Id: vpar_headers.c,v 1.69 2001/01/15 18:02:49 massiot Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *          Stéphane Borel <stef@via.ecp.fr>
@@ -542,11 +542,9 @@ static void PictureHeader( vpar_thread_t * p_vpar )
         p_vpar->picture.b_intra_vlc_format = GetBits( &p_vpar->bit_stream, 1 );
         p_vpar->picture.b_alternate_scan = GetBits( &p_vpar->bit_stream, 1 );
         p_vpar->picture.b_repeat_first_field = GetBits( &p_vpar->bit_stream, 1 );
-        /* repeat_first_field (ISO/IEC 13818-2 6.3.10 is necessary to know
-         * the length of the picture_display_extension structure.
-         * chroma_420_type (obsolete) */
+        /* chroma_420_type (obsolete) */
         RemoveBits( &p_vpar->bit_stream, 1 );
-        p_vpar->picture.b_progressive_frame = GetBits( &p_vpar->bit_stream, 1 );
+        p_vpar->picture.b_progressive = GetBits( &p_vpar->bit_stream, 1 );
 
         /* composite_display_flag */
         if( GetBits( &p_vpar->bit_stream, 1 ) )
@@ -561,13 +559,14 @@ static void PictureHeader( vpar_thread_t * p_vpar )
         /* MPEG-1 compatibility flags */
         p_vpar->picture.i_intra_dc_precision = 0; /* 8 bits */
         i_structure = FRAME_STRUCTURE;
+        p_vpar->picture.b_top_field_first = 0;
         p_vpar->picture.b_frame_pred_frame_dct = 1;
         p_vpar->picture.b_concealment_mv = 0;
         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 = 0;
-        p_vpar->picture.b_progressive_frame = 1;
+        p_vpar->picture.b_repeat_first_field = 1;
+        p_vpar->picture.b_progressive = 1;
     }
 
 #ifdef STATS
@@ -619,9 +618,30 @@ static void PictureHeader( vpar_thread_t * p_vpar )
     }
     else
     {
+        int     i_repeat_field;
+
+        /* Compute the number of times the frame will be emitted by the
+         * decoder (number of 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;
+        }
+        else
+        {
+            if( p_vpar->picture.b_progressive )
+            {
+                i_repeat_field = 2 + p_vpar->picture.b_repeat_first_field;
+            }
+            else
+            {
+                i_repeat_field = 2;
+            }
+        }
+
         /* Warn synchro we have a new picture (updates pictures index). */
         vpar_SynchroNewPicture( p_vpar, p_vpar->picture.i_coding_type,
-                                p_vpar->picture.b_repeat_first_field );
+                                i_repeat_field );
 
         if( b_parsable )
         {
@@ -751,7 +771,6 @@ static void PictureHeader( vpar_thread_t * p_vpar )
     if( p_vpar->picture.b_error )
     {
         /* Trash picture. */
-//fprintf(stderr, "Image trashee\n");
 #ifdef VDEC_SMP
         for( i_mb = 1; p_vpar->picture.pp_mb[i_mb] != NULL; i_mb++ )
         {
@@ -778,7 +797,6 @@ static void PictureHeader( vpar_thread_t * p_vpar )
     }
     else if( p_vpar->picture.i_current_structure == FRAME_STRUCTURE )
     {
-//fprintf(stderr, "Image parsee (%d)\n", p_vpar->picture.i_coding_type);
         /* Frame completely parsed. */
 #ifdef VDEC_SMP
         for( i_mb = 1; p_vpar->picture.pp_mb[i_mb] != NULL; i_mb++ )
index 47dc95efe2e790ed6fcb1a73cd6550be4748ffbc..324f1cb414a3ff8e037a4fa05f511cc6b35fe23b 100644 (file)
@@ -2,7 +2,7 @@
  * vpar_synchro.c : frame dropping routines
  *****************************************************************************
  * Copyright (C) 1999, 2000 VideoLAN
- * $Id: vpar_synchro.c,v 1.72 2001/01/15 13:25:09 massiot Exp $
+ * $Id: vpar_synchro.c,v 1.73 2001/01/15 18:02:49 massiot Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *          Samuel Hocevar <sam@via.ecp.fr>
@@ -130,7 +130,6 @@ static int  SynchroType( void );
 
 /* Error margins */
 #define DELTA                   (int)(0.040*CLOCK_FREQ)
-#define PTS_THRESHOLD           (int)(0.030*CLOCK_FREQ)
 
 #define DEFAULT_NB_P            5
 #define DEFAULT_NB_B            1
@@ -151,7 +150,7 @@ void vpar_SynchroInit( vpar_thread_t * p_vpar )
     memset( p_vpar->synchro.pi_meaningful, 0, 4 * sizeof(unsigned int) );
     p_vpar->synchro.b_dropped_last = 0;
     p_vpar->synchro.current_pts = mdate() + DEFAULT_PTS_DELAY;
-    p_vpar->synchro.backward_pts = 0;
+    p_vpar->synchro.backward_pts = p_vpar->synchro.next_period = 0;
 #ifdef STATS
     p_vpar->synchro.i_trashed_pic = p_vpar->synchro.i_not_chosen_pic = 
         p_vpar->synchro.i_pic = 0;
@@ -419,7 +418,7 @@ mtime_t vpar_SynchroDate( vpar_thread_t * p_vpar )
  * vpar_SynchroNewPicture: Update stream structure and PTS
  *****************************************************************************/
 void vpar_SynchroNewPicture( vpar_thread_t * p_vpar, int i_coding_type,
-                             boolean_t b_repeat_field )
+                             int i_repeat_field )
 {
     mtime_t         period = 1000000 / (p_vpar->sequence.i_frame_rate) * 1001;
 
@@ -469,18 +468,14 @@ void vpar_SynchroNewPicture( vpar_thread_t * p_vpar, int i_coding_type,
         break;
     }
 
-    if( b_repeat_field )
-    {
-        /* MPEG-2 repeat_first_field */
-        /* FIXME : this is not exactly what we should do, repeat_first_field
-         * only regards the next picture */
-        p_vpar->synchro.current_pts += period + (period >> 1);
-    }
-    else
-    {
-        p_vpar->synchro.current_pts += period;
-    }
+    p_vpar->synchro.current_pts += p_vpar->synchro.next_period;
+
+    /* A video frame can be displayed 1, 2 or 3 times, according to
+     * repeat_first_field, top_field_first, progressive_sequence and
+     * progressive_frame. */
+    p_vpar->synchro.next_period = i_repeat_field * (period >> 1);
 
+#define PTS_THRESHOLD   (period >> 2)
     if( i_coding_type == B_CODING_TYPE )
     {
         if( p_vpar->sequence.next_pts )
@@ -551,6 +546,7 @@ void vpar_SynchroNewPicture( vpar_thread_t * p_vpar, int i_coding_type,
             p_vpar->sequence.next_pts = 0;
         }
     }
+#undef PTS_THRESHOLD
 
 #ifdef STATS
     p_vpar->synchro.i_pic++;