/*****************************************************************************
* libmpeg2.c: mpeg2 video decoder module making use of libmpeg2.
*****************************************************************************
- * Copyright (C) 1999-2001 VideoLAN
+ * Copyright (C) 1999-2001 the VideoLAN team
* $Id$
*
* Authors: Gildas Bazin <gbazin@videolan.org>
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include <vlc/vlc.h>
-#include <vlc/vout.h>
-#include <vlc/decoder.h>
+#include <vlc_vout.h>
+#include <vlc_codec.h>
#include <mpeg2dec/mpeg2.h>
-#include "vout_synchro.h"
+#include <vlc_vout_synchro.h>
/* Aspect ratio (ISO/IEC 13818-2 section 6.3.3, table 6-3) */
#define AR_SQUARE_PICTURE 1 /* square pixels */
-#define AR_3_4_PICTURE 2 /* 3:4 picture (TV) */
+#define AR_4_3_PICTURE 2 /* 4:3 picture (TV) */
#define AR_16_9_PICTURE 3 /* 16:9 picture (wide screen) */
#define AR_221_1_PICTURE 4 /* 2.21:1 picture (movie) */
vlc_bool_t b_after_sequence_header; /* is it the next frame after
* the sequence header ? */
vlc_bool_t b_slice_i; /* intra-slice refresh stream */
+ vlc_bool_t b_second_field;
- vlc_bool_t b_preroll;
+ vlc_bool_t b_preroll;
/*
* Output properties
*/
vout_synchro_t *p_synchro;
int i_aspect;
+ int i_sar_num;
+ int i_sar_den;
mtime_t i_last_frame_pts;
};
p_dec->fmt_in.i_codec != VLC_FOURCC('P','I','M','1') &&
/* ATI Video */
p_dec->fmt_in.i_codec != VLC_FOURCC('V','C','R','2') &&
- p_dec->fmt_in.i_codec != VLC_FOURCC('m','p','g','2') )
+ p_dec->fmt_in.i_codec != VLC_FOURCC('m','p','2','v') &&
+ p_dec->fmt_in.i_codec != VLC_FOURCC('m','p','g','2') &&
+ p_dec->fmt_in.i_codec != VLC_FOURCC('h','d','v','2') )
{
return VLC_EGENERIC;
}
p_sys->p_picture_to_destroy = NULL;
p_sys->b_garbage_pic = 0;
p_sys->b_slice_i = 0;
+ p_sys->b_second_field = 0;
p_sys->b_skip = 0;
p_sys->b_preroll = VLC_FALSE;
#if defined( __i386__ ) || defined( __x86_64__ )
- if( p_dec->p_libvlc->i_cpu & CPU_CAPABILITY_MMX )
+ if( p_dec->p_libvlc_global->i_cpu & CPU_CAPABILITY_MMX )
{
i_accel |= MPEG2_ACCEL_X86_MMX;
}
- if( p_dec->p_libvlc->i_cpu & CPU_CAPABILITY_3DNOW )
+ if( p_dec->p_libvlc_global->i_cpu & CPU_CAPABILITY_3DNOW )
{
i_accel |= MPEG2_ACCEL_X86_3DNOW;
}
- if( p_dec->p_libvlc->i_cpu & CPU_CAPABILITY_MMXEXT )
+ if( p_dec->p_libvlc_global->i_cpu & CPU_CAPABILITY_MMXEXT )
{
i_accel |= MPEG2_ACCEL_X86_MMXEXT;
}
-#elif defined( __powerpc__ ) || defined( SYS_DARWIN )
- if( p_dec->p_libvlc->i_cpu & CPU_CAPABILITY_ALTIVEC )
+#elif defined( __powerpc__ ) || defined( __ppc__ ) || defined( __ppc64__ )
+ if( p_dec->p_libvlc_global->i_cpu & CPU_CAPABILITY_ALTIVEC )
{
i_accel |= MPEG2_ACCEL_PPC_ALTIVEC;
}
if( (p_pic = GetNewPicture( p_dec, buf )) == NULL )
break;
mpeg2_set_buf( p_sys->p_mpeg2dec, buf, p_pic );
+ mpeg2_stride( p_sys->p_mpeg2dec, p_pic->format.i_width );
}
p_sys->p_picture_to_destroy = p_pic;
}
mpeg2_set_buf( p_sys->p_mpeg2dec, buf, p_pic );
+ mpeg2_stride( p_sys->p_mpeg2dec, p_pic->format.i_width );
/* This picture will never go through display_picture. */
p_pic->date = 0;
break;
case STATE_PICTURE_2ND:
- vout_SynchroNewPicture( p_sys->p_synchro,
- p_sys->p_info->current_picture->flags & PIC_MASK_CODING_TYPE,
- p_sys->p_info->current_picture->nb_fields,
- 0, 0, p_sys->i_current_rate,
- p_sys->p_info->sequence->flags & SEQ_FLAG_LOW_DELAY );
-
- if( p_sys->b_skip )
- {
- vout_SynchroTrash( p_sys->p_synchro );
- }
- else
- {
- vout_SynchroDecode( p_sys->p_synchro );
- }
+ p_sys->b_second_field = 1;
break;
case STATE_PICTURE:
p_sys->i_current_dts : p_sys->i_previous_dts ) : 0;
#endif
+ /* If nb_fields == 1, it is a field picture, and it will be
+ * followed by another field picture for which we won't call
+ * vout_SynchroNewPicture() because this would have other
+ * problems, so we take it into account here.
+ * This kind of sucks, but I didn't think better. --Meuuh
+ */
vout_SynchroNewPicture( p_sys->p_synchro,
p_sys->p_info->current_picture->flags & PIC_MASK_CODING_TYPE,
+ p_sys->p_info->current_picture->nb_fields == 1 ? 2 :
p_sys->p_info->current_picture->nb_fields, i_pts, i_dts,
p_sys->i_current_rate,
p_sys->p_info->sequence->flags & SEQ_FLAG_LOW_DELAY );
}
mpeg2_set_buf( p_sys->p_mpeg2dec, buf, p_pic );
+ mpeg2_stride( p_sys->p_mpeg2dec, p_pic->format.i_width );
}
}
break;
if( (p_pic = GetNewPicture( p_dec, buf )) == NULL )
break;
mpeg2_set_buf( p_sys->p_mpeg2dec, buf, p_pic );
+ mpeg2_stride( p_sys->p_mpeg2dec, p_pic->format.i_width );
}
p_sys->p_picture_to_destroy = p_pic;
p_dec->fmt_out.video.i_visible_height =
p_sys->p_info->sequence->picture_height;
p_dec->fmt_out.video.i_aspect = p_sys->i_aspect;
+ p_dec->fmt_out.video.i_sar_num = p_sys->i_sar_num;
+ p_dec->fmt_out.video.i_sar_den = p_sys->i_sar_den;
if( p_sys->p_info->sequence->frame_period > 0 )
{
*****************************************************************************/
static void GetAR( decoder_t *p_dec )
{
- decoder_sys_t *p_sys = p_dec->p_sys;
+ decoder_sys_t *p_sys = p_dec->p_sys;
/* Check whether the input gave a particular aspect ratio */
if( p_dec->fmt_in.video.i_aspect )
if( p_sys->i_aspect <= AR_221_1_PICTURE )
switch( p_sys->i_aspect )
{
- case AR_3_4_PICTURE:
+ case AR_4_3_PICTURE:
p_sys->i_aspect = VOUT_ASPECT_FACTOR * 4 / 3;
+ p_sys->i_sar_num = p_sys->p_info->sequence->picture_height * 4;
+ p_sys->i_sar_den = p_sys->p_info->sequence->picture_width * 3;
break;
case AR_16_9_PICTURE:
p_sys->i_aspect = VOUT_ASPECT_FACTOR * 16 / 9;
+ p_sys->i_sar_num = p_sys->p_info->sequence->picture_height * 16;
+ p_sys->i_sar_den = p_sys->p_info->sequence->picture_width * 9;
break;
case AR_221_1_PICTURE:
p_sys->i_aspect = VOUT_ASPECT_FACTOR * 221 / 100;
+ p_sys->i_sar_num = p_sys->p_info->sequence->picture_height * 221;
+ p_sys->i_sar_den = p_sys->p_info->sequence->picture_width * 100;
break;
case AR_SQUARE_PICTURE:
p_sys->i_aspect = VOUT_ASPECT_FACTOR *
- p_sys->p_info->sequence->width /
- p_sys->p_info->sequence->height;
+ p_sys->p_info->sequence->picture_width /
+ p_sys->p_info->sequence->picture_height;
+ p_sys->i_sar_num = p_sys->i_sar_den = 1;
break;
}
}
if( p_sys->p_info->sequence->pixel_height > 0 )
{
p_sys->i_aspect =
- ((uint64_t)p_sys->p_info->sequence->display_width) *
+ ((uint64_t)p_sys->p_info->sequence->picture_width) *
p_sys->p_info->sequence->pixel_width *
VOUT_ASPECT_FACTOR /
- p_sys->p_info->sequence->display_height /
+ p_sys->p_info->sequence->picture_height /
p_sys->p_info->sequence->pixel_height;
+ p_sys->i_sar_num = p_sys->p_info->sequence->pixel_width;
+ p_sys->i_sar_den = p_sys->p_info->sequence->pixel_height;
}
else
{
* This shouldn't happen and if it does it is a bug
* in libmpeg2 (likely triggered by an invalid stream) */
p_sys->i_aspect = VOUT_ASPECT_FACTOR * 4 / 3;
+ p_sys->i_sar_num = p_sys->p_info->sequence->picture_height * 4;
+ p_sys->i_sar_den = p_sys->p_info->sequence->picture_width * 3;
}
}
- msg_Dbg( p_dec, "%dx%d, aspect %d, %u.%03u fps",
- p_sys->p_info->sequence->width,
- p_sys->p_info->sequence->height, p_sys->i_aspect,
+ msg_Dbg( p_dec, "%dx%d (display %d,%d), aspect %d, sar %i:%i, %u.%03u fps",
+ p_sys->p_info->sequence->picture_width,
+ p_sys->p_info->sequence->picture_height,
+ p_sys->p_info->sequence->display_width,
+ p_sys->p_info->sequence->display_height,
+ p_sys->i_aspect, p_sys->i_sar_num, p_sys->i_sar_den,
(uint32_t)((uint64_t)1001000000 * 27 /
p_sys->p_info->sequence->frame_period / 1001),
(uint32_t)((uint64_t)1001000000 * 27 /
p_sys->p_info->sequence->frame_period % 1001) );
}
-