* vpar_headers.c : headers parsing
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
- * $Id: vpar_headers.c,v 1.66 2001/01/05 18:46:45 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.h"
#include "video_output.h"
+#include "video_decoder.h"
+#include "vdec_motion.h"
#include "../video_decoder/vdec_idct.h"
-#include "../video_decoder/video_decoder.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
*/
/*****************************************************************************
* pi_default_intra_quant : default quantization matrix
*****************************************************************************/
-#ifndef VDEC_DFT
-int pi_default_intra_quant[] =
+u8 pi_default_intra_quant[] =
{
8, 16, 19, 22, 26, 27, 29, 34,
16, 16, 22, 24, 27, 29, 34, 37,
26, 27, 29, 34, 38, 46, 56, 69,
27, 29, 35, 38, 46, 56, 69, 83
};
-#else
-int pi_default_intra_quant[] =
-{
- 2048, 5681, 6355, 6623, 6656, 5431, 4018, 2401,
- 5681, 7880, 10207, 10021, 9587, 8091, 6534, 3625,
- 6355, 10207, 11363, 10619, 9700, 8935, 6155, 3507,
- 6623, 9186, 10226, 9557, 8730, 8041, 6028, 3322,
- 5632, 9232, 9031, 8730, 8192, 7040, 5542, 3390,
- 5230, 7533, 7621, 7568, 7040, 6321, 5225, 3219,
- 3602, 5189, 5250, 5539, 5265, 5007, 4199, 2638,
- 1907, 2841, 3230, 3156, 3249, 3108, 2638, 1617
-};
-#endif
/*****************************************************************************
* pi_default_nonintra_quant : default quantization matrix
*****************************************************************************/
-#ifndef VDEC_DFT
-int pi_default_nonintra_quant[] =
+u8 pi_default_nonintra_quant[] =
{
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16
};
-#else
-int pi_default_nonintra_quanit[] =
-{
- 4096, 5680, 5344, 4816, 4096, 3216, 2224, 1136,
- 5680, 7888, 7424, 6688, 5680, 4464, 3072, 1568,
- 5344, 7424, 6992, 6288, 5344, 4208, 2896, 1472,
- 4816, 6688, 6288, 5664, 4816, 3792, 2608, 1328,
- 4096, 5680, 5344, 4816, 4096, 3216, 2224, 1136,
- 3216, 4464, 4208, 3792, 3216, 2528, 1744, 880,
- 2224, 3072, 2896, 2608, 2224, 1744, 1200, 608,
- 1136, 1568, 1472, 1328, 1136, 880, 608, 304
-};
-#endif
/*****************************************************************************
* pi_scan : zig-zag and alternate scan patterns
/*****************************************************************************
* LoadMatrix : Load a quantization matrix
*****************************************************************************/
-static __inline__ void LoadMatrix( vpar_thread_t * p_vpar, quant_matrix_t * p_matrix )
+static __inline__ void LoadMatrix( vpar_thread_t * p_vpar,
+ quant_matrix_t * p_matrix )
{
int i_dummy;
if( !p_matrix->b_allocated )
{
/* Allocate a piece of memory to load the matrix. */
- if( (p_matrix->pi_matrix = (int *)malloc( 64*sizeof(int) )) == NULL )
+ if( (p_matrix->pi_matrix = (u8 *)malloc( 64*sizeof(u8) )) == NULL )
{
intf_ErrMsg( "vpar error: allocation error in LoadMatrix()" );
p_vpar->p_fifo->b_error = 1;
for( i_dummy = 0; i_dummy < 64; i_dummy++ )
{
- p_matrix->pi_matrix[pi_scan[SCAN_ZIGZAG][i_dummy]]
+ p_matrix->pi_matrix[p_vpar->ppi_scan[SCAN_ZIGZAG][i_dummy]]
= GetBits( &p_vpar->bit_stream, 8 );
}
/*****************************************************************************
* LinkMatrix : Link a quantization matrix to another
*****************************************************************************/
-static __inline__ void LinkMatrix( quant_matrix_t * p_matrix, int * pi_array )
+static __inline__ void LinkMatrix( quant_matrix_t * p_matrix, u8 * pi_array )
{
if( p_matrix->b_allocated )
{
break;
default:
+ break;
}
}
else
{
/* Use default matrix. */
- LinkMatrix( &p_vpar->sequence.intra_quant, pi_default_intra_quant );
+ LinkMatrix( &p_vpar->sequence.intra_quant,
+ 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 );
}
else
{
/* Use default matrix. */
- LinkMatrix( &p_vpar->sequence.nonintra_quant, pi_default_nonintra_quant );
+ LinkMatrix( &p_vpar->sequence.nonintra_quant,
+ p_vpar->pi_default_nonintra_quant );
}
/* Unless later overwritten by a matrix extension, we have the same
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 );
/* 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 );
+ }
}
/*****************************************************************************
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 */
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 ) )
/* 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_progressive = 1;
}
#ifdef STATS
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 ? */
}
else
{
+ int i_repeat_field;
+
+ /* Compute the number of times the frame will be emitted by the
+ * 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) * 2;
+ }
+ 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 )
{
{
/* 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 )
<< ( 1 - p_vpar->picture.b_frame_structure ));
P_picture->i_deccount = p_vpar->sequence.i_mb_size;
- vlc_mutex_init( &p_vpar->picture.p_picture->lock_deccount );
#ifdef VDEC_SMP
memset( p_vpar->picture.pp_mb, 0, MAX_MB*sizeof(macroblock_t *) );
#endif
#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 )
{
/* 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 )
{
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++ )
{
}
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++ )
CopyrightExtension( p_vpar );
break;
default:
+ break;
}
break;
{
/* Use the default matrix. */
LinkMatrix( &p_vpar->sequence.intra_quant,
- pi_default_intra_quant );
+ p_vpar->pi_default_intra_quant );
}
if( GetBits( &p_vpar->bit_stream, 1 ) )
{
{
/* Use the default matrix. */
LinkMatrix( &p_vpar->sequence.nonintra_quant,
- pi_default_nonintra_quant );
+ p_vpar->pi_default_nonintra_quant );
}
if( GetBits( &p_vpar->bit_stream, 1 ) )
{