* modules/codec/libmpeg2.c: fixed aspect ratio when reading DVDs.
authorGildas Bazin <gbazin@videolan.org>
Tue, 25 Mar 2003 23:06:49 +0000 (23:06 +0000)
committerGildas Bazin <gbazin@videolan.org>
Tue, 25 Mar 2003 23:06:49 +0000 (23:06 +0000)
modules/codec/libmpeg2.c

index 40bbbc2..61d565f 100755 (executable)
@@ -2,7 +2,7 @@
  * libmpeg2.c: mpeg2 video decoder module making use of libmpeg2.\r
  *****************************************************************************\r
  * Copyright (C) 1999-2001 VideoLAN\r
- * $Id: libmpeg2.c,v 1.3 2003/03/20 21:45:01 gbazin Exp $\r
+ * $Id: libmpeg2.c,v 1.4 2003/03/25 23:06:49 gbazin Exp $\r
  *\r
  * Authors: Gildas Bazin <gbazin@netcourrier.com>\r
  *\r
 \r
 #include <mpeg2dec/mpeg2.h>\r
 \r
+/* Aspect ratio (ISO/IEC 13818-2 section 6.3.3, table 6-3) */\r
+#define AR_SQUARE_PICTURE       1                           /* square pixels */\r
+#define AR_3_4_PICTURE          2                        /* 3:4 picture (TV) */\r
+#define AR_16_9_PICTURE         3              /* 16:9 picture (wide screen) */\r
+#define AR_221_1_PICTURE        4                  /* 2.21:1 picture (movie) */\r
+\r
 /*****************************************************************************\r
  * dec_thread_t : libmpeg2 decoder thread descriptor\r
  *****************************************************************************/\r
@@ -53,6 +59,7 @@ typedef struct dec_thread_t
     mtime_t          i_pts;\r
     mtime_t          i_previous_pts;\r
     mtime_t          i_current_pts;\r
+    mtime_t          i_period_remainder;\r
 \r
     /*\r
      * Output properties\r
@@ -122,6 +129,7 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
     p_dec->i_pts      = mdate() + DEFAULT_PTS_DELAY;\r
     p_dec->i_current_pts  = 0;\r
     p_dec->i_previous_pts = 0;\r
+    p_dec->i_period_remainder = 0;\r
 \r
     /* Initialize decoder */\r
     p_dec->p_mpeg2dec = mpeg2_init();\r
@@ -175,10 +183,39 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
 \r
         case STATE_SEQUENCE:\r
             /* Initialize video output */\r
-            i_aspect = ((uint64_t)p_dec->p_info->sequence->width) *\r
-                p_dec->p_info->sequence->pixel_width * VOUT_ASPECT_FACTOR /\r
-                p_dec->p_info->sequence->height /\r
-                p_dec->p_info->sequence->pixel_height;\r
+\r
+            /* Check whether the input gives a particular aspect ratio */\r
+            if( p_dec->p_fifo->p_demux_data\r
+                && ( *(int*)(p_dec->p_fifo->p_demux_data) & 0x7 ) )\r
+            {\r
+                i_aspect = *(int*)(p_dec->p_fifo->p_demux_data);\r
+                switch( i_aspect )\r
+                {\r
+                case AR_3_4_PICTURE:\r
+                    i_aspect = VOUT_ASPECT_FACTOR * 4 / 3;\r
+                    break;\r
+                case AR_16_9_PICTURE:\r
+                    i_aspect = VOUT_ASPECT_FACTOR * 16 / 9;\r
+                    break;\r
+                case AR_221_1_PICTURE:\r
+                    i_aspect = VOUT_ASPECT_FACTOR * 221 / 100;\r
+                    break;\r
+                case AR_SQUARE_PICTURE:\r
+                default:\r
+                    i_aspect = VOUT_ASPECT_FACTOR *\r
+                                   p_dec->p_info->sequence->width /\r
+                                   p_dec->p_info->sequence->height;\r
+                    break;\r
+                }\r
+            }\r
+            else\r
+            {\r
+                /* Use the value provided in the MPEG sequence header */\r
+                i_aspect = ((uint64_t)p_dec->p_info->sequence->width) *\r
+                    p_dec->p_info->sequence->pixel_width * VOUT_ASPECT_FACTOR /\r
+                    p_dec->p_info->sequence->height /\r
+                    p_dec->p_info->sequence->pixel_height;\r
+            }\r
 \r
             i_chroma = VLC_FOURCC('Y','V','1','2');\r
 \r
@@ -232,7 +269,13 @@ static int RunDecoder( decoder_fifo_t *p_fifo )
                 }\r
                 else\r
                 {\r
-                    p_dec->i_pts += (p_dec->p_info->sequence->frame_period/27);\r
+                    p_dec->i_pts += ( (p_dec->p_info->sequence->frame_period +\r
+                                       p_dec->i_period_remainder) / 27 );\r
+                    p_dec->i_period_remainder =\r
+                        p_dec->p_info->sequence->frame_period +\r
+                        p_dec->i_period_remainder -\r
+                        ( p_dec->p_info->sequence->frame_period +\r
+                          p_dec->i_period_remainder ) / 27 * 27;\r
                 }\r
                 vout_DatePicture( p_dec->p_vout, p_pic, p_dec->i_pts );\r
 \r